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