Deleted Added
sdiff udiff text old ( 36440 ) new ( 78720 )
full compact
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
9static const char rcsid[] =
10 "$FreeBSD: head/usr.sbin/mtest/mtest.c 78720 2001-06-24 20:25:23Z dd $";
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
24int
25main( 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 }