lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <5d787f17d58fb66c671a90d2cfc8f47eaaf730e8.1583347351.git.mkubecek@suse.cz>
Date:   Wed,  4 Mar 2020 21:26:41 +0100 (CET)
From:   Michal Kubecek <mkubecek@...e.cz>
To:     John Linville <linville@...driver.com>, netdev@...r.kernel.org
Cc:     Andrew Lunn <andrew@...n.ch>,
        Florian Fainelli <f.fainelli@...il.com>
Subject: [PATCH ethtool v2 25/25] netlink: use pretty printing for ethtool
 netlink messages

Introduce new debugging flag DEBUG_NL_PRETTY_MSG (0x10) which has two
effects:

  - show request messages embedded in extack error messages in human
    readable form; if failing attribute offset is provided, highlight the
    attribute
  - if DEBUG_NL_MSGS is also set, show structure of all outgoing and
    incoming ethtool netlink messages in addition to their summary

Signed-off-by: Michal Kubecek <mkubecek@...e.cz>
---
 internal.h       |  1 +
 netlink/nlsock.c | 71 +++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 56 insertions(+), 16 deletions(-)

diff --git a/internal.h b/internal.h
index a518bfa99380..edb07bddd073 100644
--- a/internal.h
+++ b/internal.h
@@ -122,6 +122,7 @@ enum {
 	DEBUG_NL_MSGS,		/* incoming/outgoing netlink messages */
 	DEBUG_NL_DUMP_SND,	/* dump outgoing netlink messages */
 	DEBUG_NL_DUMP_RCV,	/* dump incoming netlink messages */
+	DEBUG_NL_PRETTY_MSG,	/* pretty print of messages and errors */
 };
 
 static inline bool debug_on(unsigned long debug, unsigned int bit)
diff --git a/netlink/nlsock.c b/netlink/nlsock.c
index 4366c52ce390..22abb68b6646 100644
--- a/netlink/nlsock.c
+++ b/netlink/nlsock.c
@@ -10,6 +10,7 @@
 #include "../internal.h"
 #include "nlsock.h"
 #include "netlink.h"
+#include "prettymsg.h"
 
 #define NLSOCK_RECV_BUFFSIZE 65536
 
