From f731b6b1e619138a3b76362f3b4c7198f0b64b4e Mon Sep 17 00:00:00 2001 From: JingPiao Chen Date: Wed, 28 Jun 2017 09:40:04 +0800 Subject: [PATCH] netlink: decode AF_NETLINK netlink_diag_msg attributes * linux/netlink_diag.h (netlink_diag_ring): New structure. (NDIAG_FLAG_*): New macros. * netlink_sock_diag.c: Include "xlat/netlink_socket_flags.h". (print_group, decode_netlink_diag_groups, decode_netlink_diag_ring, decode_netlink_diag_flags): New functions. (netlink_diag_msg_nla_decoders): New array. (decode_netlink_diag_msg): Use it. * xlat/netlink_socket_flags.in: New file. --- linux/netlink_diag.h | 15 +++++++ netlink_sock_diag.c | 78 +++++++++++++++++++++++++++++++++++- xlat/netlink_socket_flags.in | 6 +++ 3 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 xlat/netlink_socket_flags.in diff --git a/linux/netlink_diag.h b/linux/netlink_diag.h index eda3ec39..88dde228 100644 --- a/linux/netlink_diag.h +++ b/linux/netlink_diag.h @@ -23,6 +23,13 @@ struct netlink_diag_msg { uint32_t ndiag_cookie[2]; }; +struct netlink_diag_ring { + uint32_t ndr_block_size; + uint32_t ndr_block_nr; + uint32_t ndr_frame_size; + uint32_t ndr_frame_nr; +}; + enum { NETLINK_DIAG_MEMINFO, NETLINK_DIAG_GROUPS, @@ -37,4 +44,12 @@ enum { #define NDIAG_SHOW_FLAGS 0x00000008 #define NDIAG_PROTO_ALL ((uint8_t) ~0) +/* flags */ +#define NDIAG_FLAG_CB_RUNNING 0x00000001 +#define NDIAG_FLAG_PKTINFO 0x00000002 +#define NDIAG_FLAG_BROADCAST_ERROR 0x00000004 +#define NDIAG_FLAG_NO_ENOBUFS 0x00000008 +#define NDIAG_FLAG_LISTEN_ALL_NSID 0x00000010 +#define NDIAG_FLAG_CAP_ACK 0x00000020 + #endif /* !STRACE_LINUX_NETLINK_DIAG_H */ diff --git a/netlink_sock_diag.c b/netlink_sock_diag.c index c32480ea..7fe0e7d1 100644 --- a/netlink_sock_diag.c +++ b/netlink_sock_diag.c @@ -50,6 +50,7 @@ #include "xlat/netlink_diag_attrs.h" #include "xlat/netlink_diag_show.h" +#include "xlat/netlink_socket_flags.h" #include "xlat/netlink_states.h" #include "xlat/packet_diag_attrs.h" @@ -235,6 +236,80 @@ decode_netlink_diag_req(struct tcb *const tcp, tprints("}"); } +static bool +print_group(struct tcb *tcp, void *elem_buf, + size_t elem_size, void *opaque_data) +{ + if (elem_size < sizeof(kernel_ulong_t)) + tprintf("%#0*x", (int) elem_size * 2 + 2, + *(unsigned int *) elem_buf); + else + tprintf("%#0*" PRI_klx, (int) elem_size * 2 + 2, + *(kernel_ulong_t *) elem_buf); + + return true; +} + +static bool +decode_netlink_diag_groups(struct tcb *tcp, kernel_ulong_t addr, + kernel_ulong_t len, const void *const opaque_data) +{ + kernel_ulong_t buf; + size_t nmemb = len / current_wordsize; + + if (!nmemb) + return false; + + print_array(tcp, addr, nmemb, &buf, current_wordsize, + umoven_or_printaddr, print_group, 0); + + return true; +} + +static bool +decode_netlink_diag_ring(struct tcb *tcp, kernel_ulong_t addr, + kernel_ulong_t len, const void *const opaque_data) +{ + struct netlink_diag_ring ndr; + + if (len < sizeof(ndr)) + return false; + if (umove_or_printaddr(tcp, addr, &ndr)) + return true; + + tprintf("{ndr_block_size=%" PRIu32 ", ndr_block_nr=%" PRIu32 + ", ndr_frame_size=%" PRIu32 ", ndr_frame_nr=%" PRIu32, + ndr.ndr_block_size, ndr.ndr_block_nr, + ndr.ndr_frame_size, ndr.ndr_frame_nr); + tprints("}"); + + return true; +} + +static bool +decode_netlink_diag_flags(struct tcb *tcp, kernel_ulong_t addr, + kernel_ulong_t len, const void *const opaque_data) +{ + uint32_t flags; + + if (len < sizeof(flags)) + return false; + if (umove_or_printaddr(tcp, addr, &flags)) + return true; + + printflags(netlink_socket_flags, flags, "NDIAG_FLAG_???"); + + return true; +} + +static const nla_decoder_t netlink_diag_msg_nla_decoders[] = { + [NETLINK_DIAG_MEMINFO] = decode_meminfo, + [NETLINK_DIAG_GROUPS] = decode_netlink_diag_groups, + [NETLINK_DIAG_RX_RING] = decode_netlink_diag_ring, + [NETLINK_DIAG_TX_RING] = decode_netlink_diag_ring, + [NETLINK_DIAG_FLAGS] = decode_netlink_diag_flags +}; + static void decode_netlink_diag_msg(struct tcb *const tcp, const struct nlmsghdr *const nlmsghdr, @@ -274,7 +349,8 @@ decode_netlink_diag_msg(struct tcb *const tcp, tprints(", "); decode_nlattr(tcp, addr + offset, len - offset, netlink_diag_attrs, "NETLINK_DIAG_???", - NULL, 0, NULL); + netlink_diag_msg_nla_decoders, + ARRAY_SIZE(netlink_diag_msg_nla_decoders), NULL); } } diff --git a/xlat/netlink_socket_flags.in b/xlat/netlink_socket_flags.in new file mode 100644 index 00000000..f36e35c6 --- /dev/null +++ b/xlat/netlink_socket_flags.in @@ -0,0 +1,6 @@ +NDIAG_FLAG_CB_RUNNING +NDIAG_FLAG_PKTINFO +NDIAG_FLAG_BROADCAST_ERROR +NDIAG_FLAG_NO_ENOBUFS +NDIAG_FLAG_LISTEN_ALL_NSID +NDIAG_FLAG_CAP_ACK