MFC r1.6 r1.30 r1.28 (HEAD):
[dragonfly.git] / usr.sbin / mtest / mtest.c
blobea19578e548be152091908fd18a904a651c1cbdd
1 /*
2 * Program to test new [sg]etsockopts and ioctls for manipulating IP and
3 * Ethernet multicast address filters.
5 * Written by Steve Deering, Stanford University, February 1989.
7 * $FreeBSD: src/usr.sbin/mtest/mtest.c,v 1.4.6.1 2001/07/19 05:09:25 kris Exp $
8 * $DragonFly: src/usr.sbin/mtest/mtest.c,v 1.2 2003/06/17 04:29:57 dillon Exp $
9 */
11 #include <err.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <sys/time.h>
17 #include <net/if.h>
18 #include <net/if_dl.h>
19 #include <sys/ioctl.h>
20 #include <netinet/in.h>
22 int
23 main( argc, argv )
24 int argc;
25 char **argv;
27 int so;
28 char line[80];
29 char *lineptr;
30 struct ip_mreq imr;
31 struct ifreq ifr;
32 int n, f;
33 unsigned i1, i2, i3, i4, g1, g2, g3, g4;
34 unsigned e1, e2, e3, e4, e5, e6;
36 if( (so = socket( AF_INET, SOCK_DGRAM, 0 )) == -1)
37 err( 1, "can't open socket" );
39 printf( "multicast membership test program; " );
40 printf( "enter ? for list of commands\n" );
42 while( fgets( line, 79, stdin ) != NULL )
44 lineptr = line;
45 while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr;
46 switch( *lineptr )
48 case '?':
50 printf( "%s%s%s%s%s%s%s",
51 " j g.g.g.g i.i.i.i - join IP multicast group \n",
52 " l g.g.g.g i.i.i.i - leave IP multicast group \n",
53 " a ifname e.e.e.e.e.e - add ether multicast address \n",
54 " d ifname e.e.e.e.e.e - del ether multicast address \n",
55 " m ifname 1/0 - set/clear ether allmulti flag \n",
56 " p ifname 1/0 - set/clear ether promisc flag \n",
57 " q - quit \n\n" );
58 break;
61 case 'j':
63 ++lineptr;
64 while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr;
65 if( (n = sscanf( lineptr, "%u.%u.%u.%u %u.%u.%u.%u",
66 &g1, &g2, &g3, &g4, &i1, &i2, &i3, &i4 )) != 8 )
68 printf( "bad args\n" );
69 break;
71 imr.imr_multiaddr.s_addr = (g1<<24) | (g2<<16) | (g3<<8) | g4;
72 imr.imr_multiaddr.s_addr = htonl(imr.imr_multiaddr.s_addr);
73 imr.imr_interface.s_addr = (i1<<24) | (i2<<16) | (i3<<8) | i4;
74 imr.imr_interface.s_addr = htonl(imr.imr_interface.s_addr);
75 if( setsockopt( so, IPPROTO_IP, IP_ADD_MEMBERSHIP,
76 &imr, sizeof(struct ip_mreq) ) == -1 )
77 warn( "can't join group" );
78 else printf( "group joined\n" );
79 break;
82 case 'l':
84 ++lineptr;
85 while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr;
86 if( (n = sscanf( lineptr, "%u.%u.%u.%u %u.%u.%u.%u",
87 &g1, &g2, &g3, &g4, &i1, &i2, &i3, &i4 )) != 8 )
89 printf( "bad args\n" );
90 break;
92 imr.imr_multiaddr.s_addr = (g1<<24) | (g2<<16) | (g3<<8) | g4;
93 imr.imr_multiaddr.s_addr = htonl(imr.imr_multiaddr.s_addr);
94 imr.imr_interface.s_addr = (i1<<24) | (i2<<16) | (i3<<8) | i4;
95 imr.imr_interface.s_addr = htonl(imr.imr_interface.s_addr);
96 if( setsockopt( so, IPPROTO_IP, IP_DROP_MEMBERSHIP,
97 &imr, sizeof(struct ip_mreq) ) == -1 )
98 warn( "can't leave group" );
99 else printf( "group left\n" );
100 break;
103 case 'a':
105 struct sockaddr_dl *dlp;
106 unsigned char *bp;
107 ++lineptr;
108 while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr;
109 if( (n = sscanf( lineptr, "%s %x.%x.%x.%x.%x.%x",
110 ifr.ifr_name, &e1, &e2, &e3, &e4, &e5, &e6 )) != 7 )
112 printf( "bad args\n" );
113 break;
115 dlp = (struct sockaddr_dl *)&ifr.ifr_addr;
116 dlp->sdl_len = sizeof(struct sockaddr_dl);
117 dlp->sdl_family = AF_LINK;
118 dlp->sdl_index = 0;
119 dlp->sdl_nlen = 0;
120 dlp->sdl_alen = 6;
121 dlp->sdl_slen = 0;
122 bp = LLADDR(dlp);
123 bp[0] = e1;
124 bp[1] = e2;
125 bp[2] = e3;
126 bp[3] = e4;
127 bp[4] = e5;
128 bp[5] = e6;
129 if( ioctl( so, SIOCADDMULTI, &ifr ) == -1 )
130 warn( "can't add ether address" );
131 else printf( "ether address added\n" );
132 break;
135 case 'd':
137 struct sockaddr_dl *dlp;
138 unsigned char *bp;
139 ++lineptr;
140 while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr;
141 if( (n = sscanf( lineptr, "%s %x.%x.%x.%x.%x.%x",
142 ifr.ifr_name, &e1, &e2, &e3, &e4, &e5, &e6 )) != 7 )
144 printf( "bad args\n" );
145 break;
147 dlp = (struct sockaddr_dl *)&ifr.ifr_addr;
148 dlp->sdl_len = sizeof(struct sockaddr_dl);
149 dlp->sdl_family = AF_LINK;
150 dlp->sdl_index = 0;
151 dlp->sdl_nlen = 0;
152 dlp->sdl_alen = 6;
153 dlp->sdl_slen = 0;
154 bp = LLADDR(dlp);
155 bp[0] = e1;
156 bp[1] = e2;
157 bp[2] = e3;
158 bp[3] = e4;
159 bp[4] = e5;
160 bp[5] = e6;
161 if( ioctl( so, SIOCDELMULTI, &ifr ) == -1 )
162 warn( "can't delete ether address" );
163 else printf( "ether address deleted\n" );
164 break;
167 case 'm':
169 ++lineptr;
170 while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr;
171 if( (n = sscanf( lineptr, "%s %u", ifr.ifr_name, &f )) != 2 )
173 printf( "bad args\n" );
174 break;
176 if( ioctl( so, SIOCGIFFLAGS, &ifr ) == -1 )
178 warn( "can't get interface flags" );
179 break;
181 printf( "interface flags %x, ", ifr.ifr_flags );
182 fflush( stdout );
183 if( f ) ifr.ifr_flags |= IFF_ALLMULTI;
184 else ifr.ifr_flags &= ~IFF_ALLMULTI;
185 if( ioctl( so, SIOCSIFFLAGS, &ifr ) == -1 )
186 warn( "can't set" );
187 else printf( "changed to %x\n", ifr.ifr_flags );
188 break;
191 case 'p':
193 ++lineptr;
194 while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr;
195 if( (n = sscanf( lineptr, "%s %u", ifr.ifr_name, &f )) != 2 )
197 printf( "bad args\n" );
198 break;
200 if( ioctl( so, SIOCGIFFLAGS, &ifr ) == -1 )
202 warn( "can't get interface flags" );
203 break;
205 printf( "interface flags %x, ", ifr.ifr_flags );
206 fflush( stdout );
207 if( f ) ifr.ifr_flags |= IFF_PROMISC;
208 else ifr.ifr_flags &= ~IFF_PROMISC;
209 if( ioctl( so, SIOCSIFFLAGS, &ifr ) == -1 )
210 warn( "can't set" );
211 else printf( "changed to %x\n", ifr.ifr_flags );
212 break;
215 case 'q': exit( 0 );
217 case 0:
218 case '\n': break;
220 default:
222 printf( "bad command\n" );
223 break;
227 return(0);