Cuberite
A lightweight, fast and extensible game server for Minecraft
NetworkInterfaceEnum.cpp
Go to the documentation of this file.
1 
2 // NetworkInterfaceEnum.cpp
3 
4 // Implements the cNetwork::EnumLocalIPAddresses() interface enumeration function
5 
6 #include "Globals.h"
7 #include "Network.h"
8 #include "event2/util.h"
9 
10 #if defined(_WIN32)
11  #include <IPHlpApi.h>
12  #pragma comment(lib, "IPHLPAPI.lib")
13 #elif !defined(ANDROID) // _WIN32
14  #include <sys/types.h>
15  #include <ifaddrs.h>
16  #include <netinet/in.h>
17  #include <arpa/inet.h>
18 #endif // else _WIN32
19 
20 
21 
22 
23 
24 #if defined(_WIN32)
25 
27 static AString PrintAddress(SOCKET_ADDRESS & a_Addr)
28 {
29  char IP[128];
30  switch (a_Addr.lpSockaddr->sa_family)
31  {
32  case AF_INET:
33  {
34  auto sin = reinterpret_cast<const sockaddr_in *>(a_Addr.lpSockaddr);
35  evutil_inet_ntop(a_Addr.lpSockaddr->sa_family, &(sin->sin_addr), IP, sizeof(IP));
36  break;
37  }
38  case AF_INET6:
39  {
40  auto sin = reinterpret_cast<const sockaddr_in6 *>(a_Addr.lpSockaddr);
41  evutil_inet_ntop(a_Addr.lpSockaddr->sa_family, &(sin->sin6_addr), IP, sizeof(IP));
42  break;
43  }
44  default:
45  {
46  IP[0] = 0;
47  break;
48  }
49  }
50  return IP;
51 }
52 
53 #elif !defined(ANDROID) // _WIN32
54 
55 static AString PrintAddress(ifaddrs * InterfaceAddress)
56 {
57  switch (InterfaceAddress->ifa_addr->sa_family)
58  {
59  case AF_INET:
60  { // IPv4
61  char AddressBuffer[INET_ADDRSTRLEN];
62  sockaddr_in InternetSocket;
63 
64  std::memcpy(&InternetSocket, InterfaceAddress->ifa_addr, sizeof(InternetSocket));
65  inet_ntop(AF_INET, &InternetSocket.sin_addr, AddressBuffer, INET_ADDRSTRLEN);
66  return AddressBuffer;
67  }
68  case AF_INET6:
69  { // IPv6
70  char AddressBuffer[INET6_ADDRSTRLEN];
71  sockaddr_in6 InternetSocket;
72 
73  std::memcpy(&InternetSocket, InterfaceAddress->ifa_addr, sizeof(InternetSocket));
74  inet_ntop(AF_INET6, &InternetSocket.sin6_addr, AddressBuffer, INET6_ADDRSTRLEN);
75  return AddressBuffer;
76  }
77  default:
78  {
79  LOG("Unknown address family: %i", InterfaceAddress->ifa_addr->sa_family);
80  return "";
81  }
82  }
83 }
84 
85 #endif // else !ANDROID
86 
87 
88 
89 
90 
92 {
93  AStringVector res;
94 
95  #if defined(_WIN32)
96 
97  // Query the OS for all adapters' addresses:
98  char buffer[64 KiB]; // A buffer backing the address list
99  PIP_ADAPTER_ADDRESSES pAddresses = reinterpret_cast<PIP_ADAPTER_ADDRESSES>(&buffer);
100  ULONG outBufLen = sizeof(buffer);
101  DWORD dwRetVal = GetAdaptersAddresses(
102  AF_UNSPEC,
103  GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME, nullptr,
104  pAddresses, &outBufLen
105  );
106  if (dwRetVal != ERROR_SUCCESS)
107  {
108  LOG("GetAdaptersAddresses() failed: %u", dwRetVal);
109  return res;
110  }
111 
112  // Enumerate all active adapters
113  for (auto pCurrAddresses = pAddresses; pCurrAddresses != nullptr; pCurrAddresses = pCurrAddresses->Next)
114  {
115  if (pCurrAddresses->OperStatus != IfOperStatusUp)
116  {
117  // Adapter not active, skip it:
118  continue;
119  }
120 
121  // Collect all IP addresses on this adapter:
122  for (auto pUnicast = pCurrAddresses->FirstUnicastAddress; pUnicast != nullptr; pUnicast = pUnicast->Next)
123  {
124  auto Address = PrintAddress(pUnicast->Address);
125  if (!Address.empty())
126  {
127  res.push_back(Address);
128  }
129  } // for pUnicast
130  } // for pCurrAddresses
131 
132  #elif !defined(ANDROID) // _WIN32
133 
134  struct ifaddrs * ifAddrStruct = nullptr;
135  getifaddrs(&ifAddrStruct);
136 
137  for (auto ifa = ifAddrStruct; ifa != nullptr; ifa = ifa->ifa_next)
138  {
139  if (ifa->ifa_addr == nullptr)
140  {
141  continue;
142  }
143 
144  auto Address = PrintAddress(ifa);
145  if (!Address.empty())
146  {
147  res.emplace_back(Address);
148  }
149  }
150 
151  if (ifAddrStruct != nullptr)
152  {
153  freeifaddrs(ifAddrStruct);
154  }
155 
156  #endif // else _WIN32
157 
158  return res;
159 }
160 
161 
162 
163 
#define KiB
Allows arithmetic expressions like "32 KiB" (but consider using parenthesis around it,...
Definition: Globals.h:234
void LOG(std::string_view a_Format, const Args &... args)
Definition: LoggerSimple.h:55
static AString PrintAddress(ifaddrs *InterfaceAddress)
std::vector< AString > AStringVector
Definition: StringUtils.h:12
std::string AString
Definition: StringUtils.h:11
static AStringVector EnumLocalIPAddresses(void)
Returns all local IP addresses for network interfaces currently available.