@@ -43,10 +44,12 @@ static void ctrl_msg_summary(const struct nlmsghdr *nlhdr)
 }
 
 static void genl_msg_summary(const struct nlmsghdr *nlhdr, int ethnl_fam,
-			     bool outgoing)
+			     bool outgoing, bool pretty)
 {
 	if (nlhdr->nlmsg_type == ethnl_fam) {
+		const struct pretty_nlmsg_desc *msg_desc;
 		const struct genlmsghdr *ghdr;
+		unsigned int n_desc;
 
 		printf(" ethool");
 		if (nlhdr->nlmsg_len < NLMSG_HDRLEN + GENL_HDRLEN) {
@@ -55,27 +58,46 @@ static void genl_msg_summary(const struct nlmsghdr *nlhdr, int ethnl_fam,
 		}
 		ghdr = mnl_nlmsg_get_payload(nlhdr);
 
-		printf(" cmd %u", ghdr->cmd);
+		msg_desc = outgoing ? ethnl_umsg_desc : ethnl_kmsg_desc;
+		n_desc = outgoing ? ethnl_umsg_n_desc : ethnl_kmsg_n_desc;
+		if (ghdr->cmd < n_desc && msg_desc[ghdr->cmd].name)
+			printf(" %s", msg_desc[ghdr->cmd].name);
+		else
+			printf(" cmd %u", ghdr->cmd);
 		fputc('\n', stdout);
 
+		if (pretty)
+			pretty_print_genlmsg(nlhdr, msg_desc, n_desc, 0);
 		return;
 	}
 
-	if (nlhdr->nlmsg_type == GENL_ID_CTRL)
+	if (nlhdr->nlmsg_type == GENL_ID_CTRL) {
 		printf(" genl-ctrl\n");
-	else
+		if (pretty)
+			pretty_print_genlmsg(nlhdr, genlctrl_msg_desc,
+					     genlctrl_msg_n_desc, 0);
+	} else {
 		fputc('\n', stdout);
+		if (pretty)
+			pretty_print_genlmsg(nlhdr, NULL, 0, 0);
+	}
 }
 
-static void rtnl_msg_summary(const struct nlmsghdr *nlhdr)
+static void rtnl_msg_summary(const struct nlmsghdr *nlhdr, bool pretty)
 {
 	unsigned int type = nlhdr->nlmsg_type;
 
-	printf(" type %u\n", type);
+	if (type < rtnl_msg_n_desc && rtnl_msg_desc[type].name)
+		printf(" %s\n", rtnl_msg_desc[type].name);
+	else
+		printf(" type %u\n", type);
+
+	if (pretty)
+		pretty_print_rtnlmsg(nlhdr, 0);
 }
 
 static void debug_msg_summary(const struct nlmsghdr *nlhdr, int ethnl_fam,
-			      int nl_fam, bool outgoing)
+			      int nl_fam, bool outgoing, bool pretty)
 {
 	printf("    msg length %u", nlhdr->nlmsg_len);
 
@@ -86,10 +108,10 @@ static void debug_msg_summary(const struct nlmsghdr *nlhdr, int ethnl_fam,
 
 	switch(nl_fam) {
 	case NETLINK_GENERIC:
-		genl_msg_summary(nlhdr, ethnl_fam, outgoing);
+		genl_msg_summary(nlhdr, ethnl_fam, outgoing, pretty);
 		break;
 	case NETLINK_ROUTE:
-		rtnl_msg_summary(nlhdr);
+		rtnl_msg_summary(nlhdr, pretty);
 		break;
 	default:
 		fputc('\n', stdout);
@@ -103,13 +125,14 @@ static void debug_msg(struct nl_socket *nlsk, const void *msg, unsigned int len,
 	const char *dirlabel = outgoing ? "sending" : "received";
 	uint32_t debug = nlsk->nlctx->ctx->debug;
 	const struct nlmsghdr *nlhdr = msg;
-	bool summary, dump;
+	bool summary, dump, pretty;
 	const char *nl_fam_label;
 	int left = len;
 
 	summary = debug_on(debug, DEBUG_NL_MSGS);
 	dump = debug_on(debug,
 			outgoing ? DEBUG_NL_DUMP_SND : DEBUG_NL_DUMP_RCV);
+	pretty = debug_on(debug, DEBUG_NL_PRETTY_MSG);
 	if (!summary && !dump)
 		return;
 	switch(nlsk->nl_fam) {
@@ -128,7 +151,7 @@ static void debug_msg(struct nl_socket *nlsk, const void *msg, unsigned int len,
 	while (nlhdr && left > 0 && mnl_nlmsg_ok(nlhdr, left)) {
 		if (summary)
 			debug_msg_summary(nlhdr, nlsk->nlctx->ethnl_fam,
-					  nlsk->nl_fam, outgoing);
+					  nlsk->nl_fam, outgoing, pretty);
 		if (dump)
 			mnl_nlmsg_fprintf(stdout, nlhdr, nlhdr->nlmsg_len,
 					  GENL_HDRLEN);
@@ -146,7 +169,7 @@ static void debug_msg(struct nl_socket *nlsk, const void *msg, unsigned int len,
  * Return: error code extracted from the message
  */
 static int nlsock_process_ack(struct nlmsghdr *nlhdr, ssize_t len,
-			      unsigned int suppress_nlerr)
+			      unsigned int suppress_nlerr, bool pretty)
 {
 	const struct nlattr *tb[NLMSGERR_ATTR_MAX + 1] = {};
 	DECLARE_ATTR_TB_INFO(tb);
@@ -174,12 +197,23 @@ static int nlsock_process_ack(struct nlmsghdr *nlhdr, ssize_t len,
 
 		fprintf(stderr, "netlink %s: %s",
 			nlerr->error ? "error" : "warning", msg);
-		if (tb[NLMSGERR_ATTR_OFFS])
+		if (!pretty && tb[NLMSGERR_ATTR_OFFS])
 			fprintf(stderr, " (offset %u)",
 				mnl_attr_get_u32(tb[NLMSGERR_ATTR_OFFS]));
 		fputc('\n', stderr);
 	}
 
+	if (nlerr->error && pretty) {
+		unsigned int err_offset = 0;
+
+		if (tb[NLMSGERR_ATTR_OFFS])
+			err_offset = mnl_attr_get_u32(tb[NLMSGERR_ATTR_OFFS]);
+		fprintf(stderr, "offending message%s:\n",
+			err_offset ? " and attribute" : "");
+		pretty_print_genlmsg(&nlerr->msg, ethnl_umsg_desc,
+				     ethnl_umsg_n_desc, err_offset);
+	}
+
 out:
 	if (nlerr->error) {
 		errno = -nlerr->error;
@@ -223,9 +257,14 @@ int nlsock_process_reply(struct nl_socket *nlsk, mnl_cb_t reply_cb, void *data)
 			return -EFAULT;
 
 		nlhdr = (struct nlmsghdr *)buff;
-		if (nlhdr->nlmsg_type == NLMSG_ERROR)
-			return nlsock_process_ack(nlhdr, len,
-						  nlsk->nlctx->suppress_nlerr);
+		if (nlhdr->nlmsg_type == NLMSG_ERROR) {
+			bool silent = nlsk->nlctx->suppress_nlerr;
+			bool pretty;
+
+			pretty = debug_on(nlsk->nlctx->ctx->debug,
+					  DEBUG_NL_PRETTY_MSG);
+			return nlsock_process_ack(nlhdr, len, silent, pretty);
+		}
 
 		msgbuff->nlhdr = nlhdr;
 		msgbuff->genlhdr = mnl_nlmsg_get_payload(nlhdr);
-- 
2.25.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