Subject: Re: EUI64 patch for ifconfig.c
To: None <itojun@iijlab.net>
From: None <ww@styx.org>
List: tech-net
Date: 06/14/2002 02:46:17
On Fri, Jun 14, 2002 at 08:16:56AM +0900, itojun@iijlab.net wrote:
> 
> 	couple of points:
> 	- the code duplicates logic in sys/netinet6/in6_ifattach.c.

Well, that's where I got it from. ;)  But the point is well taken.
 
Is it correct to just grab the first link local address as in:

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/14 06:31:32
@@ -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,36 @@
 		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_in6 *sin6 = NULL;
+	const struct in6_addr *lladdr = 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_INET6) {
+			sin6 = (const struct sockaddr_in6 *) ifa->ifa_addr;
+			if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+				lladdr = &sin6->sin6_addr;
+				break;
+			}
+		}
+	}
+	if (!lladdr)
+		err(EXIT_FAILURE, "could not determine link local address"); 
+
+ 	in6 = (struct in6_addr *)&in6_addreq.ifra_addr.sin6_addr;
+ 	bcopy(&lladdr->s6_addr[8], &in6->s6_addr[8], 8);
+
+	freeifaddrs(ifap);
 }
 #endif