xref: /dragonfly/usr.sbin/mtest/mtest.c (revision 984263bc)
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 #ifndef lint
9 static const char rcsid[] =
10   "$FreeBSD: src/usr.sbin/mtest/mtest.c,v 1.4.6.1 2001/07/19 05:09:25 kris Exp $";
11 #endif /* not lint */
12 
13 #include <err.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <sys/types.h>
17 #include <sys/socket.h>
18 #include <sys/time.h>
19 #include <net/if.h>
20 #include <net/if_dl.h>
21 #include <sys/ioctl.h>
22 #include <netinet/in.h>
23 
24 int
25 main( argc, argv )
26     int argc;
27     char **argv;
28   {
29     int so;
30     char line[80];
31     char *lineptr;
32     struct ip_mreq imr;
33     struct ifreq ifr;
34     int n, f;
35     unsigned i1, i2, i3, i4, g1, g2, g3, g4;
36     unsigned e1, e2, e3, e4, e5, e6;
37 
38     if( (so = socket( AF_INET, SOCK_DGRAM, 0 )) == -1)
39 	err( 1, "can't open socket" );
40 
41     printf( "multicast membership test program; " );
42     printf( "enter ? for list of commands\n" );
43 
44     while( fgets( line, 79, stdin ) != NULL )
45       {
46 	lineptr = line;
47 	while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr;
48 	switch( *lineptr )
49 	  {
50 	    case '?':
51 	      {
52 		printf( "%s%s%s%s%s%s%s",
53 		" j g.g.g.g i.i.i.i      - join  IP  multicast group     \n",
54 		" l g.g.g.g i.i.i.i      - leave IP  multicast group     \n",
55 		" a ifname e.e.e.e.e.e   - add ether multicast address   \n",
56 		" d ifname e.e.e.e.e.e   - del ether multicast address   \n",
57 		" m ifname 1/0           - set/clear ether allmulti flag \n",
58 		" p ifname 1/0           - set/clear ether promisc flag  \n",
59 		" q                      - quit                      \n\n" );
60 		break;
61 	      }
62 
63 	    case 'j':
64 	      {
65 		++lineptr;
66 		while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr;
67 		if( (n = sscanf( lineptr, "%u.%u.%u.%u %u.%u.%u.%u",
68 		    &g1, &g2, &g3, &g4, &i1, &i2, &i3, &i4 )) != 8 )
69 		  {
70 		    printf( "bad args\n" );
71 		    break;
72 		  }
73 		imr.imr_multiaddr.s_addr = (g1<<24) | (g2<<16) | (g3<<8) | g4;
74 		imr.imr_multiaddr.s_addr = htonl(imr.imr_multiaddr.s_addr);
75 		imr.imr_interface.s_addr = (i1<<24) | (i2<<16) | (i3<<8) | i4;
76 		imr.imr_interface.s_addr = htonl(imr.imr_interface.s_addr);
77 		if( setsockopt( so, IPPROTO_IP, IP_ADD_MEMBERSHIP,
78 				&imr, sizeof(struct ip_mreq) ) == -1 )
79 		     warn( "can't join group" );
80 		else printf( "group joined\n" );
81 		break;
82 	      }
83 
84 	    case 'l':
85 	      {
86 		++lineptr;
87 		while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr;
88 		if( (n = sscanf( lineptr, "%u.%u.%u.%u %u.%u.%u.%u",
89 		    &g1, &g2, &g3, &g4, &i1, &i2, &i3, &i4 )) != 8 )
90 		  {
91 		    printf( "bad args\n" );
92 		    break;
93 		  }
94 		imr.imr_multiaddr.s_addr = (g1<<24) | (g2<<16) | (g3<<8) | g4;
95 		imr.imr_multiaddr.s_addr = htonl(imr.imr_multiaddr.s_addr);
96 		imr.imr_interface.s_addr = (i1<<24) | (i2<<16) | (i3<<8) | i4;
97 		imr.imr_interface.s_addr = htonl(imr.imr_interface.s_addr);
98 		if( setsockopt( so, IPPROTO_IP, IP_DROP_MEMBERSHIP,
99 				&imr, sizeof(struct ip_mreq) ) == -1 )
100 		     warn( "can't leave group" );
101 		else printf( "group left\n" );
102 		break;
103 	      }
104 
105 	    case 'a':
106 	      {
107 		struct sockaddr_dl *dlp;
108 		unsigned char *bp;
109 		++lineptr;
110 		while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr;
111 		if( (n = sscanf( lineptr, "%s %x.%x.%x.%x.%x.%x",
112 			ifr.ifr_name, &e1, &e2, &e3, &e4, &e5, &e6 )) != 7 )
113 		  {
114 		    printf( "bad args\n" );
115 		    break;
116 		  }
117 		dlp = (struct sockaddr_dl *)&ifr.ifr_addr;
118 		dlp->sdl_len = sizeof(struct sockaddr_dl);
119 		dlp->sdl_family = AF_LINK;
120 		dlp->sdl_index = 0;
121 		dlp->sdl_nlen = 0;
122 		dlp->sdl_alen = 6;
123 		dlp->sdl_slen = 0;
124 		bp = LLADDR(dlp);
125 		bp[0] = e1;
126 		bp[1] = e2;
127 		bp[2] = e3;
128 		bp[3] = e4;
129 		bp[4] = e5;
130 		bp[5] = e6;
131 		if( ioctl( so, SIOCADDMULTI, &ifr ) == -1 )
132 		     warn( "can't add ether address" );
133 		else printf( "ether address added\n" );
134 		break;
135 	      }
136 
137 	    case 'd':
138 	      {
139 		struct sockaddr_dl *dlp;
140 		unsigned char *bp;
141 		++lineptr;
142 		while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr;
143 		if( (n = sscanf( lineptr, "%s %x.%x.%x.%x.%x.%x",
144 			ifr.ifr_name, &e1, &e2, &e3, &e4, &e5, &e6 )) != 7 )
145 		  {
146 		    printf( "bad args\n" );
147 		    break;
148 		  }
149 		dlp = (struct sockaddr_dl *)&ifr.ifr_addr;
150 		dlp->sdl_len = sizeof(struct sockaddr_dl);
151 		dlp->sdl_family = AF_LINK;
152 		dlp->sdl_index = 0;
153 		dlp->sdl_nlen = 0;
154 		dlp->sdl_alen = 6;
155 		dlp->sdl_slen = 0;
156 		bp = LLADDR(dlp);
157 		bp[0] = e1;
158 		bp[1] = e2;
159 		bp[2] = e3;
160 		bp[3] = e4;
161 		bp[4] = e5;
162 		bp[5] = e6;
163 		if( ioctl( so, SIOCDELMULTI, &ifr ) == -1 )
164 		     warn( "can't delete ether address" );
165 		else printf( "ether address deleted\n" );
166 		break;
167 	      }
168 
169 	    case 'm':
170 	      {
171 		++lineptr;
172 		while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr;
173 		if( (n = sscanf( lineptr, "%s %u", ifr.ifr_name, &f )) != 2 )
174 		  {
175 		    printf( "bad args\n" );
176 		    break;
177 		  }
178 		if( ioctl( so, SIOCGIFFLAGS, &ifr ) == -1 )
179 		  {
180 		    warn( "can't get interface flags" );
181 		    break;
182 		  }
183 		printf( "interface flags %x, ", ifr.ifr_flags );
184 		fflush( stdout );
185 		if( f ) ifr.ifr_flags |=  IFF_ALLMULTI;
186 		else    ifr.ifr_flags &= ~IFF_ALLMULTI;
187 		if( ioctl( so, SIOCSIFFLAGS, &ifr ) == -1 )
188 		     warn( "can't set" );
189 		else printf( "changed to %x\n", ifr.ifr_flags );
190 		break;
191 	      }
192 
193 	    case 'p':
194 	      {
195 		++lineptr;
196 		while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr;
197 		if( (n = sscanf( lineptr, "%s %u", ifr.ifr_name, &f )) != 2 )
198 		  {
199 		    printf( "bad args\n" );
200 		    break;
201 		  }
202 		if( ioctl( so, SIOCGIFFLAGS, &ifr ) == -1 )
203 		  {
204 		    warn( "can't get interface flags" );
205 		    break;
206 		  }
207 		printf( "interface flags %x, ", ifr.ifr_flags );
208 		fflush( stdout );
209 		if( f ) ifr.ifr_flags |=  IFF_PROMISC;
210 		else    ifr.ifr_flags &= ~IFF_PROMISC;
211 		if( ioctl( so, SIOCSIFFLAGS, &ifr ) == -1 )
212 		     warn( "can't set" );
213 		else printf( "changed to %x\n", ifr.ifr_flags );
214 		break;
215 	      }
216 
217 	    case 'q': exit( 0 );
218 
219 	    case 0:
220 	    case '\n': break;
221 
222 	    default:
223 	      {
224 		printf( "bad command\n" );
225 		break;
226 	      }
227 	  }
228       }
229   return(0);
230   }
231