From 9f06ec0c13f0b25ce3bb2c0c352edb04083dbe2c Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 12 Dec 2011 11:37:02 -0500 Subject: [PATCH] Add interface enumeration based on SIOCGIFCONF for older unixes --- configure.in | 2 ++ src/common/address.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/configure.in b/configure.in index a2aa417502..c3d53f79b6 100644 --- a/configure.in +++ b/configure.in @@ -305,6 +305,7 @@ AC_CHECK_FUNCS( gettimeofday \ gmtime_r \ inet_aton \ + ioctl \ localtime_r \ lround \ memmem \ @@ -634,6 +635,7 @@ AC_CHECK_HEADERS( malloc/malloc.h \ malloc_np.h \ netdb.h \ + net/if.h \ netinet/in.h \ netinet/in6.h \ pwd.h \ diff --git a/src/common/address.c b/src/common/address.c index be205e4725..2e9892c4dc 100644 --- a/src/common/address.c +++ b/src/common/address.c @@ -55,6 +55,12 @@ #ifdef HAVE_IFADDRS_H #include #endif +#ifdef HAVE_SYS_IOCTL_H +#include +#endif +#ifdef HAVE_NET_IF_H +#include +#endif #include #include #include @@ -1198,6 +1204,43 @@ get_interface_addresses_raw(int severity) FreeLibrary(lib); tor_free(addresses); return result; +#elif defined(SIOCGIFCONF) && defined(HAVE_IOCTL) + /* Some older unixy systems make us use ioctl(SIOCGIFCONF) */ + struct ifconf ifc; + int fd, i, sz, n; + smartlist_t *result = NULL; + /* This interface, AFAICT, only supports AF_INET addresses */ + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + log(severity, LD_NET, "socket failed: %s", strerror(errno)); + goto done; + } + /* Guess how much space we need. */ + ifc.ifc_len = sz = 15*1024; + ifc.ifc_ifcu.ifcu_req = tor_malloc(sz); + if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) { + log(severity, LD_NET, "ioctl failed: %s", strerror(errno)); + close(fd); + goto done; + } + close(fd); + result = smartlist_create(); + if (ifc.ifc_len < sz) + sz = ifc.ifc_len; + n = sz / sizeof(struct ifreq); + for (i = 0; i < n ; ++i) { + struct ifreq *r = &ifc.ifc_ifcu.ifcu_req[i]; + struct sockaddr *sa = &r->ifr_addr; + tor_addr_t tmp; + if (sa->sa_family != AF_INET && sa->sa_family != AF_INET6) + continue; /* should be impossible */ + if (tor_addr_from_sockaddr(&tmp, sa, NULL) < 0) + continue; + smartlist_add(result, tor_memdup(&tmp, sizeof(tmp))); + } + done: + tor_free(ifc.ifc_ifcu.ifcu_req); + return result; #else (void) severity; return NULL;