mtest.c revision 20531
163499Sps/* 263499Sps * Program to test new [sg]etsockopts and ioctls for manipulating IP and 363499Sps * Ethernet multicast address filters. 463499Sps * 563499Sps * Written by Steve Deering, Stanford University, February 1989. 6 */ 7 8#include <stdio.h> 9#include <sys/types.h> 10#include <sys/socket.h> 11#include <sys/time.h> 12#include <net/if.h> 13#include <sys/ioctl.h> 14#include <netinet/in.h> 15 16main( argc, argv ) 17 int argc; 18 char **argv; 19 { 20 int so; 21 char line[80]; 22 char *lineptr; 23 struct ip_mreq imr; 24 struct ifreq ifr; 25 int n, f; 26 unsigned i1, i2, i3, i4, g1, g2, g3, g4; 27 unsigned e1, e2, e3, e4, e5, e6; 28 29 if( (so = socket( AF_INET, SOCK_DGRAM, 0 )) == -1) 30 { 31 perror( "can't open socket" ); 32 exit( 1 ); 33 } 34 35 printf( "multicast membership test program; " ); 36 printf( "enter ? for list of commands\n" ); 37 38 while( fgets( line, 79, stdin ) != NULL ) 39 { 40 lineptr = line; 41 while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr; 42 switch( *lineptr ) 43 { 44 case '?': 45 { 46 printf( "%s%s%s%s%s%s%s", 47 " j g.g.g.g i.i.i.i - join IP multicast group \n", 48 " l g.g.g.g i.i.i.i - leave IP multicast group \n", 49 " a ifname e.e.e.e.e.e - add ether multicast address \n", 50 " d ifname e.e.e.e.e.e - del ether multicast address \n", 51 " m ifname 1/0 - set/clear ether allmulti flag \n", 52 " p ifname 1/0 - set/clear ether promisc flag \n", 53 " q - quit \n\n" ); 54 break; 55 } 56 57 case 'j': 58 { 59 ++lineptr; 60 while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr; 61 if( (n = sscanf( lineptr, "%u.%u.%u.%u %u.%u.%u.%u %u", 62 &g1, &g2, &g3, &g4, &i1, &i2, &i3, &i4 )) != 8 ) 63 { 64 printf( "bad args\n" ); 65 break; 66 } 67 imr.imr_multiaddr.s_addr = (g1<<24) | (g2<<16) | (g3<<8) | g4; 68 imr.imr_multiaddr.s_addr = htonl(imr.imr_multiaddr.s_addr); 69 imr.imr_interface.s_addr = (i1<<24) | (i2<<16) | (i3<<8) | i4; 70 imr.imr_interface.s_addr = htonl(imr.imr_interface.s_addr); 71 if( setsockopt( so, IPPROTO_IP, IP_ADD_MEMBERSHIP, 72 &imr, sizeof(struct ip_mreq) ) == -1 ) 73 perror( "can't join group" ); 74 else printf( "group joined\n" ); 75 break; 76 } 77 78 case 'l': 79 { 80 ++lineptr; 81 while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr; 82 if( (n = sscanf( lineptr, "%u.%u.%u.%u %u.%u.%u.%u %u", 83 &g1, &g2, &g3, &g4, &i1, &i2, &i3, &i4 )) != 8 ) 84 { 85 printf( "bad args\n" ); 86 break; 87 } 88 imr.imr_multiaddr.s_addr = (g1<<24) | (g2<<16) | (g3<<8) | g4; 89 imr.imr_multiaddr.s_addr = htonl(imr.imr_multiaddr.s_addr); 90 imr.imr_interface.s_addr = (i1<<24) | (i2<<16) | (i3<<8) | i4; 91 imr.imr_interface.s_addr = htonl(imr.imr_interface.s_addr); 92 if( setsockopt( so, IPPROTO_IP, IP_DROP_MEMBERSHIP, 93 &imr, sizeof(struct ip_mreq) ) == -1 ) 94 perror( "can't leave group" ); 95 else printf( "group left\n" ); 96 break; 97 } 98 99 case 'a': 100 { 101 ++lineptr; 102 while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr; 103 if( (n = sscanf( lineptr, "%s %x.%x.%x.%x.%x.%x", 104 ifr.ifr_name, &e1, &e2, &e3, &e4, &e5, &e6 )) != 7 ) 105 { 106 printf( "bad args\n" ); 107 break; 108 } 109 ifr.ifr_addr.sa_family = AF_UNSPEC; 110 ifr.ifr_addr.sa_data[0] = e1; 111 ifr.ifr_addr.sa_data[1] = e2; 112 ifr.ifr_addr.sa_data[2] = e3; 113 ifr.ifr_addr.sa_data[3] = e4; 114 ifr.ifr_addr.sa_data[4] = e5; 115 ifr.ifr_addr.sa_data[5] = e6; 116 if( ioctl( so, SIOCADDMULTI, &ifr ) == -1 ) 117 perror( "can't add ether adress" ); 118 else printf( "ether address added\n" ); 119 break; 120 } 121 122 case 'd': 123 { 124 ++lineptr; 125 while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr; 126 if( (n = sscanf( lineptr, "%s %x.%x.%x.%x.%x.%x", 127 ifr.ifr_name, &e1, &e2, &e3, &e4, &e5, &e6 )) != 7 ) 128 { 129 printf( "bad args\n" ); 130 break; 131 } 132 ifr.ifr_addr.sa_family = AF_UNSPEC; 133 ifr.ifr_addr.sa_data[0] = e1; 134 ifr.ifr_addr.sa_data[1] = e2; 135 ifr.ifr_addr.sa_data[2] = e3; 136 ifr.ifr_addr.sa_data[3] = e4; 137 ifr.ifr_addr.sa_data[4] = e5; 138 ifr.ifr_addr.sa_data[5] = e6; 139 if( ioctl( so, SIOCDELMULTI, &ifr ) == -1 ) 140 perror( "can't delete ether adress" ); 141 else printf( "ether address deleted\n" ); 142 break; 143 } 144 145 case 'm': 146 { 147 ++lineptr; 148 while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr; 149 if( (n = sscanf( lineptr, "%s %u", ifr.ifr_name, &f )) != 2 ) 150 { 151 printf( "bad args\n" ); 152 break; 153 } 154 if( ioctl( so, SIOCGIFFLAGS, &ifr ) == -1 ) 155 { 156 perror( "can't get interface flags" ); 157 break; 158 } 159 printf( "interface flags %x, ", ifr.ifr_flags ); 160 fflush( stdout ); 161 if( f ) ifr.ifr_flags |= IFF_ALLMULTI; 162 else ifr.ifr_flags &= ~IFF_ALLMULTI; 163 if( ioctl( so, SIOCSIFFLAGS, &ifr ) == -1 ) 164 perror( "can't set" ); 165 else printf( "changed to %x\n", ifr.ifr_flags ); 166 break; 167 } 168 169 case 'p': 170 { 171 ++lineptr; 172 while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr; 173 if( (n = sscanf( lineptr, "%s %u", ifr.ifr_name, &f )) != 2 ) 174 { 175 printf( "bad args\n" ); 176 break; 177 } 178 if( ioctl( so, SIOCGIFFLAGS, &ifr ) == -1 ) 179 { 180 perror( "can't get interface flags" ); 181 break; 182 } 183 printf( "interface flags %x, ", ifr.ifr_flags ); 184 fflush( stdout ); 185 if( f ) ifr.ifr_flags |= IFF_PROMISC; 186 else ifr.ifr_flags &= ~IFF_PROMISC; 187 if( ioctl( so, SIOCSIFFLAGS, &ifr ) == -1 ) 188 perror( "can't set" ); 189 else printf( "changed to %x\n", ifr.ifr_flags ); 190 break; 191 } 192 193 case 'q': exit( 0 ); 194 195 case 0: 196 case '\n': break; 197 198 default: 199 { 200 printf( "bad command\n" ); 201 break; 202 } 203 } 204 } 205 } 206