summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortron <tron@openttd.org>2006-06-17 08:16:58 +0000
committertron <tron@openttd.org>2006-06-17 08:16:58 +0000
commitbdf64588d3c99ccaa7e6fbc2e96a3d2dd032ee6a (patch)
tree2b7b21435c77cd188982419a422bf0c9a05e392d
parentdcfcf7df4ace8aea0e03190a01867892d7278099 (diff)
downloadopenttd-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.c56
-rw-r--r--network_core.h3
2 files changed, 33 insertions, 26 deletions
diff --git a/network.c b/network.c
index 0e4f6bd9a..12427373e 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;
+ 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())