misc/146889: Not having NET_RT_IFLIST #defined causes getifaddrs.c (libc) to fail to build

Haven Hash havenster at gmail.com
Sun May 23 22:07:09 UTC 2010


>Number:         146889
>Category:       misc
>Synopsis:       Not having NET_RT_IFLIST #defined causes getifaddrs.c (libc) to fail to build
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun May 23 22:07:08 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Haven Hash
>Release:        8.0 Release
>Organization:
>Environment:
FreeBSD hashbsd 8.0-RELEASE FreeBSD 8.0-RELEASE #0: Sat Nov 21 15:48:17 UTC 2009     root at almeida.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  i386
>Description:

Very minor issue that is most likely completely ignorable, but since I had a patch that seems to work I figured I'd put it here in case anyone else ever hit this.

The getifaddrs() libc call does its magic by default by using the NET_RT_IFLIST sysctl call, however it also looks to attempt to support another method using the SIOCGIFCONF ioctl call. It prefers the sysctl method unless the NET_RT_IFLIST #define is not defined. I had reason to want to use the SIOCGIFCONF ioctl method so I undefined NET_RT_IFLIST in lib/libc/net/getifaddrs.c (right after the first #ifdef check) however this causes the getifaddrs.c file to fail to build. The build errors are slight issues concerning variables only being declared inside the NET_RT_IFLIST ifdef blocks and the need for one additional header file (unistd.h) in the #else code. This looks to have always been the case (non-NET_RT_IFLIST code fails to build) and maybe the right thing to do is to just remove all of the non-NET_RT_IFLIST code? (given that is does not build it is unlikely anyone uses it).


>How-To-Repeat:

Edit lib/libc/net/getifaddrs.c and add the following: #undef NET_RT_IFLIST 
in between current lines 40 and 41 (immediately after the first #ifdef NET_RT_IFLIST) to simulate building getifaddrs.c without this define.

Try to rebuild libc and you will see build errors in getifaddrs.c because some variables are only declared inside #ifdef NET_RT_IFLIST specific code, but are used outside of #ifdef NET_RT_IFLIST code.
>Fix:

Attached patch works for me. 

It puts the declaration of the ifa and ift variables into non-#ifdef NET_RT_IFLIST code, removes the variable m since it is not used, moves the declaration of the len and alen variables into #ifdef NET_RT_IFLIST specific code since that is the only code they are used in and adds the unistd.h include because #else code makes use of a _close() call that prevented it from building without this header.

To reiterate this is only helpful for the very rare case that someone would like getifaddrs() to not use the NET_RT_IFLIST sysctl method to obtain interface addresses from the kernel, since the getifaddrs() code looks to support two methods this seems like something it is attempting to support, however the second method currently fails to build. The NET_RT_IFLIST sysctl method is definitely preferred (i.e. for instance the ioctl alternative will not get you netmasks as the ifreq struct it gets back from the kernel does not contain a netmask field).

Patch attached with submission follows:

Index: lib/libc/net/getifaddrs.c
===================================================================
--- lib/libc/net/getifaddrs.c	(revision 208457)
+++ lib/libc/net/getifaddrs.c	(working copy)
@@ -44,6 +44,7 @@
 #include <net/if_dl.h>
 #endif
 
+#include <unistd.h>
 #include <errno.h>
 #include <ifaddrs.h>
 #include <stdlib.h>
@@ -97,6 +98,7 @@
 	int ntry = 0;
 	int mib[6];
 	size_t needed;
+	size_t len, alen;
 	char *buf;
 	char *next;
 	struct ifaddrs *cif = 0;
@@ -106,19 +108,18 @@
 	struct ifa_msghdr *ifam;
 	struct sockaddr_dl *dl;
 	struct sockaddr *sa;
-	struct ifaddrs *ifa, *ift;
 	u_short idx = 0;
 #else	/* NET_RT_IFLIST */
 	char buf[1024];
-	int m, sock;
+	int sock;
 	struct ifconf ifc;
 	struct ifreq *ifr;
 	struct ifreq *lifr;
 #endif	/* NET_RT_IFLIST */
 	int i;
-	size_t len, alen;
 	char *data;
 	char *names;
+	struct ifaddrs *ifa, *ift;
 
 #ifdef	NET_RT_IFLIST
 	mib[0] = CTL_NET;



>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list