diff options
author | ume <ume@FreeBSD.org> | 2002-06-15 15:35:24 +0000 |
---|---|---|
committer | ume <ume@FreeBSD.org> | 2002-06-15 15:35:24 +0000 |
commit | 5d491107087efa8a27bf20b95a62726cd4cd9ce2 (patch) | |
tree | 07a726df50b1efdac1e685534a6ebb799463b1d8 /sbin | |
parent | 04a334b0ceba34a98d340bcfdc7f4d357d4c174e (diff) | |
download | FreeBSD-src-5d491107087efa8a27bf20b95a62726cd4cd9ce2.zip FreeBSD-src-5d491107087efa8a27bf20b95a62726cd4cd9ce2.tar.gz |
Add eui64 option which fills interface index (lowermost 64bit of
an IPv6 address) automatically.
This should obsolete prefix(8).
Obtained from: NetBSD
MFC after: 2 weeks
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/ifconfig/ifconfig.8 | 5 | ||||
-rw-r--r-- | sbin/ifconfig/ifconfig.c | 37 |
2 files changed, 42 insertions, 0 deletions
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 index 0870e65..9fee24e 100644 --- a/sbin/ifconfig/ifconfig.8 +++ b/sbin/ifconfig/ifconfig.8 @@ -248,6 +248,11 @@ the system will not attempt to transmit messages through that interface. If possible, the interface will be reset to disable reception as well. This action does not automatically disable routes using the interface. +.It Cm eui64 +(Inet6 only.) +Fill interface index +.Pq lowermost 64bit of an IPv6 address +automatically. .\" .It Cm ipdst .\" This is used to specify an Internet host who is willing to receive .\" ip packets encapsulating NS packets bound for a remote network. diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index 62ccdc2..9f37f99 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -98,6 +98,7 @@ static const char rcsid[] = #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <ifaddrs.h> #include "ifconfig.h" @@ -175,6 +176,7 @@ c_func setip6flags; c_func setip6pltime; c_func setip6vltime; c_func2 setip6lifetime; +c_func setip6eui64; #endif c_func setifipdst; c_func setifflags, setifmetric, setifmtu, setifcap; @@ -222,6 +224,7 @@ struct cmd { { "-autoconf", -IN6_IFF_AUTOCONF, setip6flags }, { "pltime", NEXTARG, setip6pltime }, { "vltime", NEXTARG, setip6vltime }, + { "eui64", 0, setip6eui64 }, #endif { "range", NEXTARG, setatrange }, { "phase", NEXTARG, setatphase }, @@ -898,6 +901,40 @@ setip6lifetime(const char *cmd, const char *val, int s, in6_addreq.ifra_lifetime.ia6t_pltime = newval; } } + +void +setip6eui64(const char *cmd, int dummy __unused, int s, + const struct afswtch *afp) +{ + struct ifaddrs *ifap, *ifa; + const struct sockaddr_in6 *sin6 = NULL; + const struct in6_addr *lladdr = NULL; + struct in6_addr *in6; + + if (afp->af_af != AF_INET6) + errx(EXIT_FAILURE, "%s not allowed for the AF", cmd); + in6 = (struct in6_addr *)&in6_addreq.ifra_addr.sin6_addr; + if (memcmp(&in6addr_any.s6_addr[8], &in6->s6_addr[8], 8) != 0) + errx(EXIT_FAILURE, "interface index is already filled"); + if (getifaddrs(&ifap) != 0) + err(EXIT_FAILURE, "getifaddrs"); + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + if (ifa->ifa_addr->sa_family == AF_INET6 && + strcmp(ifa->ifa_name, name) == 0) { + sin6 = (const struct sockaddr_in6 *)ifa->ifa_addr; + if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { + lladdr = &sin6->sin6_addr; + break; + } + } + } + if (!lladdr) + errx(EXIT_FAILURE, "could not determine link local address"); + + memcpy(&in6->s6_addr[8], &lladdr->s6_addr[8], 8); + + freeifaddrs(ifap); +} #endif void |