From ac55e95265194286ad7db771d95bd73b521e92b6 Mon Sep 17 00:00:00 2001
From: millert <>
Date: Thu, 7 Mar 2002 22:40:23 +0000
Subject: Replace SIOCGIFCONF-using NRL versions with KAME versions that use
 getifaddrs(3).  Fixes problems on LP64 platforms.

---
 src/lib/libc/net/if_indextoname.c | 155 +++++++++----------------
 src/lib/libc/net/if_nameindex.c   | 233 +++++++++++++++++---------------------
 src/lib/libc/net/if_nametoindex.c | 146 ++++++++----------------
 3 files changed, 201 insertions(+), 333 deletions(-)

diff --git a/src/lib/libc/net/if_indextoname.c b/src/lib/libc/net/if_indextoname.c
index 4f3990b4c2..f99e52e387 100644
--- a/src/lib/libc/net/if_indextoname.c
+++ b/src/lib/libc/net/if_indextoname.c
@@ -1,26 +1,20 @@
-/*
- * Copyright (c) 1998-1999, Craig Metz, All rights reserved.
+/*	$OpenBSD: if_indextoname.c,v 1.9 2002/03/07 22:40:23 millert Exp $	*/
+/*	$KAME: if_indextoname.c,v 1.6 2000/11/07 22:33:25 jinmei Exp $	*/
+
+/*-
+ * Copyright (c) 1997, 2000
+ *	Berkeley Software Design, Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Craig Metz and
- *      by other contributors.
- * 4. Neither the name of the author nor the names of contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -28,112 +22,65 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
+ *
+ *	BSDI Id: if_indextoname.c,v 2.3 2000/04/17 22:38:05 dab Exp
  */
 
 #include <sys/types.h>
-#include <stdlib.h>
 #include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
 #include <net/if_dl.h>
-#include <errno.h>
-#include <unistd.h>
+#include <net/if.h>
+#include <ifaddrs.h>
+#include <stdlib.h>
 #include <string.h>
+#include <errno.h>
 
-static char __name[IFNAMSIZ];
+/*
+ * From RFC 2533:
+ *
+ * The second function maps an interface index into its corresponding
+ * name.
+ *
+ *    #include <net/if.h>
+ *
+ *    char  *if_indextoname(unsigned int ifindex, char *ifname);
+ *
+ * The ifname argument must point to a buffer of at least IF_NAMESIZE
+ * bytes into which the interface name corresponding to the specified
+ * index is returned.  (IF_NAMESIZE is also defined in <net/if.h> and
+ * its value includes a terminating null byte at the end of the
+ * interface name.) This pointer is also the return value of the
+ * function.  If there is no interface corresponding to the specified
+ * index, NULL is returned, and errno is set to ENXIO, if there was a
+ * system error (such as running out of memory), if_indextoname returns
+ * NULL and errno would be set to the proper value (e.g., ENOMEM).
+ */
 
 char *
