Cogs.Core
Adapter.cpp
1#if !defined( EMSCRIPTEN )
2
3#include "Adapter.h"
4
5#include "../Logging/Logger.h"
6#include "../Platform/Unicode.h"
7
8#ifdef _WIN32
9#include <winsock2.h>
10#include <iphlpapi.h>
11#pragma comment(lib, "IPHLPAPI.lib")
12#else
13#include <arpa/inet.h>
14#include <ifaddrs.h>
15#include <net/if.h>
16#endif
17
18#include <cassert>
19#include <vector>
20
21namespace
22{
23 Cogs::Logging::Log logger = Cogs::Logging::getLogger("Connection");
24}
25
26namespace Cogs::Network{
27
28static std::vector<NetworkAdapter> adapters;
29
30void UpdateAdapters(AdapterFlags adapter_flags)
31{
32 adapters.clear();
33 if(adapter_flags & AdapterFlags::IncludeAny)
34 adapters.push_back({"Any", AddrIn(0, 0, 0, 0), AddrIn(255, 255, 255, 255), AddrIn(0, 0, 0, 0)});
35 if(adapter_flags & AdapterFlags::IncludeLocalhost)
36 adapters.push_back({"Localhost", AddrIn(127, 0, 0, 1), AddrIn(255, 0, 0, 0), AddrIn(127, 255, 255, 255)});
37#ifdef _WIN32
38 ULONG family = AF_INET; // TODO AF_UNSPEC
39 ULONG flags = 0;
40 ULONG bufferSize = 16384;
41 std::vector<char> buffer(bufferSize);
42 ULONG ret = GetAdaptersAddresses(family, flags, nullptr, reinterpret_cast<IP_ADAPTER_ADDRESSES*>(buffer.data()), &bufferSize);
43
44 if (ret == ERROR_BUFFER_OVERFLOW) {
45 buffer.resize(bufferSize);
46 ret = GetAdaptersAddresses(family, flags, nullptr, reinterpret_cast<IP_ADAPTER_ADDRESSES*>(buffer.data()), &bufferSize);
47 }
48 if (ret == ERROR_SUCCESS) {
49 IP_ADAPTER_ADDRESSES* ptr = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(buffer.data());
50
51 while(ptr){
52 if((ptr->IfType != IF_TYPE_ETHERNET_CSMACD) && // Ethernet
53 (ptr->IfType != IF_TYPE_IEEE80211)){ // Wireless
54 ptr = ptr->Next;
55 continue;
56 }
57
58 adapters.push_back({});
59 NetworkAdapter &adapter = adapters.back();
60 adapter.name = narrow(ptr->FriendlyName); // narrow(ptr->AdapterName);
61
62 PIP_ADAPTER_UNICAST_ADDRESS pUnicast = ptr->FirstUnicastAddress;
63 if(pUnicast){
64 sockaddr_in *addr = reinterpret_cast<sockaddr_in*>(pUnicast->Address.lpSockaddr);
65 assert(addr->sin_family == AF_INET);
66 adapter.addr = AddrIn(addr->sin_addr);
67
68 ULONG mask;
69 ConvertLengthToIpv4Mask(pUnicast->OnLinkPrefixLength, &mask);
70 adapter.mask.addr.s_addr = mask;
71 adapter.broadcast.addr.s_addr = addr->sin_addr.s_addr | ~mask;
72 }
73
74 ptr = ptr->Next;
75 }
76 }
77 else{
78 LOG_DEBUG(logger, "UpdateAdapters(): GetAdaptersAddresses failed with %08x error code.", ret);
79 assert(false); // TODO
80 }
81#else
82 struct ifaddrs *ifa = nullptr;
83 int ret = getifaddrs(&ifa);
84 if(ret == -1){
85 // TODO errno
86 return;
87 }
88
89 struct ifaddrs *next = ifa;
90 for(; next; next = next->ifa_next){
91 if(next->ifa_addr && next->ifa_addr->sa_family == AF_INET){
92 sockaddr_in *addr = reinterpret_cast<sockaddr_in*>(next->ifa_addr);
93 sockaddr_in *mask = reinterpret_cast<sockaddr_in*>(next->ifa_netmask);
94#if defined( __APPLE__ )
95 sockaddr_in *broadcast = reinterpret_cast<sockaddr_in*>(next->ifa_dstaddr);
96#else
97 sockaddr_in *broadcast = reinterpret_cast<sockaddr_in*>(next->ifa_ifu.ifu_broadaddr);
98#endif
99
100 adapters.push_back({});
101 NetworkAdapter &adapter = adapters.back();
102 adapter.name = next->ifa_name;
103 adapter.addr = AddrIn(addr->sin_addr);
104 adapter.mask = AddrIn(mask->sin_addr);
105 adapter.broadcast = AddrIn(broadcast->sin_addr);
106 }
107 }
108
109 freeifaddrs(ifa);
110#endif
111}
112void PrintAdapters()
113{
114 LOG_INFO(logger, "Adapters(%zu):", adapters.size());
115 for(auto &adapter : adapters){
116 LOG_INFO(logger, "%s: ip %s (mask %s) (broadcast %s)",
117 adapter.name.c_str(),
118 adapter.addr.string().c_str(),
119 adapter.mask.string().c_str(),
120 adapter.broadcast.string().c_str());
121 }
122}
123NetworkAdapter GetAdapter(size_t i)
124{
125 return adapters[i];
126}
127size_t GetAdapterCount()
128{
129 return adapters.size();
130}
131
132int FindAdapter(const AddrIn& address) {
133 for (int idx = 0, count = static_cast<int>(adapters.size()); idx < count; ++idx) {
134 if (adapters[idx].addr == address) {
135 return idx;
136 }
137 }
138 return -1;
139}
140
141}// namespace ...
142
143#endif
Log implementation class.
Definition: LogManager.h:139
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:180