mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-06 22:28:56 +00:00
(svn r5293) -Fix: Not all network interfaces are capable of broadcasting. Don't record those which aren't
-Fix: Not all networks are /24. Generate proper broadcast addresses for non-/24 nets
This commit is contained in:
parent
bdf64588d3
commit
670e47eec3
64
network.c
64
network.c
@ -285,7 +285,7 @@ char *GetNetworkErrorMsg(char *buf, NetworkErrorCode err)
|
|||||||
// Find all IP-aliases for this host
|
// Find all IP-aliases for this host
|
||||||
static void NetworkFindIPs(void)
|
static void NetworkFindIPs(void)
|
||||||
{
|
{
|
||||||
int i, last;
|
int i;
|
||||||
|
|
||||||
#if defined(BEOS_NET_SERVER) /* doesn't have neither getifaddrs or net/if.h */
|
#if defined(BEOS_NET_SERVER) /* doesn't have neither getifaddrs or net/if.h */
|
||||||
/* Based on Andrew Bachmann's netstat+.c. Big thanks to him! */
|
/* Based on Andrew Bachmann's netstat+.c. Big thanks to him! */
|
||||||
@ -307,7 +307,7 @@ static void NetworkFindIPs(void)
|
|||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
// If something fails, make sure the list is empty
|
// If something fails, make sure the list is empty
|
||||||
_network_ip_list[0] = 0;
|
_broadcast_list[0] = 0;
|
||||||
|
|
||||||
if (sock < 0) {
|
if (sock < 0) {
|
||||||
DEBUG(net, 0)("Error creating socket!");
|
DEBUG(net, 0)("Error creating socket!");
|
||||||
@ -326,15 +326,22 @@ static void NetworkFindIPs(void)
|
|||||||
uint32 n, fields, read;
|
uint32 n, fields, read;
|
||||||
uint8 i1, i2, i3, i4, j1, j2, j3, j4;
|
uint8 i1, i2, i3, i4, j1, j2, j3, j4;
|
||||||
struct in_addr inaddr;
|
struct in_addr inaddr;
|
||||||
|
uint32 ip;
|
||||||
|
uint32 netmask;
|
||||||
|
|
||||||
fields = sscanf(*output, "%u: %hhu.%hhu.%hhu.%hhu, netmask %hhu.%hhu.%hhu.%hhu%n",
|
fields = sscanf(*output, "%u: %hhu.%hhu.%hhu.%hhu, netmask %hhu.%hhu.%hhu.%hhu%n",
|
||||||
&n, &i1,&i2,&i3,&i4, &j1,&j2,&j3,&j4, &read);
|
&n, &i1,&i2,&i3,&i4, &j1,&j2,&j3,&j4, &read);
|
||||||
read += 1;
|
read += 1;
|
||||||
if (fields != 9) {
|
if (fields != 9) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
inaddr.s_addr = htonl((uint32)i1 << 24 | (uint32)i2 << 16 | (uint32)i3 << 8 | (uint32)i4);
|
|
||||||
if (inaddr.s_addr != 0) {
|
ip = (uint32)i1 << 24 | (uint32)i2 << 16 | (uint32)i3 << 8 | (uint32)i4;
|
||||||
_network_ip_list[i] = inaddr.s_addr;
|
netmask = (uint32)j1 << 24 | (uint32)j2 << 16 | (uint32)j3 << 8 | (uint32)j4;
|
||||||
|
|
||||||
|
if (ip != INADDR_LOOPBACK && ip != INADDR_ANY) {
|
||||||
|
inaddr.s_addr = htonl(ip | ~netmask);
|
||||||
|
_broadcast_list[i] = inaddr.s_addr;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (read < 0) {
|
if (read < 0) {
|
||||||
@ -351,16 +358,17 @@ static void NetworkFindIPs(void)
|
|||||||
struct ifaddrs *ifap, *ifa;
|
struct ifaddrs *ifap, *ifa;
|
||||||
|
|
||||||
// If something fails, make sure the list is empty
|
// If something fails, make sure the list is empty
|
||||||
_network_ip_list[0] = 0;
|
_broadcast_list[0] = 0;
|
||||||
|
|
||||||
if (getifaddrs(&ifap) != 0)
|
if (getifaddrs(&ifap) != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
|
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
|
||||||
if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET)
|
if (!(ifa->ifa_flags & IFF_BROADCAST)) continue;
|
||||||
continue;
|
if (ifa->ifa_broadaddr == NULL) continue;
|
||||||
_network_ip_list[i] = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
|
if (ifa->ifa_broadaddr->sa_family != AF_INET) continue;
|
||||||
|
_broadcast_list[i] = ((struct sockaddr_in*)ifa->ifa_broadaddr)->sin_addr.s_addr;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
freeifaddrs(ifap);
|
freeifaddrs(ifap);
|
||||||
@ -370,6 +378,7 @@ static void NetworkFindIPs(void)
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
DWORD len = 0;
|
DWORD len = 0;
|
||||||
INTERFACE_INFO ifo[MAX_INTERFACES];
|
INTERFACE_INFO ifo[MAX_INTERFACES];
|
||||||
|
uint j;
|
||||||
#else
|
#else
|
||||||
char buf[4 * 1024]; // Arbitrary buffer size
|
char buf[4 * 1024]; // Arbitrary buffer size
|
||||||
struct ifconf ifconf;
|
struct ifconf ifconf;
|
||||||
@ -378,7 +387,7 @@ static void NetworkFindIPs(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// If something fails, make sure the list is empty
|
// If something fails, make sure the list is empty
|
||||||
_network_ip_list[0] = 0;
|
_broadcast_list[0] = 0;
|
||||||
|
|
||||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
if (sock == INVALID_SOCKET) return;
|
if (sock == INVALID_SOCKET) return;
|
||||||
@ -391,9 +400,9 @@ static void NetworkFindIPs(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now walk through all IPs and list them
|
// Now walk through all IPs and list them
|
||||||
for (i = 0; i < (int)(len / sizeof(IFREQ)); i++) {
|
for (j = 0; j < len / sizeof(*ifo); j++) {
|
||||||
// Request IP for this interface
|
if (!(ifo[j].iiFlags & IFF_BROADCAST)) continue;
|
||||||
_network_ip_list[i] = *(&ifo[i].iiAddress.AddressIn.sin_addr.s_addr);
|
_broadcast_list[i++] = ifo[j].iiBroadcastAddress.AddressIn.sin_addr.s_addr;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
ifconf.ifc_len = sizeof(buf);
|
ifconf.ifc_len = sizeof(buf);
|
||||||
@ -412,9 +421,9 @@ static void NetworkFindIPs(void)
|
|||||||
struct ifreq r;
|
struct ifreq r;
|
||||||
|
|
||||||
strncpy(r.ifr_name, req->ifr_name, lengthof(r.ifr_name));
|
strncpy(r.ifr_name, req->ifr_name, lengthof(r.ifr_name));
|
||||||
if (ioctl(sock, SIOCGIFADDR, &r) != -1) {
|
if (ioctl(sock, SIOCGIFBRDADDR, &r) != -1) {
|
||||||
_network_ip_list[i++] =
|
_broadcast_list[i++] =
|
||||||
((struct sockaddr_in*)&r.ifr_addr)->sin_addr.s_addr;
|
((struct sockaddr_in*)&r.ifr_broadaddr)->sin_addr.s_addr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,27 +437,12 @@ static void NetworkFindIPs(void)
|
|||||||
closesocket(sock);
|
closesocket(sock);
|
||||||
#endif /* not HAVE_GETIFADDRS */
|
#endif /* not HAVE_GETIFADDRS */
|
||||||
|
|
||||||
_network_ip_list[i] = 0;
|
_broadcast_list[i] = 0;
|
||||||
last = i - 1;
|
|
||||||
|
|
||||||
DEBUG(net, 3)("Detected IPs:");
|
DEBUG(net, 3)("Detected broadcast addresses:");
|
||||||
// Now display to the debug all the detected ips
|
// Now display to the debug all the detected ips
|
||||||
i = 0;
|
for (i = 0; _broadcast_list[i] != 0; i++) {
|
||||||
while (_network_ip_list[i] != 0) {
|
DEBUG(net, 3)(" %d) %s", i, inet_ntoa(*(struct in_addr *)&_broadcast_list[i]));//inet_ntoa(inaddr));
|
||||||
// Also check for non-used ips (127.0.0.1)
|
|
||||||
if (_network_ip_list[i] == inet_addr("127.0.0.1")) {
|
|
||||||
// If there is an ip after thisone, put him in here
|
|
||||||
if (last > i)
|
|
||||||
_network_ip_list[i] = _network_ip_list[last];
|
|
||||||
// Clear the last ip
|
|
||||||
_network_ip_list[last] = 0;
|
|
||||||
// And we have 1 ip less
|
|
||||||
last--;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG(net, 3)(" %d) %s", i, inet_ntoa(*(struct in_addr *)&_network_ip_list[i]));//inet_ntoa(inaddr));
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ VARDEF uint32 _frame_counter_max; // To where we may go with our clients
|
|||||||
VARDEF uint32 _last_sync_frame; // Used in the server to store the last time a sync packet was sent to clients.
|
VARDEF uint32 _last_sync_frame; // Used in the server to store the last time a sync packet was sent to clients.
|
||||||
|
|
||||||
// networking settings
|
// networking settings
|
||||||
VARDEF uint32 _network_ip_list[MAX_INTERFACES + 1]; // Network IPs
|
VARDEF uint32 _broadcast_list[MAX_INTERFACES + 1];
|
||||||
|
|
||||||
VARDEF uint16 _network_server_port;
|
VARDEF uint16 _network_server_port;
|
||||||
/* We use bind_ip and bind_ip_host, where bind_ip_host is the readable form of
|
/* We use bind_ip and bind_ip_host, where bind_ip_host is the readable form of
|
||||||
|
@ -472,26 +472,18 @@ static void NetworkUDPBroadCast(SOCKET udp)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct sockaddr_in out_addr;
|
struct sockaddr_in out_addr;
|
||||||
byte *bcptr;
|
|
||||||
uint32 bcaddr;
|
|
||||||
Packet *p;
|
Packet *p;
|
||||||
|
|
||||||
// Init the packet
|
// Init the packet
|
||||||
p = NetworkSend_Init(PACKET_UDP_CLIENT_FIND_SERVER);
|
p = NetworkSend_Init(PACKET_UDP_CLIENT_FIND_SERVER);
|
||||||
|
|
||||||
// Go through all the ips on this pc
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (_network_ip_list[i] != 0) {
|
while (_broadcast_list[i] != 0) {
|
||||||
bcaddr = _network_ip_list[i];
|
|
||||||
bcptr = (byte *)&bcaddr;
|
|
||||||
// Make the address a broadcast address
|
|
||||||
bcptr[3] = 255;
|
|
||||||
|
|
||||||
DEBUG(net, 6)("[NET][UDP] Broadcasting to %s", inet_ntoa(*(struct in_addr *)&bcaddr));
|
|
||||||
|
|
||||||
out_addr.sin_family = AF_INET;
|
out_addr.sin_family = AF_INET;
|
||||||
out_addr.sin_port = htons(_network_server_port);
|
out_addr.sin_port = htons(_network_server_port);
|
||||||
out_addr.sin_addr.s_addr = bcaddr;
|
out_addr.sin_addr.s_addr = _broadcast_list[i];
|
||||||
|
|
||||||
|
DEBUG(net, 6)("[NET][UDP] Broadcasting to %s", inet_ntoa(out_addr.sin_addr));
|
||||||
|
|
||||||
NetworkSendUDP_Packet(udp, p, &out_addr);
|
NetworkSendUDP_Packet(udp, p, &out_addr);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user