]> granicus.if.org Git - strace/commitdiff
netlink: decode AF_PACKET packet_diag_msg attributes
authorJingPiao Chen <chenjingpiao@gmail.com>
Sun, 21 May 2017 03:42:13 +0000 (11:42 +0800)
committerDmitry V. Levin <ldv@altlinux.org>
Sun, 9 Jul 2017 00:21:02 +0000 (00:21 +0000)
* linux/packet_diag.h (packet_diag_info, packet_diag_mclist,
packet_diag_ring): New structures.
(PDI_*): New macros.
* netlink_sock_diag.c: Include <linux/filter.h>
and "xlat/packet_diag_info_flags.h".
(decode_packet_diag_info, decode_packet_diag_mclist,
decode_packet_diag_ring, decode_packet_diag_filter): New functions.
(packet_diag_msg_nla_decoders): New array.
(decode_packet_diag_msg): Use it.
* print_fields.h (PRINT_FIELD_QUOTED_STRING): New macro.
* xlat/packet_diag_info_flags.in: New file.

Co-authored-by: Dmitry V. Levin <ldv@altlinux.org>
linux/packet_diag.h
netlink_sock_diag.c
print_fields.h
xlat/packet_diag_info_flags.in [new file with mode: 0644]

index 3e8120b77c115fbc13b795cffd1fe08ccfc4a06a..368e26ff3594170d32b208e2fb78d04a9b538fb4 100644 (file)
@@ -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 */
index 0d27f78d40cab9f45970043c322a05a7b79e7859..525dc9e6b1e8cd2dc2ae24c5070d096a72c0da1d 100644 (file)
@@ -33,6 +33,8 @@
 #include "print_fields.h"
 
 #include <arpa/inet.h>
+#include <linux/filter.h>
+
 #include <linux/inet_diag.h>
 #include <linux/netlink_diag.h>
 #include <linux/packet_diag.h>
@@ -55,6 +57,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
@@ -447,6 +450,119 @@ decode_packet_diag_req(struct tcb *const tcp,
        tprints("}");
 }
 
+static bool
+decode_packet_diag_info(struct tcb *const tcp,
+                       const kernel_ulong_t addr,
+                       const kernel_ulong_t len,
+                       const void *const opaque_data)
+{
+       struct packet_diag_info pinfo;
+
+       if (len < sizeof(pinfo))
+               return false;
+       if (umove_or_printaddr(tcp, addr, &pinfo))
+               return true;
+
+       PRINT_FIELD_U("{", pinfo, pdi_index);
+       PRINT_FIELD_U(", ", pinfo, pdi_version);
+       PRINT_FIELD_U(", ", pinfo, pdi_reserve);
+       PRINT_FIELD_U(", ", pinfo, pdi_copy_thresh);
+       PRINT_FIELD_U(", ", pinfo, pdi_tstamp);
+       PRINT_FIELD_FLAGS(", ", pinfo, pdi_flags,
+                         packet_diag_info_flags, "PDI_???");
+       tprints("}");
+
+       return true;
+}
+
+static bool
+print_packet_diag_mclist(struct tcb *const tcp, void *const elem_buf,
+                        const size_t elem_size, void *const opaque_data)
+{
+       struct packet_diag_mclist *dml = elem_buf;
+       uint16_t alen = dml->pdmc_alen > sizeof(dml->pdmc_addr) ?
+               sizeof(dml->pdmc_addr) : dml->pdmc_alen;
+
+       tprints("{pdmc_index=");
+       print_ifindex(dml->pdmc_index);
+       PRINT_FIELD_U(", ", *dml, pdmc_count);
+       PRINT_FIELD_U(", ", *dml, pdmc_type);
+       PRINT_FIELD_U(", ", *dml, pdmc_alen);
+       PRINT_FIELD_QUOTED_STRING(", ", *dml, pdmc_addr, alen, QUOTE_FORCE_HEX);
+       tprints("}");
+
+       return true;
+}
+
+static bool
+decode_packet_diag_mclist(struct tcb *const tcp,
+                         const kernel_ulong_t addr,
+                         const kernel_ulong_t len,
+                         const void *const opaque_data)
+{
+       struct packet_diag_mclist dml;
+       const size_t nmemb = len / sizeof(dml);
+
+       if (!nmemb)
+               return false;
+
+       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 *const tcp,
+                       const kernel_ulong_t addr,
+                       const kernel_ulong_t len,
+                       const void *const opaque_data)
+{
+       struct packet_diag_ring pdr;
+
+       if (len < sizeof(pdr))
+               return false;
+       if (umove_or_printaddr(tcp, addr, &pdr))
+               return true;
+
+       PRINT_FIELD_U("{", pdr, pdr_block_size);
+       PRINT_FIELD_U(", ", pdr, pdr_block_nr);
+       PRINT_FIELD_U(", ", pdr, pdr_frame_size);
+       PRINT_FIELD_U(", ", pdr, pdr_frame_nr);
+       PRINT_FIELD_U(", ", pdr, pdr_retire_tmo);
+       PRINT_FIELD_U(", ", pdr, pdr_sizeof_priv);
+       PRINT_FIELD_U(", ", pdr, pdr_features);
+       tprints("}");
+
+       return true;
+}
+
+static bool
+decode_packet_diag_filter(struct tcb *const tcp,
+                         const kernel_ulong_t addr,
+                         const kernel_ulong_t len,
+                         const void *const opaque_data)
+{
+       const kernel_ulong_t nmemb = len / sizeof(struct sock_filter);
+       if (!nmemb || (unsigned short) nmemb != nmemb)
+               return false;
+
+       print_sock_fprog(tcp, addr, nmemb);
+
+       return true;
+}
+
+static const nla_decoder_t packet_diag_msg_nla_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_packet_diag_filter
+};
+
 static void
 decode_packet_diag_msg(struct tcb *const tcp,
                       const struct nlmsghdr *const nlmsghdr,
@@ -480,7 +596,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_diag_msg_nla_decoders,
+                             ARRAY_SIZE(packet_diag_msg_nla_decoders), NULL);
        }
 }
 
index 43a26bc77ba44c7e135a32bab09399c4786a03e6..abf2cf616eb973f678f8311a01e276a2f1d39f74 100644 (file)
                                      zero_extend_signed_to_ull((where_).field_));      \
        } while (0)
 
+#define PRINT_FIELD_QUOTED_STRING(prefix_, where_, field_, len_, style_)               \
+       do {                                                                            \
+               STRACE_PRINTF("%s%s=", (prefix_), #field_);                             \
+               print_quoted_string((const char *)(where_).field_, len_, style_);       \
+       } while (0)
+
 #endif /* !STRACE_PRINT_FIELDS_H */
diff --git a/xlat/packet_diag_info_flags.in b/xlat/packet_diag_info_flags.in
new file mode 100644 (file)
index 0000000..7e591d8
--- /dev/null
@@ -0,0 +1,5 @@
+PDI_RUNNING
+PDI_AUXDATA
+PDI_ORIGDEV
+PDI_VNETHDR
+PDI_LOSS