(root)/
strace-6.5/
tests-mx32/
net-packet_mreq.c
       1  /*
       2   * Copyright (c) 2018-2019 The strace developers.
       3   * All rights reserved.
       4   *
       5   * SPDX-License-Identifier: GPL-2.0-or-later
       6   */
       7  
       8  #include "tests.h"
       9  #include <stdio.h>
      10  #include <sys/socket.h>
      11  #include <linux/if_packet.h>
      12  
      13  static const char *errstr;
      14  
      15  static long
      16  packet_mreq_membership(int optname, void *optval, socklen_t len)
      17  {
      18  	long rc = setsockopt(-1, SOL_PACKET, optname, optval, len);
      19  	errstr = sprintrc(rc);
      20  	return rc;
      21  }
      22  
      23  static void
      24  test_packet_mreq(const int optname, const char *const optname_str)
      25  {
      26  	TAIL_ALLOC_OBJECT_CONST_PTR(struct packet_mreq, pmreq);
      27  	socklen_t len = sizeof(struct packet_mreq);
      28  
      29  	/* setsockopt with optname unknown */
      30  	packet_mreq_membership(-1, NULL, 0);
      31  #if XLAT_RAW
      32  	printf("setsockopt(-1, %#x, %#x, NULL, 0) = %s\n",
      33  	       SOL_PACKET, -1, errstr);
      34  #elif XLAT_VERBOSE
      35  	printf("setsockopt(-1, %#x /* SOL_PACKET */, %#x /* PACKET_??? */"
      36  	       ", NULL, 0) = %s\n", SOL_PACKET, -1, errstr);
      37  #else
      38  	printf("setsockopt(-1, SOL_PACKET, %#x /* PACKET_??? */, NULL, 0) = %s\n",
      39  	       -1, errstr);
      40  #endif
      41  
      42  	/* setsockopt with mr_type unknown */
      43  	pmreq->mr_ifindex = 0;
      44  	pmreq->mr_alen = ARRAY_SIZE(pmreq->mr_address);
      45  	packet_mreq_membership(optname, pmreq, len);
      46  #if XLAT_RAW
      47  	printf("setsockopt(-1, %#x, %#x, {mr_ifindex=%d,"
      48  	       " mr_type=%#x, mr_alen=%d, mr_address=",
      49  	       SOL_PACKET, optname, pmreq->mr_ifindex,
      50  	       pmreq->mr_type, pmreq->mr_alen);
      51  	print_quoted_hex((const void *) pmreq->mr_address,
      52  			 ARRAY_SIZE(pmreq->mr_address));
      53  	printf("}, %d) = %s\n", len, errstr);
      54  #elif XLAT_VERBOSE
      55  	printf("setsockopt(-1, %#x /* SOL_PACKET */, %#x /* %s */"
      56  	       ", {mr_ifindex=%d, mr_type=%#x /* PACKET_MR_??? */"
      57  	       ", mr_alen=%d, mr_address=",
      58  	       SOL_PACKET, optname, optname_str, pmreq->mr_ifindex,
      59  	       pmreq->mr_type, pmreq->mr_alen);
      60  	print_quoted_hex((const void *) pmreq->mr_address,
      61  			 ARRAY_SIZE(pmreq->mr_address));
      62  	printf(" /* ");
      63  	for (unsigned int i = 0; i < ARRAY_SIZE(pmreq->mr_address); i++)
      64  		printf("%s%02x", i > 0 ? ":" : "", pmreq->mr_address[i]);
      65  	printf(" */}, %d) = %s\n", len, errstr);
      66  #else
      67  	printf("setsockopt(-1, SOL_PACKET, %s, {mr_ifindex=%d,"
      68  	       " mr_type=%#x /* PACKET_MR_??? */, mr_alen=%d, mr_address=",
      69  	       optname_str, pmreq->mr_ifindex, pmreq->mr_type, pmreq->mr_alen);
      70  	for (unsigned int i = 0; i < ARRAY_SIZE(pmreq->mr_address); i++)
      71  		printf("%s%02x", i > 0 ? ":" : "", pmreq->mr_address[i]);
      72  	printf("}, %d) = %s\n", len, errstr);
      73  #endif
      74  
      75  	/* setsockopt with mr_type unknown and mr_alen > sizeof(mr_address) */
      76  	pmreq->mr_alen = ARRAY_SIZE(pmreq->mr_address) + 1;
      77  	packet_mreq_membership(optname, pmreq, len);
      78  #if XLAT_RAW
      79  	printf("setsockopt(-1, %#x, %#x, {mr_ifindex=%d,"
      80  	       " mr_type=%#x, mr_alen=%d, mr_address=",
      81  	       SOL_PACKET, optname, pmreq->mr_ifindex,
      82  	       pmreq->mr_type, pmreq->mr_alen);
      83  	print_quoted_hex((const void *) pmreq->mr_address,
      84  			 ARRAY_SIZE(pmreq->mr_address));
      85  	printf("}, %d) = %s\n", len, errstr);
      86  #elif XLAT_VERBOSE
      87  	printf("setsockopt(-1, %#x /* SOL_PACKET */, %#x /* %s */"
      88  	       ", {mr_ifindex=%d, mr_type=%#x /* PACKET_MR_??? */"
      89  	       ", mr_alen=%d, mr_address=",
      90  	       SOL_PACKET, optname, optname_str, pmreq->mr_ifindex,
      91  	       pmreq->mr_type, pmreq->mr_alen);
      92  	print_quoted_hex((const void *) pmreq->mr_address,
      93  			 ARRAY_SIZE(pmreq->mr_address));
      94  	printf(" /* ");
      95  	for (unsigned int i = 0; i < ARRAY_SIZE(pmreq->mr_address); i++)
      96  		printf("%s%02x", i > 0 ? ":" : "", pmreq->mr_address[i]);
      97  	printf(" */}, %d) = %s\n", len, errstr);
      98  #else
      99  	printf("setsockopt(-1, SOL_PACKET, %s, {mr_ifindex=%d,"
     100  	       " mr_type=%#x /* PACKET_MR_??? */, mr_alen=%d, mr_address=",
     101  	       optname_str, pmreq->mr_ifindex, pmreq->mr_type, pmreq->mr_alen);
     102  	for (unsigned int i = 0; i < ARRAY_SIZE(pmreq->mr_address); i++)
     103  		printf("%s%02x", i > 0 ? ":" : "", pmreq->mr_address[i]);
     104  	printf("}, %d) = %s\n", len, errstr);
     105  #endif
     106  
     107  	/* setsockopt with mr_type unknown and mr_alen < sizeof(mr_address) */
     108  	pmreq->mr_alen = ARRAY_SIZE(pmreq->mr_address) - 1;
     109  	packet_mreq_membership(optname, pmreq, len);
     110  #if XLAT_RAW
     111  	printf("setsockopt(-1, %#x, %#x, {mr_ifindex=%d,"
     112  	       " mr_type=%#x, mr_alen=%d, mr_address=",
     113  	       SOL_PACKET, optname, pmreq->mr_ifindex,
     114  	       pmreq->mr_type, pmreq->mr_alen);
     115  	print_quoted_hex((const void *) pmreq->mr_address, pmreq->mr_alen);
     116  	printf("}, %d) = %s\n", len, errstr);
     117  #elif XLAT_VERBOSE
     118  	printf("setsockopt(-1, %#x /* SOL_PACKET */, %#x /* %s */"
     119  	       ", {mr_ifindex=%d, mr_type=%#x /* PACKET_MR_??? */"
     120  	       ", mr_alen=%d, mr_address=",
     121  	       SOL_PACKET, optname, optname_str, pmreq->mr_ifindex,
     122  	       pmreq->mr_type, pmreq->mr_alen);
     123  	print_quoted_hex((const void *) pmreq->mr_address, pmreq->mr_alen);
     124  	printf(" /* ");
     125  	for (unsigned int i = 0; i < pmreq->mr_alen; i++)
     126  		printf("%s%02x", i > 0 ? ":" : "", pmreq->mr_address[i]);
     127  	printf(" */}, %d) = %s\n", len, errstr);
     128  #else
     129  	printf("setsockopt(-1, SOL_PACKET, %s, {mr_ifindex=%d,"
     130  	       " mr_type=%#x /* PACKET_MR_??? */, mr_alen=%d, mr_address=",
     131  	       optname_str, pmreq->mr_ifindex, pmreq->mr_type, pmreq->mr_alen);
     132  	for (unsigned int i = 0; i < pmreq->mr_alen; i++)
     133  		printf("%s%02x", i > 0 ? ":" : "", pmreq->mr_address[i]);
     134  	printf("}, %d) = %s\n", len, errstr);
     135  #endif
     136  
     137  	/* setsockopt with valid mr_type */
     138  	pmreq->mr_alen = ARRAY_SIZE(pmreq->mr_address);
     139  	static const struct {
     140  		unsigned short type;
     141  		const char *const type_str;
     142  	} a[] = {
     143  		{ ARG_STR(PACKET_MR_MULTICAST) },
     144  		{ ARG_STR(PACKET_MR_PROMISC) },
     145  		{ ARG_STR(PACKET_MR_ALLMULTI) },
     146  #ifdef PACKET_MR_UNICAST
     147  		{ ARG_STR(PACKET_MR_UNICAST) },
     148  #endif
     149  	};
     150  
     151  	for (unsigned int i = 0; i < ARRAY_SIZE(a); i++) {
     152  		pmreq->mr_type = a[i].type;
     153  		packet_mreq_membership(optname, pmreq, len);
     154  #if XLAT_RAW
     155  		printf("setsockopt(-1, %#x, %#x, {mr_ifindex=%d,"
     156  		       " mr_type=%#x, mr_alen=%d, mr_address=",
     157  		       SOL_PACKET, optname, pmreq->mr_ifindex,
     158  		       pmreq->mr_type, pmreq->mr_alen);
     159  		print_quoted_hex((const void *) pmreq->mr_address, pmreq->mr_alen);
     160  		printf("}, %d) = %s\n", len, errstr);
     161  #elif XLAT_VERBOSE
     162  		printf("setsockopt(-1, %#x /* SOL_PACKET */, %#x /* %s */"
     163  		       ", {mr_ifindex=%d, mr_type=%#x /* %s */"
     164  		       ", mr_alen=%d, mr_address=",
     165  		       SOL_PACKET, optname, optname_str, pmreq->mr_ifindex,
     166  		       pmreq->mr_type, a[i].type_str, pmreq->mr_alen);
     167  		print_quoted_hex((const void *) pmreq->mr_address, pmreq->mr_alen);
     168  		printf(" /* ");
     169  		for (unsigned int i = 0; i < pmreq->mr_alen; i++)
     170  			printf("%s%02x", i > 0 ? ":" : "", pmreq->mr_address[i]);
     171  		printf(" */}, %d) = %s\n", len, errstr);
     172  #else
     173  		printf("setsockopt(-1, SOL_PACKET, %s, {mr_ifindex=%d,"
     174  		       " mr_type=%s, mr_alen=%d, mr_address=",
     175  		       optname_str, pmreq->mr_ifindex, a[i].type_str, pmreq->mr_alen);
     176  		for (unsigned int i = 0; i < pmreq->mr_alen; i++)
     177  			printf("%s%02x", i > 0 ? ":" : "", pmreq->mr_address[i]);
     178  		printf("}, %d) = %s\n", len, errstr);
     179  #endif
     180  	}
     181  
     182  	/* setsockopt with optlen larger than usual */
     183  	len = len + 1;
     184  	packet_mreq_membership(optname, pmreq, len);
     185  #if XLAT_RAW
     186  	printf("setsockopt(-1, %#x, %#x, %p, %d) = %s\n",
     187  	       SOL_PACKET, optname, pmreq, len, errstr);
     188  #elif XLAT_VERBOSE
     189  	printf("setsockopt(-1, %#x /* SOL_PACKET */, %#x /* %s */"
     190  	       ", %p, %d) = %s\n", SOL_PACKET, optname, optname_str,
     191  	       pmreq, len, errstr);
     192  #else
     193  	printf("setsockopt(-1, SOL_PACKET, %s, %p,"
     194  	       " %d) = %s\n", optname_str, pmreq, len, errstr);
     195  #endif
     196  }
     197  
     198  int
     199  main(void)
     200  {
     201  	test_packet_mreq(ARG_STR(PACKET_ADD_MEMBERSHIP));
     202  	test_packet_mreq(ARG_STR(PACKET_DROP_MEMBERSHIP));
     203  
     204  	puts("+++ exited with 0 +++");
     205  	return 0;
     206  }