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