* netlink_sock_diag.c: Include <linux/filter.h>
and "xlat/packet_diag_info_flags.h".
(packet_decoders): New array.
(decode_packet_diag_msg): Use it.
* linux/packet_diag.h (packet_diag_info, packet_diag_mclist,
packet_diag_ring): New structures.
(PDI_*): New macros.
* xlat/packet_diag_info_flags.in: New file.
---
 linux/packet_diag.h            |  33 ++++++++++++
 netlink_sock_diag.c            | 120 ++++++++++++++++++++++++++++++++++++++++-
 xlat/packet_diag_info_flags.in |   5 ++
 3 files changed, 157 insertions(+), 1 deletion(-)
 create mode 100644 xlat/packet_diag_info_flags.in

diff --git a/linux/packet_diag.h b/linux/packet_diag.h
index 3e8120b..368e26f 100644
--- a/linux/packet_diag.h
+++ b/linux/packet_diag.h
@@ -37,4 +37,37 @@ enum {
        PACKET_DIAG_FILTER,
 };
 
+struct packet_diag_info {
+       uint32_t pdi_index;
+       uint32_t pdi_version;
+       uint32_t pdi_reserve;
+       uint32_t pdi_copy_thresh;
+       uint32_t pdi_tstamp;
+       uint32_t pdi_flags;
+
+#define PDI_RUNNING    0x1
+#define PDI_AUXDATA    0x2
+#define PDI_ORIGDEV    0x4
+#define PDI_VNETHDR    0x8
+#define PDI_LOSS       0x10
+};
+
+struct packet_diag_mclist {
+       uint32_t pdmc_index;
+       uint32_t pdmc_count;
+       uint16_t pdmc_type;
+       uint16_t pdmc_alen;
+       uint8_t pdmc_addr[32]; /* MAX_ADDR_LEN */
+};
+
+struct packet_diag_ring {
+       uint32_t pdr_block_size;
+       uint32_t pdr_block_nr;
+       uint32_t pdr_frame_size;
+       uint32_t pdr_frame_nr;
+       uint32_t pdr_retire_tmo;
+       uint32_t pdr_sizeof_priv;
+       uint32_t pdr_features;
+};
+
 #endif /* !STRACE_LINUX_PACKET_DIAG_H */
diff --git a/netlink_sock_diag.c b/netlink_sock_diag.c
index 8fc5a94..43e6f0b 100644
--- a/netlink_sock_diag.c
+++ b/netlink_sock_diag.c
@@ -32,6 +32,7 @@
 
 #include <sys/socket.h>
 #include <arpa/inet.h>
+#include <linux/filter.h>
 #include <linux/inet_diag.h>
 #include <linux/netlink.h>
 #include <linux/netlink_diag.h>
@@ -54,6 +55,7 @@
 #include "xlat/netlink_states.h"
 
 #include "xlat/packet_diag_attrs.h"
+#include "xlat/packet_diag_info_flags.h"
 #include "xlat/packet_diag_show.h"
 
 #ifdef AF_SMC
@@ -424,6 +426,121 @@ decode_packet_diag_req(struct tcb *const tcp,
        tprints("}");
 }
 
