|
|
|
@ -6,6 +6,13 @@ |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#include "Utilities.h" |
|
|
|
|
|
|
|
|
|
#if defined(WIN32) || defined(WIN64) |
|
|
|
|
#include <winsock2.h> |
|
|
|
|
#include <iphlpapi.h> |
|
|
|
|
#include <cstdlib> |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#include <fmt/format.h> |
|
|
|
|
#include <cstdint> |
|
|
|
|
#include <cstdio> |
|
|
|
@ -39,6 +46,100 @@ std::string getIpFromSecondToken(const std::string& input) |
|
|
|
|
return input.substr(start, len); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if defined(__linux__) || defined(__linux) |
|
|
|
|
std::string getIpAddress_Linux() |
|
|
|
|
{ |
|
|
|
|
std::string ipaddr{ DefaultIpAddress }; |
|
|
|
|
std::string iface; |
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
char buf[64]{}; |
|
|
|
|
// This command will return either empty or something like "dev eth0 some more data here" - we want the eth0 part.
|
|
|
|
|
auto fd = popen(R"(ip route show default | grep -E -o 'dev\s.+(\s|$)')", "r"); |
|
|
|
|
auto readres = fgets(buf, sizeof(buf), fd); |
|
|
|
|
pclose(fd); |
|
|
|
|
|
|
|
|
|
if (!readres) |
|
|
|
|
return ipaddr; |
|
|
|
|
|
|
|
|
|
iface.assign(buf, sizeof(buf)); |
|
|
|
|
iface = getIpFromSecondToken(iface); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!iface.empty()) { |
|
|
|
|
char buf[64]{}; |
|
|
|
|
// This command will match either empty or exactly "inet 123.45.67.89" though with a proper IP address.
|
|
|
|
|
static constexpr auto regex{ R"(inet\s[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3})" }; |
|
|
|
|
const auto cmd{ fmt::format("ip address show {} | grep -E -o '{}'", iface, regex) }; |
|
|
|
|
auto fd = popen(cmd.c_str(), "r"); |
|
|
|
|
auto readres = fgets(buf, sizeof(buf) - 1, fd); |
|
|
|
|
pclose(fd); |
|
|
|
|
|
|
|
|
|
if (!readres) |
|
|
|
|
return ipaddr; |
|
|
|
|
|
|
|
|
|
// We use strlen() since buf will hold many zero-bytes and popen() doesn't give us a size.
|
|
|
|
|
ipaddr.assign(buf, strlen(buf)); |
|
|
|
|
|
|
|
|
|
auto start = ipaddr.find(' ') + 1; |
|
|
|
|
ipaddr = ipaddr.substr(start); |
|
|
|
|
|
|
|
|
|
if (ipaddr.back() == '\n') |
|
|
|
|
ipaddr.erase(ipaddr.end() - 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return ipaddr; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(WIN32) || defined(WIN64) |
|
|
|
|
std::string getIpAddress_Windows() |
|
|
|
|
{ |
|
|
|
|
// This function is based on the example given here:
|
|
|
|
|
// https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersinfo
|
|
|
|
|
|
|
|
|
|
std::string ipaddr{ DefaultIpAddress }; |
|
|
|
|
|
|
|
|
|
/* Get the index of the adapter with default route (0.0.0.0) */ |
|
|
|
|
DWORD adpidx{}; |
|
|
|
|
if (GetBestInterface(0, &adpidx) != NO_ERROR) |
|
|
|
|
return ipaddr; |
|
|
|
|
|
|
|
|
|
PIP_ADAPTER_INFO pAdapterInfo; |
|
|
|
|
PIP_ADAPTER_INFO pAdapter = NULL; |
|
|
|
|
|
|
|
|
|
ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO); |
|
|
|
|
pAdapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO)); |
|
|
|
|
if (!pAdapterInfo) |
|
|
|
|
return ipaddr; |
|
|
|
|
|
|
|
|
|
/* Make an initial call to GetAdaptersInfo to get the necessary size into the ulOutBufLen variable */ |
|
|
|
|
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { |
|
|
|
|
free(pAdapterInfo); |
|
|
|
|
pAdapterInfo = (IP_ADAPTER_INFO*)malloc(ulOutBufLen); |
|
|
|
|
if (!pAdapterInfo) |
|
|
|
|
return ipaddr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Actual call for adapter info */ |
|
|
|
|
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) != NO_ERROR) |
|
|
|
|
return ipaddr; |
|
|
|
|
|
|
|
|
|
for (pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next) { |
|
|
|
|
if (pAdapter->Index == adpidx) { |
|
|
|
|
ipaddr = pAdapter->IpAddressList.IpAddress.String; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (pAdapterInfo) |
|
|
|
|
free(pAdapterInfo); |
|
|
|
|
|
|
|
|
|
return ipaddr; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
|
|
|
|
std::pair<std::string,std::string> FormatCTCPLine(std::string line) |
|
|
|
@ -173,9 +274,9 @@ bool strEquals(const std::string& l, const std::string& r) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
return std::equal(l.begin(), l.end(), r.begin(), |
|
|
|
|
[](char cl, char cr) { |
|
|
|
|
return toupper(cl) == toupper(cr); |
|
|
|
|
} |
|
|
|
|
[](char cl, char cr) { |
|
|
|
|
return toupper(cl) == toupper(cr); |
|
|
|
|
} |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -231,56 +332,13 @@ std::string toBase64(const std::string& input) |
|
|
|
|
|
|
|
|
|
std::string findOwnIpAddress() |
|
|
|
|
{ |
|
|
|
|
std::string ipaddr{ DefaultIpAddress }; |
|
|
|
|
|
|
|
|
|
#if defined(__linux__) || defined(__linux) |
|
|
|
|
|
|
|
|
|
std::string iface; |
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
char buf[64]{}; |
|
|
|
|
// This command will return either empty or something like "dev eth0 some more data here" - we want the eth0 part.
|
|
|
|
|
auto fd = popen(R"(ip route show default | grep -E -o 'dev\s.+(\s|$)')", "r"); |
|
|
|
|
auto readres = fgets(buf, sizeof(buf), fd); |
|
|
|
|
pclose(fd); |
|
|
|
|
|
|
|
|
|
if (!readres) |
|
|
|
|
return ipaddr; |
|
|
|
|
|
|
|
|
|
iface.assign(buf, sizeof(buf)); |
|
|
|
|
iface = getIpFromSecondToken(iface); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!iface.empty()) { |
|
|
|
|
char buf[64]{}; |
|
|
|
|
// This command will match either empty or exactly "inet 123.45.67.89" though with a proper IP address.
|
|
|
|
|
static constexpr auto regex{ R"(inet\s[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3})" }; |
|
|
|
|
const auto cmd{ fmt::format("ip address show {} | grep -E -o '{}'", iface, regex) }; |
|
|
|
|
auto fd = popen(cmd.c_str(), "r"); |
|
|
|
|
auto readres = fgets(buf, sizeof(buf) - 1, fd); |
|
|
|
|
pclose(fd); |
|
|
|
|
|
|
|
|
|
if (!readres) |
|
|
|
|
return ipaddr; |
|
|
|
|
|
|
|
|
|
// We use strlen() since buf will hold many zero-bytes and popen() doesn't give us a size.
|
|
|
|
|
ipaddr.assign(buf, strlen(buf)); |
|
|
|
|
|
|
|
|
|
auto start = ipaddr.find(' ') + 1; |
|
|
|
|
ipaddr = ipaddr.substr(start); |
|
|
|
|
|
|
|
|
|
if (ipaddr.back() == '\n') |
|
|
|
|
ipaddr.erase(ipaddr.end() - 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#elif defined(WI32) || defined(WIN64) |
|
|
|
|
|
|
|
|
|
return "127.0.0.1"; // TODO
|
|
|
|
|
|
|
|
|
|
auto ipaddr = getIpAddress_Linux(); |
|
|
|
|
#elif defined(WIN32) || defined(WIN64) |
|
|
|
|
auto ipaddr = getIpAddress_Windows(); |
|
|
|
|
#else |
|
|
|
|
#error Unsupported platform, implementation of findOwnIpAddress() missing! |
|
|
|
|
#error Unsupported platform, implementation of findOwnIpAddress() missing! |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
return ipaddr.empty() ? DefaultIpAddress : ipaddr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|