From: JingPiao Chen Date: Tue, 13 Jun 2017 02:32:55 +0000 (+0800) Subject: netlink: add a basic socket diag parser of AF_NETLINK messages X-Git-Tag: v4.18~88 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cbb03086401314d874f6e0107645da891f3c8aee;p=strace netlink: add a basic socket diag parser of AF_NETLINK messages * linux/netlink_diag.h (NDIAG_SHOW_GROUPS, NDIAG_SHOW_RING_CFG): New macros. * netlink_sock_diag.c: Include , "xlat/netlink_diag_show.h" and "xlat/netlink_states.h". (decode_netlink_diag_req, decode_netlink_diag_msg): New functions. (diag_decoders): Add AF_NETLINK. * xlat/netlink_diag_show.in: New file. * xlat/netlink_states.in: Likewise. Co-authored-by: Fabien Siron --- diff --git a/linux/netlink_diag.h b/linux/netlink_diag.h index a52507c7..49b7550b 100644 --- a/linux/netlink_diag.h +++ b/linux/netlink_diag.h @@ -23,7 +23,9 @@ struct netlink_diag_msg { uint32_t ndiag_cookie[2]; }; -#define NDIAG_SHOW_MEMINFO 0x00000001 -#define NDIAG_PROTO_ALL ((uint8_t) ~0) +#define NDIAG_SHOW_MEMINFO 0x00000001 +#define NDIAG_SHOW_GROUPS 0x00000002 +#define NDIAG_SHOW_RING_CFG 0x00000004 /* deprecated since 4.6 */ +#define NDIAG_PROTO_ALL ((uint8_t) ~0) #endif /* !STRACE_LINUX_NETLINK_DIAG_H */ diff --git a/netlink_sock_diag.c b/netlink_sock_diag.c index 4687b119..f4829572 100644 --- a/netlink_sock_diag.c +++ b/netlink_sock_diag.c @@ -31,11 +31,15 @@ #include #include +#include #include #include "xlat/tcp_states.h" #include "xlat/tcp_state_flags.h" +#include "xlat/netlink_diag_show.h" +#include "xlat/netlink_states.h" + #include "xlat/unix_diag_show.h" static void @@ -118,6 +122,86 @@ decode_unix_diag_msg(struct tcb *const tcp, tprints("}"); } +static void +decode_netlink_diag_req(struct tcb *const tcp, + const struct nlmsghdr *const nlmsghdr, + const uint8_t family, + const kernel_ulong_t addr, + const kernel_ulong_t len) +{ + struct netlink_diag_req req = { .sdiag_family = family }; + const size_t offset = sizeof(req.sdiag_family); + + tprints("{sdiag_family="); + printxval(addrfams, req.sdiag_family, "AF_???"); + + tprints(", "); + if (len >= sizeof(req)) { + if (!umoven_or_printaddr(tcp, addr + offset, + sizeof(req) - offset, + (void *) &req + offset)) { + tprints("sdiag_protocol="); + if (NDIAG_PROTO_ALL == req.sdiag_protocol) + tprints("NDIAG_PROTO_ALL"); + else + printxval(netlink_protocols, + req.sdiag_protocol, "NETLINK_???"); + tprintf(", ndiag_ino=%" PRIu32 ", ndiag_show=", + req.ndiag_ino); + printflags(netlink_diag_show, req.ndiag_show, + "NDIAG_SHOW_???"); + tprintf(", ndiag_cookie=[%" PRIu32 ", %" PRIu32 "]", + req.ndiag_cookie[0], req.ndiag_cookie[1]); + } + } else + tprints("..."); + tprints("}"); +} + +static void +decode_netlink_diag_msg(struct tcb *const tcp, + const struct nlmsghdr *const nlmsghdr, + const uint8_t family, + const kernel_ulong_t addr, + const kernel_ulong_t len) +{ + struct netlink_diag_msg msg = { .ndiag_family = family }; + const size_t offset = sizeof(msg.ndiag_family); + + tprints("{ndiag_family="); + printxval(addrfams, msg.ndiag_family, "AF_???"); + + tprints(", "); + if (len >= sizeof(msg)) { + if (!umoven_or_printaddr(tcp, addr + offset, + sizeof(msg) - offset, + (void *) &msg + offset)) { + tprints("ndiag_type="); + printxval(socktypes, msg.ndiag_type, "SOCK_???"); + tprints(", ndiag_protocol="); + printxval(netlink_protocols, msg.ndiag_protocol, + "NETLINK_???"); + tprints(", ndiag_state="); + printxval(netlink_states, msg.ndiag_state, + "NETLINK_???"); + tprintf(", ndiag_portid=%" PRIu32 + ", ndiag_dst_portid=%" PRIu32 + ", ndiag_dst_group=%" PRIu32 + ", ndiag_ino=%" PRIu32 + ", ndiag_cookie=[%" PRIu32 + ", %" PRIu32 "]", + msg.ndiag_portid, + msg.ndiag_dst_portid, + msg.ndiag_dst_group, + msg.ndiag_ino, + msg.ndiag_cookie[0], + msg.ndiag_cookie[1]); + } + } else + tprints("..."); + tprints("}"); +} + typedef void (*netlink_diag_decoder_t)(struct tcb *, const struct nlmsghdr *, uint8_t family, @@ -127,6 +211,7 @@ typedef void (*netlink_diag_decoder_t)(struct tcb *, static const struct { const netlink_diag_decoder_t request, response; } diag_decoders[] = { + [AF_NETLINK] = { decode_netlink_diag_req, decode_netlink_diag_msg }, [AF_UNIX] = { decode_unix_diag_req, decode_unix_diag_msg } }; diff --git a/xlat/netlink_diag_show.in b/xlat/netlink_diag_show.in new file mode 100644 index 00000000..9639c5a6 --- /dev/null +++ b/xlat/netlink_diag_show.in @@ -0,0 +1,3 @@ +NDIAG_SHOW_MEMINFO +NDIAG_SHOW_GROUPS +NDIAG_SHOW_RING_CFG diff --git a/xlat/netlink_states.in b/xlat/netlink_states.in new file mode 100644 index 00000000..4d4aee7e --- /dev/null +++ b/xlat/netlink_states.in @@ -0,0 +1,2 @@ +NETLINK_UNCONNECTED 0 +NETLINK_CONNECTED 1