xref: /freebsd/sbin/ifconfig/ifstf.c (revision 7fa282e616c303261904cb6158959d5a784dc3ee)
119dc6445SKristof Provost /*-
219dc6445SKristof Provost  * Copyright 2013 Ermal Luci
319dc6445SKristof Provost  * All rights reserved.
419dc6445SKristof Provost  *
519dc6445SKristof Provost  * Redistribution and use in source and binary forms, with or without
619dc6445SKristof Provost  * modification, are permitted provided that the following conditions
719dc6445SKristof Provost  * are met:
819dc6445SKristof Provost  * 1. Redistributions of source code must retain the above copyright
919dc6445SKristof Provost  *    notice, this list of conditions and the following disclaimer.
1019dc6445SKristof Provost  * 2. Redistributions in binary form must reproduce the above copyright
1119dc6445SKristof Provost  *    notice, this list of conditions and the following disclaimer in the
1219dc6445SKristof Provost  *    documentation and/or other materials provided with the distribution.
1319dc6445SKristof Provost  *
1419dc6445SKristof Provost  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
1519dc6445SKristof Provost  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1619dc6445SKristof Provost  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1719dc6445SKristof Provost  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
1819dc6445SKristof Provost  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1919dc6445SKristof Provost  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2019dc6445SKristof Provost  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2119dc6445SKristof Provost  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2219dc6445SKristof Provost  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2319dc6445SKristof Provost  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2419dc6445SKristof Provost  * POSSIBILITY OF SUCH DAMAGE.
2519dc6445SKristof Provost  */
2619dc6445SKristof Provost 
2719dc6445SKristof Provost #include <sys/param.h>
2819dc6445SKristof Provost #include <sys/ioctl.h>
2919dc6445SKristof Provost #include <sys/socket.h>
3019dc6445SKristof Provost #include <sys/sockio.h>
3119dc6445SKristof Provost 
3219dc6445SKristof Provost #include <stdlib.h>
3319dc6445SKristof Provost #include <unistd.h>
3419dc6445SKristof Provost 
3519dc6445SKristof Provost #include <net/ethernet.h>
3619dc6445SKristof Provost #include <net/if.h>
3719dc6445SKristof Provost #include <net/route.h>
3819dc6445SKristof Provost 
3919dc6445SKristof Provost #include <netinet/in.h>
4019dc6445SKristof Provost #include <sys/mbuf.h>
4119dc6445SKristof Provost #include <net/if_stf.h>
4219dc6445SKristof Provost #include <arpa/inet.h>
4319dc6445SKristof Provost 
4419dc6445SKristof Provost #include <ctype.h>
4519dc6445SKristof Provost #include <stdio.h>
4619dc6445SKristof Provost #include <string.h>
4719dc6445SKristof Provost #include <stdlib.h>
4819dc6445SKristof Provost #include <unistd.h>
4919dc6445SKristof Provost #include <err.h>
5019dc6445SKristof Provost #include <errno.h>
5119dc6445SKristof Provost 
5219dc6445SKristof Provost #include "ifconfig.h"
5319dc6445SKristof Provost 
5419dc6445SKristof Provost static int
do_cmd(if_ctx * ctx,u_long op,void * arg,size_t argsize,int set)556e3a9d7fSAlexander V. Chernikov do_cmd(if_ctx *ctx, u_long op, void *arg, size_t argsize, int set)
5619dc6445SKristof Provost {
57*7fa282e6SAlexander V. Chernikov 	struct ifdrv ifd = {};
5819dc6445SKristof Provost 
59*7fa282e6SAlexander V. Chernikov 	strlcpy(ifd.ifd_name, ctx->ifname, sizeof(ifd.ifd_name));
6019dc6445SKristof Provost 	ifd.ifd_cmd = op;
6119dc6445SKristof Provost 	ifd.ifd_len = argsize;
6219dc6445SKristof Provost 	ifd.ifd_data = arg;
6319dc6445SKristof Provost 
646e3a9d7fSAlexander V. Chernikov 	return (ioctl_ctx(ctx, set ? SIOCSDRVSPEC : SIOCGDRVSPEC, &ifd));
6519dc6445SKristof Provost }
6619dc6445SKristof Provost 
6719dc6445SKristof Provost static void
stf_status(if_ctx * ctx)686e3a9d7fSAlexander V. Chernikov stf_status(if_ctx *ctx)
6919dc6445SKristof Provost {
7019dc6445SKristof Provost 	struct stfv4args param;
7119dc6445SKristof Provost 
726e3a9d7fSAlexander V. Chernikov 	if (do_cmd(ctx, STF6RD_GV4NET, &param, sizeof(param), 0) < 0)
7319dc6445SKristof Provost 		return;
7419dc6445SKristof Provost 
7519dc6445SKristof Provost 	printf("\tv4net %s/%d -> ", inet_ntoa(param.srcv4_addr),
7619dc6445SKristof Provost 	    param.v4_prefixlen ? param.v4_prefixlen : 32);
7719dc6445SKristof Provost 	printf("tv4br %s\n", inet_ntoa(param.braddr));
7819dc6445SKristof Provost }
7919dc6445SKristof Provost 
8019dc6445SKristof Provost static void
setstf_br(if_ctx * ctx,const char * val,int d __unused)816e3a9d7fSAlexander V. Chernikov setstf_br(if_ctx *ctx, const char *val, int d __unused)
8219dc6445SKristof Provost {
8319dc6445SKristof Provost 	struct stfv4args req;
8419dc6445SKristof Provost 	struct sockaddr_in sin;
8519dc6445SKristof Provost 
8619dc6445SKristof Provost 	memset(&req, 0, sizeof(req));
8719dc6445SKristof Provost 
8819dc6445SKristof Provost 	sin.sin_len = sizeof(sin);
8919dc6445SKristof Provost 	sin.sin_family = AF_INET;
9019dc6445SKristof Provost 
9119dc6445SKristof Provost 	if (!inet_aton(val, &sin.sin_addr))
9219dc6445SKristof Provost 		errx(1, "%s: bad value", val);
9319dc6445SKristof Provost 
9419dc6445SKristof Provost 	req.braddr = sin.sin_addr;
956e3a9d7fSAlexander V. Chernikov 	if (do_cmd(ctx, STF6RD_SBR, &req, sizeof(req), 1) < 0)
9619dc6445SKristof Provost 		err(1, "STF6RD_SBR%s",  val);
9719dc6445SKristof Provost }
9819dc6445SKristof Provost 
9919dc6445SKristof Provost static void
setstf_set(if_ctx * ctx,const char * val,int d __unused)1006e3a9d7fSAlexander V. Chernikov setstf_set(if_ctx *ctx, const char *val, int d __unused)
10119dc6445SKristof Provost {
10219dc6445SKristof Provost 	struct stfv4args req;
10319dc6445SKristof Provost 	struct sockaddr_in sin;
10419dc6445SKristof Provost 	const char *errstr;
10519dc6445SKristof Provost 	char *p = NULL;
10619dc6445SKristof Provost 
10719dc6445SKristof Provost 	memset(&req, 0, sizeof(req));
10819dc6445SKristof Provost 
10919dc6445SKristof Provost 	sin.sin_len = sizeof(sin);
11019dc6445SKristof Provost 	sin.sin_family = AF_INET;
11119dc6445SKristof Provost 
11219dc6445SKristof Provost 	p = strrchr(val, '/');
11319dc6445SKristof Provost 	if (p == NULL)
11419dc6445SKristof Provost 		errx(2, "Wrong argument given");
11519dc6445SKristof Provost 
11619dc6445SKristof Provost 	*p = '\0';
11719dc6445SKristof Provost 	req.v4_prefixlen = (int)strtonum(p + 1, 0, 32, &errstr);
11819dc6445SKristof Provost 	if (errstr != NULL || req.v4_prefixlen == 0) {
11919dc6445SKristof Provost 		*p = '/';
12019dc6445SKristof Provost 		errx(1, "%s: bad value (prefix length %s)", val, errstr);
12119dc6445SKristof Provost 	}
12219dc6445SKristof Provost 
12319dc6445SKristof Provost 	if (!inet_aton(val, &sin.sin_addr))
12419dc6445SKristof Provost 		errx(1, "%s: bad value", val);
12519dc6445SKristof Provost 
12619dc6445SKristof Provost 	memcpy(&req.srcv4_addr, &sin.sin_addr, sizeof(req.srcv4_addr));
1276e3a9d7fSAlexander V. Chernikov 	if (do_cmd(ctx, STF6RD_SV4NET, &req, sizeof(req), 1) < 0)
12819dc6445SKristof Provost 		err(1, "STF6RD_SV4NET %s",  val);
12919dc6445SKristof Provost }
13019dc6445SKristof Provost 
13119dc6445SKristof Provost static struct cmd stf_cmds[] = {
13219dc6445SKristof Provost 	DEF_CMD_ARG("stfv4net",		setstf_set),
13319dc6445SKristof Provost 	DEF_CMD_ARG("stfv4br",		setstf_br),
13419dc6445SKristof Provost };
13519dc6445SKristof Provost 
13619dc6445SKristof Provost static struct afswtch af_stf = {
13719dc6445SKristof Provost 	.af_name		= "af_stf",
13819dc6445SKristof Provost 	.af_af			= AF_UNSPEC,
13919dc6445SKristof Provost 	.af_other_status	= stf_status,
14019dc6445SKristof Provost };
14119dc6445SKristof Provost 
14219dc6445SKristof Provost static __constructor void
stf_ctor(void)14319dc6445SKristof Provost stf_ctor(void)
14419dc6445SKristof Provost {
14544cd85d4SAlexander V. Chernikov 	for (size_t i = 0; i < nitems(stf_cmds);  i++)
14619dc6445SKristof Provost 		cmd_register(&stf_cmds[i]);
14719dc6445SKristof Provost 	af_register(&af_stf);
14819dc6445SKristof Provost }
149