+static bool
+decode_packet_diag_info(struct tcb *tcp, kernel_ulong_t addr,
+                       kernel_ulong_t len, void *const opaque_data)
+{
+       struct packet_diag_info pinfo;
+
+       if (len < sizeof(pinfo))
+               return false;
+       if (umove_or_printaddr(tcp, addr, &pinfo))
+               return true;
+
+       tprintf("{pdi_index=%" PRIu32 ", pdi_version=%" PRIu32
+               ", pdi_reserve=%" PRIu32 ", pdi_copy_thresh=%" PRIu32
+               ", pdi_tstamp=%" PRIu32 ", pdi_flags=",
+               pinfo.pdi_index, pinfo.pdi_version, pinfo.pdi_reserve,
+               pinfo.pdi_copy_thresh, pinfo.pdi_tstamp);
+       printflags(packet_diag_info_flags, pinfo.pdi_flags, "PDI_???");
+       tprints("}");
+
+       return true;
+}
+
+static bool
+print_packet_diag_mclist(struct tcb *tcp, void *elem_buf,
+                        size_t elem_size, void *opaque_data)
+{
+       struct packet_diag_mclist *dml;
+
+       dml = (struct packet_diag_mclist *) elem_buf;
+
+       tprintf("{pdmc_index=%" PRIu32 ", pdmc_count=%" PRIu32
+               ", pdmc_type=%" PRIu16 ", pdmc_alen=%" PRIu16
+               ", pdmc_addr=",
+               dml->pdmc_index, dml->pdmc_count, dml->pdmc_type,
+               dml->pdmc_alen);
+       print_quoted_string((char *) dml->pdmc_addr, sizeof(dml->pdmc_addr),
+                           QUOTE_0_TERMINATED);
+       tprints("}");
+
+       return true;
+}
+
+static bool
+decode_packet_diag_mclist(struct tcb *tcp, kernel_ulong_t addr,
+                         kernel_ulong_t len, void *const opaque_data)
+{
+       struct packet_diag_mclist dml;
+       int nmemb = len / sizeof(dml);
+
+       print_array(tcp, addr, nmemb, &dml, sizeof(dml),
+                   umoven_or_printaddr, print_packet_diag_mclist, 0);
+
+       return true;
+}
+
+static bool
+decode_packet_diag_ring(struct tcb *tcp, kernel_ulong_t addr,
+                       kernel_ulong_t len, void *const opaque_data)
+{
+       struct packet_diag_ring pdr;
+
+       if (len < sizeof(pdr))
+               return false;
+       if (umove_or_printaddr(tcp, addr, &pdr))
+               return true;
+
+       tprintf("{pdr_block_size=%" PRIu32 ", pdr_block_nr=%" PRIu32
+               ", pdr_frame_size=%" PRIu32 ", pdr_frame_nr=%" PRIu32
+               ", pdr_retire_tmo=%" PRIu32 ", pdr_sizeof_priv=%" PRIu32
+               ", pdr_features=%" PRIu32 "}",
+               pdr.pdr_block_size, pdr.pdr_block_nr,
+               pdr.pdr_frame_size, pdr.pdr_frame_nr,
+               pdr.pdr_retire_tmo, pdr.pdr_sizeof_priv,
+               pdr.pdr_features);
+
+       return true;
+}
+
+static bool
+print_sock_filter(struct tcb *tcp, void *elem_buf,
+                 size_t elem_size, void *opaque_data)
+{
+       struct sock_filter *filter = (struct sock_filter *)elem_buf;
+
+       tprintf("{code=%" PRIu16 ", jt=%" PRIu8 ", jf=%" PRIu8 ", k=%" PRIu32,
+               filter->code, filter->jt, filter->jf, filter->k);
+       tprints("}");
+
+       return true;
+}
+
+static bool
+decode_sock_filter(struct tcb *tcp, kernel_ulong_t addr,
+                  kernel_ulong_t len, void *const opaque_data)
+{
+       struct sock_filter filter;
+       int nmemb = len / sizeof(filter);
+
+       print_array(tcp, addr, nmemb, &filter, sizeof(filter),
+                   umoven_or_printaddr, print_sock_filter, 0);
+
+       return true;
+}
+
+static nla_decoder_t packet_decoders[] = {
+       [PACKET_DIAG_INFO]      = decode_packet_diag_info,
+       [PACKET_DIAG_MCLIST]    = decode_packet_diag_mclist,
+       [PACKET_DIAG_RX_RING]   = decode_packet_diag_ring,
+       [PACKET_DIAG_TX_RING]   = decode_packet_diag_ring,
+       [PACKET_DIAG_FANOUT]    = decode_nla_u32,
+       [PACKET_DIAG_UID]       = decode_nla_u32,
+       [PACKET_DIAG_MEMINFO]   = decode_meminfo,
+       [PACKET_DIAG_FILTER]    = decode_sock_filter
+};
+
 static void
 decode_packet_diag_msg(struct tcb *const tcp,
                       const struct nlmsghdr *const nlmsghdr,
@@ -460,7 +577,8 @@ decode_packet_diag_msg(struct tcb *const tcp,
                tprints(", ");
                decode_nlattr(tcp, addr + offset, len - offset,
                              packet_diag_attrs, "PACKET_DIAG_???",
-                             NULL, 0, NULL);
+                             packet_decoders,
+                             ARRAY_SIZE(packet_decoders), NULL);
        }
 }
 
diff --git a/xlat/packet_diag_info_flags.in b/xlat/packet_diag_info_flags.in
new file mode 100644
index 0000000..30a47b1
--- /dev/null
+++ b/xlat/packet_diag_info_flags.in
@@ -0,0 +1,5 @@
+PDI_RUNNING    0x1
+PDI_AUXDATA    0x2
+PDI_ORIGDEV    0x4
+PDI_VNETHDR    0x8
+PDI_LOSS       0x10
-- 
2.7.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Strace-devel mailing list
Strace-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/strace-devel

Reply via email to