summaryrefslogtreecommitdiff
path: root/src/lib/libc/net/if_indextoname.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc/net/if_indextoname.c')
-rw-r--r--src/lib/libc/net/if_indextoname.c155
1 files changed, 51 insertions, 104 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 @@
1/* 1/* $OpenBSD: if_indextoname.c,v 1.9 2002/03/07 22:40:23 millert Exp $ */
2 * Copyright (c) 1998-1999, Craig Metz, All rights reserved. 2/* $KAME: if_indextoname.c,v 1.6 2000/11/07 22:33:25 jinmei Exp $ */
3
4/*-
5 * Copyright (c) 1997, 2000
6 * Berkeley Software Design, Inc. All rights reserved.
3 * 7 *
4 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
6 * are met: 10 * are met:
7 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. All advertising materials mentioning features or use of this software
13 * must display the following acknowledgement:
14 * This product includes software developed by Craig Metz and
15 * by other contributors.
16 * 4. Neither the name of the author nor the names of contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 * 13 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 14 * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 17 * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -28,112 +22,65 @@
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE. 24 * SUCH DAMAGE.
25 *
26 * BSDI Id: if_indextoname.c,v 2.3 2000/04/17 22:38:05 dab Exp
31 */ 27 */
32 28
33#include <sys/types.h> 29#include <sys/types.h>
34#include <stdlib.h>
35#include <sys/socket.h> 30#include <sys/socket.h>
36#include <sys/ioctl.h>
37#include <net/if.h>
38#include <net/if_dl.h> 31#include <net/if_dl.h>
39#include <errno.h> 32#include <net/if.h>
40#include <unistd.h> 33#include <ifaddrs.h>
34#include <stdlib.h>
41#include <string.h> 35#include <string.h>
36#include <errno.h>
42 37
43static char __name[IFNAMSIZ]; 38/*
39 * From RFC 2533:
40 *
41 * The second function maps an interface index into its corresponding
42 * name.
43 *
44 * #include <net/if.h>
45 *
46 * char *if_indextoname(unsigned int ifindex, char *ifname);
47 *
48 * The ifname argument must point to a buffer of at least IF_NAMESIZE
49 * bytes into which the interface name corresponding to the specified
50 * index is returned. (IF_NAMESIZE is also defined in <net/if.h> and
51 * its value includes a terminating null byte at the end of the
52 * interface name.) This pointer is also the return value of the
53 * function. If there is no interface corresponding to the specified
54 * index, NULL is returned, and errno is set to ENXIO, if there was a
55 * system error (such as running out of memory), if_indextoname returns
56 * NULL and errno would be set to the proper value (e.g., ENOMEM).
57 */
44 58
45char * 59char *
46if_indextoname(unsigned int index, char *name) 60if_indextoname(unsigned int ifindex, char *ifname)
47{ 61{
48 int i, fd = -1, extra, len = 0; 62 struct ifaddrs *ifaddrs, *ifa;
49 struct ifconf ifconf; 63 int error = 0;
50 char lastname[IFNAMSIZ], iname[IFNAMSIZ], *retname = NULL, *inbuf;
51 struct sockaddr *sa;
52 void *p;
53
54 ifconf.ifc_buf = 0;
55
56 if (!name)
57 name = __name;
58 64
59 if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) 65 if (getifaddrs(&ifaddrs) < 0)
60 goto ret; 66 return(NULL); /* getifaddrs properly set errno */
61 67
62 /* 68 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
63 * Try ifc_len == 0 hack first, to get the actual length. 69 if (ifa->ifa_addr &&
64 * If that fails, revert to a loop which grows the ifc_buf 70 ifa->ifa_addr->sa_family == AF_LINK &&
65 * until it is sufficiently large. 71 ifindex == ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index)
66 */
67 extra = sizeof(struct ifreq);
68 while (1) {
69 ifconf.ifc_len = len;
70 if (ioctl(fd, SIOCGIFCONF, (void *) &ifconf) == -1 &&
71 ifconf.ifc_buf)
72 goto ret;
73 if (ifconf.ifc_buf &&
74 ifconf.ifc_len + extra < len)
75 break; 72 break;
76 if (ifconf.ifc_buf) {
77 if (len == 0)
78 len = 4096;
79 ifconf.ifc_len = len *= 2;
80 } else {
81 len = ifconf.ifc_len;
82 extra = 0;
83 }
84 inbuf = realloc(ifconf.ifc_buf, ifconf.ifc_len);
85 if (inbuf == NULL)
86 goto ret;
87 ifconf.ifc_buf = inbuf;
88 } 73 }
89 74
90 i = 0; 75 if (ifa == NULL) {
91 p = ifconf.ifc_buf; 76 error = ENXIO;
92 len = ifconf.ifc_len; 77 ifname = NULL;
93 lastname[0] = 0;
94 lastname[sizeof(lastname)-1] = 0;
95 iname[0] = 0;
96
97 while (len > 0) {
98 if (len < (IFNAMSIZ + sizeof(struct sockaddr)))
99 goto ret;
100 if (strncmp(lastname, p, IFNAMSIZ)) {
101 if (i == index)
102 memcpy(iname, lastname, sizeof(iname));
103 strlcpy(lastname, p, sizeof(lastname));
104 i++;
105 }
106 len -= IFNAMSIZ;
107 p += IFNAMSIZ;
108 sa = p;
109
110 if (sa->sa_family == AF_LINK) {
111 struct sockaddr_dl *sd = p;
112
113 if (sd->sdl_index == index) {
114 strlcpy(name, lastname, IFNAMSIZ);
115 retname = name;
116 goto ret;
117 }
118 }
119
120 if (len < sa->sa_len)
121 goto ret;
122 len -= sa->sa_len;
123 p += sa->sa_len;
124 } 78 }
79 else
80 strlcpy(ifname, ifa->ifa_name, IFNAMSIZ);
125 81
126 if (i == index) 82 freeifaddrs(ifaddrs);
127 strlcpy(iname, lastname, sizeof(iname));
128 83
129 if (iname[0]) { 84 errno = error;
130 strlcpy(name, iname, IFNAMSIZ); 85 return(ifname);
131 retname = name;
132 }
133ret:
134 if (fd != -1)
135 close(fd);
136 if (ifconf.ifc_buf)
137 free(ifconf.ifc_buf);
138 return (retname);
139} 86}