From 1a16a61ceda49cb9b855ae4e0223ccc2999a0d82 Mon Sep 17 00:00:00 2001 From: Fedotov Anton Date: Thu, 2 Dec 2021 15:08:54 +0300 Subject: [PATCH] added the method to get the route table --- client/3rd/AdpInfo/netadpinfo.h | 15 +++ client/3rd/AdpInfo/win_netadpinfo.cc | 143 +++++++++++++++++++----- client/protocols/ikev2_vpn_protocol.cpp | 17 ++- client/protocols/openvpnprotocol.cpp | 20 +++- client/protocols/wireguardprotocol.cpp | 21 +++- 5 files changed, 176 insertions(+), 40 deletions(-) diff --git a/client/3rd/AdpInfo/netadpinfo.h b/client/3rd/AdpInfo/netadpinfo.h index 90c98a90..8ad5fdec 100644 --- a/client/3rd/AdpInfo/netadpinfo.h +++ b/client/3rd/AdpInfo/netadpinfo.h @@ -11,6 +11,20 @@ namespace adpinfo{ // {false,""} - no error // {true,"descr"} - error with description using RET_TYPE = std::tuple; + +//using ROUTE_TABLE = std::tuple; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +/* + * Getting the route table +*/ +typedef struct route_table{ + std::string szDestIp; + std::string szMaskIp; + std::string szGatewayIp; + std::string szInterfaceIp; +}route_table; +std::vector>get_route_table(); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /* * The object uses for collect the information about active network adapters/interfaces @@ -52,6 +66,7 @@ public: std::string_view get_adapter_route_gateway()const; std::string_view get_adapter_local_address()const; std::string_view get_adapter_local_gateway()const; + }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/client/3rd/AdpInfo/win_netadpinfo.cc b/client/3rd/AdpInfo/win_netadpinfo.cc index d36777b4..8cf1967c 100644 --- a/client/3rd/AdpInfo/win_netadpinfo.cc +++ b/client/3rd/AdpInfo/win_netadpinfo.cc @@ -7,37 +7,48 @@ #include #include -//#include -//#include -//#include #include #pragma comment(lib, "iphlpapi.lib") -//#pragma comment(lib, "wbemuuid.lib") -//#pragma comment(lib, "comsuppw.lib") + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -static std::string convert_wide_to_ansi(const std::wstring& widestring) { - auto nchars = WideCharToMultiByte( - CP_ACP, - 0, - widestring.c_str(), - static_cast(widestring.length() + 1), - nullptr, - 0, - nullptr, - nullptr); - std::string converted_string{}; - converted_string.resize(nchars); - WideCharToMultiByte(CP_ACP, - 0, - widestring.c_str(), - -1, - &converted_string[0], - static_cast(widestring.length()), - nullptr, - nullptr); - return converted_string; +//static std::string convert_wide_to_ansi(const std::wstring& widestring) { +// auto nchars = WideCharToMultiByte( +// CP_ACP, +// 0, +// widestring.c_str(), +// static_cast(widestring.length() + 1), +// nullptr, +// 0, +// nullptr, +// nullptr); +// std::string converted_string{}; +// converted_string.resize(nchars); +// WideCharToMultiByte(CP_ACP, +// 0, +// widestring.c_str(), +// -1, +// &converted_string[0], +// static_cast(widestring.length()), +// nullptr, +// nullptr); +// return converted_string; +//} +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +static std::string get_founded_route(std::string_view ip_address){ + + MIB_IPFORWARDROW br{0}; + ZeroMemory(&br, sizeof(MIB_IPFORWARDROW)); + struct in_addr ia; + std::string sTmp{}; + DWORD dwRes = GetBestRoute(inet_addr(ip_address.data()), 0, &br); + if( dwRes == NO_ERROR ){ + ia.S_un.S_addr = (u_long) br.dwForwardDest; + sTmp = inet_ntoa(ia); + qDebug()<<"Best Route:"<< sTmp.data(); + } + return sTmp; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ static std::string get_route_gateway() @@ -52,12 +63,9 @@ static std::string get_route_gateway() DWORD dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder); if (dwStatus == ERROR_INSUFFICIENT_BUFFER) { - // Allocate the memory for the table if (!(pIpForwardTable = (PMIB_IPFORWARDTABLE) malloc(dwSize))) { - //printf("Malloc failed. Out of memory.\n"); return {"Out of memory"}; } - // Now get the table. dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder); } if (dwStatus != ERROR_SUCCESS) { @@ -68,7 +76,6 @@ static std::string get_route_gateway() const DWORD end = pIpForwardTable->dwNumEntries; for (DWORD i = 0; i < end; i++) { if (pIpForwardTable->table[i].dwForwardDest == 0) { - // We have found the default gateway. IpAddr.S_un.S_addr = (u_long) pIpForwardTable->table[i].dwForwardNextHop; strcpy_s(szGatewayIp, sizeof (szGatewayIp), inet_ntoa(IpAddr)); @@ -82,6 +89,80 @@ static std::string get_route_gateway() return route_gateway; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +static std::string get_interface_ip(DWORD index){ + std::string _ipaddr{'\0'}; + std::vector buffer{}; + IP_ADAPTER_INFO *adapter_info{nullptr}; + DWORD result{ERROR_BUFFER_OVERFLOW}; + ULONG buffer_len = sizeof(IP_ADAPTER_INFO) * 10; + while (result == ERROR_BUFFER_OVERFLOW){ + buffer.resize(buffer_len); + adapter_info = reinterpret_cast(&buffer[0]); + result = GetAdaptersInfo(adapter_info, &buffer_len); + if (result == ERROR_NO_DATA){ + return _ipaddr; + } + }//end while + if (result != NO_ERROR){ + return _ipaddr; + } + IP_ADAPTER_INFO *adapter_iterator = adapter_info; + while(adapter_iterator){ + if (adapter_iterator->Index == index) + break; + adapter_iterator = adapter_iterator->Next; + }//end while + if (adapter_iterator != nullptr || adapter_iterator != 0x0 || adapter_iterator != NULL) + _ipaddr = std::string(adapter_iterator->IpAddressList.IpAddress.String, 16); + else + _ipaddr = "127.0.0.1"; + return _ipaddr; +} +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +namespace adpinfo { +std::vector>get_route_table(){ + + std::vector< std::tuple>ret_table{}; + PMIB_IPFORWARDTABLE p_table{nullptr}; + struct in_addr ip_addr{}; + DWORD size{}; + p_table = (MIB_IPFORWARDTABLE *) HeapAlloc(GetProcessHeap(), 0, (sizeof (MIB_IPFORWARDTABLE))); + if (p_table == nullptr) + { + return ret_table; + } + if (GetIpForwardTable(p_table, &size, 0) == ERROR_INSUFFICIENT_BUFFER) { + HeapFree(GetProcessHeap(), 0, p_table); + p_table = (MIB_IPFORWARDTABLE *) HeapAlloc(GetProcessHeap(), 0, size); + if (p_table == nullptr) { + return ret_table; + } + } + DWORD ret = GetIpForwardTable(p_table, &size, 0); + if (ret == NO_ERROR) { + const int &numEntries = static_cast(p_table->dwNumEntries); + for (int i = 0; i table[i].dwForwardDest; + strcpy_s(szDestIp, sizeof (szDestIp), inet_ntoa(ip_addr)); + ip_addr.S_un.S_addr = (u_long) p_table->table[i].dwForwardMask; + strcpy_s(szMaskIp, sizeof (szMaskIp), inet_ntoa(ip_addr)); + ip_addr.S_un.S_addr = (u_long) p_table->table[i].dwForwardNextHop; + strcpy_s(szGatewayIp, sizeof (szGatewayIp), inet_ntoa(ip_addr)); + const auto &ifname = get_interface_ip(p_table->table[i].dwForwardIfIndex); + const auto &ifnameSize = ifname.length() + 1; + strcpy_s(szInterfaceIp, ifnameSize, ifname.data()); + const auto &mt = std::make_tuple(std::string(szDestIp), std::string(szMaskIp), std::string(szGatewayIp), std::string(szInterfaceIp)); + ret_table.emplace_back(mt); + }//end for + }//end if + return ret_table; +} +}//end namespace adpinfo +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ namespace adpinfo { void NetAdpInfo::Adapter::set_name(std::string_view value){ @@ -144,13 +225,13 @@ RET_TYPE NetAdpInfo::collect_adapters_data(){ std::string lgw = adapter_iterator->GatewayList.IpAddress.String; if (lgw.length() == 0 || lgw.find("0.0.0.0") != std::string::npos) { + lgw = get_founded_route("8.8.8.8"); if (adapter_iterator->DhcpEnabled == 1) { lgw = adapter_iterator->DhcpServer.IpAddress.String; } } _tmp->set_local_gateway(lgw); - //_tmp->set_local_gateway(adapter_iterator->GatewayList.IpAddress.String); _tmp->set_route_gateway(get_route_gateway()); _adapters.emplace_back(_tmp); adapter_iterator = adapter_iterator->Next; diff --git a/client/protocols/ikev2_vpn_protocol.cpp b/client/protocols/ikev2_vpn_protocol.cpp index 9b79125b..bb89be85 100644 --- a/client/protocols/ikev2_vpn_protocol.cpp +++ b/client/protocols/ikev2_vpn_protocol.cpp @@ -1,11 +1,10 @@ #include #include #include -//#include -//#include #include #include +#include #include "debug.h" #include "ikev2_vpn_protocol.h" @@ -171,6 +170,7 @@ void Ikev2Protocol::newConnectionStateEventReceived(UINT unMsg, tagRASCONNSTATE //SetEvent(gEvent_handle); { //get the network settings of adapters + std::this_thread::sleep_for(std::chrono::seconds(3)); std::string p1,p2,p3; const auto ret = adpInfo.get_adapter_info(tunnelName().toStdString()); if (std::get<0>(ret) == false){ @@ -183,6 +183,19 @@ void Ikev2Protocol::newConnectionStateEventReceived(UINT unMsg, tagRASCONNSTATE qDebug()<<"My ikev2 m_routeGateway "<(itret); + const auto msk = std::get<1>(itret); + const auto gw = std::get<2>(itret); + const auto itf = std::get<3>(itret); + qDebug()<<"IP["<STATE")) { if (line.contains("CONNECTED,SUCCESS")) { + sendByteCount(); + stopTimeoutTimer(); + setConnectionState(VpnProtocol::Connected); { + std::this_thread::sleep_for(std::chrono::seconds(3)); std::string p1,p2,p3; const auto &ret = adpInfo.get_adapter_info("TAP-Windows Adapter V9"); if (std::get<0>(ret) == false){ @@ -259,14 +263,24 @@ void OpenVpnProtocol::onReadyReadDataFromManagementServer() qDebug()<<"My openvpn m_routeGateway "<(itret); + const auto msk = std::get<1>(itret); + const auto gw = std::get<2>(itret); + const auto itf = std::get<3>(itret); + qDebug()<<"IP["<(ret)); } } - sendByteCount(); - stopTimeoutTimer(); - setConnectionState(VpnProtocol::Connected); continue; } else if (line.contains("EXITING,SIGTER")) { //openVpnStateSigTermHandler(); diff --git a/client/protocols/wireguardprotocol.cpp b/client/protocols/wireguardprotocol.cpp index f1e9919a..c256c31e 100644 --- a/client/protocols/wireguardprotocol.cpp +++ b/client/protocols/wireguardprotocol.cpp @@ -174,19 +174,32 @@ ErrorCode WireguardProtocol::start() setConnectionState(ConnectionState::Connected); { //TODO:FIXME: without some ugly sleep we have't get a adapter parametrs - std::this_thread::sleep_for(std::chrono::seconds(2)); - std::string p1,p2,p3; + std::this_thread::sleep_for(std::chrono::seconds(3)); + std::string p1{},p2{};//,p3; const auto &ret = adpInfo.get_adapter_info("WireGuard Tunnel");//serviceName().toStdString());//("AmneziaVPN IKEv2"); if (std::get<0>(ret) == false){ p1 = adpInfo.get_adapter_route_gateway(); p2 = adpInfo.get_adapter_local_address(); - p3 = adpInfo.get_adapter_local_gateway(); + //p3 = adpInfo.get_adapter_local_gateway(); m_routeGateway = QString::fromStdString(p1); m_vpnLocalAddress = QString::fromStdString(p2); - m_vpnGateway = QString::fromStdString(p3); + m_vpnGateway = protocols::wireguard::defaultSubnetAddress;//QString::fromStdString(p3); qDebug()<<"My wireguard m_routeGateway "<(itret); + const auto msk = std::get<1>(itret); + const auto gw = std::get<2>(itret); + const auto itf = std::get<3>(itret); + qDebug()<<"IP["<(ret));