summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMattes D <github@xoft.cz>2015-03-12 13:35:45 +0100
committerMattes D <github@xoft.cz>2015-03-12 13:35:45 +0100
commitf9991c9f92dac9df5b3ea62e69d46830adf9fa62 (patch)
treeb754ba22c81b4738226b933a2f718bc194bfe0d6 /src
parentMerge pull request #1807 from flx5/master (diff)
parentUse std::memcpy to fix alignment (diff)
downloadcuberite-f9991c9f92dac9df5b3ea62e69d46830adf9fa62.tar
cuberite-f9991c9f92dac9df5b3ea62e69d46830adf9fa62.tar.gz
cuberite-f9991c9f92dac9df5b3ea62e69d46830adf9fa62.tar.bz2
cuberite-f9991c9f92dac9df5b3ea62e69d46830adf9fa62.tar.lz
cuberite-f9991c9f92dac9df5b3ea62e69d46830adf9fa62.tar.xz
cuberite-f9991c9f92dac9df5b3ea62e69d46830adf9fa62.tar.zst
cuberite-f9991c9f92dac9df5b3ea62e69d46830adf9fa62.zip
Diffstat (limited to '')
-rw-r--r--src/Bindings/ManualBindings_Network.cpp35
-rw-r--r--src/OSSupport/CMakeLists.txt1
-rw-r--r--src/OSSupport/Network.h3
-rw-r--r--src/OSSupport/NetworkInterfaceEnum.cpp185
4 files changed, 219 insertions, 5 deletions
diff --git a/src/Bindings/ManualBindings_Network.cpp b/src/Bindings/ManualBindings_Network.cpp
index a628eb9ca..628cda7f0 100644
--- a/src/Bindings/ManualBindings_Network.cpp
+++ b/src/Bindings/ManualBindings_Network.cpp
@@ -129,6 +129,30 @@ static int tolua_cNetwork_CreateUDPEndpoint(lua_State * L)
+/** Binds cNetwork::EnumLocalIPAddresses */
+static int tolua_cNetwork_EnumLocalIPAddresses(lua_State * L)
+{
+ // Function signature:
+ // cNetwork:EnumLocalIPAddresses() -> {string, ...}
+
+ cLuaState S(L);
+ if (
+ !S.CheckParamUserTable(1, "cNetwork") ||
+ !S.CheckParamEnd(2)
+ )
+ {
+ return 0;
+ }
+
+ // Push the enumerated addresses:
+ S.Push(cNetwork::EnumLocalIPAddresses());
+ return 1;
+}
+
+
+
+
+
/** Binds cNetwork::HostnameToIP */
static int tolua_cNetwork_HostnameToIP(lua_State * L)
{
@@ -903,11 +927,12 @@ void ManualBindings::BindNetwork(lua_State * tolua_S)
// Fill in the functions (alpha-sorted):
tolua_beginmodule(tolua_S, "cNetwork");
- tolua_function(tolua_S, "Connect", tolua_cNetwork_Connect);
- tolua_function(tolua_S, "CreateUDPEndpoint", tolua_cNetwork_CreateUDPEndpoint);
- tolua_function(tolua_S, "HostnameToIP", tolua_cNetwork_HostnameToIP);
- tolua_function(tolua_S, "IPToHostname", tolua_cNetwork_IPToHostname);
- tolua_function(tolua_S, "Listen", tolua_cNetwork_Listen);
+ tolua_function(tolua_S, "Connect", tolua_cNetwork_Connect);
+ tolua_function(tolua_S, "CreateUDPEndpoint", tolua_cNetwork_CreateUDPEndpoint);
+ tolua_function(tolua_S, "EnumLocalIPAddresses", tolua_cNetwork_EnumLocalIPAddresses);
+ tolua_function(tolua_S, "HostnameToIP", tolua_cNetwork_HostnameToIP);
+ tolua_function(tolua_S, "IPToHostname", tolua_cNetwork_IPToHostname);
+ tolua_function(tolua_S, "Listen", tolua_cNetwork_Listen);
tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cServerHandle");
diff --git a/src/OSSupport/CMakeLists.txt b/src/OSSupport/CMakeLists.txt
index 81b37ef0e..0d3c9a63e 100644
--- a/src/OSSupport/CMakeLists.txt
+++ b/src/OSSupport/CMakeLists.txt
@@ -13,6 +13,7 @@ SET (SRCS
HostnameLookup.cpp
IPLookup.cpp
IsThread.cpp
+ NetworkInterfaceEnum.cpp
NetworkSingleton.cpp
Semaphore.cpp
ServerHandleImpl.cpp
diff --git a/src/OSSupport/Network.h b/src/OSSupport/Network.h
index 5dd596223..95a935bbe 100644
--- a/src/OSSupport/Network.h
+++ b/src/OSSupport/Network.h
@@ -318,6 +318,9 @@ public:
If a_Port is 0, the OS is free to assign any port number it likes to the endpoint.
Returns the endpoint object that can be interacted with. */
static cUDPEndpointPtr CreateUDPEndpoint(UInt16 a_Port, cUDPEndpoint::cCallbacks & a_Callbacks);
+
+ /** Returns all local IP addresses for network interfaces currently available. */
+ static AStringVector EnumLocalIPAddresses(void);
};
diff --git a/src/OSSupport/NetworkInterfaceEnum.cpp b/src/OSSupport/NetworkInterfaceEnum.cpp
new file mode 100644
index 000000000..c4af1e93c
--- /dev/null
+++ b/src/OSSupport/NetworkInterfaceEnum.cpp
@@ -0,0 +1,185 @@
+
+// NetworkInterfaceEnum.cpp
+
+// Implements the cNetwork::EnumLocalIPAddresses() interface enumeration function
+
+#include "Globals.h"
+#include "Network.h"
+#include "event2/util.h"
+#ifdef _WIN32
+ #include <IPHlpApi.h>
+ #pragma comment(lib, "IPHLPAPI.lib")
+#else // _WIN32
+ #include <sys/types.h>
+ #include <ifaddrs.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+#endif // else _WIN32
+
+
+
+
+
+#ifdef SELF_TEST
+
+static class cEnumIPAddressTest
+{
+public:
+ cEnumIPAddressTest(void)
+ {
+ printf("Enumerating all IP addresses...\n");
+ auto IPs = cNetwork::EnumLocalIPAddresses();
+ for (auto & ip: IPs)
+ {
+ printf(" %s\n", ip.c_str());
+ }
+ printf("Done.\n");
+ }
+} g_EnumIPAddressTest;
+
+#endif // SELF_TEST
+
+
+
+
+
+#ifdef _WIN32
+
+/** Converts the SOCKET_ADDRESS structure received from the OS into an IP address string. */
+static AString PrintAddress(SOCKET_ADDRESS & a_Addr)
+{
+ char IP[128];
+ switch (a_Addr.lpSockaddr->sa_family)
+ {
+ case AF_INET:
+ {
+ auto sin = reinterpret_cast<const sockaddr_in *>(a_Addr.lpSockaddr);
+ evutil_inet_ntop(a_Addr.lpSockaddr->sa_family, &(sin->sin_addr), IP, sizeof(IP));
+ break;
+ }
+ case AF_INET6:
+ {
+ auto sin = reinterpret_cast<const sockaddr_in6 *>(a_Addr.lpSockaddr);
+ evutil_inet_ntop(a_Addr.lpSockaddr->sa_family, &(sin->sin6_addr), IP, sizeof(IP));
+ break;
+ }
+ default:
+ {
+ IP[0] = 0;
+ break;
+ }
+ }
+ return IP;
+}
+
+#else // _WIN32
+
+static AString PrintAddress(ifaddrs * InterfaceAddress)
+{
+ switch (InterfaceAddress->ifa_addr->sa_family)
+ {
+ case AF_INET:
+ { // IPv4
+ char AddressBuffer[INET_ADDRSTRLEN];
+ sockaddr_in InternetSocket;
+
+ std::memcpy(&InternetSocket, InterfaceAddress->ifa_addr, sizeof(InternetSocket));
+ inet_ntop(AF_INET, &InternetSocket.sin_addr, AddressBuffer, INET_ADDRSTRLEN);
+ return AddressBuffer;
+ }
+ case AF_INET6:
+ { // IPv6
+ char AddressBuffer[INET6_ADDRSTRLEN];
+ sockaddr_in6 InternetSocket;
+
+ std::memcpy(&InternetSocket, InterfaceAddress->ifa_addr, sizeof(InternetSocket));
+ inet_ntop(AF_INET6, &InternetSocket.sin6_addr, AddressBuffer, INET6_ADDRSTRLEN);
+ return AddressBuffer;
+ }
+ default:
+ {
+ LOG("Unknown address family: %i", InterfaceAddress->ifa_addr->sa_family);
+ return "";
+ }
+ }
+}
+
+#endif // else _WIN32
+
+
+
+
+
+AStringVector cNetwork::EnumLocalIPAddresses(void)
+{
+ AStringVector res;
+
+ #ifdef _WIN32
+
+ // Query the OS for all adapters' addresses:
+ char buffer[64 KiB]; // A buffer backing the address list
+ PIP_ADAPTER_ADDRESSES pAddresses = reinterpret_cast<PIP_ADAPTER_ADDRESSES>(&buffer);
+ ULONG outBufLen = sizeof(buffer);
+ DWORD dwRetVal = GetAdaptersAddresses(
+ AF_UNSPEC,
+ GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME, nullptr,
+ pAddresses, &outBufLen
+ );
+ if (dwRetVal != ERROR_SUCCESS)
+ {
+ LOG("GetAdaptersAddresses() failed: %u", dwRetVal);
+ return res;
+ }
+
+ // Enumerate all active adapters
+ for (auto pCurrAddresses = pAddresses; pCurrAddresses != nullptr; pCurrAddresses = pCurrAddresses->Next)
+ {
+ if (pCurrAddresses->OperStatus != IfOperStatusUp)
+ {
+ // Adapter not active, skip it:
+ continue;
+ }
+
+ // Collect all IP addresses on this adapter:
+ for (auto pUnicast = pCurrAddresses->FirstUnicastAddress; pUnicast != nullptr; pUnicast = pUnicast->Next)
+ {
+ auto Address = PrintAddress(pUnicast->Address);
+ if (!Address.empty())
+ {
+ res.push_back(Address);
+ }
+ } // for pUnicast
+ } // for pCurrAddresses
+
+ #else // _WIN32
+
+ struct ifaddrs * ifAddrStruct = nullptr;
+ getifaddrs(&ifAddrStruct);
+
+ for (auto ifa = ifAddrStruct; ifa != nullptr; ifa = ifa->ifa_next)
+ {
+ if (ifa->ifa_addr == nullptr)
+ {
+ continue;
+ }
+
+ auto Address = PrintAddress(ifa);
+ if (!Address.empty())
+ {
+ res.emplace_back(Address);
+ }
+ }
+
+ if (ifAddrStruct != nullptr)
+ {
+ freeifaddrs(ifAddrStruct);
+ }
+
+ #endif // else _WIN32
+
+ return res;
+}
+
+
+
+