From 331a2db8a9aa26b8d09fdea1fd00d3a1a392d685 Mon Sep 17 00:00:00 2001 From: Hajimu UMEMOTO Date: Sat, 15 Jun 2002 15:35:24 +0000 Subject: [PATCH] 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 --- sbin/ifconfig/ifconfig.8 | 5 +++++ sbin/ifconfig/ifconfig.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 index 0870e6589bc7..9fee24e11e4d 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 62ccdc264763..9f37f9903aed 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -98,6 +98,7 @@ static const char rcsid[] = #include #include #include +#include #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