summaryrefslogtreecommitdiffstats
path: root/sbin/ifconfig
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2001-06-11 12:39:29 +0000
committerume <ume@FreeBSD.org>2001-06-11 12:39:29 +0000
commit832f8d224926758a9ae0b23a6b45353e44fbc87a (patch)
treea79fc7ad2b97862c4a404f352f0211ad93a7b5f1 /sbin/ifconfig
parent2693854b01a52b0395a91322aa3edf926bddff38 (diff)
downloadFreeBSD-src-832f8d224926758a9ae0b23a6b45353e44fbc87a.zip
FreeBSD-src-832f8d224926758a9ae0b23a6b45353e44fbc87a.tar.gz
Sync with recent KAME.
This work was based on kame-20010528-freebsd43-snap.tgz and some critical problem after the snap was out were fixed. There are many many changes since last KAME merge. TODO: - The definitions of SADB_* in sys/net/pfkeyv2.h are still different from RFC2407/IANA assignment because of binary compatibility issue. It should be fixed under 5-CURRENT. - ip6po_m member of struct ip6_pktopts is no longer used. But, it is still there because of binary compatibility issue. It should be removed under 5-CURRENT. Reviewed by: itojun Obtained from: KAME MFC after: 3 weeks
Diffstat (limited to 'sbin/ifconfig')
-rw-r--r--sbin/ifconfig/ifconfig.813
-rw-r--r--sbin/ifconfig/ifconfig.c231
2 files changed, 232 insertions, 12 deletions
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
index 176af6a..e4ef0f4 100644
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -256,6 +256,19 @@ list of available options.
.It Fl mediaopt Ar opts
If the driver supports the media selection system, disable the
specified media options on the interface.
+.It Cm tunnel Ar src_addr Ar dest_addr
+(IP tunnel devices only)
+Configure the physical source and destination address for IP tunnel
+interfaces (gif). The arguments
+.Ar src_addr
+and
+.Ar dest_addr
+are interpreted as the outer source/destination for the encapsulating
+IPv4/IPv6 header.
+.It Cm deletetunnel
+Unconfigure the physical source and destination address for IP tunnel
+interfaces previously configured with
+.Cm tunnel .
.It Cm vlan Ar vlan_tag
If the interface is a vlan pseudo interface, set the vlan tag value
to
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index f865af24..72c0f16 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -149,35 +149,43 @@ void rt_xaddrs __P((caddr_t, caddr_t, struct rt_addrinfo *));
void status __P((const struct afswtch *afp, int addrcount,
struct sockaddr_dl *sdl, struct if_msghdr *ifm,
struct ifa_msghdr *ifam));
+void tunnel_status __P((int s));
void usage __P((void));
void ifmaybeload __P((char *name));
#ifdef INET6
+void in6_fillscopeid __P((struct sockaddr_in6 *sin6));
int prefix __P((void *, int));
static char *sec2str __P((time_t));
int explicit_prefix = 0;
#endif
typedef void c_func __P((const char *cmd, int arg, int s, const struct afswtch *afp));
+typedef void c_func2 __P((const char *arg, const char *arg2, int s, const struct afswtch *afp));
c_func setatphase, setatrange;
c_func setifaddr, setifbroadaddr, setifdstaddr, setifnetmask;
+c_func2 settunnel;
+c_func deletetunnel;
#ifdef INET6
c_func setifprefixlen;
c_func setip6flags;
-c_func setip6vltime;
c_func setip6pltime;
+c_func setip6vltime;
+c_func2 setip6lifetime;
#endif
c_func setifipdst;
c_func setifflags, setifmetric, setifmtu, setiflladdr;
#define NEXTARG 0xffffff
+#define NEXTARG2 0xfffffe
const
struct cmd {
const char *c_name;
int c_parameter; /* NEXTARG means next argv */
void (*c_func) __P((const char *, int, int, const struct afswtch *afp));
+ void (*c_func2) __P((const char *, const char *, int, const struct afswtch *afp));
} cmds[] = {
{ "up", IFF_UP, setifflags } ,
{ "down", -IFF_UP, setifflags },
@@ -201,14 +209,20 @@ struct cmd {
{ "anycast", IN6_IFF_ANYCAST, setip6flags },
{ "tentative", IN6_IFF_TENTATIVE, setip6flags },
{ "-tentative", -IN6_IFF_TENTATIVE, setip6flags },
- { "vltime", NEXTARG, setip6vltime },
+ { "deprecated", IN6_IFF_DEPRECATED, setip6flags },
+ { "-deprecated", -IN6_IFF_DEPRECATED, setip6flags },
+ { "autoconf", IN6_IFF_AUTOCONF, setip6flags },
+ { "-autoconf", -IN6_IFF_AUTOCONF, setip6flags },
{ "pltime", NEXTARG, setip6pltime },
+ { "vltime", NEXTARG, setip6vltime },
#endif
{ "range", NEXTARG, setatrange },
{ "phase", NEXTARG, setatphase },
{ "metric", NEXTARG, setifmetric },
{ "broadcast", NEXTARG, setifbroadaddr },
{ "ipdst", NEXTARG, setifipdst },
+ { "tunnel", NEXTARG2, NULL, settunnel },
+ { "deletetunnel", 0, deletetunnel },
{ "link0", IFF_LINK0, setifflags },
{ "-link0", -IFF_LINK0, setifflags },
{ "link1", IFF_LINK1, setifflags },
@@ -600,13 +614,19 @@ ifconfig(argc, argv, afp)
break;
if (p->c_name == 0 && setaddr)
p++; /* got src, do dst */
- if (p->c_func) {
+ if (p->c_func || p->c_func2) {
if (p->c_parameter == NEXTARG) {
if (argv[1] == NULL)
errx(1, "'%s' requires argument",
p->c_name);
(*p->c_func)(argv[1], 0, s, afp);
argc--, argv++;
+ } else if (p->c_parameter == NEXTARG2) {
+ if (argc < 3)
+ errx(1, "'%s' requires 2 arguments",
+ p->c_name);
+ (*p->c_func2)(argv[1], argv[2], s, afp);
+ argc -= 2, argv += 2;
} else
(*p->c_func)(*argv, p->c_parameter, s, afp);
}
@@ -704,6 +724,82 @@ setifaddr(addr, param, s, afp)
}
void
+settunnel(src, dst, s, afp)
+ const char *src, *dst;
+ int s;
+ const struct afswtch *afp;
+{
+ struct addrinfo hints, *srcres, *dstres;
+ struct ifaliasreq addreq;
+ int ecode;
+#ifdef INET6
+ struct in6_aliasreq in6_addreq;
+#endif
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = afp->af_af;
+
+ if ((ecode = getaddrinfo(src, NULL, NULL, &srcres)) != 0)
+ errx(1, "error in parsing address string: %s",
+ gai_strerror(ecode));
+
+ if ((ecode = getaddrinfo(dst, NULL, NULL, &dstres)) != 0)
+ errx(1, "error in parsing address string: %s",
+ gai_strerror(ecode));
+
+ if (srcres->ai_addr->sa_family != dstres->ai_addr->sa_family)
+ errx(1,
+ "source and destination address families do not match");
+
+ switch (srcres->ai_addr->sa_family) {
+ case AF_INET:
+ memset(&addreq, 0, sizeof(addreq));
+ strncpy(addreq.ifra_name, name, IFNAMSIZ);
+ memcpy(&addreq.ifra_addr, srcres->ai_addr,
+ srcres->ai_addr->sa_len);
+ memcpy(&addreq.ifra_dstaddr, dstres->ai_addr,
+ dstres->ai_addr->sa_len);
+
+ if (ioctl(s, SIOCSIFPHYADDR, &addreq) < 0)
+ warn("SIOCSIFPHYADDR");
+ break;
+
+#ifdef INET6
+ case AF_INET6:
+ memset(&in6_addreq, 0, sizeof(in6_addreq));
+ strncpy(in6_addreq.ifra_name, name, IFNAMSIZ);
+ memcpy(&in6_addreq.ifra_addr, srcres->ai_addr,
+ srcres->ai_addr->sa_len);
+ memcpy(&in6_addreq.ifra_dstaddr, dstres->ai_addr,
+ dstres->ai_addr->sa_len);
+
+ if (ioctl(s, SIOCSIFPHYADDR_IN6, &in6_addreq) < 0)
+ warn("SIOCSIFPHYADDR_IN6");
+ break;
+#endif /* INET6 */
+
+ default:
+ warn("address family not supported");
+ }
+
+ freeaddrinfo(srcres);
+ freeaddrinfo(dstres);
+}
+
+/* ARGSUSED */
+void
+deletetunnel(vname, param, s, afp)
+ const char *vname;
+ int param;
+ int s;
+ const struct afswtch *afp;
+{
+
+ if (ioctl(s, SIOCDIFPHYADDR, &ifr) < 0)
+ err(1, "SIOCDIFPHYADDR");
+}
+
+void
setifnetmask(addr, dummy, s, afp)
const char *addr;
int dummy __unused;
@@ -745,23 +841,48 @@ setip6flags(dummyaddr, flag, dummysoc, afp)
}
void
-setip6vltime(seconds, dummy, s, afp)
+setip6pltime(seconds, dummy, s, afp)
const char *seconds;
int dummy __unused;
int s;
const struct afswtch *afp;
{
- in6_addreq.ifra_lifetime.ia6t_vltime = atoi(seconds);
+ setip6lifetime("pltime", seconds, s, afp);
}
void
-setip6pltime(seconds, dummy, s, afp)
+setip6vltime(seconds, dummy, s, afp)
const char *seconds;
int dummy __unused;
int s;
const struct afswtch *afp;
{
- in6_addreq.ifra_lifetime.ia6t_pltime = atoi(seconds);
+ setip6lifetime("vltime", seconds, s, afp);
+}
+
+void
+setip6lifetime(cmd, val, s, afp)
+ const char *cmd;
+ const char *val;
+ int s;
+ const struct afswtch *afp;
+{
+ time_t newval, t;
+ char *ep;
+
+ t = time(NULL);
+ newval = (time_t)strtoul(val, &ep, 0);
+ if (val == ep)
+ errx(1, "invalid %s", cmd);
+ if (afp->af_af != AF_INET6)
+ errx(1, "%s not allowed for the AF", cmd);
+ if (strcmp(cmd, "vltime") == 0) {
+ in6_addreq.ifra_lifetime.ia6t_expire = t + newval;
+ in6_addreq.ifra_lifetime.ia6t_vltime = newval;
+ } else if (strcmp(cmd, "pltime") == 0) {
+ in6_addreq.ifra_lifetime.ia6t_preferred = t + newval;
+ in6_addreq.ifra_lifetime.ia6t_pltime = newval;
+ }
}
#endif
@@ -964,6 +1085,8 @@ status(afp, addrcount, sdl, ifm, ifam)
printf(" mtu %d", mtu);
putchar('\n');
+ tunnel_status(s);
+
while (addrcount > 0) {
info.rti_addrs = ifam->ifam_addrs;
@@ -1015,6 +1138,73 @@ status(afp, addrcount, sdl, ifm, ifam)
}
void
+tunnel_status(s)
+ int s;
+{
+ char psrcaddr[NI_MAXHOST];
+ char pdstaddr[NI_MAXHOST];
+ u_long srccmd, dstcmd;
+ struct ifreq *ifrp;
+ const char *ver = "";
+#ifdef NI_WITHSCOPEID
+ const int niflag = NI_NUMERICHOST | NI_WITHSCOPEID;
+#else
+ const int niflag = NI_NUMERICHOST;
+#endif
+#ifdef INET6
+ struct in6_ifreq in6_ifr;
+ int s6;
+#endif /* INET6 */
+
+ psrcaddr[0] = pdstaddr[0] = '\0';
+
+#ifdef INET6
+ memset(&in6_ifr, 0, sizeof(in6_ifr));
+ strncpy(in6_ifr.ifr_name, name, IFNAMSIZ);
+ s6 = socket(AF_INET6, SOCK_DGRAM, 0);
+ if (s6 < 0) {
+ srccmd = SIOCGIFPSRCADDR;
+ dstcmd = SIOCGIFPDSTADDR;
+ ifrp = &ifr;
+ } else {
+ close(s6);
+ srccmd = SIOCGIFPSRCADDR_IN6;
+ dstcmd = SIOCGIFPDSTADDR_IN6;
+ ifrp = (struct ifreq *)&in6_ifr;
+ }
+#else /* INET6 */
+ srccmd = SIOCGIFPSRCADDR;
+ dstcmd = SIOCGIFPDSTADDR;
+ ifrp = &ifr;
+#endif /* INET6 */
+
+ if (ioctl(s, srccmd, (caddr_t)ifrp) < 0)
+ return;
+#ifdef INET6
+ if (ifrp->ifr_addr.sa_family == AF_INET6)
+ in6_fillscopeid((struct sockaddr_in6 *)&ifrp->ifr_addr);
+#endif
+ getnameinfo(&ifrp->ifr_addr, ifrp->ifr_addr.sa_len,
+ psrcaddr, sizeof(psrcaddr), 0, 0, niflag);
+#ifdef INET6
+ if (ifrp->ifr_addr.sa_family == AF_INET6)
+ ver = "6";
+#endif
+
+ if (ioctl(s, dstcmd, (caddr_t)ifrp) < 0)
+ return;
+#ifdef INET6
+ if (ifrp->ifr_addr.sa_family == AF_INET6)
+ in6_fillscopeid((struct sockaddr_in6 *)&ifrp->ifr_addr);
+#endif
+ getnameinfo(&ifrp->ifr_addr, ifrp->ifr_addr.sa_len,
+ pdstaddr, sizeof(pdstaddr), 0, 0, niflag);
+
+ printf("\ttunnel inet%s %s --> %s\n", ver,
+ psrcaddr, pdstaddr);
+}
+
+void
in_status(s, info)
int s __unused;
struct rt_addrinfo * info;
@@ -1050,6 +1240,19 @@ in_status(s, info)
#ifdef INET6
void
+in6_fillscopeid(sin6)
+ struct sockaddr_in6 *sin6;
+{
+#if defined(__KAME__) && defined(KAME_SCOPEID)
+ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+ sin6->sin6_scope_id =
+ ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]);
+ sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0;
+ }
+#endif
+}
+
+void
in6_status(s, info)
int s __unused;
struct rt_addrinfo * info;
@@ -1146,16 +1349,20 @@ in6_status(s, info)
printf("prefixlen %d ", prefix(&sin->sin6_addr,
sizeof(struct in6_addr)));
- if (flags6 & IN6_IFF_ANYCAST)
+ if ((flags6 & IN6_IFF_ANYCAST) != 0)
printf("anycast ");
- if (flags6 & IN6_IFF_TENTATIVE)
+ if ((flags6 & IN6_IFF_TENTATIVE) != 0)
printf("tentative ");
- if (flags6 & IN6_IFF_DUPLICATED)
+ if ((flags6 & IN6_IFF_DUPLICATED) != 0)
printf("duplicated ");
- if (flags6 & IN6_IFF_DETACHED)
+ if ((flags6 & IN6_IFF_DETACHED) != 0)
printf("detached ");
- if (flags6 & IN6_IFF_DEPRECATED)
+ if ((flags6 & IN6_IFF_DEPRECATED) != 0)
printf("deprecated ");
+ if ((flags6 & IN6_IFF_AUTOCONF) != 0)
+ printf("autoconf ");
+ if ((flags6 & IN6_IFF_TEMPORARY) != 0)
+ printf("temporary ");
if (scopeid)
printf("scopeid 0x%x ", scopeid);
OpenPOWER on IntegriCloud