On Wed, Jun 28, 2017 at 09:40:08AM +0800, JingPiao Chen wrote: > * netlink_sock_diag.c: Include <linux/filter.h> > and "xlat/packet_diag_info_flags.h". > (packet_diag_msg_nla_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 | 126 > ++++++++++++++++++++++++++++++++++++++++- > xlat/packet_diag_info_flags.in | 5 ++ > 3 files changed, 163 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 f5b53b5..c0709c0 100644 > --- a/netlink_sock_diag.c > +++ b/netlink_sock_diag.c > @@ -32,6 +32,7 @@ > #include "nlattr.h" > > #include <arpa/inet.h> > +#include <linux/filter.h>
<linux/filter.h> is not universally available yet, on other parts of strace we wrap its use in #ifdef HAVE_LINUX_FILTER_H/#endif. > #include <linux/inet_diag.h> > #include <linux/netlink_diag.h> > #include <linux/packet_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 > @@ -451,6 +453,127 @@ 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, 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; > + > + 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); I don't think packet_diag_mclist is printed properly here. For example, pdmc_index seems to be an interface index we print using print_ifindex; pdmc_addr is an address, not nul-terminated string, and pdmc_alen is its actual length. Please investigate what would be a correct representation of this structure. > + tprints("}"); > + > + return true; > +} > + > +static bool > +decode_packet_diag_mclist(struct tcb *tcp, kernel_ulong_t addr, > + kernel_ulong_t len, const void *const opaque_data) > +{ > + struct packet_diag_mclist dml; > + 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 *tcp, kernel_ulong_t addr, > + 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; > + > + 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; No need to cast. > + tprintf("{code=%" PRIu16 ", jt=%" PRIu8 ", jf=%" PRIu8 ", k=%" PRIu32, > + filter->code, filter->jt, filter->jf, filter->k); > + tprints("}"); > + > + return true; > +} Note that this is a very primitive parser compared to print_bpf_filter in seccomp.c. > + > +static bool > +decode_sock_filter(struct tcb *tcp, kernel_ulong_t addr, > + kernel_ulong_t len, const void *const opaque_data) > +{ > + struct sock_filter filter; > + size_t nmemb = len / sizeof(filter); > + > + if (!nmemb) > + return false; > + > + print_array(tcp, addr, nmemb, &filter, sizeof(filter), > + umoven_or_printaddr, print_sock_filter, 0); > + > + 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_sock_filter > +}; > + > static void > decode_packet_diag_msg(struct tcb *const tcp, > const struct nlmsghdr *const nlmsghdr, > @@ -487,7 +610,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); > } > } > > 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 These constants are defined in local linux/packet_diag.h already, no fallback definitions are needed. -- ldv
signature.asc
Description: PGP signature
------------------------------------------------------------------------------ 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