From: JingPiao Chen Date: Sun, 21 May 2017 03:42:13 +0000 (+0800) Subject: netlink: decode AF_PACKET packet_diag_msg attributes X-Git-Tag: v4.19~308 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f8ce9d580ce9f19aa1c0c3de797f6dbf6f241eb9;p=strace netlink: decode AF_PACKET packet_diag_msg attributes * linux/packet_diag.h (packet_diag_info, packet_diag_mclist, packet_diag_ring): New structures. (PDI_*): New macros. * netlink_sock_diag.c: Include 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 --- diff --git a/linux/packet_diag.h b/linux/packet_diag.h index 3e8120b7..368e26ff 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 0d27f78d..525dc9e6 100644 --- a/netlink_sock_diag.c +++ b/netlink_sock_diag.c @@ -33,6 +33,8 @@ #include "print_fields.h" #include +#include + #include #include #include @@ -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); } } diff --git a/print_fields.h b/print_fields.h index 43a26bc7..abf2cf61 100644 --- a/print_fields.h +++ b/print_fields.h @@ -74,4 +74,10 @@ 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 index 00000000..7e591d85 --- /dev/null +++ b/xlat/packet_diag_info_flags.in @@ -0,0 +1,5 @@ +PDI_RUNNING +PDI_AUXDATA +PDI_ORIGDEV +PDI_VNETHDR +PDI_LOSS