summaryrefslogtreecommitdiff
path: root/network.c
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 /network.c
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
Diffstat (limited to 'network.c')
-rw-r--r--network.c56
1 files changed, 33 insertions, 23 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;