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