mtest.c revision 20530
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