diff options
author | Nick Mathewson <nickm@torproject.org> | 2011-12-12 11:37:02 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2011-12-28 16:34:16 -0500 |
commit | 9f06ec0c13f0b25ce3bb2c0c352edb04083dbe2c (patch) | |
tree | d84dd3e3d68b57a5364da001c9feac1c2f7148b0 /src/common/address.c | |
parent | 5d44a6b334f647b162801aa4d0c8607ac14c3ef7 (diff) | |
download | tor-9f06ec0c13f0b25ce3bb2c0c352edb04083dbe2c.tar.gz tor-9f06ec0c13f0b25ce3bb2c0c352edb04083dbe2c.zip |
Add interface enumeration based on SIOCGIFCONF for older unixes
Diffstat (limited to 'src/common/address.c')
-rw-r--r-- | src/common/address.c | 43 |
1 files changed, 43 insertions, 0 deletions
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 <ifaddrs.h> #endif +#ifdef HAVE_SYS_IOCTL_H +#include <sys/ioctl.h> +#endif +#ifdef HAVE_NET_IF_H +#include <net/if.h> +#endif #include <stdarg.h> #include <stdio.h> #include <stdlib.h> @@ -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; |