[PATCH v9 4/4] Netlink: Add support for NLMSG_ERROR and NLMSG_DONE
Fabien Siron
fabien.siron at epita.fr
Wed Jul 6 15:49:25 UTC 2016
Manage netlink "error" messages and "done" messages mainly to avoid
later garbage printing.
* netlink.c (nlmsg_data, decode_netlink_nlmsghdr, decode_netlink_error):
New functions.
(decode_netlink_msg): Change return type to int and call
decode_netlink_nlmsghdr() and decode_netlink_error().
(decode_netlink): Break loop if decode_netlink_msg() returns 0.
---
netlink.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 58 insertions(+), 11 deletions(-)
diff --git a/netlink.c b/netlink.c
index fc746ed..aea1bc7 100644
--- a/netlink.c
+++ b/netlink.c
@@ -26,6 +26,7 @@
*/
#include "defs.h"
+#include <string.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include "xlat/netlink_flags.h"
@@ -69,34 +70,79 @@ next_nlmsg(struct nlmsghdr *nlmsghdr, unsigned long addr, unsigned long *len) {
return 0;
}
+static unsigned long
+nlmsg_data(unsigned long nlh) {
+ return nlh + NLMSG_LENGTH(0);
+}
+
static void
-decode_netlink_msg(struct tcb *tcp, struct nlmsghdr *nlmsghdr,
- unsigned long addr, unsigned long size)
+decode_netlink_nlmsghdr(struct tcb *tcp, struct nlmsghdr *nlmsghdr)
{
- if (size < sizeof(struct nlmsghdr)) {
- printstr(tcp, addr, size);
- return;
- }
-
- tprintf("{{len=%u, type=", nlmsghdr->nlmsg_len);
+ tprintf("{len=%u, type=", nlmsghdr->nlmsg_len);
printxval(netlink_types, nlmsghdr->nlmsg_type, "NLMSG_???");
tprints(", flags=");
printflags(netlink_flags, nlmsghdr->nlmsg_flags, "NLM_F_???");
- /* manage get/new requests */
tprintf(", seq=%u, pid=%u}", nlmsghdr->nlmsg_seq,
nlmsghdr->nlmsg_pid);
+}
+
+static void
+decode_netlink_error(struct tcb *tcp, unsigned long addr, unsigned long size)
+{
+ struct nlmsgerr err;
+
+ if (umove_or_printaddr(tcp, addr, &err) < 0)
+ return;
+
+ tprintf(", {error=\"%s\", msg=", strerror(-err.error));
+
+ decode_netlink_nlmsghdr(tcp, &err.msg);
+
+ tprints("}");
+}
+
+static int
+decode_netlink_msg(struct tcb *tcp, struct nlmsghdr *nlmsghdr,
+ unsigned long addr, unsigned long size)
+{
+ if (size < sizeof(struct nlmsghdr)) {
+ printstr(tcp, addr, size);
+ return 0;
+ }
+
+ tprints("{");
+
+ decode_netlink_nlmsghdr(tcp, nlmsghdr);
if (nlmsghdr->nlmsg_len - sizeof(struct nlmsghdr) > 0) {
- tprints(", ");
+ unsigned long data;
+ data = nlmsg_data(addr);
+
+ if (nlmsghdr->nlmsg_type < NLMSG_MIN_TYPE)
+ {
+ switch (nlmsghdr->nlmsg_type)
+ {
+ case NLMSG_ERROR:
+ decode_netlink_error(tcp, data,
+ nlmsghdr->nlmsg_len -
+ sizeof(struct nlmsghdr));
+ case NLMSG_DONE:
+ tprints("}");
+ return 0;
+ }
+ }
+ tprints(", ");
printstr(tcp, addr + sizeof(struct nlmsghdr),
nlmsghdr->nlmsg_len - sizeof(struct nlmsghdr));
}
tprints("}");
+
+ return 1;
}
void
@@ -128,7 +174,8 @@ decode_netlink(struct tcb *tcp, unsigned long addr, unsigned long total_size) {
tprints("[");
}
- decode_netlink_msg(tcp, &nlmsghdr, addr, size);
+ if (!decode_netlink_msg(tcp, &nlmsghdr, addr, size))
+ break;
if (size > nlmsghdr.nlmsg_len)
tprints(", ");
--
2.9.0
More information about the Strace-devel
mailing list