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