diff --git a/network.c b/network.c index 0e4f6bd9ab..12427373e8 100644 --- a/network.c +++ b/network.c @@ -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; - } - - _network_ip_list[i] = ((struct sockaddr_in *)&ifo[i].ifr_addr)->sin_addr.s_addr; -#endif + ifconf.ifc_len = sizeof(buf); + ifconf.ifc_buf = buf; + if (ioctl(sock, SIOCGIFCONF, &ifconf) == -1) { + closesocket(sock); + return; } - closesocket(sock); + 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; + } + } + + 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 7a9dd4e420..f2373574c8 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())