2 * Copyright 2013 Ermal Luci
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
16 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
27 #include <sys/param.h>
28 #include <sys/ioctl.h>
29 #include <sys/socket.h>
30 #include <sys/sockio.h>
35 #include <net/ethernet.h>
37 #include <net/route.h>
39 #include <netinet/in.h>
41 #include <net/if_stf.h>
42 #include <arpa/inet.h>
55 do_cmd(int sock, u_long op, void *arg, size_t argsize, int set)
59 memset(&ifd, 0, sizeof(ifd));
61 strlcpy(ifd.ifd_name, ifr.ifr_name, sizeof(ifd.ifd_name));
63 ifd.ifd_len = argsize;
66 return (ioctl(sock, set ? SIOCSDRVSPEC : SIOCGDRVSPEC, &ifd));
72 struct stfv4args param;
74 if (do_cmd(s, STF6RD_GV4NET, ¶m, sizeof(param), 0) < 0)
77 printf("\tv4net %s/%d -> ", inet_ntoa(param.srcv4_addr),
78 param.v4_prefixlen ? param.v4_prefixlen : 32);
79 printf("tv4br %s\n", inet_ntoa(param.braddr));
83 setstf_br(const char *val, int d, int s, const struct afswtch *afp)
86 struct sockaddr_in sin;
88 memset(&req, 0, sizeof(req));
90 sin.sin_len = sizeof(sin);
91 sin.sin_family = AF_INET;
93 if (!inet_aton(val, &sin.sin_addr))
94 errx(1, "%s: bad value", val);
96 req.braddr = sin.sin_addr;
97 if (do_cmd(s, STF6RD_SBR, &req, sizeof(req), 1) < 0)
98 err(1, "STF6RD_SBR%s", val);
102 setstf_set(const char *val, int d, int s, const struct afswtch *afp)
104 struct stfv4args req;
105 struct sockaddr_in sin;
109 memset(&req, 0, sizeof(req));
111 sin.sin_len = sizeof(sin);
112 sin.sin_family = AF_INET;
114 p = strrchr(val, '/');
116 errx(2, "Wrong argument given");
119 req.v4_prefixlen = (int)strtonum(p + 1, 0, 32, &errstr);
120 if (errstr != NULL || req.v4_prefixlen == 0) {
122 errx(1, "%s: bad value (prefix length %s)", val, errstr);
125 if (!inet_aton(val, &sin.sin_addr))
126 errx(1, "%s: bad value", val);
128 memcpy(&req.srcv4_addr, &sin.sin_addr, sizeof(req.srcv4_addr));
129 if (do_cmd(s, STF6RD_SV4NET, &req, sizeof(req), 1) < 0)
130 err(1, "STF6RD_SV4NET %s", val);
133 static struct cmd stf_cmds[] = {
134 DEF_CMD_ARG("stfv4net", setstf_set),
135 DEF_CMD_ARG("stfv4br", setstf_br),
138 static struct afswtch af_stf = {
141 .af_other_status = stf_status,
144 static __constructor void
149 for (i = 0; i < nitems(stf_cmds); i++)
150 cmd_register(&stf_cmds[i]);
151 af_register(&af_stf);