Subject: EUI64 patch for ifconfig.c
To: None <tech-net@netbsd.org>
From: None <ww@styx.org>
List: tech-net
Date: 06/13/2002 18:34:24
There has been some discussion on various lists recently
about making it possible to cause ifconfig to automatically
calculate the appropriate IPv6 address to use, given a
prefix. I guess there are differing opinions about where
such functionality belongs. In any case, below is a patch
that makes it possible to do something like:
# ifconfig hme0 inet6 3ffe:1cdc:0:1234:: eui64
and have the lower 64 bits of the address filled in
for you.
Is the consensus that this is something useful and good,
or misguided and inappropriate?
Cheers,
-w
Index: ifconfig.c
===================================================================
RCS file: /cvs/NetBSD/basesrc/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.124
diff -u -r1.124 ifconfig.c
--- ifconfig.c 2002/05/23 21:38:01 1.124
+++ ifconfig.c 2002/06/13 22:21:08
@@ -181,6 +181,7 @@
void setia6pltime __P((const char *, int));
void setia6vltime __P((const char *, int));
void setia6lifetime __P((const char *, const char *));
+void setia6eui64 __P((const char *, int));
#endif
void checkatrange __P ((struct sockaddr_at *));
void setmedia __P((const char *, int));
@@ -261,6 +262,7 @@
{ "-deprecated", -IN6_IFF_DEPRECATED, 0, setia6flags },
{ "pltime", NEXTARG, 0, setia6pltime },
{ "vltime", NEXTARG, 0, setia6vltime },
+ { "eui64", 0, 0, setia6eui64 },
#endif /*INET6*/
#ifndef INET_ONLY
{ "range", NEXTARG, 0, setatrange },
@@ -1213,6 +1215,44 @@
in6_addreq.ifra_lifetime.ia6t_preferred = t + newval;
in6_addreq.ifra_lifetime.ia6t_pltime = newval;
}
+}
+
+void
+setia6eui64(cmd, val)
+ const char *cmd;
+ int val;
+{
+ struct ifaddrs *ifap, *ifa;
+ const struct sockaddr_dl *sdl = NULL;
+ struct in6_addr *in6;
+
+ if (getifaddrs(&ifap) != 0)
+ err(EXIT_FAILURE, "getifaddrs");
+ for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+ if (ifa->ifa_addr->sa_family == AF_LINK) {
+ sdl = (const struct sockaddr_dl *) ifa->ifa_addr;
+ break;
+ }
+ }
+ if (!sdl)
+ err(EXIT_FAILURE, "could not determine link layer address");
+
+ in6 = (struct in6_addr *)&in6_addreq.ifra_addr.sin6_addr;
+
+ /* make EUI64 address */
+ if (sdl->sdl_alen == 8)
+ bcopy(LLADDR(sdl), &in6->s6_addr[8], 8);
+ else if (sdl->sdl_alen == 6) {
+ in6->s6_addr[8] = LLADDR(sdl)[0];
+ in6->s6_addr[9] = LLADDR(sdl)[1];
+ in6->s6_addr[10] = LLADDR(sdl)[2];
+ in6->s6_addr[11] = 0xff;
+ in6->s6_addr[12] = 0xfe;
+ in6->s6_addr[13] = LLADDR(sdl)[3];
+ in6->s6_addr[14] = LLADDR(sdl)[4];
+ in6->s6_addr[15] = LLADDR(sdl)[5];
+ } else
+ err(EXIT_FAILURE, "could not construct EUI64");
}
#endif