Module Name:    src
Committed By:   dyoung
Date:           Mon Apr 27 20:10:49 UTC 2009

Modified Files:
        src/lib/libc/net: getifaddrs.c
        src/sbin/ifconfig: util.c

Log Message:
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.11 -r1.12 src/lib/libc/net/getifaddrs.c
cvs rdiff -u -r1.10 -r1.11 src/sbin/ifconfig/util.c

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.c
diff -u src/lib/libc/net/getifaddrs.c:1.11 src/lib/libc/net/getifaddrs.c:1.12
--- src/lib/libc/net/getifaddrs.c:1.11	Thu Dec  6 22:51:57 2007
+++ src/lib/libc/net/getifaddrs.c	Mon Apr 27 20:10:49 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: getifaddrs.c,v 1.11 2007/12/06 22:51:57 dyoung Exp $	*/
+/*	$NetBSD: getifaddrs.c,v 1.12 2009/04/27 20:10:49 dyoung 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.12 2009/04/27 20:10:49 dyoung 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/util.c
diff -u src/sbin/ifconfig/util.c:1.10 src/sbin/ifconfig/util.c:1.11
--- src/sbin/ifconfig/util.c:1.10	Tue Apr 21 22:46:39 2009
+++ src/sbin/ifconfig/util.c	Mon Apr 27 20:10:49 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: util.c,v 1.10 2009/04/21 22:46:39 dyoung Exp $	*/
+/*	$NetBSD: util.c,v 1.11 2009/04/27 20:10:49 dyoung Exp $	*/
 
 /*-
  * Copyright (c) 2008 David Young.  All rights reserved.
@@ -27,7 +27,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: util.c,v 1.10 2009/04/21 22:46:39 dyoung Exp $");
+__RCSID("$NetBSD: util.c,v 1.11 2009/04/27 20:10:49 dyoung Exp $");
 #endif /* not lint */
 
 #include <ctype.h>
@@ -264,8 +264,6 @@
 			continue;
 		if (ifa->ifa_addr->sa_family != AF_LINK)
 			continue;
-		if (ifa->ifa_data != NULL)
-			continue;
 
 		sdl = satocsdl(ifa->ifa_addr);
 

Reply via email to