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" );