(root)/
strace-6.5/
tests/
nlattr_packet_diag_msg.c
       1  /*
       2   * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
       3   * Copyright (c) 2017-2021 The strace developers.
       4   * All rights reserved.
       5   *
       6   * SPDX-License-Identifier: GPL-2.0-or-later
       7   */
       8  
       9  #include "tests.h"
      10  
      11  #include <stdio.h>
      12  #include <string.h>
      13  #include <stdint.h>
      14  #include <net/if.h>
      15  #include "test_nlattr.h"
      16  #include <sys/socket.h>
      17  #include <linux/filter.h>
      18  #include <linux/packet_diag.h>
      19  #include <linux/rtnetlink.h>
      20  #include <linux/sock_diag.h>
      21  
      22  static void
      23  init_packet_diag_msg(struct nlmsghdr *const nlh, const unsigned int msg_len)
      24  {
      25  	SET_STRUCT(struct nlmsghdr, nlh,
      26  		.nlmsg_len = msg_len,
      27  		.nlmsg_type = SOCK_DIAG_BY_FAMILY,
      28  		.nlmsg_flags = NLM_F_DUMP
      29  	);
      30  
      31  	struct packet_diag_msg *const msg = NLMSG_DATA(nlh);
      32  	SET_STRUCT(struct packet_diag_msg, msg,
      33  		.pdiag_family = AF_PACKET,
      34  		.pdiag_type = SOCK_STREAM,
      35  		.pdiag_num = 3,
      36  	);
      37  }
      38  
      39  static void
      40  print_packet_diag_msg(const unsigned int msg_len)
      41  {
      42  	printf("{nlmsg_len=%u, nlmsg_type=SOCK_DIAG_BY_FAMILY"
      43  	       ", nlmsg_flags=NLM_F_DUMP, nlmsg_seq=0, nlmsg_pid=0}"
      44  	       ", {pdiag_family=AF_PACKET"
      45  	       ", pdiag_type=SOCK_STREAM, pdiag_num=ETH_P_ALL"
      46  	       ", pdiag_ino=0, pdiag_cookie=[0, 0]}",
      47  	       msg_len);
      48  }
      49  
      50  static void
      51  print_packet_diag_mclist(const struct packet_diag_mclist *const dml, size_t i)
      52  {
      53  	printf("{pdmc_index=" IFINDEX_LO_STR);
      54  	printf(", ");
      55  	PRINT_FIELD_U(*dml, pdmc_count);
      56  	printf(", ");
      57  	PRINT_FIELD_U(*dml, pdmc_type);
      58  	printf(", ");
      59  	PRINT_FIELD_U(*dml, pdmc_alen);
      60  	printf(", pdmc_addr=");
      61  	print_quoted_hex(dml->pdmc_addr, dml->pdmc_alen);
      62  	printf("}");
      63  }
      64  
      65  static const struct sock_filter filter[] = {
      66  	BPF_STMT(BPF_LD|BPF_B|BPF_ABS, SKF_AD_OFF+SKF_AD_PKTTYPE),
      67  	BPF_STMT(BPF_RET|BPF_K, 0x2a)
      68  };
      69  
      70  static void
      71  print_sock_filter(const struct sock_filter *const f, size_t i)
      72  {
      73  	if (f == filter)
      74  		printf("BPF_STMT(BPF_LD|BPF_B|BPF_ABS"
      75  		       ", SKF_AD_OFF+SKF_AD_PKTTYPE)");
      76  	else
      77  		printf("BPF_STMT(BPF_RET|BPF_K, 0x2a)");
      78  }
      79  
      80  int
      81  main(void)
      82  {
      83  	skip_if_unavailable("/proc/self/fd/");
      84  
      85  	struct packet_diag_info pinfo = {
      86  		.pdi_index = ifindex_lo(),
      87  		.pdi_version = 2,
      88  		.pdi_reserve = 0xcfaacdaf,
      89  		.pdi_copy_thresh = 0xdabacdaf,
      90  		.pdi_tstamp = 0xeafbaadf,
      91  		.pdi_flags = PDI_RUNNING
      92  	};
      93  	const struct packet_diag_mclist dml[] = {
      94  		{
      95  			.pdmc_index = ifindex_lo(),
      96  			.pdmc_count = 0xabcdaefc,
      97  			.pdmc_type = 0xcdaf,
      98  			.pdmc_alen = 4,
      99  			.pdmc_addr = "1234"
     100  		},
     101  		{
     102  			.pdmc_index = ifindex_lo(),
     103  			.pdmc_count = 0xdaefeafc,
     104  			.pdmc_type = 0xadef,
     105  			.pdmc_alen = 4,
     106  			.pdmc_addr = "5678"
     107  		}
     108  	};
     109  	static const struct packet_diag_ring pdr = {
     110  		.pdr_block_size = 0xabcdafed,
     111  		.pdr_block_nr = 0xbcadefae,
     112  		.pdr_frame_size = 0xcabdfeac,
     113  		.pdr_frame_nr = 0xdeaeadef,
     114  		.pdr_retire_tmo = 0xedbafeac,
     115  		.pdr_sizeof_priv = 0xfeadeacd,
     116  		.pdr_features = 0xadebadea
     117  	};
     118  
     119  	int fd = create_nl_socket(NETLINK_SOCK_DIAG);
     120  	const unsigned int hdrlen = sizeof(struct packet_diag_msg);
     121  	void *const nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen),
     122  					 NLA_HDRLEN + sizeof(dml));
     123  
     124  	static char pattern[4096];
     125  	fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);
     126  
     127  	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
     128  			   init_packet_diag_msg, print_packet_diag_msg,
     129  			   PACKET_DIAG_INFO, pattern, pinfo,
     130  			   printf("{pdi_index=%s", IFINDEX_LO_STR);
     131  			   printf(", pdi_version=TPACKET_V3");
     132  			   printf(", ");
     133  			   PRINT_FIELD_U(pinfo, pdi_reserve);
     134  			   printf(", ");
     135  			   PRINT_FIELD_U(pinfo, pdi_copy_thresh);
     136  			   printf(", ");
     137  			   PRINT_FIELD_U(pinfo, pdi_tstamp);
     138  			   printf(", pdi_flags=PDI_RUNNING}"));
     139  
     140  	TEST_NLATTR_ARRAY(fd, nlh0, hdrlen,
     141  			  init_packet_diag_msg, print_packet_diag_msg,
     142  			  PACKET_DIAG_MCLIST, pattern, dml,
     143  			  print_packet_diag_mclist);
     144  
     145  	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
     146  			   init_packet_diag_msg, print_packet_diag_msg,
     147  			   PACKET_DIAG_RX_RING, pattern, pdr,
     148  			   printf("{");
     149  			   PRINT_FIELD_U(pdr, pdr_block_size);
     150  			   printf(", ");
     151  			   PRINT_FIELD_U(pdr, pdr_block_nr);
     152  			   printf(", ");
     153  			   PRINT_FIELD_U(pdr, pdr_frame_size);
     154  			   printf(", ");
     155  			   PRINT_FIELD_U(pdr, pdr_frame_nr);
     156  			   printf(", ");
     157  			   PRINT_FIELD_U(pdr, pdr_retire_tmo);
     158  			   printf(", ");
     159  			   PRINT_FIELD_U(pdr, pdr_sizeof_priv);
     160  			   printf(", ");
     161  			   PRINT_FIELD_U(pdr, pdr_features);
     162  			   printf("}"));
     163  
     164  	TEST_NLATTR_ARRAY(fd, nlh0, hdrlen,
     165  			  init_packet_diag_msg, print_packet_diag_msg,
     166  			  PACKET_DIAG_FILTER, pattern, filter,
     167  			  print_sock_filter);
     168  
     169  	printf("+++ exited with 0 +++\n");
     170  	return 0;
     171  }