xref: /netbsd-src/tests/net/if_vlan/siocXmulti.c (revision 78a704859847f403a13f5905b5616d8b3b7a580e)
1*78a70485Syamaguchi /*	$NetBSD: siocXmulti.c,v 1.3 2021/08/19 03:36:42 yamaguchi Exp $	*/
2*78a70485Syamaguchi 
3*78a70485Syamaguchi /*
4*78a70485Syamaguchi  * Copyright (c) 2021 Internet Initiative Japan Inc.
5*78a70485Syamaguchi  * All rights reserved.
6*78a70485Syamaguchi  *
7*78a70485Syamaguchi  * Redistribution and use in source and binary forms, with or without
8*78a70485Syamaguchi  * modification, are permitted provided that the following conditions
9*78a70485Syamaguchi  * are met:
10*78a70485Syamaguchi  * 1. Redistributions of source code must retain the above copyright
11*78a70485Syamaguchi  *    notice, this list of conditions and the following disclaimer.
12*78a70485Syamaguchi  * 2. Redistributions in binary form must reproduce the above copyright
13*78a70485Syamaguchi  *    notice, this list of conditions and the following disclaimer in the
14*78a70485Syamaguchi  *    documentation and/or other materials provided with the distribution.
15*78a70485Syamaguchi  *
16*78a70485Syamaguchi  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17*78a70485Syamaguchi  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18*78a70485Syamaguchi  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19*78a70485Syamaguchi  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20*78a70485Syamaguchi  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*78a70485Syamaguchi  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*78a70485Syamaguchi  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*78a70485Syamaguchi  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*78a70485Syamaguchi  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*78a70485Syamaguchi  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*78a70485Syamaguchi  * POSSIBILITY OF SUCH DAMAGE.
27*78a70485Syamaguchi  */
28*78a70485Syamaguchi 
29*78a70485Syamaguchi #include <sys/cdefs.h>
30*78a70485Syamaguchi __RCSID("$NetBSD: siocXmulti.c,v 1.3 2021/08/19 03:36:42 yamaguchi Exp $");
319de5f4c0Syamaguchi 
329de5f4c0Syamaguchi #include <sys/socket.h>
339de5f4c0Syamaguchi #include <sys/ioctl.h>
349de5f4c0Syamaguchi 
359de5f4c0Syamaguchi #include <net/if.h>
369de5f4c0Syamaguchi #include <netinet/in.h>
379de5f4c0Syamaguchi #include <arpa/inet.h>
389de5f4c0Syamaguchi 
399de5f4c0Syamaguchi #include <stdio.h>
409de5f4c0Syamaguchi #include <stdlib.h>
419de5f4c0Syamaguchi #include <string.h>
429de5f4c0Syamaguchi #include <strings.h>
439de5f4c0Syamaguchi #include <unistd.h>
449de5f4c0Syamaguchi #include <err.h>
459de5f4c0Syamaguchi 
469de5f4c0Syamaguchi enum{
479de5f4c0Syamaguchi 	ARG_PROG = 0,
489de5f4c0Syamaguchi 	ARG_OP,
499de5f4c0Syamaguchi 	ARG_IFNAME,
509de5f4c0Syamaguchi 	ARG_ADDR,
519de5f4c0Syamaguchi 	ARG_NUM
529de5f4c0Syamaguchi };
539de5f4c0Syamaguchi 
549de5f4c0Syamaguchi static void
usage(void)559de5f4c0Syamaguchi usage(void)
569de5f4c0Syamaguchi {
579de5f4c0Syamaguchi 
589de5f4c0Syamaguchi 	printf("%s <add|del> <ifname> <IPv4 addr>\n",
599de5f4c0Syamaguchi 	    getprogname());
609de5f4c0Syamaguchi 	exit(1);
619de5f4c0Syamaguchi }
629de5f4c0Syamaguchi 
639de5f4c0Syamaguchi int
main(int argc,char * argv[])649de5f4c0Syamaguchi main(int argc, char *argv[])
659de5f4c0Syamaguchi {
669de5f4c0Syamaguchi 	int			 fd, rv;
679de5f4c0Syamaguchi 	unsigned long		 req;
689de5f4c0Syamaguchi 	struct ifreq		 ifr;
699de5f4c0Syamaguchi 	unsigned int		 ifidx;
709de5f4c0Syamaguchi 	struct sockaddr_in	*sin;
719de5f4c0Syamaguchi 	struct sockaddr_in6	*sin6;
729de5f4c0Syamaguchi 
739de5f4c0Syamaguchi 	bzero(&ifr, sizeof(ifr));
749de5f4c0Syamaguchi 
759de5f4c0Syamaguchi 	if (argc != ARG_NUM)
769de5f4c0Syamaguchi 		usage();
779de5f4c0Syamaguchi 
789de5f4c0Syamaguchi 	if (strcmp(argv[ARG_OP], "add") == 0)
799de5f4c0Syamaguchi 		req = SIOCADDMULTI;
809de5f4c0Syamaguchi 	else if (strcmp(argv[ARG_OP], "del") == 0)
819de5f4c0Syamaguchi 		req = SIOCDELMULTI;
829de5f4c0Syamaguchi 	else
839de5f4c0Syamaguchi 		usage();
849de5f4c0Syamaguchi 
859de5f4c0Syamaguchi 	ifidx = if_nametoindex(argv[ARG_IFNAME]);
869de5f4c0Syamaguchi 	if (ifidx == 0)
879de5f4c0Syamaguchi 		err(1, "if_nametoindex(%s)", argv[ARG_IFNAME]);
889de5f4c0Syamaguchi 
894e545ef7Smrg 	strncpy(ifr.ifr_name, argv[ARG_IFNAME], sizeof(ifr.ifr_name) - 1);
904e545ef7Smrg 	ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
919de5f4c0Syamaguchi 
929de5f4c0Syamaguchi 	sin = (struct sockaddr_in *)&ifr.ifr_addr;
939de5f4c0Syamaguchi 	sin->sin_family = AF_INET;
949de5f4c0Syamaguchi 	sin->sin_len = sizeof(*sin);
959de5f4c0Syamaguchi 	rv = inet_pton(AF_INET, argv[ARG_ADDR], &sin->sin_addr);
969de5f4c0Syamaguchi 
979de5f4c0Syamaguchi 	if (rv != 1) {
989de5f4c0Syamaguchi 		sin6 = (struct sockaddr_in6 *)&ifr.ifr_addr;
999de5f4c0Syamaguchi 		sin6->sin6_family = AF_INET6;
1009de5f4c0Syamaguchi 		sin6->sin6_len = sizeof(*sin6);
1019de5f4c0Syamaguchi 		rv = inet_pton(AF_INET6, argv[ARG_ADDR], &sin6->sin6_addr);
1029de5f4c0Syamaguchi 
1039de5f4c0Syamaguchi 		if (rv != 1)
1049de5f4c0Syamaguchi 			errx(1, "inet_pton(%s)", argv[ARG_ADDR]);
1059de5f4c0Syamaguchi 	}
1069de5f4c0Syamaguchi 
1079de5f4c0Syamaguchi 	fd = socket(AF_INET, SOCK_DGRAM, 0);
1089de5f4c0Syamaguchi 	if (fd < 0)
1099de5f4c0Syamaguchi 		err(1, "socket");
1109de5f4c0Syamaguchi 
1119de5f4c0Syamaguchi 	if (ioctl(fd, req, (caddr_t)&ifr) < 0) {
1129de5f4c0Syamaguchi 		err(1, "ioctl(%s)",
1139de5f4c0Syamaguchi 		    (req == SIOCADDMULTI) ? "SIOCADDMULTI" : "SIOCDELMULTI");
1149de5f4c0Syamaguchi 	}
1159de5f4c0Syamaguchi 
1169de5f4c0Syamaguchi 	close(fd);
1179de5f4c0Syamaguchi 
1189de5f4c0Syamaguchi 	return 0;
1199de5f4c0Syamaguchi }
120