cNetwork: Added EnumLocalIPAddresses() function.
This commit is contained in:
parent
1bcc4abd68
commit
c758482ece
@ -289,6 +289,7 @@ g_Server = nil
|
||||
{
|
||||
Connect = { Params = "Host, Port, LinkCallbacks", Return = "bool", Notes = "(STATIC) Begins establishing a (client) TCP connection to the specified host. Uses the LinkCallbacks table to report progress, success, errors and incoming data. Returns false if it fails immediately (bad port value, bad hostname format), true otherwise. Host can be either an IP address or a hostname." },
|
||||
CreateUDPEndpoint = { Params = "Port, UDPCallbacks", Return = "{{cUDPEndpoint|UDPEndpoint}}", Notes = "(STATIC) Creates a UDP endpoint that listens for incoming datagrams on the specified port, and can be used to send or broadcast datagrams. Uses the UDPCallbacks to report incoming datagrams or errors. If the endpoint cannot be created, the OnError callback is called with the error details and the returned endpoint will report IsOpen() == false. The plugin needs to store the returned endpoint object for as long as it needs the UDP port open; if the endpoint is garbage-collected by Lua, the socket will be closed and no more incoming data will be reported.<br>If the Port is zero, the OS chooses an available UDP port for the endpoint; use {{cUDPEndpoint}}:GetPort() to query the port number in such case." },
|
||||
EnumLocalIPAddresses = { Params = "", Return = "array-table of strings", Notes = "(STATIC) Returns all local IP addresses for network interfaces currently available on the machine." },
|
||||
HostnameToIP = { Params = "Host, LookupCallbacks", Return = "bool", Notes = "(STATIC) Begins a DNS lookup to find the IP address(es) for the specified host. Uses the LookupCallbacks table to report progress, success or errors. Returns false if it fails immediately (bad hostname format), true if the lookup started successfully. Host can be either a hostname or an IP address." },
|
||||
IPToHostname = { Params = "Address, LookupCallbacks", Return = "bool", Notes = "(STATIC) Begins a reverse-DNS lookup to find out the hostname for the specified IP address. Uses the LookupCallbacks table to report progress, success or errors. Returns false if it fails immediately (bad address format), true if the lookup started successfully." },
|
||||
Listen = { Params = "Port, ListenCallbacks", Return = "{{cServerHandle|ServerHandle}}", Notes = "(STATIC) Starts listening on the specified port. Uses the ListenCallbacks to report incoming connections or errors. Returns a {{cServerHandle}} object representing the server. If the listen operation failed, the OnError callback is called with the error details and the returned server handle will report IsListening() == false. The plugin needs to store the server handle object for as long as it needs the server running, if the server handle is garbage-collected by Lua, the listening socket will be closed and all current connections dropped." },
|
||||
|
@ -50,6 +50,12 @@ g_PluginInfo =
|
||||
}, -- ParameterCombinations
|
||||
}, -- close
|
||||
|
||||
ips =
|
||||
{
|
||||
HelpString = "Prints all locally available IP addresses",
|
||||
Handler = HandleConsoleNetIps,
|
||||
}, -- ips
|
||||
|
||||
listen =
|
||||
{
|
||||
HelpString = "Creates a new listening socket on the specified port with the specified service attached to it",
|
||||
|
@ -288,6 +288,19 @@ end
|
||||
|
||||
|
||||
|
||||
function HandleConsoleNetIps(a_Split)
|
||||
local Addresses = cNetwork:EnumLocalIPAddresses()
|
||||
LOG("IP addresses enumerated, " .. #Addresses .. " found")
|
||||
for idx, addr in ipairs(Addresses) do
|
||||
LOG(" IP #" .. idx .. ": " .. addr)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function HandleConsoleNetLookup(a_Split)
|
||||
-- Get the name to look up:
|
||||
local Addr = a_Split[3] or "google.com"
|
||||
|
@ -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");
|
||||
|
@ -13,6 +13,7 @@ SET (SRCS
|
||||
HostnameLookup.cpp
|
||||
IPLookup.cpp
|
||||
IsThread.cpp
|
||||
NetworkInterfaceEnum.cpp
|
||||
NetworkSingleton.cpp
|
||||
Semaphore.cpp
|
||||
ServerHandleImpl.cpp
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
129
src/OSSupport/NetworkInterfaceEnum.cpp
Normal file
129
src/OSSupport/NetworkInterfaceEnum.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
|
||||
// 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
|
||||
#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 AString(IP);
|
||||
}
|
||||
|
||||
#endif // _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 != 1)
|
||||
{
|
||||
// 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
|
||||
|
||||
// TODO: Enumerate network interfaces on Linux
|
||||
|
||||
#endif // else _WIN32
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user