summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormillert <>2002-03-07 22:40:23 +0000
committermillert <>2002-03-07 22:40:23 +0000
commitac55e95265194286ad7db771d95bd73b521e92b6 (patch)
treef13fe9b86c4ef03932d1e2d666076fea9acd6350
parent409c42a31740ca9da36e066b8f180e668520958c (diff)
downloadopenbsd-ac55e95265194286ad7db771d95bd73b521e92b6.tar.gz
openbsd-ac55e95265194286ad7db771d95bd73b521e92b6.tar.bz2
openbsd-ac55e95265194286ad7db771d95bd73b521e92b6.zip
Replace SIOCGIFCONF-using NRL versions with KAME versions that use
getifaddrs(3). Fixes problems on LP64 platforms.
-rw-r--r--src/lib/libc/net/if_indextoname.c155
-rw-r--r--src/lib/libc/net/if_nameindex.c233
-rw-r--r--src/lib/libc/net/if_nametoindex.c146
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 @@
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}
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 @@
1/* 1/* $OpenBSD: if_nameindex.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_nameindex.c,v 1.7 2000/11/24 08:17:20 itojun 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,140 +22,119 @@
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_nameindex.c,v 2.3 2000/04/17 22:38:05 dab Exp
31 */ 27 */
32 28
33#include <stdlib.h>
34#include <sys/types.h> 29#include <sys/types.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>
42 36
37/*
38 * From RFC 2553:
39 *
40 * 4.3 Return All Interface Names and Indexes
41 *
42 * The if_nameindex structure holds the information about a single
43 * interface and is defined as a result of including the <net/if.h>
44 * header.
45 *
46 * struct if_nameindex {
47 * unsigned int if_index;
48 * char *if_name;
49 * };
50 *
51 * The final function returns an array of if_nameindex structures, one
52 * structure per interface.
53 *
54 * struct if_nameindex *if_nameindex(void);
55 *
56 * The end of the array of structures is indicated by a structure with
57 * an if_index of 0 and an if_name of NULL. The function returns a NULL
58 * pointer upon an error, and would set errno to the appropriate value.
59 *
60 * The memory used for this array of structures along with the interface
61 * names pointed to by the if_name members is obtained dynamically.
62 * This memory is freed by the next function.
63 *
64 * 4.4. Free Memory
65 *
66 * The following function frees the dynamic memory that was allocated by
67 * if_nameindex().
68 *
69 * #include <net/if.h>
70 *
71 * void if_freenameindex(struct if_nameindex *ptr);
72 *
73 * The argument to this function must be a pointer that was returned by
74 * if_nameindex().
75 */
76
43struct if_nameindex * 77struct if_nameindex *
44if_nameindex(void) 78if_nameindex(void)
45{ 79{
46 int i, j, fd = -1, extra, len = 0; 80 struct ifaddrs *ifaddrs, *ifa;
47 struct if_nameindex *nameindex = NULL; 81 unsigned int ni;
48 struct ifconf ifconf; 82 size_t nbytes;
49 char lastname[IFNAMSIZ], *c, *inbuf; 83 struct if_nameindex *ifni, *ifni2;
50 struct if_nameindex *n; 84 char *cp;
51 struct sockaddr *sa;
52 void *p;
53
54 ifconf.ifc_buf = NULL;
55 85
56 if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) 86 if (getifaddrs(&ifaddrs) < 0)
57 goto ret; 87 return(NULL);
58 88
59 /* 89 /*
60 * Try ifc_len == 0 hack first, to get the actual length. 90 * First, find out how many interfaces there are, and how
61 * If that fails, revert to a loop which grows the ifc_buf 91 * much space we need for the string names.
62 * until it is sufficiently large.
63 */ 92 */
64 extra = sizeof(struct ifreq); 93 ni = 0;
65 while (1) { 94 nbytes = 0;
66 ifconf.ifc_len = len; 95 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
67 if (ioctl(fd, SIOCGIFCONF, (void *) &ifconf) == -1 && 96 if (ifa->ifa_addr &&
68 ifconf.ifc_buf) 97 ifa->ifa_addr->sa_family == AF_LINK) {
69 goto ret; 98 nbytes += strlen(ifa->ifa_name) + 1;
70 if (ifconf.ifc_buf && 99 ni++;
71 ifconf.ifc_len + extra < len)
72 break;
73 if (ifconf.ifc_buf) {
74 if (len == 0)
75 len = 4096;
76 ifconf.ifc_len = len *= 2;
77 } else {
78 len = ifconf.ifc_len;
79 extra = 0;
80 }
81 inbuf = realloc(ifconf.ifc_buf, ifconf.ifc_len);
82 if (inbuf == NULL)
83 goto ret;
84 ifconf.ifc_buf = inbuf;
85 }
86
87 i = sizeof(struct if_nameindex);
88 j = 0;
89 p = ifconf.ifc_buf;
90 len = ifconf.ifc_len;
91 lastname[0] = 0;
92 lastname[sizeof(lastname)-1] = 0;
93
94 while (len > 0) {
95 if (len < (IFNAMSIZ + sizeof(struct sockaddr)))
96 goto ret;
97 if (strncmp(lastname, p, IFNAMSIZ)) {
98 strlcpy(lastname, p, sizeof(lastname));
99 i += sizeof(struct if_nameindex);
100 j += strlen(lastname) + 1;
101 } 100 }
102 len -= IFNAMSIZ;
103 p += IFNAMSIZ;
104 sa = p;
105
106 if (sa->sa_len < sizeof(struct sockaddr))
107 sa->sa_len = sizeof(struct sockaddr);
108
109 if (len < sa->sa_len)
110 goto ret;
111 len -= sa->sa_len;
112 p += sa->sa_len;
113 }
114
115 nameindex = malloc(i + j);
116 if (nameindex == NULL) {
117 errno = ENOMEM;
118 goto ret;
119 } 101 }
120 memset(nameindex, 0, i + j);
121 102
122 n = nameindex; 103 /*
123 p = ifconf.ifc_buf; 104 * Next, allocate a chunk of memory, use the first part
124 c = (void *) nameindex + i; 105 * for the array of structures, and the last part for
125 i = 0; 106 * the strings.
126 len = ifconf.ifc_len; 107 */
127 lastname[0] = 0; 108 cp = malloc((ni + 1) * sizeof(struct if_nameindex) + nbytes);
128 109 ifni = (struct if_nameindex *)cp;
129 while (len > 0) { 110 if (ifni == NULL)
130 if (len < IFNAMSIZ + sizeof(struct sockaddr)) 111 goto out;
131 goto ret; 112 cp += (ni + 1) * sizeof(struct if_nameindex);
132 if (strncmp(lastname, p, IFNAMSIZ)) {
133 if (i) {
134 if (!n->if_index)
135 n->if_index = i;
136 n++;
137 }
138 i++;
139 memcpy(lastname, p, sizeof(lastname));
140 strlcpy(c, lastname, sizeof(lastname));
141 n->if_name = c;
142 c += strlen(c) + 1;
143 }
144 len -= IFNAMSIZ;
145 p += IFNAMSIZ;
146 sa = p;
147 113
148 if (len < sa->sa_len) 114 /*
149 goto ret; 115 * Now just loop through the list of interfaces again,
150 if (sa->sa_family == AF_LINK) { 116 * filling in the if_nameindex array and making copies
151 struct sockaddr_dl *sd = (struct sockaddr_dl *)sa; 117 * of all the strings.
152 n->if_index = sd->sdl_index; 118 */
119 ifni2 = ifni;
120 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
121 if (ifa->ifa_addr &&
122 ifa->ifa_addr->sa_family == AF_LINK) {
123 ifni2->if_index =
124 ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index;
125 ifni2->if_name = cp;
126 nbytes = strlen(ifa->ifa_name) + 1;
127 memcpy(cp, ifa->ifa_name, nbytes);
128 ifni2++;
129 cp += nbytes;
153 } 130 }
154 len -= sa->sa_len;
155 p += sa->sa_len;
156 } 131 }
157 132 /*
158 if (n->if_index == 0) 133 * Finally, don't forget to terminate the array.
159 n->if_index = i; 134 */
160 135 ifni2->if_index = 0;
161ret: 136 ifni2->if_name = NULL;
162 if (fd != -1) 137out:
163 close(fd); 138 freeifaddrs(ifaddrs);
164 if (ifconf.ifc_buf) 139 return(ifni);
165 free(ifconf.ifc_buf);
166 return (nameindex);
167} 140}
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 @@
1/* 1/* $OpenBSD: if_nametoindex.c,v 1.8 2002/03/07 22:40:23 millert Exp $ */
2 * Copyright (c) 1998-1999, Craig Metz, All rights reserved. 2/* $KAME: if_nametoindex.c,v 1.5 2000/11/24 08:04:40 itojun 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,106 +22,60 @@
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_nametoindex.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> 31#include <net/if.h>
38#include <net/if_dl.h> 32#include <net/if_dl.h>
33#include <ifaddrs.h>
34#include <stdlib.h>
39#include <string.h> 35#include <string.h>
40#include <unistd.h>
41#include <errno.h> 36#include <errno.h>
42 37
43unsigned int 38/*
44if_nametoindex(const char *name) 39 * From RFC 2553:
40 *
41 * 4.1 Name-to-Index
42 *
43 *
44 * The first function maps an interface name into its corresponding
45 * index.
46 *
47 * #include <net/if.h>
48 *
49 * unsigned int if_nametoindex(const char *ifname);
50 *
51 * If the specified interface name does not exist, the return value is
52 * 0, and errno is set to ENXIO. If there was a system error (such as
53 * running out of memory), the return value is 0 and errno is set to the
54 * proper value (e.g., ENOMEM).
55 */
56
57unsigned int
58if_nametoindex(const char *ifname)
45{ 59{
46 int i, fd = -1, extra, len = 0; 60 struct ifaddrs *ifaddrs, *ifa;
47 struct ifconf ifconf; 61 unsigned int ni;
48 char lastname[IFNAMSIZ], *thisname, *inbuf;
49 unsigned int index = 0;
50 struct sockaddr *sa;
51 void *p;
52 62
53 ifconf.ifc_buf = 0; 63 if (getifaddrs(&ifaddrs) < 0)
64 return(0);
54 65
55 if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) 66 ni = 0;
56 goto ret;
57 67
58 /* 68 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
59 * Try ifc_len == 0 hack first, to get the actual length. 69 if (ifa->ifa_addr &&
60 * If that fails, revert to a loop which grows the ifc_buf 70 ifa->ifa_addr->sa_family == AF_LINK &&
61 * until it is sufficiently large. 71 strcmp(ifa->ifa_name, ifname) == 0) {
62 */ 72 ni = ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index;
63 extra = sizeof(struct ifreq);
64 while (1) {
65 ifconf.ifc_len = len;
66 if (ioctl(fd, SIOCGIFCONF, (void *) &ifconf) == -1 &&
67 ifconf.ifc_buf)
68 goto ret;
69 if (ifconf.ifc_buf &&
70 ifconf.ifc_len + extra < len)
71 break; 73 break;
72 if (ifconf.ifc_buf) {
73 if (len == 0)
74 len = 4096;
75 ifconf.ifc_len = len *= 2;
76 } else {
77 len = ifconf.ifc_len;
78 extra = 0;
79 }
80 inbuf = realloc(ifconf.ifc_buf, ifconf.ifc_len);
81 if (inbuf == NULL)
82 goto ret;
83 ifconf.ifc_buf = inbuf;
84 }
85
86 i = 0;
87 p = ifconf.ifc_buf;
88 len = ifconf.ifc_len;
89 lastname[0] = 0;
90 lastname[sizeof(lastname)-1] = 0;
91
92 while (len > 0) {
93 if (len < IFNAMSIZ + sizeof(struct sockaddr))
94 goto ret;
95
96 thisname = p;
97 if (strncmp(lastname, p, IFNAMSIZ)) {
98 if (!strcmp(lastname, name)) {
99 index = i;
100 goto ret;
101 }
102 memcpy(lastname, thisname, IFNAMSIZ);
103 i++;
104 } 74 }
105
106 len -= IFNAMSIZ;
107 p += IFNAMSIZ;
108 sa = (struct sockaddr *)p;
109
110 if (!strncmp(thisname, name, IFNAMSIZ) &&
111 sa->sa_family == AF_LINK) {
112 struct sockaddr_dl *sd = p;
113
114 index = sd->sdl_index;
115 goto ret;
116 }
117
118 if (len < sa->sa_len)
119 goto ret;
120 len -= sa->sa_len;
121 p += sa->sa_len;
122 } 75 }
123 76
124 if (!strcmp(lastname, name)) 77 freeifaddrs(ifaddrs);
125 index = i; 78 if (!ni)
126 79 errno = ENXIO;
127ret: 80 return(ni);
128 if (fd != -1)
129 close(fd);
130 if (ifconf.ifc_buf)
131 free(ifconf.ifc_buf);
132 return index;
133} 81}