2 * Program to test new [sg]etsockopts and ioctls for manipulating IP and
3 * Ethernet multicast address filters.
5 * Written by Steve Deering, Stanford University, February 1989.
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 $
14 #include <sys/types.h>
15 #include <sys/socket.h>
18 #include <net/if_dl.h>
19 #include <sys/ioctl.h>
20 #include <netinet/in.h>
23 main(int argc, char **argv)
31 unsigned i1, i2, i3, i4, g1, g2, g3, g4;
32 unsigned e1, e2, e3, e4, e5, e6;
34 if( (so = socket( AF_INET, SOCK_DGRAM, 0 )) == -1)
35 err( 1, "can't open socket" );
37 printf( "multicast membership test program; " );
38 printf( "enter ? for list of commands\n" );
40 while( fgets( line, 79, stdin ) != NULL )
43 while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr;
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",
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 )
66 printf( "bad args\n" );
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" );
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 )
87 printf( "bad args\n" );
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" );
103 struct sockaddr_dl *dlp;
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 )
110 printf( "bad args\n" );
113 dlp = (struct sockaddr_dl *)&ifr.ifr_addr;
114 dlp->sdl_len = sizeof(struct sockaddr_dl);
115 dlp->sdl_family = AF_LINK;
127 if( ioctl( so, SIOCADDMULTI, &ifr ) == -1 )
128 warn( "can't add ether address" );
129 else printf( "ether address added\n" );
135 struct sockaddr_dl *dlp;
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 )
142 printf( "bad args\n" );
145 dlp = (struct sockaddr_dl *)&ifr.ifr_addr;
146 dlp->sdl_len = sizeof(struct sockaddr_dl);
147 dlp->sdl_family = AF_LINK;
159 if( ioctl( so, SIOCDELMULTI, &ifr ) == -1 )
160 warn( "can't delete ether address" );
161 else printf( "ether address deleted\n" );
168 while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr;
169 if( (n = sscanf( lineptr, "%s %u", ifr.ifr_name, &f )) != 2 )
171 printf( "bad args\n" );
174 if( ioctl( so, SIOCGIFFLAGS, &ifr ) == -1 )
176 warn( "can't get interface flags" );
179 printf( "interface flags %x, ", ifr.ifr_flags );
181 if( f ) ifr.ifr_flags |= IFF_ALLMULTI;
182 else ifr.ifr_flags &= ~IFF_ALLMULTI;
183 if( ioctl( so, SIOCSIFFLAGS, &ifr ) == -1 )
185 else printf( "changed to %x\n", ifr.ifr_flags );
192 while( *lineptr == ' ' || *lineptr == '\t' ) ++lineptr;
193 if( (n = sscanf( lineptr, "%s %u", ifr.ifr_name, &f )) != 2 )
195 printf( "bad args\n" );
198 if( ioctl( so, SIOCGIFFLAGS, &ifr ) == -1 )
200 warn( "can't get interface flags" );
203 printf( "interface flags %x, ", ifr.ifr_flags );
205 if( f ) ifr.ifr_flags |= IFF_PROMISC;
206 else ifr.ifr_flags &= ~IFF_PROMISC;
207 if( ioctl( so, SIOCSIFFLAGS, &ifr ) == -1 )
209 else printf( "changed to %x\n", ifr.ifr_flags );
220 printf( "bad command\n" );