12 #include "../../stdafx.h" 13 #include "../../debug.h" 16 #include "../../safeguards.h" 25 #if defined(__HAIKU__) 27 extern "C" int _netstat(
int fd,
char **output,
int verbose);
29 int seek_past_header(
char **pos,
const char *header)
31 char *new_pos = strstr(*pos, header);
35 *pos += strlen(header) + new_pos - *pos + 1;
41 int sock = socket(AF_INET, SOCK_DGRAM, 0);
44 DEBUG(net, 0,
"[core] error creating socket");
48 char *output_pointer =
nullptr;
49 int output_length = _netstat(sock, &output_pointer, 1);
50 if (output_length < 0) {
51 DEBUG(net, 0,
"[core] error running _netstat");
55 char **output = &output_pointer;
56 if (seek_past_header(output,
"IP Interfaces:") == B_OK) {
60 uint8 i1, i2, i3, i4, j1, j2, j3, j4;
64 fields = sscanf(*output,
"%u: %hhu.%hhu.%hhu.%hhu, netmask %hhu.%hhu.%hhu.%hhu%n",
65 &n, &i1, &i2, &i3, &i4, &j1, &j2, &j3, &j4, &read);
71 ip = (uint32)i1 << 24 | (uint32)i2 << 16 | (uint32)i3 << 8 | (uint32)i4;
72 netmask = (uint32)j1 << 24 | (uint32)j2 << 16 | (uint32)j3 << 8 | (uint32)j4;
74 if (ip != INADDR_LOOPBACK && ip != INADDR_ANY) {
75 sockaddr_storage address;
76 memset(&address, 0,
sizeof(address));
77 ((sockaddr_in*)&address)->sin_addr.s_addr = htonl(ip | ~netmask);
79 if (std::none_of(broadcast->begin(), broadcast->end(), [&addr](
NetworkAddress const& elem) ->
bool {
return elem == addr; })) broadcast->push_back(addr);
90 #elif defined(HAVE_GETIFADDRS) 93 struct ifaddrs *ifap, *ifa;
95 if (getifaddrs(&ifap) != 0)
return;
97 for (ifa = ifap; ifa !=
nullptr; ifa = ifa->ifa_next) {
98 if (!(ifa->ifa_flags & IFF_BROADCAST))
continue;
99 if (ifa->ifa_broadaddr ==
nullptr)
continue;
100 if (ifa->ifa_broadaddr->sa_family != AF_INET)
continue;
103 if (std::none_of(broadcast->begin(), broadcast->end(), [&addr](
NetworkAddress const& elem) ->
bool {
return elem == addr; })) broadcast->push_back(addr);
108 #elif defined(_WIN32) 111 SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
112 if (sock == INVALID_SOCKET)
return;
116 INTERFACE_INFO *ifo = CallocT<INTERFACE_INFO>(num);
119 if (WSAIoctl(sock, SIO_GET_INTERFACE_LIST,
nullptr, 0, ifo, num *
sizeof(*ifo), &len,
nullptr,
nullptr) == 0)
break;
121 if (WSAGetLastError() != WSAEFAULT) {
126 ifo = CallocT<INTERFACE_INFO>(num);
129 for (uint j = 0; j < len /
sizeof(*ifo); j++) {
130 if (ifo[j].iiFlags & IFF_LOOPBACK)
continue;
131 if (!(ifo[j].iiFlags & IFF_BROADCAST))
continue;
133 sockaddr_storage address;
134 memset(&address, 0,
sizeof(address));
136 memcpy(&address, &ifo[j].iiAddress.Address,
sizeof(sockaddr));
137 ((sockaddr_in*)&address)->sin_addr.s_addr = ifo[j].iiAddress.AddressIn.sin_addr.s_addr | ~ifo[j].iiNetmask.AddressIn.sin_addr.s_addr;
139 if (std::none_of(broadcast->begin(), broadcast->end(), [&addr](
NetworkAddress const& elem) ->
bool {
return elem == addr; })) broadcast->push_back(addr);
148 #include "../../string_func.h" 152 SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
153 if (sock == INVALID_SOCKET)
return;
156 struct ifconf ifconf;
158 ifconf.ifc_len =
sizeof(buf);
159 ifconf.ifc_buf = buf;
160 if (ioctl(sock, SIOCGIFCONF, &ifconf) == -1) {
165 const char *buf_end = buf + ifconf.ifc_len;
166 for (
const char *p = buf; p < buf_end;) {
167 const struct ifreq *req = (
const struct ifreq*)p;
169 if (req->ifr_addr.sa_family == AF_INET) {
173 if (ioctl(sock, SIOCGIFFLAGS, &r) != -1 &&
174 (r.ifr_flags & IFF_BROADCAST) &&
175 ioctl(sock, SIOCGIFBRDADDR, &r) != -1) {
177 if (std::none_of(broadcast->begin(), broadcast->end(), [&addr](
NetworkAddress const& elem) ->
bool {
return elem == addr; })) broadcast->push_back(addr);
181 p +=
sizeof(
struct ifreq);
182 #if defined(AF_LINK) && !defined(SUNOS) 183 p += req->ifr_addr.sa_len -
sizeof(
struct sockaddr);
201 DEBUG(net, 3,
"Detected broadcast addresses:");
205 DEBUG(net, 3,
"%d) %s", i++, addr.GetHostname());
Wrapper for (un)resolved network addresses; there's no reason to transform a numeric IP to a string a...
void NetworkFindBroadcastIPs(NetworkAddressList *broadcast)
Find the IPv4 broadcast addresses; IPv6 uses a completely different strategy for broadcasting.
#define lastof(x)
Get the last element of an fixed size array.
std::vector< NetworkAddress > NetworkAddressList
Type for a list of addresses.
Wrapper for network addresses.
#define DEBUG(name, level,...)
Output a line of debugging information.
static const uint16 NETWORK_DEFAULT_PORT
The default port of the game server (TCP & UDP)
char * strecpy(char *dst, const char *src, const char *last)
Copies characters from one buffer to another.
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast)
Internal implementation for finding the broadcast IPs.