mtest.c revision 20531
120529Sfenner/* 220529Sfenner * Program to test new [sg]etsockopts and ioctls for manipulating IP and 320529Sfenner * Ethernet multicast address filters. 420529Sfenner * 520529Sfenner * Written by Steve Deering, Stanford University, February 1989. 620529Sfenner */ 720529Sfenner 820529Sfenner#include <stdio.h> 920529Sfenner#include <sys/types.h> 1020529Sfenner#include <sys/socket.h> 1120531Sfenner#include <sys/time.h> 1220529Sfenner#include <net/if.h> 1320529Sfenner#include <sys/ioctl.h> 1420529Sfenner#include <netinet/in.h> 1520529Sfenner 1620529Sfennermain( argc, argv ) 1720529Sfenner int argc; 1820529Sfenner char **argv; 1920529Sfenner { 2020529Sfenner int so; 2120529Sfenner char line[80]; 2220529Sfenner char *lineptr; 2320529Sfenner struct ip_mreq imr; 2420529Sfenner struct ifreq ifr; 2520529Sfenner int n, f; 2620529Sfenner unsigned i1, i2, i3, i4, g1, g2, g3, g4; 2720529Sfenner unsigned e1, e2, e3, e4, e5, e6; 2820529Sfenner 2920529Sfenner if( (so = socket( AF_INET, SOCK_DGRAM, 0 )) == -1) 3020529Sfenner { 3120529Sfenner perror( "can't open socket" ); 3220529Sfenner exit( 1 ); 3320529Sfenner } 3420529Sfenner 3520529Sfenner printf( "multicast membership test program; " ); 3620529Sfenner printf( "enter ? for list of commands\n" ); 3720529Sfenner 3820529Sfenner while( fgets( line, 79, stdin ) != NULL ) 3920529Sfenner { 4020529Sfenner lineptr = line; 4120529Sfenner while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr; 4220529Sfenner switch( *lineptr ) 4320529Sfenner { 4420529Sfenner case '?': 4520529Sfenner { 4620529Sfenner printf( "%s%s%s%s%s%s%s", 4720529Sfenner " j g.g.g.g i.i.i.i - join IP multicast group \n", 4820529Sfenner " l g.g.g.g i.i.i.i - leave IP multicast group \n", 4920529Sfenner " a ifname e.e.e.e.e.e - add ether multicast address \n", 5020529Sfenner " d ifname e.e.e.e.e.e - del ether multicast address \n", 5120529Sfenner " m ifname 1/0 - set/clear ether allmulti flag \n", 5220529Sfenner " p ifname 1/0 - set/clear ether promisc flag \n", 5320529Sfenner " q - quit \n\n" ); 5420529Sfenner break; 5520529Sfenner } 5620529Sfenner 5720529Sfenner case 'j': 5820529Sfenner { 5920529Sfenner ++lineptr; 6020529Sfenner while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr; 6120529Sfenner if( (n = sscanf( lineptr, "%u.%u.%u.%u %u.%u.%u.%u %u", 6220529Sfenner &g1, &g2, &g3, &g4, &i1, &i2, &i3, &i4 )) != 8 ) 6320529Sfenner { 6420529Sfenner printf( "bad args\n" ); 6520529Sfenner break; 6620529Sfenner } 6720529Sfenner imr.imr_multiaddr.s_addr = (g1<<24) | (g2<<16) | (g3<<8) | g4; 6820529Sfenner imr.imr_multiaddr.s_addr = htonl(imr.imr_multiaddr.s_addr); 6920529Sfenner imr.imr_interface.s_addr = (i1<<24) | (i2<<16) | (i3<<8) | i4; 7020529Sfenner imr.imr_interface.s_addr = htonl(imr.imr_interface.s_addr); 7120529Sfenner if( setsockopt( so, IPPROTO_IP, IP_ADD_MEMBERSHIP, 7220529Sfenner &imr, sizeof(struct ip_mreq) ) == -1 ) 7320529Sfenner perror( "can't join group" ); 7420529Sfenner else printf( "group joined\n" ); 7520529Sfenner break; 7620529Sfenner } 7720529Sfenner 7820529Sfenner case 'l': 7920529Sfenner { 8020529Sfenner ++lineptr; 8120529Sfenner while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr; 8220529Sfenner if( (n = sscanf( lineptr, "%u.%u.%u.%u %u.%u.%u.%u %u", 8320529Sfenner &g1, &g2, &g3, &g4, &i1, &i2, &i3, &i4 )) != 8 ) 8420529Sfenner { 8520529Sfenner printf( "bad args\n" ); 8620529Sfenner break; 8720529Sfenner } 8820529Sfenner imr.imr_multiaddr.s_addr = (g1<<24) | (g2<<16) | (g3<<8) | g4; 8920529Sfenner imr.imr_multiaddr.s_addr = htonl(imr.imr_multiaddr.s_addr); 9020529Sfenner imr.imr_interface.s_addr = (i1<<24) | (i2<<16) | (i3<<8) | i4; 9120529Sfenner imr.imr_interface.s_addr = htonl(imr.imr_interface.s_addr); 9220529Sfenner if( setsockopt( so, IPPROTO_IP, IP_DROP_MEMBERSHIP, 9320529Sfenner &imr, sizeof(struct ip_mreq) ) == -1 ) 9420529Sfenner perror( "can't leave group" ); 9520529Sfenner else printf( "group left\n" ); 9620529Sfenner break; 9720529Sfenner } 9820529Sfenner 9920529Sfenner case 'a': 10020529Sfenner { 10120529Sfenner ++lineptr; 10220529Sfenner while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr; 10320529Sfenner if( (n = sscanf( lineptr, "%s %x.%x.%x.%x.%x.%x", 10420529Sfenner ifr.ifr_name, &e1, &e2, &e3, &e4, &e5, &e6 )) != 7 ) 10520529Sfenner { 10620529Sfenner printf( "bad args\n" ); 10720529Sfenner break; 10820529Sfenner } 10920529Sfenner ifr.ifr_addr.sa_family = AF_UNSPEC; 11020529Sfenner ifr.ifr_addr.sa_data[0] = e1; 11120529Sfenner ifr.ifr_addr.sa_data[1] = e2; 11220529Sfenner ifr.ifr_addr.sa_data[2] = e3; 11320529Sfenner ifr.ifr_addr.sa_data[3] = e4; 11420529Sfenner ifr.ifr_addr.sa_data[4] = e5; 11520529Sfenner ifr.ifr_addr.sa_data[5] = e6; 11620529Sfenner if( ioctl( so, SIOCADDMULTI, &ifr ) == -1 ) 11720529Sfenner perror( "can't add ether adress" ); 11820529Sfenner else printf( "ether address added\n" ); 11920529Sfenner break; 12020529Sfenner } 12120529Sfenner 12220529Sfenner case 'd': 12320529Sfenner { 12420529Sfenner ++lineptr; 12520529Sfenner while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr; 12620529Sfenner if( (n = sscanf( lineptr, "%s %x.%x.%x.%x.%x.%x", 12720529Sfenner ifr.ifr_name, &e1, &e2, &e3, &e4, &e5, &e6 )) != 7 ) 12820529Sfenner { 12920529Sfenner printf( "bad args\n" ); 13020529Sfenner break; 13120529Sfenner } 13220529Sfenner ifr.ifr_addr.sa_family = AF_UNSPEC; 13320529Sfenner ifr.ifr_addr.sa_data[0] = e1; 13420529Sfenner ifr.ifr_addr.sa_data[1] = e2; 13520529Sfenner ifr.ifr_addr.sa_data[2] = e3; 13620529Sfenner ifr.ifr_addr.sa_data[3] = e4; 13720529Sfenner ifr.ifr_addr.sa_data[4] = e5; 13820529Sfenner ifr.ifr_addr.sa_data[5] = e6; 13920529Sfenner if( ioctl( so, SIOCDELMULTI, &ifr ) == -1 ) 14020529Sfenner perror( "can't delete ether adress" ); 14120529Sfenner else printf( "ether address deleted\n" ); 14220529Sfenner break; 14320529Sfenner } 14420529Sfenner 14520529Sfenner case 'm': 14620529Sfenner { 14720529Sfenner ++lineptr; 14820529Sfenner while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr; 14920529Sfenner if( (n = sscanf( lineptr, "%s %u", ifr.ifr_name, &f )) != 2 ) 15020529Sfenner { 15120529Sfenner printf( "bad args\n" ); 15220529Sfenner break; 15320529Sfenner } 15420529Sfenner if( ioctl( so, SIOCGIFFLAGS, &ifr ) == -1 ) 15520529Sfenner { 15620529Sfenner perror( "can't get interface flags" ); 15720529Sfenner break; 15820529Sfenner } 15920529Sfenner printf( "interface flags %x, ", ifr.ifr_flags ); 16020529Sfenner fflush( stdout ); 16120529Sfenner if( f ) ifr.ifr_flags |= IFF_ALLMULTI; 16220529Sfenner else ifr.ifr_flags &= ~IFF_ALLMULTI; 16320529Sfenner if( ioctl( so, SIOCSIFFLAGS, &ifr ) == -1 ) 16420529Sfenner perror( "can't set" ); 16520529Sfenner else printf( "changed to %x\n", ifr.ifr_flags ); 16620529Sfenner break; 16720529Sfenner } 16820529Sfenner 16920529Sfenner case 'p': 17020529Sfenner { 17120529Sfenner ++lineptr; 17220529Sfenner while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr; 17320529Sfenner if( (n = sscanf( lineptr, "%s %u", ifr.ifr_name, &f )) != 2 ) 17420529Sfenner { 17520529Sfenner printf( "bad args\n" ); 17620529Sfenner break; 17720529Sfenner } 17820529Sfenner if( ioctl( so, SIOCGIFFLAGS, &ifr ) == -1 ) 17920529Sfenner { 18020529Sfenner perror( "can't get interface flags" ); 18120529Sfenner break; 18220529Sfenner } 18320529Sfenner printf( "interface flags %x, ", ifr.ifr_flags ); 18420529Sfenner fflush( stdout ); 18520529Sfenner if( f ) ifr.ifr_flags |= IFF_PROMISC; 18620529Sfenner else ifr.ifr_flags &= ~IFF_PROMISC; 18720529Sfenner if( ioctl( so, SIOCSIFFLAGS, &ifr ) == -1 ) 18820529Sfenner perror( "can't set" ); 18920529Sfenner else printf( "changed to %x\n", ifr.ifr_flags ); 19020529Sfenner break; 19120529Sfenner } 19220529Sfenner 19320529Sfenner case 'q': exit( 0 ); 19420529Sfenner 19520529Sfenner case 0: 19620529Sfenner case '\n': break; 19720529Sfenner 19820529Sfenner default: 19920529Sfenner { 20020529Sfenner printf( "bad command\n" ); 20120529Sfenner break; 20220529Sfenner } 20320529Sfenner } 20420529Sfenner } 20520529Sfenner } 206