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