diff options
Diffstat (limited to 'lib/libc/net/if_indextoname.c')
-rw-r--r-- | lib/libc/net/if_indextoname.c | 155 |
1 files changed, 51 insertions, 104 deletions
diff --git a/lib/libc/net/if_indextoname.c b/lib/libc/net/if_indextoname.c index 4f3990b4c26..f99e52e387e 100644 --- a/lib/libc/net/if_indextoname.c +++ b/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); } |