From 25db34ffae569e9ff78fd3f5f6f621ee73da9a2f Mon Sep 17 00:00:00 2001 From: deraadt <> Date: Thu, 8 Jul 1999 22:29:53 +0000 Subject: use SIOCGIFCONF much more carefully --- src/lib/libc/net/if_nameindex.c | 48 +++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 14 deletions(-) (limited to 'src/lib/libc/net/if_nameindex.c') 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 @@ struct if_nameindex * if_nameindex(void) { - int i, j, fd, len; + int i, j, fd = -1, extra, len = 0; struct if_nameindex *nameindex = NULL; struct ifconf ifconf; - char lastname[IFNAMSIZ], *c; + char lastname[IFNAMSIZ], *c, *inbuf; struct if_nameindex *n; struct sockaddr_dl *sd; struct sockaddr *sa; void *p; - if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) - return NULL; + ifconf.ifc_buf = NULL; - ifconf.ifc_len = 0; - ifconf.ifc_buf = 0; - if (ioctl(fd, SIOCGIFCONF, (void *) &ifconf)) - goto ret; - if (ifconf.ifc_len < IFNAMSIZ) - goto ret; - if (!(ifconf.ifc_buf = malloc(ifconf.ifc_len))) - goto ret; - if (ioctl(fd, SIOCGIFCONF, (void *) &ifconf)) + if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) goto ret; + /* + * 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) + 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; @@ -138,7 +157,8 @@ if_nameindex(void) n->if_index = i; ret: - close(fd); + if (fd != -1) + close(fd); if (ifconf.ifc_buf) free(ifconf.ifc_buf); return (nameindex); -- cgit v1.2.3-55-g6feb