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