-if_indextoname(unsigned int index, char *name)
+if_indextoname(unsigned int ifindex, char *ifname)
 {
-	int     i, fd = -1, extra, len = 0;
-	struct ifconf ifconf;
-	char    lastname[IFNAMSIZ], iname[IFNAMSIZ], *retname = NULL, *inbuf;
-	struct sockaddr *sa;
-	void	*p;
-
-	ifconf.ifc_buf = 0;
-
-	if (!name)
-		name = __name;
+	struct ifaddrs *ifaddrs, *ifa;
+	int error = 0;
 
-	if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
-		goto ret;
+	if (getifaddrs(&ifaddrs) < 0)
+		return(NULL);	/* getifaddrs properly set errno */
 
-	/*
-	 * Try ifc_len == 0 hack first, to get the actual length.
-	 * If that fails, revert to a loop which grows the ifc_buf
-	 * until it is sufficiently large.
-	 */
-	extra = sizeof(struct ifreq);
-	while (1) {
-		ifconf.ifc_len = len;
-		if (ioctl(fd, SIOCGIFCONF, (void *) &ifconf) == -1 &&
-		    ifconf.ifc_buf)
-			goto ret;
-		if (ifconf.ifc_buf &&
-		    ifconf.ifc_len + extra < len)
+	for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
+		if (ifa->ifa_addr &&
+		    ifa->ifa_addr->sa_family == AF_LINK &&
+		    ifindex == ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index)
 			break;
-		if (ifconf.ifc_buf) {
-			if (len == 0)
-				len = 4096;
-			ifconf.ifc_len = len *= 2;
-		} else {
-			len = ifconf.ifc_len;
-			extra = 0;
-		}
-		inbuf = realloc(ifconf.ifc_buf, ifconf.ifc_len);
-		if (inbuf == NULL)
-			goto ret;
-		ifconf.ifc_buf = inbuf;
 	}
 
-	i = 0;
-	p = ifconf.ifc_buf;
-	len = ifconf.ifc_len;
-	lastname[0] = 0;
-	lastname[sizeof(lastname)-1] = 0;
-	iname[0] = 0;
-
-	while (len > 0) {
-		if (len < (IFNAMSIZ + sizeof(struct sockaddr)))
-			goto ret;
-		if (strncmp(lastname, p, IFNAMSIZ)) {
-			if (i == index)
-				memcpy(iname, lastname, sizeof(iname));
-			strlcpy(lastname, p, sizeof(lastname));
-			i++;
-		}
-		len -= IFNAMSIZ;
-		p += IFNAMSIZ;
-		sa = p;
-
-		if (sa->sa_family == AF_LINK) {
-			struct sockaddr_dl *sd = p;
-
-			if (sd->sdl_index == index) {
-				strlcpy(name, lastname, IFNAMSIZ);
-				retname = name;
-				goto ret;
-			}
-		}
-
-		if (len < sa->sa_len)
-			goto ret;
-		len -= sa->sa_len;
-		p += sa->sa_len;
+	if (ifa == NULL) {
+		error = ENXIO;
+		ifname = NULL;
 	}
+	else
+		strlcpy(ifname, ifa->ifa_name, IFNAMSIZ);
 
-	if (i == index)
-		strlcpy(iname, lastname, sizeof(iname));
+	freeifaddrs(ifaddrs);
 
-	if (iname[0]) {
-		strlcpy(name, iname, IFNAMSIZ);
-		retname = name;
-	}
-ret:
-	if (fd != -1)
-		close(fd);
-	if (ifconf.ifc_buf)
-		free(ifconf.ifc_buf);
-	return (retname);
+	errno = error;
+	return(ifname);
 }
diff --git a/src/lib/libc/net/if_nameindex.c b/src/lib/libc/net/if_nameindex.c
index 2b85fbae95..3675a2a450 100644
--- a/src/lib/libc/net/if_nameindex.c
+++ b/src/lib/libc/net/if_nameindex.c
@@ -1,26 +1,20 @@
-/*
- * Copyright (c) 1998-1999, Craig Metz, All rights reserved.
+/*	$OpenBSD: if_nameindex.c,v 1.9 2002/03/07 22:40:23 millert Exp $	*/
+/*	$KAME: if_nameindex.c,v 1.7 2000/11/24 08:17:20 itojun Exp $	*/
+
+/*-
+ * Copyright (c) 1997, 2000
+ *	Berkeley Software Design, Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Craig Metz and
- *      by other contributors.
- * 4. Neither the name of the author nor the names of contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -28,140 +22,119 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
+ *
+ *	BSDI Id: if_nameindex.c,v 2.3 2000/04/17 22:38:05 dab Exp
  */
 
-#include <stdlib.h>
 #include <sys/types.h>
 #include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
 #include <net/if_dl.h>
-#include <errno.h>
-#include <unistd.h>
+#include <net/if.h>
+#include <ifaddrs.h>
+#include <stdlib.h>
 #include <string.h>
 
+/*
+ * From RFC 2553:
+ *
+ * 4.3 Return All Interface Names and Indexes
+ *
+ *    The if_nameindex structure holds the information about a single
+ *    interface and is defined as a result of including the <net/if.h>
+ *    header.
+ *
+ *       struct if_nameindex {
+ *         unsigned int   if_index;
+ *         char          *if_name;
+ *       };
+ *
+ *    The final function returns an array of if_nameindex structures, one
+ *    structure per interface.
+ *
+ *       struct if_nameindex  *if_nameindex(void);
+ *
+ *    The end of the array of structures is indicated by a structure with
+ *    an if_index of 0 and an if_name of NULL.  The function returns a NULL
+ *    pointer upon an error, and would set errno to the appropriate value.
+ *
+ *    The memory used for this array of structures along with the interface
+ *    names pointed to by the if_name members is obtained dynamically.
+ *    This memory is freed by the next function.
+ *
+ * 4.4.  Free Memory
+ *
+ *    The following function frees the dynamic memory that was allocated by
+ *    if_nameindex().
+ *
+ *        #include <net/if.h>
+ *
+ *        void  if_freenameindex(struct if_nameindex *ptr);
+ *
+ *    The argument to this function must be a pointer that was returned by
+ *    if_nameindex().
+ */
+
 struct if_nameindex *
 if_nameindex(void)
 {
-	int     i, j, fd = -1, extra, len = 0;
-	struct if_nameindex *nameindex = NULL;
-	struct ifconf ifconf;
-	char    lastname[IFNAMSIZ], *c, *inbuf;
-	struct if_nameindex *n;
-	struct sockaddr *sa;
-	void   *p;
-
-	ifconf.ifc_buf = NULL;
+	struct ifaddrs *ifaddrs, *ifa;
+	unsigned int ni;
+	size_t nbytes;
+	struct if_nameindex *ifni, *ifni2;
+	char *cp;
 
-	if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
-		goto ret;
+	if (getifaddrs(&ifaddrs) < 0)
+		return(NULL);
 
 	/*
-	 * Try ifc_len == 0 hack first, to get the actual length.
-	 * If that fails, revert to a loop which grows the ifc_buf
-	 * until it is sufficiently large.
+	 * First, find out how many interfaces there are, and how
+	 * much space we need for the string names.
 	 */
-	extra = sizeof(struct ifreq);
-	while (1) {
-		ifconf.ifc_len = len;
-		if (ioctl(fd, SIOCGIFCONF, (void *) &ifconf) == -1 &&
-		    ifconf.ifc_buf)
-			goto ret;
-		if (ifconf.ifc_buf &&
-		    ifconf.ifc_len + extra < len)
-			break;
-		if (ifconf.ifc_buf) {
-			if (len == 0)
-				len = 4096;
-			ifconf.ifc_len = len *= 2;
-		} else {
-			len = ifconf.ifc_len;
-			extra = 0;
-		}
-		inbuf = realloc(ifconf.ifc_buf, ifconf.ifc_len);
-		if (inbuf == NULL)
-			goto ret;
-		ifconf.ifc_buf = inbuf;
-	}
-
-	i = sizeof(struct if_nameindex);
-	j = 0;
-	p = ifconf.ifc_buf;
-	len = ifconf.ifc_len;
-	lastname[0] = 0;
-	lastname[sizeof(lastname)-1] = 0;
-
-	while (len > 0) {
-		if (len < (IFNAMSIZ + sizeof(struct sockaddr)))
-			goto ret;
-		if (strncmp(lastname, p, IFNAMSIZ)) {
-			strlcpy(lastname, p, sizeof(lastname));
-			i += sizeof(struct if_nameindex);
-			j += strlen(lastname) + 1;
+	ni = 0;
+	nbytes = 0;
+	for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
+		if (ifa->ifa_addr &&
+		    ifa->ifa_addr->sa_family == AF_LINK) {
+			nbytes += strlen(ifa->ifa_name) + 1;
+			ni++;
 		}
-		len -= IFNAMSIZ;
-		p += IFNAMSIZ;
-		sa = p;
-
-		if (sa->sa_len < sizeof(struct sockaddr))
-			sa->sa_len = sizeof(struct sockaddr);
-
-		if (len < sa->sa_len)
-			goto ret;
-		len -= sa->sa_len;
-		p += sa->sa_len;
-	}
-
-	nameindex = malloc(i + j);
-	if (nameindex == NULL) {
-		errno = ENOMEM;
-		goto ret;
 	}
-	memset(nameindex, 0, i + j);
 
-	n = nameindex;
-	p = ifconf.ifc_buf;
-	c = (void *) nameindex + i;
-	i = 0;
-	len = ifconf.ifc_len;
-	lastname[0] = 0;
-
-	while (len > 0) {
-		if (len < IFNAMSIZ + sizeof(struct sockaddr))
-			goto ret;
-		if (strncmp(lastname, p, IFNAMSIZ)) {
-			if (i) {
-				if (!n->if_index)
-					n->if_index = i;
-				n++;
-			}
-			i++;
-			memcpy(lastname, p, sizeof(lastname));
-			strlcpy(c, lastname, sizeof(lastname));
-			n->if_name = c;
-			c += strlen(c) + 1;
-		}
-		len -= IFNAMSIZ;
-		p += IFNAMSIZ;
-		sa = p;
+	/*
+	 * Next, allocate a chunk of memory, use the first part
+	 * for the array of structures, and the last part for
+	 * the strings.
+	 */
+	cp = malloc((ni + 1) * sizeof(struct if_nameindex) + nbytes);
+	ifni = (struct if_nameindex *)cp;
+	if (ifni == NULL)
+		goto out;
+	cp += (ni + 1) * sizeof(struct if_nameindex);
 
-		if (len < sa->sa_len)
-			goto ret;
-		if (sa->sa_family == AF_LINK) {
-			struct sockaddr_dl *sd = (struct sockaddr_dl *)sa;
-			n->if_index = sd->sdl_index;
+	/*
+	 * Now just loop through the list of interfaces again,
+	 * filling in the if_nameindex array and making copies
+	 * of all the strings.
+	 */
+	ifni2 = ifni;
+	for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
+		if (ifa->ifa_addr &&
+		    ifa->ifa_addr->sa_family == AF_LINK) {
+			ifni2->if_index =
+			    ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index;
+			ifni2->if_name = cp;
+			nbytes = strlen(ifa->ifa_name) + 1;
+			memcpy(cp, ifa->ifa_name, nbytes);
+			ifni2++;
+			cp += nbytes;
 		}
-		len -= sa->sa_len;
-		p += sa->sa_len;
 	}
-
-	if (n->if_index == 0)
-		n->if_index = i;
-
-ret:
-	if (fd != -1)
-		close(fd);
-	if (ifconf.ifc_buf)
-		free(ifconf.ifc_buf);
-	return (nameindex);
+	/*
+	 * Finally, don't forget to terminate the array.
+	 */
+	ifni2->if_index = 0;
+	ifni2->if_name = NULL;
+out:
+	freeifaddrs(ifaddrs);
+	return(ifni);
 }
diff --git a/src/lib/libc/net/if_nametoindex.c b/src/lib/libc/net/if_nametoindex.c
index e7e8b6c22a..8bd792b949 100644
--- a/src/lib/libc/net/if_nametoindex.c
+++ b/src/lib/libc/net/if_nametoindex.c
@@ -1,26 +1,20 @@
-/*
- * Copyright (c) 1998-1999, Craig Metz, All rights reserved.
+/*	$OpenBSD: if_nametoindex.c,v 1.8 2002/03/07 22:40:23 millert Exp $	*/
+/*	$KAME: if_nametoindex.c,v 1.5 2000/11/24 08:04:40 itojun Exp $	*/
+
+/*-
+ * Copyright (c) 1997, 2000
+ *	Berkeley Software Design, Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Craig Metz and
- *      by other contributors.
- * 4. Neither the name of the author nor the names of contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -28,106 +22,60 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
+ *
+ *	BSDI Id: if_nametoindex.c,v 2.3 2000/04/17 22:38:05 dab Exp
  */
 
 #include <sys/types.h>
-#include <stdlib.h>
 #include <sys/socket.h>
-#include <sys/ioctl.h>
 #include <net/if.h>
 #include <net/if_dl.h>
+#include <ifaddrs.h>
+#include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 #include <errno.h>
 
-unsigned int 
-if_nametoindex(const char *name)
+/*
+ * From RFC 2553:
+ *
+ * 4.1 Name-to-Index
+ *
+ *
+ *    The first function maps an interface name into its corresponding
+ *    index.
+ *
+ *       #include <net/if.h>
+ *
+ *       unsigned int  if_nametoindex(const char *ifname);
+ *
+ *    If the specified interface name does not exist, the return value is
+ *    0, and errno is set to ENXIO.  If there was a system error (such as
+ *    running out of memory), the return value is 0 and errno is set to the
+ *    proper value (e.g., ENOMEM).
+ */
+
+unsigned int
+if_nametoindex(const char *ifname)
 {
-	int     i, fd = -1, extra, len = 0;
-	struct ifconf ifconf;
-	char    lastname[IFNAMSIZ], *thisname, *inbuf;
-	unsigned int index = 0;
-	struct sockaddr *sa;
-	void	*p;
+	struct ifaddrs *ifaddrs, *ifa;
+	unsigned int ni;
 
-	ifconf.ifc_buf = 0;
+	if (getifaddrs(&ifaddrs) < 0)
+		return(0);
 
-	if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
-		goto ret;
+	ni = 0;
 
-	/*
-	 * Try ifc_len == 0 hack first, to get the actual length.
-	 * If that fails, revert to a loop which grows the ifc_buf
-	 * until it is sufficiently large.
-	 */
-	extra = sizeof(struct ifreq);
-	while (1) {
-		ifconf.ifc_len = len;
-		if (ioctl(fd, SIOCGIFCONF, (void *) &ifconf) == -1 &&
-		    ifconf.ifc_buf)
-			goto ret;
-		if (ifconf.ifc_buf &&
-		    ifconf.ifc_len + extra < len)
+	for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
+		if (ifa->ifa_addr &&
+		    ifa->ifa_addr->sa_family == AF_LINK &&
+		    strcmp(ifa->ifa_name, ifname) == 0) {
+			ni = ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index;
 			break;
-		if (ifconf.ifc_buf) {
-			if (len == 0)
-				len = 4096;
-			ifconf.ifc_len = len *= 2;
-		} else {
-			len = ifconf.ifc_len;
-			extra = 0;
-		}
-		inbuf = realloc(ifconf.ifc_buf, ifconf.ifc_len);
-		if (inbuf == NULL)
-			goto ret;
-		ifconf.ifc_buf = inbuf;
-	}
-
-	i = 0;
-	p = ifconf.ifc_buf;
-	len = ifconf.ifc_len;
-	lastname[0] = 0;
-	lastname[sizeof(lastname)-1] = 0;
-
-	while (len > 0) {
-		if (len < IFNAMSIZ + sizeof(struct sockaddr))
-			goto ret;
-
-		thisname = p;
-		if (strncmp(lastname, p, IFNAMSIZ)) {
-			if (!strcmp(lastname, name)) {
-				index = i;
-				goto ret;
-			}
-			memcpy(lastname, thisname, IFNAMSIZ);
-			i++;
 		}
-
-		len -= IFNAMSIZ;
-		p += IFNAMSIZ;
-		sa = (struct sockaddr *)p;
-
-		if (!strncmp(thisname, name, IFNAMSIZ) &&
-		    sa->sa_family == AF_LINK) {
-			struct sockaddr_dl *sd = p;
-
-			index = sd->sdl_index;
-			goto ret;
-		}
-
-		if (len < sa->sa_len)
-			goto ret;
-		len -= sa->sa_len;
-		p += sa->sa_len;
 	}
 
-	if (!strcmp(lastname, name))
-		index = i;
-
-ret:
-	if (fd != -1)
-		close(fd);
-	if (ifconf.ifc_buf)
-		free(ifconf.ifc_buf);
-	return index;
+	freeifaddrs(ifaddrs);
+	if (!ni)
+		errno = ENXIO;
+	return(ni);
 }
-- 
cgit v1.2.3-55-g6feb