$NetBSD: patch-ae,v 1.3 2009/02/11 08:06:17 obache Exp $ --- getifname.c.orig 2004-05-03 08:55:53.000000000 +0000 +++ getifname.c @@ -17,7 +17,7 @@ #include /* close */ #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \ - defined(__bsdi__) || defined(__APPLE__) + defined(__bsdi__) || defined(__APPLE__) || defined(__DragonFly__) #include #include #include @@ -27,12 +27,12 @@ #include "globals.h" #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && \ - !defined(__linux__) && !defined(__sun__) && !defined(__bsdi__) && \ - !defined(__APPLE__) + !defined(__linux__) && !defined(__sun) && !defined(__bsdi__) && \ + !defined(__APPLE__) && !defined(__DragonFly__) #error Sorry, interface code not implemented. #endif -#ifdef __sun__ +#ifdef __sun #include #include #include @@ -40,15 +40,16 @@ static int get_output_if(struct sockaddr_in *dest, struct sockaddr_in *ifip); -#if (defined OSTYPE_LINUX) || (defined __sun__) +#if (defined OSTYPE_LINUX) || (defined __sun) int get_if_name(void) { int fd; struct ifconf ifc; - struct ifreq ibuf[16], - ifr, + struct ifreq ifr, *ifrp, *ifend; + char *ibuf; + int ibuflen; struct sockaddr_in sa; struct sockaddr_in output_if_addr; int known_output_if = 0; @@ -72,21 +73,40 @@ int get_if_name(void) return -1; } - memset(ibuf, 0, sizeof(struct ifreq)*16); - ifc.ifc_len = sizeof ibuf; + ibuf = NULL; + ibuflen = 16 * sizeof(struct ifreq); + for (;;) { + char *nibuf = (char *) realloc(ibuf, ibuflen); + if (!nibuf) { + perror("[get_if_name] realloc"); + goto go_out; + } + + ibuf = nibuf; + memset(ibuf, 0, ibuflen); + ifc.ifc_len = ibuflen; ifc.ifc_buf = (caddr_t) ibuf; /* gets interfaces list */ if ( ioctl(fd, SIOCGIFCONF, (char*)&ifc) == -1 || ifc.ifc_len < sizeof(struct ifreq) ) { perror("[get_if_name] ioctl(SIOCGIFCONF)"); - close(fd); - return -1; + goto go_out; + } + + if (ifc.ifc_len + sizeof(struct ifreq) <= ibuflen) + break; + if (ibuflen >= 1024 * sizeof(struct ifreq)) { + fprintf(stderr, "Warning: Too many network " + "interfaces.\n"); + break; + } + ibuflen *= 2; } /* ifrp points to buffer and ifend points to buffer's end */ - ifrp = ibuf; - ifend = (struct ifreq*) ((char*)ibuf + ifc.ifc_len); + ifrp = (struct ifreq *) ibuf; + ifend = (struct ifreq *) (ibuf + ifc.ifc_len); for (; ifrp < ifend; ifrp++) { strlcpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name)); @@ -155,27 +175,28 @@ int get_if_name(void) } else { -#ifdef __sun__ +#ifdef __sun /* somehow solaris is braidamaged in wrt ifr_mtu */ h_if_mtu = ifr.ifr_metric; #else h_if_mtu = ifr.ifr_mtu; #endif } - close(fd); - return 0; + goto go_out; } /* interface not found, use 'lo' */ strlcpy(ifname, "lo", 1024); strlcpy(ifstraddr, "127.0.0.1", 1024); h_if_mtu = 1500; +go_out: + free(ibuf); close(fd); return 0; } #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ - defined(__bsdi__) || defined(__APPLE__) + defined(__bsdi__) || defined(__APPLE__) || defined(__DragonFly__) /* return interface informations : - from the specified (-I) interface