[PATCH v4 03/11] netlink: decode AF_PACKET packet_diag_msg attributes

Dmitry V. Levin ldv at altlinux.org
Thu Jul 6 11:45:23 UTC 2017


On Thu, Jul 06, 2017 at 09:57:29AM +0800, JingPiao Chen wrote:
> * netlink_sock_diag.c: Include "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.
> * 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            | 115 ++++++++++++++++++++++++++++++++++++++++-
>  print_fields.h                 |   6 +++
>  xlat/packet_diag_info_flags.in |   5 ++
>  4 files changed, 158 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 3888934..f0466b9 100644
> --- a/netlink_sock_diag.c
> +++ b/netlink_sock_diag.c
> @@ -55,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
> @@ -447,6 +448,117 @@ 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 *tcp, void *elem_buf,
> +			 size_t elem_size, void *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, 0);

Don't you think the address should be printed in 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)
> +{
> +	print_seccomp_fprog(tcp, addr, len);
> +
> +	return true;
> +}

This bpf filter is not a seccomp filter, although it shares a lot with it.
In particular, SECCOMP_RET_* stuff is not applicable here.

Looks like print_seccomp_fprog needs to be generalized.
I'll have a look.


> +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 +592,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 92b8a8a..c0a5dfc 100644
> --- a/print_fields.h
> +++ b/print_fields.h
> @@ -65,4 +65,10 @@
>  		printxval((xlat_), (where_).field_, (dflt_));		\
>  	} while (0)
>  
> +#define PRINT_FIELD_QUOTED_STRING(prefix_, where_, field_, len_, style_)	\
> +	do {									\
> +		STRACE_PRINTF("%s%s=", (prefix_), #field_);			\
> +		print_quoted_string((char *)(where_).field_, len_, style_);	\
> +	} while (0)

I think a cast to (const char *) would be more appropriate.


-- 
ldv
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20170706/a05bbd43/attachment.bin>


More information about the Strace-devel mailing list