Initial import from FreeBSD RELENG_4:
[dragonfly.git] / usr.sbin / mtest / mtest.c
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   }