| 22 | |
| 23 | #ifdef _WIN32 |
| 24 | static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast) // Win32 implementation |
| 25 | { |
| 26 | SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0); |
| 27 | if (sock == INVALID_SOCKET) return; |
| 28 | |
| 29 | std::vector<INTERFACE_INFO> ifos; |
| 30 | ifos.resize(2); |
| 31 | |
| 32 | for (;;) { |
| 33 | DWORD len = 0; |
| 34 | if (WSAIoctl(sock, SIO_GET_INTERFACE_LIST, nullptr, 0, ifos.data(), static_cast<DWORD>(ifos.size() * sizeof(INTERFACE_INFO)), &len, nullptr, nullptr) == 0) { |
| 35 | ifos.resize(len / sizeof(INTERFACE_INFO)); |
| 36 | break; |
| 37 | } |
| 38 | if (WSAGetLastError() != WSAEFAULT) { |
| 39 | closesocket(sock); |
| 40 | return; |
| 41 | } |
| 42 | ifos.resize(ifos.size() * 2); |
| 43 | } |
| 44 | |
| 45 | for (auto &ifo : ifos) { |
| 46 | if (ifo.iiFlags & IFF_LOOPBACK) continue; |
| 47 | if (!(ifo.iiFlags & IFF_BROADCAST)) continue; |
| 48 | |
| 49 | sockaddr_storage address{}; |
| 50 | /* iiBroadcast is unusable, because it always seems to be set to 255.255.255.255. */ |
| 51 | std::copy_n(reinterpret_cast<const std::byte *>(&ifo.iiAddress.Address), sizeof(sockaddr), reinterpret_cast<std::byte *>(&address)); |
| 52 | reinterpret_cast<sockaddr_in*>(&address)->sin_addr.s_addr = ifo.iiAddress.AddressIn.sin_addr.s_addr | ~ifo.iiNetmask.AddressIn.sin_addr.s_addr; |
| 53 | NetworkAddress addr(address, sizeof(sockaddr)); |
| 54 | if (std::none_of(broadcast->begin(), broadcast->end(), [&addr](NetworkAddress const &elem) -> bool { return elem == addr; })) broadcast->push_back(addr); |
| 55 | } |
| 56 | |
| 57 | closesocket(sock); |
| 58 | } |
| 59 | |
| 60 | #else /* not WIN32 */ |
| 61 | static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast) |