(root)/
strace-6.5/
src/
netlink_packet_diag.c
       1  /*
       2   * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
       3   * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
       4   * Copyright (c) 2017-2021 The strace developers.
       5   * All rights reserved.
       6   *
       7   * SPDX-License-Identifier: LGPL-2.1-or-later
       8   */
       9  
      10  #include "defs.h"
      11  #include "netlink.h"
      12  #include "netlink_sock_diag.h"
      13  #include "nlattr.h"
      14  
      15  #include <linux/filter.h>
      16  #include <linux/sock_diag.h>
      17  #include <linux/packet_diag.h>
      18  
      19  #include "xlat/af_packet_versions.h"
      20  #include "xlat/packet_diag_attrs.h"
      21  #include "xlat/packet_diag_info_flags.h"
      22  #include "xlat/packet_diag_show.h"
      23  
      24  DECL_NETLINK_DIAG_DECODER(decode_packet_diag_req)
      25  {
      26  	struct packet_diag_req req = { .sdiag_family = family };
      27  	const size_t offset = sizeof(req.sdiag_family);
      28  
      29  	tprint_struct_begin();
      30  	PRINT_FIELD_XVAL(req, sdiag_family, addrfams, "AF_???");
      31  	tprint_struct_next();
      32  
      33  	if (len >= sizeof(req)) {
      34  		if (!umoven_or_printaddr(tcp, addr + offset,
      35  					 sizeof(req) - offset,
      36  					 (char *) &req + offset)) {
      37  			/*
      38  			 * AF_PACKET currently doesn't support protocol values
      39  			 * other than 0.
      40  			 */
      41  			PRINT_FIELD_X(req, sdiag_protocol);
      42  			tprint_struct_next();
      43  			PRINT_FIELD_U(req, pdiag_ino);
      44  			tprint_struct_next();
      45  			PRINT_FIELD_FLAGS(req, pdiag_show,
      46  					  packet_diag_show, "PACKET_SHOW_???");
      47  			tprint_struct_next();
      48  			PRINT_FIELD_COOKIE(req, pdiag_cookie);
      49  		}
      50  	} else
      51  		tprint_more_data_follows();
      52  	tprint_struct_end();
      53  }
      54  
      55  static bool
      56  decode_packet_diag_info(struct tcb *const tcp,
      57  			const kernel_ulong_t addr,
      58  			const unsigned int len,
      59  			const void *const opaque_data)
      60  {
      61  	struct packet_diag_info pinfo;
      62  
      63  	if (len < sizeof(pinfo))
      64  		return false;
      65  	if (umove_or_printaddr(tcp, addr, &pinfo))
      66  		return true;
      67  
      68  	tprint_struct_begin();
      69  	PRINT_FIELD_IFINDEX(pinfo, pdi_index);
      70  	tprint_struct_next();
      71  	PRINT_FIELD_XVAL(pinfo, pdi_version, af_packet_versions, "TPACKET_???");
      72  	tprint_struct_next();
      73  	PRINT_FIELD_U(pinfo, pdi_reserve);
      74  	tprint_struct_next();
      75  	PRINT_FIELD_U(pinfo, pdi_copy_thresh);
      76  	tprint_struct_next();
      77  	PRINT_FIELD_U(pinfo, pdi_tstamp);
      78  	tprint_struct_next();
      79  	PRINT_FIELD_FLAGS(pinfo, pdi_flags, packet_diag_info_flags, "PDI_???");
      80  	tprint_struct_end();
      81  
      82  	return true;
      83  }
      84  
      85  static bool
      86  print_packet_diag_mclist(struct tcb *const tcp, void *const elem_buf,
      87  			 const size_t elem_size, void *const opaque_data)
      88  {
      89  	struct packet_diag_mclist *dml = elem_buf;
      90  	uint16_t alen = MIN(dml->pdmc_alen, sizeof(dml->pdmc_addr));
      91  
      92  	tprint_struct_begin();
      93  	PRINT_FIELD_IFINDEX(*dml, pdmc_index);
      94  	tprint_struct_next();
      95  	PRINT_FIELD_U(*dml, pdmc_count);
      96  	tprint_struct_next();
      97  	PRINT_FIELD_U(*dml, pdmc_type);
      98  	tprint_struct_next();
      99  	PRINT_FIELD_U(*dml, pdmc_alen);
     100  	tprint_struct_next();
     101  	PRINT_FIELD_STRING(*dml, pdmc_addr, alen, QUOTE_FORCE_HEX);
     102  	tprint_struct_end();
     103  
     104  	return true;
     105  }
     106  
     107  static bool
     108  decode_packet_diag_mclist(struct tcb *const tcp,
     109  			  const kernel_ulong_t addr,
     110  			  const unsigned int len,
     111  			  const void *const opaque_data)
     112  {
     113  	struct packet_diag_mclist dml;
     114  	const size_t nmemb = len / sizeof(dml);
     115  
     116  	if (!nmemb)
     117  		return false;
     118  
     119  	print_array(tcp, addr, nmemb, &dml, sizeof(dml),
     120  		    tfetch_mem, print_packet_diag_mclist, 0);
     121  
     122  	return true;
     123  }
     124  
     125  static bool
     126  decode_packet_diag_ring(struct tcb *const tcp,
     127  			const kernel_ulong_t addr,
     128  			const unsigned int len,
     129  			const void *const opaque_data)
     130  {
     131  	struct packet_diag_ring pdr;
     132  
     133  	if (len < sizeof(pdr))
     134  		return false;
     135  	if (umove_or_printaddr(tcp, addr, &pdr))
     136  		return true;
     137  
     138  	tprint_struct_begin();
     139  	PRINT_FIELD_U(pdr, pdr_block_size);
     140  	tprint_struct_next();
     141  	PRINT_FIELD_U(pdr, pdr_block_nr);
     142  	tprint_struct_next();
     143  	PRINT_FIELD_U(pdr, pdr_frame_size);
     144  	tprint_struct_next();
     145  	PRINT_FIELD_U(pdr, pdr_frame_nr);
     146  	tprint_struct_next();
     147  	PRINT_FIELD_U(pdr, pdr_retire_tmo);
     148  	tprint_struct_next();
     149  	PRINT_FIELD_U(pdr, pdr_sizeof_priv);
     150  	tprint_struct_next();
     151  	PRINT_FIELD_U(pdr, pdr_features);
     152  	tprint_struct_end();
     153  
     154  	return true;
     155  }
     156  
     157  static bool
     158  decode_packet_diag_filter(struct tcb *const tcp,
     159  			  const kernel_ulong_t addr,
     160  			  const unsigned int len,
     161  			  const void *const opaque_data)
     162  {
     163  	const unsigned int nmemb = len / sizeof(struct sock_filter);
     164  	if (!nmemb || (unsigned short) nmemb != nmemb)
     165  		return false;
     166  
     167  	print_sock_fprog(tcp, addr, nmemb);
     168  
     169  	return true;
     170  }
     171  
     172  static const nla_decoder_t packet_diag_msg_nla_decoders[] = {
     173  	[PACKET_DIAG_INFO]	= decode_packet_diag_info,
     174  	[PACKET_DIAG_MCLIST]	= decode_packet_diag_mclist,
     175  	[PACKET_DIAG_RX_RING]	= decode_packet_diag_ring,
     176  	[PACKET_DIAG_TX_RING]	= decode_packet_diag_ring,
     177  	[PACKET_DIAG_FANOUT]	= decode_nla_u32,
     178  	[PACKET_DIAG_UID]	= decode_nla_uid,
     179  	[PACKET_DIAG_MEMINFO]	= decode_nla_meminfo,
     180  	[PACKET_DIAG_FILTER]	= decode_packet_diag_filter
     181  };
     182  
     183  DECL_NETLINK_DIAG_DECODER(decode_packet_diag_msg)
     184  {
     185  	struct packet_diag_msg msg = { .pdiag_family = family };
     186  	size_t offset = sizeof(msg.pdiag_family);
     187  	bool decode_nla = false;
     188  
     189  	tprint_struct_begin();
     190  	PRINT_FIELD_XVAL(msg, pdiag_family, addrfams, "AF_???");
     191  	tprint_struct_next();
     192  
     193  	if (len >= sizeof(msg)) {
     194  		if (!umoven_or_printaddr(tcp, addr + offset,
     195  					 sizeof(msg) - offset,
     196  					 (char *) &msg + offset)) {
     197  			PRINT_FIELD_XVAL(msg, pdiag_type,
     198  					 socktypes, "SOCK_???");
     199  			tprint_struct_next();
     200  			PRINT_FIELD_XVAL(msg, pdiag_num,
     201  					 ethernet_protocols, "ETH_P_???");
     202  			tprint_struct_next();
     203  			PRINT_FIELD_U(msg, pdiag_ino);
     204  			tprint_struct_next();
     205  			PRINT_FIELD_COOKIE(msg, pdiag_cookie);
     206  			decode_nla = true;
     207  		}
     208  	} else
     209  		tprint_more_data_follows();
     210  	tprint_struct_end();
     211  
     212  	offset = NLMSG_ALIGN(sizeof(msg));
     213  	if (decode_nla && len > offset) {
     214  		tprint_array_next();
     215  		decode_nlattr(tcp, addr + offset, len - offset,
     216  			      packet_diag_attrs, "PACKET_DIAG_???",
     217  			      packet_diag_msg_nla_decoders,
     218  			      ARRAY_SIZE(packet_diag_msg_nla_decoders), NULL);
     219  	}
     220  }