Module Name:    src
Committed By:   bouyer
Date:           Sun May  3 13:17:52 UTC 2009

Modified Files:
        src/lib/libc/net [netbsd-5]: getifaddrs.3 getifaddrs.c
        src/sbin/ifconfig [netbsd-5]: af_link.c ifconfig.c util.c util.h

Log Message:
Pull up following revision(s) (requested by dyoung in ticket #730):
        sbin/ifconfig/af_link.c: revisions 1.4 - 1.6
        sbin/ifconfig/util.h: revision 1.7
        sbin/ifconfig/util.c: revisions 1.10, 1.11
        lib/libc/net/getifaddrs.c: revision 1.12
        lib/libc/net/getifaddrs.3: revision 1.10
        sbin/ifconfig/ifconfig.c: revisions 1.216 - 1.218
Fix indentation: change spaces to tabs.
Use getnameinfo(3) to render a human-readable link-layer address in the
'address: ' line, just as we do in the 'link xx:xx:...:xx' line.
There's no use casting a socket address to sockaddr_dl, only to cast it
back to sockaddr, so don't do it.
Cosmetic: add some whitespace for my ease of reading.
To make sure that we always print the active link-layer address in the
'address: ' field, don't treat the first address as the active address,
but search the link-layer addresses for the ones flagged IFLR_ACTIVE,
and print those.  Extract a subroutine, print_link_addresses(), for
printing link-layer addresses.
For non-AF_LINK ifaddrs, ifa_data is NULL.  AFAICT, this has always been
so.  Say so in the documentation.
Bring getifaddrs(3) behavior in line with the documentation: the
ifa_data member of every AF_LINK struct ifaddrs points at the
corresponding struct if_data.  In ifconfig(8), do not try to suppress
duplicate AF_LINK ifaddrs by checking for a NULL ifa_data.
Don't copy out two AF_LINK struct ifaddrs for each active link-layer
address. getifaddrs(3) used to copy out one ifaddrs for the kernel's
RTM_IFINFO message, and one more for the kernel's RTM_NEWADDR message.
I suppress the first duplicate with a highly conservative change that
wastes a little bit of ifaddrs storage.  The storage is not leaked.


To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.8.38.1 src/lib/libc/net/getifaddrs.3
cvs rdiff -u -r1.11 -r1.11.12.1 src/lib/libc/net/getifaddrs.c
cvs rdiff -u -r1.3 -r1.3.2.1 src/sbin/ifconfig/af_link.c
cvs rdiff -u -r1.213.2.1 -r1.213.2.2 src/sbin/ifconfig/ifconfig.c
cvs rdiff -u -r1.8 -r1.8.2.1 src/sbin/ifconfig/util.c
cvs rdiff -u -r1.6 -r1.6.2.1 src/sbin/ifconfig/util.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/net/getifaddrs.3
diff -u src/lib/libc/net/getifaddrs.3:1.8 src/lib/libc/net/getifaddrs.3:1.8.38.1
--- src/lib/libc/net/getifaddrs.3:1.8	Wed Apr 16 13:34:42 2003
+++ src/lib/libc/net/getifaddrs.3	Sun May  3 13:17:52 2009
@@ -1,4 +1,4 @@
-.\"	$NetBSD: getifaddrs.3,v 1.8 2003/04/16 13:34:42 wiz Exp $
+.\"	$NetBSD: getifaddrs.3,v 1.8.38.1 2009/05/03 13:17:52 bouyer Exp $
 .\"	BSDI	getifaddrs.3,v 2.5 2000/02/23 14:51:59 dab Exp
 .\"
 .\" Copyright (c) 1995, 1999
@@ -114,10 +114,7 @@
 .Fa struct if_data
 .Pq as defined in include file Aq Pa net/if.h
 which contains various interface attributes and statistics.
-For all other address families, it contains a pointer to the
-.Fa struct ifa_data
-.Pq as defined in include file Aq Pa net/if.h
-which contains per-address interface statistics.
+For all other address families, it is NULL.
 .Pp
 The data returned by
 .Fn getifaddrs

Index: src/lib/libc/net/getifaddrs.c
diff -u src/lib/libc/net/getifaddrs.c:1.11 src/lib/libc/net/getifaddrs.c:1.11.12.1
--- src/lib/libc/net/getifaddrs.c:1.11	Thu Dec  6 22:51:57 2007
+++ src/lib/libc/net/getifaddrs.c	Sun May  3 13:17:52 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: getifaddrs.c,v 1.11 2007/12/06 22:51:57 dyoung Exp $	*/
+/*	$NetBSD: getifaddrs.c,v 1.11.12.1 2009/05/03 13:17:52 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1995, 1999
@@ -27,7 +27,7 @@
 
 #include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: getifaddrs.c,v 1.11 2007/12/06 22:51:57 dyoung Exp $");
+__RCSID("$NetBSD: getifaddrs.c,v 1.11.12.1 2009/05/03 13:17:52 bouyer Exp $");
 #endif /* LIBC_SCCS and not lint */
 
 #include "namespace.h"
@@ -64,12 +64,11 @@
 	size_t needed;
 	char *buf;
 	char *next;
-	struct ifaddrs *cif = 0;
+	struct ifaddrs cif;
 	char *p, *p0;
 	struct rt_msghdr *rtm;
 	struct if_msghdr *ifm;
 	struct ifa_msghdr *ifam;
-	struct sockaddr_dl *dl;
 	struct sockaddr *sa;
 	struct ifaddrs *ifa, *ift;
 	u_short idx = 0;
@@ -103,10 +102,12 @@
 		case RTM_IFINFO:
 			ifm = (struct if_msghdr *)(void *)rtm;
 			if (ifm->ifm_addrs & RTA_IFP) {
+				const struct sockaddr_dl *dl;
+
 				idx = ifm->ifm_index;
 				++icnt;
 				dl = (struct sockaddr_dl *)(void *)(ifm + 1);
-				dcnt += SA_RLEN((struct sockaddr *)(void*)dl) +
+				dcnt += SA_RLEN((const struct sockaddr *)(const void *)dl) +
 				    ALIGNBYTES;
 				dcnt += sizeof(ifm->ifm_data);
 				ncnt += dl->sdl_nlen + 1;
@@ -181,28 +182,28 @@
 		case RTM_IFINFO:
 			ifm = (struct if_msghdr *)(void *)rtm;
 			if (ifm->ifm_addrs & RTA_IFP) {
+				const struct sockaddr_dl *dl;
+
 				idx = ifm->ifm_index;
 				dl = (struct sockaddr_dl *)(void *)(ifm + 1);
 
-				cif = ift;
-				ift->ifa_name = names;
-				ift->ifa_flags = (int)ifm->ifm_flags;
+				memset(&cif, 0, sizeof(cif));
+
+				cif.ifa_name = names;
+				cif.ifa_flags = (int)ifm->ifm_flags;
 				memcpy(names, dl->sdl_data,
 				    (size_t)dl->sdl_nlen);
 				names[dl->sdl_nlen] = 0;
 				names += dl->sdl_nlen + 1;
 
-				ift->ifa_addr = (struct sockaddr *)(void *)data;
-				memcpy(data, dl, (size_t)((struct sockaddr *)
-				    (void *)dl)->sa_len);
-				data += SA_RLEN((struct sockaddr *)(void *)dl);
+				cif.ifa_addr = (struct sockaddr *)(void *)data;
+				memcpy(data, dl, (size_t)dl->sdl_len);
+				data += SA_RLEN((const struct sockaddr *)(const void *)dl);
 
 				/* ifm_data needs to be aligned */
-				ift->ifa_data = data = (void *)ALIGN(data);
+				cif.ifa_data = data = (void *)ALIGN(data);
 				memcpy(data, &ifm->ifm_data, sizeof(ifm->ifm_data));
  				data += sizeof(ifm->ifm_data);
-
-				ift = (ift->ifa_next = ift + 1);
 			} else
 				idx = 0;
 			break;
@@ -214,8 +215,8 @@
 
 			if (idx == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0)
 				break;
-			ift->ifa_name = cif->ifa_name;
-			ift->ifa_flags = cif->ifa_flags;
+			ift->ifa_name = cif.ifa_name;
+			ift->ifa_flags = cif.ifa_flags;
 			ift->ifa_data = NULL;
 			p = (char *)(void *)(ifam + 1);
 			/* Scan to look for length of address */
@@ -244,6 +245,8 @@
 					    (struct sockaddr *)(void *)data;
 					memcpy(data, p, len);
 					data += len;
+					if (ift->ifa_addr->sa_family == AF_LINK)
+						ift->ifa_data = cif.ifa_data;
 					break;
 
 				case RTAX_NETMASK:

Index: src/sbin/ifconfig/af_link.c
diff -u src/sbin/ifconfig/af_link.c:1.3 src/sbin/ifconfig/af_link.c:1.3.2.1
--- src/sbin/ifconfig/af_link.c:1.3	Wed Jul  2 07:44:14 2008
+++ src/sbin/ifconfig/af_link.c	Sun May  3 13:17:52 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: af_link.c,v 1.3 2008/07/02 07:44:14 dyoung Exp $	*/
+/*	$NetBSD: af_link.c,v 1.3.2.1 2009/05/03 13:17:52 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2008 David Young.  All rights reserved.
@@ -27,7 +27,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: af_link.c,v 1.3 2008/07/02 07:44:14 dyoung Exp $");
+__RCSID("$NetBSD: af_link.c,v 1.3.2.1 2009/05/03 13:17:52 bouyer Exp $");
 #endif /* not lint */
 
 #include <sys/param.h> 
@@ -74,56 +74,7 @@
 static void
 link_status(prop_dictionary_t env, prop_dictionary_t oenv, bool force)
 {
-	const char *delim, *ifname;
-	int i, s;
-	struct ifaddrs *ifa, *ifap;
-	const struct sockaddr_dl *sdl;
-	struct if_laddrreq iflr;
-	const uint8_t *octets;
-
-	if ((ifname = getifname(env)) == NULL)
-		err(EXIT_FAILURE, "%s: getifname", __func__);
-
-	if ((s = getsock(AF_LINK)) == -1)
-		err(EXIT_FAILURE, "%s: getsock", __func__);
-
-	if (getifaddrs(&ifap) == -1)
-		err(EXIT_FAILURE, "%s: getifaddrs", __func__);
-
-	memset(&iflr, 0, sizeof(iflr));
-
-	strlcpy(iflr.iflr_name, ifname, sizeof(iflr.iflr_name));
-
-	for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
-		if (strcmp(ifname, ifa->ifa_name) != 0)
-			continue;
-		if (ifa->ifa_addr->sa_family != AF_LINK)
-			continue;
-		if (ifa->ifa_data != NULL)
-			continue;
-
-		sdl = satocsdl(ifa->ifa_addr);
-
-		memcpy(&iflr.addr, ifa->ifa_addr, MIN(ifa->ifa_addr->sa_len,
-		    sizeof(iflr.addr)));
-		iflr.flags = IFLR_PREFIX;
-		iflr.prefixlen = sdl->sdl_alen * NBBY;
-
-		if (ioctl(s, SIOCGLIFADDR, &iflr) == -1)
-			err(EXIT_FAILURE, "%s: ioctl", __func__);
-
-                if ((iflr.flags & IFLR_ACTIVE) != 0)
-			continue;
-
-		octets = (const uint8_t *)&sdl->sdl_data[sdl->sdl_nlen];
-
-		delim = "\tlink ";
-		for (i = 0; i < sdl->sdl_alen; i++) {
-			printf("%s%02" PRIx8, delim, octets[i]);
-			delim = ":";
-		}
-		printf("\n");
-	}
+	print_link_addresses(env, false);
 }
 
 static int

Index: src/sbin/ifconfig/ifconfig.c
diff -u src/sbin/ifconfig/ifconfig.c:1.213.2.1 src/sbin/ifconfig/ifconfig.c:1.213.2.2
--- src/sbin/ifconfig/ifconfig.c:1.213.2.1	Sat Apr  4 18:22:54 2009
+++ src/sbin/ifconfig/ifconfig.c	Sun May  3 13:17:52 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: ifconfig.c,v 1.213.2.1 2009/04/04 18:22:54 snj Exp $	*/
+/*	$NetBSD: ifconfig.c,v 1.213.2.2 2009/05/03 13:17:52 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc.
@@ -63,7 +63,7 @@
 #ifndef lint
 __COPYRIGHT("@(#) Copyright (c) 1983, 1993\
  The Regents of the University of California.  All rights reserved.");
-__RCSID("$NetBSD: ifconfig.c,v 1.213.2.1 2009/04/04 18:22:54 snj Exp $");
+__RCSID("$NetBSD: ifconfig.c,v 1.213.2.2 2009/05/03 13:17:52 bouyer Exp $");
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -126,7 +126,7 @@
 static int setifmtu(prop_dictionary_t, prop_dictionary_t);
 static int setifnetmask(prop_dictionary_t, prop_dictionary_t);
 static int setifprefixlen(prop_dictionary_t, prop_dictionary_t);
-static void status(const struct sockaddr_dl *, prop_dictionary_t,
+static void status(const struct sockaddr *, prop_dictionary_t,
     prop_dictionary_t);
 static void usage(void);
 
@@ -724,7 +724,7 @@
 {
 	struct ifaddrs *ifap, *ifa;
 	struct ifreq ifr;
-	const struct sockaddr_dl *sdl = NULL;
+	const struct sockaddr *sdl = NULL;
 	prop_dictionary_t env, oenv;
 	int idx;
 	char *p;
@@ -754,7 +754,7 @@
 		if (ifname != NULL && strcmp(ifname, ifa->ifa_name) != 0)
 			continue;
 		if (ifa->ifa_addr->sa_family == AF_LINK)
-			sdl = (const struct sockaddr_dl *) ifa->ifa_addr;
+			sdl = ifa->ifa_addr;
 		if (p && strcmp(p, ifa->ifa_name) == 0)
 			continue;
 		if (!prop_dictionary_set_cstring(env, "if", ifa->ifa_name))
@@ -1144,7 +1144,7 @@
  * specified, show it and it only; otherwise, show them all.
  */
 void
-status(const struct sockaddr_dl *sdl, prop_dictionary_t env,
+status(const struct sockaddr *sdl, prop_dictionary_t env,
     prop_dictionary_t oenv)
 {
 	const struct if_data *ifi;
@@ -1152,7 +1152,6 @@
 	statistics_func_t *statistics_f;
 	struct ifdatareq ifdr;
 	struct ifreq ifr;
-	char hbuf[NI_MAXHOST];
 	char fbuf[BUFSIZ];
 	int af, s;
 	const char *ifname;
@@ -1202,11 +1201,7 @@
 	SIMPLEQ_FOREACH(status_f, &status_funcs, f_next)
 		(*status_f->f_func)(env, oenv);
 
-	if (sdl != NULL &&
-	    getnameinfo((const struct sockaddr *)sdl, sdl->sdl_len,
-		hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) == 0 &&
-	    hbuf[0] != '\0')
-		printf("\taddress: %s\n", hbuf);
+	print_link_addresses(env, true);
 
 	media_status(env, oenv);
 
@@ -1215,7 +1210,7 @@
 
 	estrlcpy(ifdr.ifdr_name, ifname, sizeof(ifdr.ifdr_name));
 
-	if (ioctl(s, zflag ? SIOCZIFDATA:SIOCGIFDATA, &ifdr) == -1)
+	if (ioctl(s, zflag ? SIOCZIFDATA : SIOCGIFDATA, &ifdr) == -1)
 		err(EXIT_FAILURE, zflag ? "SIOCZIFDATA" : "SIOCGIFDATA");
 
 	ifi = &ifdr.ifdr_data;

Index: src/sbin/ifconfig/util.c
diff -u src/sbin/ifconfig/util.c:1.8 src/sbin/ifconfig/util.c:1.8.2.1
--- src/sbin/ifconfig/util.c:1.8	Wed Jul  2 07:44:15 2008
+++ src/sbin/ifconfig/util.c	Sun May  3 13:17:52 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: util.c,v 1.8 2008/07/02 07:44:15 dyoung Exp $	*/
+/*	$NetBSD: util.c,v 1.8.2.1 2009/05/03 13:17:52 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2008 David Young.  All rights reserved.
@@ -27,12 +27,13 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: util.c,v 1.8 2008/07/02 07:44:15 dyoung Exp $");
+__RCSID("$NetBSD: util.c,v 1.8.2.1 2009/05/03 13:17:52 bouyer Exp $");
 #endif /* not lint */
 
 #include <ctype.h>
 #include <err.h>
 #include <errno.h>
+#include <netdb.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -40,9 +41,14 @@
 #include <unistd.h>
 #include <util.h>
 
+#include <sys/param.h>
+#include <sys/types.h>
 #include <sys/socket.h>
+#include <ifaddrs.h>
+
 #include <sys/ioctl.h>
 #include <net/if.h>
+#include <net/if_dl.h>
 #include <netinet/in.h>		/* XXX */
 
 #include "env.h"
@@ -230,6 +236,58 @@
 	return direct_ioctl(env, cmd, &ifr);
 }
 
+void
+print_link_addresses(prop_dictionary_t env, bool print_active_only)
+{
+	char hbuf[NI_MAXHOST];
+	const char *ifname;
+	int s;
+	struct ifaddrs *ifa, *ifap;
+	const struct sockaddr_dl *sdl;
+	struct if_laddrreq iflr;
+
+	if ((ifname = getifname(env)) == NULL)
+		err(EXIT_FAILURE, "%s: getifname", __func__);
+
+	if ((s = getsock(AF_LINK)) == -1)
+		err(EXIT_FAILURE, "%s: getsock", __func__);
+
+	if (getifaddrs(&ifap) == -1)
+		err(EXIT_FAILURE, "%s: getifaddrs", __func__);
+
+	memset(&iflr, 0, sizeof(iflr));
+
+	strlcpy(iflr.iflr_name, ifname, sizeof(iflr.iflr_name));
+
+	for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
+		if (strcmp(ifname, ifa->ifa_name) != 0)
+			continue;
+		if (ifa->ifa_addr->sa_family != AF_LINK)
+			continue;
+
+		sdl = satocsdl(ifa->ifa_addr);
+
+		memcpy(&iflr.addr, ifa->ifa_addr, MIN(ifa->ifa_addr->sa_len,
+		    sizeof(iflr.addr)));
+		iflr.flags = IFLR_PREFIX;
+		iflr.prefixlen = sdl->sdl_alen * NBBY;
+
+		if (ioctl(s, SIOCGLIFADDR, &iflr) == -1)
+			err(EXIT_FAILURE, "%s: ioctl", __func__);
+
+		if (((iflr.flags & IFLR_ACTIVE) != 0) != print_active_only)
+			continue;
+
+		if (getnameinfo(ifa->ifa_addr, ifa->ifa_addr->sa_len,
+			hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) == 0 &&
+		    hbuf[0] != '\0') {
+			printf("\t%s %s\n",
+			    print_active_only ? "address:" : "link", hbuf);
+		}
+	}
+	freeifaddrs(ifap);
+}
+
 #ifdef INET6
 /* KAME idiosyncrasy */
 void

Index: src/sbin/ifconfig/util.h
diff -u src/sbin/ifconfig/util.h:1.6 src/sbin/ifconfig/util.h:1.6.2.1
--- src/sbin/ifconfig/util.h:1.6	Wed Jul  2 07:44:15 2008
+++ src/sbin/ifconfig/util.h	Sun May  3 13:17:52 2009
@@ -13,6 +13,7 @@
 	SIMPLEQ_ENTRY(afswtch)	af_next;
 };
 
+void print_link_addresses(prop_dictionary_t, bool);
 const char *get_string(const char *, const char *, u_int8_t *, int *);
 const struct afswtch *lookup_af_byname(const char *);
 const struct afswtch *lookup_af_bynum(int);

Reply via email to