Home | History | Annotate | Download | only in tests-m32
      1 #include "tests.h"
      2 #include <stdio.h>
      3 #include <sys/socket.h>
      4 #include <linux/if_packet.h>
      5 
      6 static const char *errstr;
      7 
      8 static long
      9 packet_mreq_membership(int optname, void *optval, socklen_t len)
     10 {
     11 	long rc = setsockopt(-1, SOL_PACKET, optname, optval, len);
     12 	errstr = sprintrc(rc);
     13 	return rc;
     14 }
     15 
     16 static void
     17 test_packet_mreq(const int optname, const char *const optname_str)
     18 {
     19 	TAIL_ALLOC_OBJECT_CONST_PTR(struct packet_mreq, pmreq);
     20 	socklen_t len = sizeof(struct packet_mreq);
     21 
     22 	/* setsockopt with optname unknown */
     23 	packet_mreq_membership(-1, NULL, 0);
     24 	printf("setsockopt(-1, SOL_PACKET, %#x /* PACKET_??? */, NULL, 0) = %s\n",
     25 	       -1, errstr);
     26 
     27 	/* setsockopt with mr_type unknown */
     28 	pmreq->mr_ifindex = 0;
     29 	pmreq->mr_alen = ARRAY_SIZE(pmreq->mr_address);
     30 	packet_mreq_membership(optname, pmreq, len);
     31 	printf("setsockopt(-1, SOL_PACKET, %s, {mr_ifindex=%d,"
     32 	       " mr_type=%#x /* PACKET_MR_??? */, mr_alen=%d, mr_address=",
     33 	       optname_str, pmreq->mr_ifindex, pmreq->mr_type, pmreq->mr_alen);
     34 	for (unsigned int i = 0; i < ARRAY_SIZE(pmreq->mr_address); i++) {
     35 		printf("%02x", pmreq->mr_address[i]);
     36 	}
     37 	printf("}, %d) = %s\n", len, errstr);
     38 
     39 	/* setsockopt with mr_type unknown and mr_alen > sizeof(mr_address) */
     40 	pmreq->mr_alen = ARRAY_SIZE(pmreq->mr_address) + 1;
     41 	packet_mreq_membership(optname, pmreq, len);
     42 	printf("setsockopt(-1, SOL_PACKET, %s, {mr_ifindex=%d,"
     43 	       " mr_type=%#x /* PACKET_MR_??? */, mr_alen=%d, mr_address=",
     44 	       optname_str, pmreq->mr_ifindex, pmreq->mr_type, pmreq->mr_alen);
     45 	for (unsigned int i = 0; i < ARRAY_SIZE(pmreq->mr_address); i++) {
     46 		printf("%02x", pmreq->mr_address[i]);
     47 	}
     48 	printf("}, %d) = %s\n", len, errstr);
     49 
     50 	/* setsockopt with mr_type unknown and mr_alen < sizeof(mr_address) */
     51 	pmreq->mr_alen = ARRAY_SIZE(pmreq->mr_address) - 1;
     52 	packet_mreq_membership(optname, pmreq, len);
     53 	printf("setsockopt(-1, SOL_PACKET, %s, {mr_ifindex=%d,"
     54 	       " mr_type=%#x /* PACKET_MR_??? */, mr_alen=%d, mr_address=",
     55 	       optname_str, pmreq->mr_ifindex, pmreq->mr_type, pmreq->mr_alen);
     56 	for (unsigned int i = 0; i < pmreq->mr_alen; i++) {
     57 		printf("%02x", pmreq->mr_address[i]);
     58 	}
     59 	printf("}, %d) = %s\n", len, errstr);
     60 
     61 	/* setsockopt with valid mr_type */
     62 	pmreq->mr_alen = ARRAY_SIZE(pmreq->mr_address);
     63 	static const struct {
     64 		unsigned short type;
     65 		const char *const type_str;
     66 	} a[] = {
     67 		{ ARG_STR(PACKET_MR_MULTICAST) },
     68 		{ ARG_STR(PACKET_MR_PROMISC) },
     69 		{ ARG_STR(PACKET_MR_ALLMULTI) },
     70 #ifdef PACKET_MR_UNICAST
     71 		{ ARG_STR(PACKET_MR_UNICAST) },
     72 #endif
     73 	};
     74 
     75 	for (unsigned int i = 0; i < ARRAY_SIZE(a); i++) {
     76 		pmreq->mr_type = a[i].type;
     77 		packet_mreq_membership(optname, pmreq, len);
     78 		printf("setsockopt(-1, SOL_PACKET, %s, {mr_ifindex=%d,"
     79 		       " mr_type=%s, mr_alen=%d, mr_address=",
     80 		       optname_str, pmreq->mr_ifindex, a[i].type_str, pmreq->mr_alen);
     81 		for (unsigned int i = 0; i < pmreq->mr_alen; i++) {
     82 			printf("%02x", pmreq->mr_address[i]);
     83 		}
     84 		printf("}, %d) = %s\n", len, errstr);
     85 	}
     86 
     87 	/* setsockopt with optlen larger than usual */
     88 	len = len + 1;
     89 	packet_mreq_membership(optname, pmreq, len);
     90 	printf("setsockopt(-1, SOL_PACKET, %s, %p,"
     91 	       " %d) = %s\n", optname_str, pmreq, len, errstr);
     92 }
     93 
     94 int
     95 main(void)
     96 {
     97 	test_packet_mreq(ARG_STR(PACKET_ADD_MEMBERSHIP));
     98 	test_packet_mreq(ARG_STR(PACKET_DROP_MEMBERSHIP));
     99 
    100 	puts("+++ exited with 0 +++");
    101 	return 0;
    102 }
    103