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