summaryrefslogtreecommitdiff
path: root/src/lib/libc/net/if_nameindex.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc/net/if_nameindex.c')
-rw-r--r--src/lib/libc/net/if_nameindex.c48
1 files changed, 34 insertions, 14 deletions
diff --git a/src/lib/libc/net/if_nameindex.c b/src/lib/libc/net/if_nameindex.c
index 8714c1f95a..8643397db2 100644
--- a/src/lib/libc/net/if_nameindex.c
+++ b/src/lib/libc/net/if_nameindex.c
@@ -43,29 +43,48 @@
43struct if_nameindex * 43struct if_nameindex *
44if_nameindex(void) 44if_nameindex(void)
45{ 45{
46 int i, j, fd, len; 46 int i, j, fd = -1, extra, len = 0;
47 struct if_nameindex *nameindex = NULL; 47 struct if_nameindex *nameindex = NULL;
48 struct ifconf ifconf; 48 struct ifconf ifconf;
49 char lastname[IFNAMSIZ], *c; 49 char lastname[IFNAMSIZ], *c, *inbuf;
50 struct if_nameindex *n; 50 struct if_nameindex *n;
51 struct sockaddr_dl *sd; 51 struct sockaddr_dl *sd;
52 struct sockaddr *sa; 52 struct sockaddr *sa;
53 void *p; 53 void *p;
54 54
55 if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) 55 ifconf.ifc_buf = NULL;
56 return NULL;
57 56
58 ifconf.ifc_len = 0; 57 if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
59 ifconf.ifc_buf = 0;
60 if (ioctl(fd, SIOCGIFCONF, (void *) &ifconf))
61 goto ret;
62 if (ifconf.ifc_len < IFNAMSIZ)
63 goto ret;
64 if (!(ifconf.ifc_buf = malloc(ifconf.ifc_len)))
65 goto ret;
66 if (ioctl(fd, SIOCGIFCONF, (void *) &ifconf))
67 goto ret; 58 goto ret;
68 59
60 /*
61 * Try ifc_len == 0 hack first, to get the actual length.
62 * If that fails, revert to a loop which grows the ifc_buf
63 * until it is sufficiently large.
64 */
65 extra = sizeof(struct ifreq);
66 while (1) {
67 ifconf.ifc_len = len;
68 if (ioctl(fd, SIOCGIFCONF, (void *) &ifconf) == -1 &&
69 ifconf.ifc_buf)
70 goto ret;
71 if (ifconf.ifc_buf &&
72 ifconf.ifc_len + extra < len)
73 break;
74 if (ifconf.ifc_buf) {
75 if (len == 0)
76 len = 4096;
77 ifconf.ifc_len = len *= 2;
78 } else {
79 len = ifconf.ifc_len;
80 extra = 0;
81 }
82 inbuf = realloc(ifconf.ifc_buf, ifconf.ifc_len);
83 if (inbuf == NULL)
84 goto ret;
85 ifconf.ifc_buf = inbuf;
86 }
87
69 i = sizeof(struct if_nameindex); 88 i = sizeof(struct if_nameindex);
70 j = 0; 89 j = 0;
71 p = ifconf.ifc_buf; 90 p = ifconf.ifc_buf;
@@ -138,7 +157,8 @@ if_nameindex(void)
138 n->if_index = i; 157 n->if_index = i;
139 158
140ret: 159ret:
141 close(fd); 160 if (fd != -1)
161 close(fd);
142 if (ifconf.ifc_buf) 162 if (ifconf.ifc_buf)
143 free(ifconf.ifc_buf); 163 free(ifconf.ifc_buf);
144 return (nameindex); 164 return (nameindex);