xref: /dragonfly/usr.sbin/mtest/mtest.c (revision 74ad0aa1)
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  * $FreeBSD: src/usr.sbin/mtest/mtest.c,v 1.4.6.1 2001/07/19 05:09:25 kris Exp $
8  */
9 
10 #include <err.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <sys/types.h>
14 #include <sys/socket.h>
15 #include <sys/time.h>
16 #include <net/if.h>
17 #include <net/if_dl.h>
18 #include <sys/ioctl.h>
19 #include <netinet/in.h>
20 
21 int
main(void)22 main(void)
23   {
24     int so;
25     char line[80];
26     char *lineptr;
27     struct ip_mreq imr;
28     struct ifreq ifr;
29     int n, f;
30     unsigned i1, i2, i3, i4, g1, g2, g3, g4;
31     unsigned e1, e2, e3, e4, e5, e6;
32 
33     if( (so = socket( AF_INET, SOCK_DGRAM, 0 )) == -1)
34 	err( 1, "can't open socket" );
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",
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 		     warn( "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",
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 		     warn( "can't leave group" );
96 		else printf( "group left\n" );
97 		break;
98 	      }
99 
100 	    case 'a':
101 	      {
102 		struct sockaddr_dl *dlp;
103 		unsigned char *bp;
104 		++lineptr;
105 		while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr;
106 		if( (n = sscanf( lineptr, "%s %x.%x.%x.%x.%x.%x",
107 			ifr.ifr_name, &e1, &e2, &e3, &e4, &e5, &e6 )) != 7 )
108 		  {
109 		    printf( "bad args\n" );
110 		    break;
111 		  }
112 		dlp = (struct sockaddr_dl *)&ifr.ifr_addr;
113 		dlp->sdl_len = sizeof(struct sockaddr_dl);
114 		dlp->sdl_family = AF_LINK;
115 		dlp->sdl_index = 0;
116 		dlp->sdl_nlen = 0;
117 		dlp->sdl_alen = 6;
118 		dlp->sdl_slen = 0;
119 		bp = LLADDR(dlp);
120 		bp[0] = e1;
121 		bp[1] = e2;
122 		bp[2] = e3;
123 		bp[3] = e4;
124 		bp[4] = e5;
125 		bp[5] = e6;
126 		if( ioctl( so, SIOCADDMULTI, &ifr ) == -1 )
127 		     warn( "can't add ether address" );
128 		else printf( "ether address added\n" );
129 		break;
130 	      }
131 
132 	    case 'd':
133 	      {
134 		struct sockaddr_dl *dlp;
135 		unsigned char *bp;
136 		++lineptr;
137 		while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr;
138 		if( (n = sscanf( lineptr, "%s %x.%x.%x.%x.%x.%x",
139 			ifr.ifr_name, &e1, &e2, &e3, &e4, &e5, &e6 )) != 7 )
140 		  {
141 		    printf( "bad args\n" );
142 		    break;
143 		  }
144 		dlp = (struct sockaddr_dl *)&ifr.ifr_addr;
145 		dlp->sdl_len = sizeof(struct sockaddr_dl);
146 		dlp->sdl_family = AF_LINK;
147 		dlp->sdl_index = 0;
148 		dlp->sdl_nlen = 0;
149 		dlp->sdl_alen = 6;
150 		dlp->sdl_slen = 0;
151 		bp = LLADDR(dlp);
152 		bp[0] = e1;
153 		bp[1] = e2;
154 		bp[2] = e3;
155 		bp[3] = e4;
156 		bp[4] = e5;
157 		bp[5] = e6;
158 		if( ioctl( so, SIOCDELMULTI, &ifr ) == -1 )
159 		     warn( "can't delete ether address" );
160 		else printf( "ether address deleted\n" );
161 		break;
162 	      }
163 
164 	    case 'm':
165 	      {
166 		++lineptr;
167 		while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr;
168 		if( (n = sscanf( lineptr, "%s %u", ifr.ifr_name, &f )) != 2 )
169 		  {
170 		    printf( "bad args\n" );
171 		    break;
172 		  }
173 		if( ioctl( so, SIOCGIFFLAGS, &ifr ) == -1 )
174 		  {
175 		    warn( "can't get interface flags" );
176 		    break;
177 		  }
178 		printf( "interface flags %x, ", ifr.ifr_flags );
179 		fflush( stdout );
180 		if( f ) ifr.ifr_flags |=  IFF_ALLMULTI;
181 		else    ifr.ifr_flags &= ~IFF_ALLMULTI;
182 		if( ioctl( so, SIOCSIFFLAGS, &ifr ) == -1 )
183 		     warn( "can't set" );
184 		else printf( "changed to %x\n", ifr.ifr_flags );
185 		break;
186 	      }
187 
188 	    case 'p':
189 	      {
190 		++lineptr;
191 		while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr;
192 		if( (n = sscanf( lineptr, "%s %u", ifr.ifr_name, &f )) != 2 )
193 		  {
194 		    printf( "bad args\n" );
195 		    break;
196 		  }
197 		if( ioctl( so, SIOCGIFFLAGS, &ifr ) == -1 )
198 		  {
199 		    warn( "can't get interface flags" );
200 		    break;
201 		  }
202 		printf( "interface flags %x, ", ifr.ifr_flags );
203 		fflush( stdout );
204 		if( f ) ifr.ifr_flags |=  IFF_PROMISC;
205 		else    ifr.ifr_flags &= ~IFF_PROMISC;
206 		if( ioctl( so, SIOCSIFFLAGS, &ifr ) == -1 )
207 		     warn( "can't set" );
208 		else printf( "changed to %x\n", ifr.ifr_flags );
209 		break;
210 	      }
211 
212 	    case 'q': exit( 0 );
213 
214 	    case 0:
215 	    case '\n': break;
216 
217 	    default:
218 	      {
219 		printf( "bad command\n" );
220 		break;
221 	      }
222 	  }
223       }
224   return(0);
225   }
226