diff options
author | tron <tron@openttd.org> | 2006-06-17 08:16:58 +0000 |
---|---|---|
committer | tron <tron@openttd.org> | 2006-06-17 08:16:58 +0000 |
commit | bdf64588d3c99ccaa7e6fbc2e96a3d2dd032ee6a (patch) | |
tree | 2b7b21435c77cd188982419a422bf0c9a05e392d | |
parent | dcfcf7df4ace8aea0e03190a01867892d7278099 (diff) | |
download | openttd-bdf64588d3c99ccaa7e6fbc2e96a3d2dd032ee6a.tar.xz |
(svn r5292) -Fix: When using SIOCGIFCONF to detect network interfaces accomodate for the fact that struct sockaddr doesn't have fixed size in all implementations
-rw-r--r-- | network.c | 56 | ||||
-rw-r--r-- | network_core.h | 3 |
2 files changed, 33 insertions, 26 deletions
@@ -366,13 +366,15 @@ static void NetworkFindIPs(void) freeifaddrs(ifap); #else /* not HAVE_GETIFADDRS */ - - unsigned long len = 0; SOCKET sock; - IFREQ ifo[MAX_INTERFACES]; - -#ifndef WIN32 - struct ifconf if_conf; +#ifdef WIN32 + DWORD len = 0; + INTERFACE_INFO ifo[MAX_INTERFACES]; +#else + char buf[4 * 1024]; // Arbitrary buffer size + struct ifconf ifconf; + const char* buf_end; + const char* p; #endif // If something fails, make sure the list is empty @@ -382,40 +384,48 @@ static void NetworkFindIPs(void) if (sock == INVALID_SOCKET) return; #ifdef WIN32 - // On windows it is easy memset(&ifo[0], 0, sizeof(ifo)); if ((WSAIoctl(sock, SIO_GET_INTERFACE_LIST, NULL, 0, &ifo[0], sizeof(ifo), &len, NULL, NULL)) != 0) { closesocket(sock); return; } -#else - // On linux a bit harder - if_conf.ifc_len = (sizeof (struct ifreq)) * MAX_INTERFACES; - if_conf.ifc_buf = (char *)&ifo[0]; - if ((ioctl(sock, SIOCGIFCONF, &if_conf)) == -1) { - closesocket(sock); - return; - } - len = if_conf.ifc_len; -#endif /* WIN32 */ // Now walk through all IPs and list them for (i = 0; i < (int)(len / sizeof(IFREQ)); i++) { // Request IP for this interface -#ifdef WIN32 _network_ip_list[i] = *(&ifo[i].iiAddress.AddressIn.sin_addr.s_addr); + } #else - if ((ioctl(sock, SIOCGIFADDR, &ifo[i])) != 0) { - closesocket(sock); - return; + ifconf.ifc_len = sizeof(buf); + ifconf.ifc_buf = buf; + if (ioctl(sock, SIOCGIFCONF, &ifconf) == -1) { + closesocket(sock); + return; + } + + i = 0; + buf_end = buf + ifconf.ifc_len; + for (p = buf; p < buf_end;) { + const struct ifreq* req = (const struct ifreq*)p; + + if (req->ifr_addr.sa_family == AF_INET) { + struct ifreq r; + + strncpy(r.ifr_name, req->ifr_name, lengthof(r.ifr_name)); + if (ioctl(sock, SIOCGIFADDR, &r) != -1) { + _network_ip_list[i++] = + ((struct sockaddr_in*)&r.ifr_addr)->sin_addr.s_addr; + } } - _network_ip_list[i] = ((struct sockaddr_in *)&ifo[i].ifr_addr)->sin_addr.s_addr; + p += sizeof(struct ifreq); +#ifdef AF_LINK + p += req->ifr_addr.sa_len - sizeof(struct sockaddr); #endif } +#endif closesocket(sock); - #endif /* not HAVE_GETIFADDRS */ _network_ip_list[i] = 0; diff --git a/network_core.h b/network_core.h index 7a9dd4e42..f2373574c 100644 --- a/network_core.h +++ b/network_core.h @@ -32,14 +32,12 @@ #define EWOULDBLOCK WSAEWOULDBLOCK // Windows has some different names for some types.. typedef unsigned long in_addr_t; -typedef INTERFACE_INFO IFREQ; #endif // WIN32 // UNIX stuff #if defined(UNIX) # define SOCKET int # define INVALID_SOCKET -1 -typedef struct ifreq IFREQ; # if !defined(__MORPHOS__) && !defined(__AMIGA__) # define ioctlsocket ioctl # if !defined(BEOS_NET_SERVER) @@ -100,7 +98,6 @@ typedef struct ifreq IFREQ; #if defined(__OS2__) # define SOCKET int # define INVALID_SOCKET -1 -typedef struct ifreq IFREQ; # define ioctlsocket ioctl # define closesocket close # define GET_LAST_ERROR() (sock_errno()) |