This commit handles the case where there are several messages in the buffer. This is very useful to some protocols like SOCK_DIAG.
* netlink.c (nlmsg_fetch, nlmsg_next): New functions. (decode_netlink_msg): New function. (decode_netlink): Call decode_netlink_msg(). * tests/netlink_parsing.c (send_query): Adapt test. --- netlink.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- tests/netlink_parsing.c | 8 ++++---- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/netlink.c b/netlink.c index 978cc6e..aff6181 100644 --- a/netlink.c +++ b/netlink.c @@ -31,8 +31,34 @@ #include "xlat/netlink_flags.h" #include "xlat/netlink_types.h" -void -decode_netlink(struct tcb *tcp, unsigned long addr, unsigned long size) +/* since our target is not in the same process, here are some utils for nlmsg */ +static int +nlmsg_fetch(struct tcb *tcp, struct nlmsghdr *nlmsghdr, unsigned long addr, + unsigned long len) { + if (len < sizeof(struct nlmsghdr)) { + if (len != 0) + printstr(tcp, addr, len); + return 0; + } + + if (umove_or_printaddr(tcp, addr, nlmsghdr) == -1) + return 0; + + return nlmsghdr->nlmsg_len >= sizeof(struct nlmsghdr) && + nlmsghdr->nlmsg_len <= len; +} + +static unsigned long +nlmsg_next(struct nlmsghdr *nlmsghdr, unsigned long addr, unsigned long *len) { + *len -= NLMSG_ALIGN(nlmsghdr->nlmsg_len); + + return (unsigned long) + ((char *)(addr) + NLMSG_ALIGN(nlmsghdr->nlmsg_len)); +} + +static void +decode_netlink_msg(struct tcb *tcp, unsigned long addr, + unsigned long size) { struct nlmsghdr nlmsghdr; @@ -62,3 +88,18 @@ decode_netlink(struct tcb *tcp, unsigned long addr, unsigned long size) tprints("}"); } + +void +decode_netlink(struct tcb *tcp, unsigned long addr, unsigned long total_size) { + struct nlmsghdr nlmsghdr; + unsigned long size = total_size; + + for (; nlmsg_fetch(tcp, &nlmsghdr, addr, size); + addr = nlmsg_next(&nlmsghdr, addr, &size)) { + if (size != total_size) + tprints(", "); + tprints("{"); + decode_netlink_msg(tcp, addr, size); + tprints("}"); + } +} diff --git a/tests/netlink_parsing.c b/tests/netlink_parsing.c index 3e7c983..61957cd 100644 --- a/tests/netlink_parsing.c +++ b/tests/netlink_parsing.c @@ -61,8 +61,8 @@ send_query(const int fd) (unsigned) sizeof(req)) perror_msg_and_skip("sendto"); - printf("sendto(%d, {{len=%u, type=NLMSG_NOOP, flags=NLM_F_REQUEST|0x%x" - ", seq=0, pid=0}, \"abcd\"}, %u, MSG_DONTWAIT, NULL, 0) = %u\n", + printf("sendto(%d, {{{len=%u, type=NLMSG_NOOP, flags=NLM_F_REQUEST|0x%x" + ", seq=0, pid=0}, \"abcd\"}}, %u, MSG_DONTWAIT, NULL, 0) = %u\n", fd, (unsigned) sizeof(req), NLM_F_DUMP, (unsigned) sizeof(req), (unsigned) sizeof(req)); @@ -73,8 +73,8 @@ send_query(const int fd) (unsigned) sizeof(req.nlh)) perror_msg_and_skip("sendto"); - printf("sendto(%d, {{len=%u, type=NLMSG_NOOP, flags=NLM_F_REQUEST|0x%x" - ", seq=0, pid=0}}, %u, MSG_DONTWAIT, NULL, 0) = %u\n", + printf("sendto(%d, {{{len=%u, type=NLMSG_NOOP, flags=NLM_F_REQUEST|0x%x" + ", seq=0, pid=0}}}, %u, MSG_DONTWAIT, NULL, 0) = %u\n", fd, (unsigned) sizeof(req.nlh), NLM_F_DUMP, (unsigned) sizeof(req.nlh), (unsigned) sizeof(req.nlh)); -- 2.8.3 ------------------------------------------------------------------------------ What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic patterns at an interface-level. Reveals which users, apps, and protocols are consuming the most bandwidth. Provides multi-vendor support for NetFlow, J-Flow, sFlow and other flows. Make informed decisions using capacity planning reports. http://sdm.link/zohomanageengine _______________________________________________ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel