321 lines
12 KiB
C++
321 lines
12 KiB
C++
#include "netadpinfo.h"
|
|
|
|
#include <QDebug>
|
|
|
|
#include <algorithm>
|
|
#include <iterator>
|
|
#include <cassert>
|
|
|
|
#include <windows.h>
|
|
#include <iphlpapi.h>
|
|
|
|
#pragma comment(lib, "iphlpapi.lib")
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//static std::string convert_wide_to_ansi(const std::wstring& widestring) {
|
|
// auto nchars = WideCharToMultiByte(
|
|
// CP_ACP,
|
|
// 0,
|
|
// widestring.c_str(),
|
|
// static_cast<int>(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<int>(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()
|
|
{
|
|
std::string route_gateway{};
|
|
PMIB_IPFORWARDTABLE pIpForwardTable{nullptr};
|
|
DWORD dwSize = 0;
|
|
BOOL bOrder = FALSE;
|
|
|
|
struct in_addr IpAddr;
|
|
char szGatewayIp[128]{'\0'};
|
|
|
|
DWORD dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder);
|
|
if (dwStatus == ERROR_INSUFFICIENT_BUFFER) {
|
|
if (!(pIpForwardTable = (PMIB_IPFORWARDTABLE) malloc(dwSize))) {
|
|
return {"Out of memory"};
|
|
}
|
|
dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder);
|
|
}
|
|
if (dwStatus != ERROR_SUCCESS) {
|
|
if (pIpForwardTable)
|
|
free(pIpForwardTable);
|
|
return {"getIpForwardTable failed"};
|
|
}
|
|
const DWORD end = pIpForwardTable->dwNumEntries;
|
|
for (DWORD i = 0; i < end; i++) {
|
|
if (pIpForwardTable->table[i].dwForwardDest == 0) {
|
|
IpAddr.S_un.S_addr =
|
|
(u_long) pIpForwardTable->table[i].dwForwardNextHop;
|
|
strcpy_s(szGatewayIp, sizeof (szGatewayIp), inet_ntoa(IpAddr));
|
|
route_gateway = std::string(szGatewayIp);
|
|
break;
|
|
}
|
|
}
|
|
if (pIpForwardTable)
|
|
free(pIpForwardTable);
|
|
|
|
return route_gateway;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
static std::string get_interface_ip(DWORD index){
|
|
std::string _ipaddr{'\0'};
|
|
std::vector<BYTE> 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<IP_ADAPTER_INFO*>(&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<route_table>get_route_table(std::string_view ipifaddrs){
|
|
|
|
/*std::tuple<std::string, std::string, std::string, std::string >*/
|
|
std::vector<route_table>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<int>(p_table->dwNumEntries);
|
|
for (int i = 0; i <numEntries; ++i) {
|
|
char szDestIp[128]{};
|
|
char szMaskIp[128]{};
|
|
char szGatewayIp[128]{};
|
|
char szInterfaceIp[21]{};
|
|
ip_addr.S_un.S_addr = (u_long) p_table->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());
|
|
if (ipifaddrs.length() == 0){
|
|
//std::make_tuple(std::string(szDestIp), std::string(szMaskIp), std::string(szGatewayIp), std::string(szInterfaceIp));
|
|
const route_table &mt = {
|
|
std::string(szDestIp),
|
|
std::string(szMaskIp),
|
|
std::string(szGatewayIp),
|
|
std::string(szInterfaceIp),
|
|
p_table->table[i].dwForwardIfIndex
|
|
};
|
|
ret_table.emplace_back(mt);
|
|
}else{
|
|
bool in_not_empty = (ifname.find(ipifaddrs) != std::string::npos);
|
|
//bool in_as_destIp = ( std::string(szDestIp).find(ipifaddrs) != std::string::npos);
|
|
bool destIp_as_zero = (std::string(szDestIp).find("0.0.0.0") != std::string::npos);
|
|
bool mask_as_zero = (std::string(szMaskIp).find("0.0.0.0") != std::string::npos);
|
|
// bool ip_the_same = (
|
|
// std::string(szDestIp).find(ipifaddrs) != std::string::npos &&
|
|
// std::string(szDestIp).find(szGatewayIp) != std::string::npos &&
|
|
// std::string(szDestIp).find(szInterfaceIp) != std::string::npos
|
|
// );
|
|
// bool not_default = (std::string(szDestIp).find("127.0.0.1") == std::string::npos);
|
|
|
|
if ( in_not_empty &&
|
|
// in_as_destIp &&
|
|
destIp_as_zero &&
|
|
mask_as_zero//) || ( ip_the_same && not_default )
|
|
)
|
|
{
|
|
// finded
|
|
const route_table &mt = {
|
|
std::string(szDestIp),
|
|
std::string(szMaskIp),
|
|
std::string(szGatewayIp),
|
|
std::string(szInterfaceIp),
|
|
p_table->table[i].dwForwardIfIndex
|
|
};//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){
|
|
name = value;
|
|
}
|
|
std::string_view NetAdpInfo::Adapter::get_name()const{
|
|
|
|
return name;
|
|
}
|
|
void NetAdpInfo::Adapter::set_description(std::string_view value){
|
|
descr = value;
|
|
}
|
|
std::string_view NetAdpInfo::Adapter::get_description()const{
|
|
return descr;
|
|
}
|
|
void NetAdpInfo::Adapter::set_route_gateway(std::string_view value){
|
|
route = value;
|
|
}
|
|
std::string_view NetAdpInfo::Adapter::get_route_gateway()const{
|
|
return route;
|
|
|
|
}
|
|
void NetAdpInfo::Adapter::set_local_address(std::string_view value){
|
|
address = value;
|
|
}
|
|
std::string_view NetAdpInfo::Adapter::get_local_address()const{
|
|
return address;
|
|
}
|
|
void NetAdpInfo::Adapter::set_local_gateway(std::string_view value){
|
|
gateway = value;
|
|
}
|
|
std::string_view NetAdpInfo::Adapter::get_local_gateway()const{
|
|
return gateway;
|
|
}
|
|
|
|
RET_TYPE NetAdpInfo::collect_adapters_data(){
|
|
_adapters.clear();
|
|
std::vector<BYTE> 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<IP_ADAPTER_INFO*>(&buffer[0]);
|
|
result = GetAdaptersInfo(adapter_info, &buffer_len);
|
|
if (result == ERROR_NO_DATA){
|
|
return {true, "GetAdaptersInfo return ERROR_NO_DATA"};
|
|
}
|
|
}//end while
|
|
if (result != NO_ERROR){
|
|
const std::string &error = "GetAdaptersInfo failed :" + std::to_string(result);
|
|
return {true, error};
|
|
}
|
|
IP_ADAPTER_INFO *adapter_iterator = adapter_info;
|
|
while(adapter_iterator){
|
|
std::shared_ptr<Adapter>_tmp{std::make_shared<Adapter>()};
|
|
_tmp->set_name(adapter_iterator->AdapterName);
|
|
_tmp->set_description(adapter_iterator->Description);
|
|
_tmp->set_local_address(adapter_iterator->IpAddressList.IpAddress.String);
|
|
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_route_gateway(get_route_gateway());
|
|
_adapters.emplace_back(_tmp);
|
|
adapter_iterator = adapter_iterator->Next;
|
|
}
|
|
return {false, ""};
|
|
}
|
|
|
|
RET_TYPE NetAdpInfo::get_adapter_info(std::string_view _adapter_name){
|
|
|
|
_index_of_adapter = -1;
|
|
const auto result{collect_adapters_data()};
|
|
if (std::get<0>(result) == true){
|
|
_index_of_adapter = -1;
|
|
return result;
|
|
}
|
|
const int16_t &len = static_cast<int16_t>(_adapters.size());
|
|
for (auto i = 0; i< len; ++i){
|
|
auto adap_name = _adapters[i]->get_name();
|
|
auto adap_desc = _adapters[i]->get_description();
|
|
if ( adap_name.find(_adapter_name) != std::string::npos || adap_desc.find(_adapter_name) != std::string::npos ){
|
|
_index_of_adapter = i;
|
|
return {false, ""};
|
|
}
|
|
}
|
|
return {true, "adapters no founded"};
|
|
}
|
|
|
|
std::string_view NetAdpInfo::get_adapter_route_gateway()const{
|
|
if (_index_of_adapter < 0)
|
|
return "error adapter index";
|
|
return _adapters.at(_index_of_adapter)->get_route_gateway();
|
|
}
|
|
std::string_view NetAdpInfo::get_adapter_local_address()const{
|
|
if (_index_of_adapter < 0)
|
|
return "error adapter index";
|
|
return _adapters.at(_index_of_adapter)->get_local_address();
|
|
}
|
|
std::string_view NetAdpInfo::get_adapter_local_gateway()const{
|
|
if (_index_of_adapter < 0)
|
|
return "error adapter index";
|
|
return _adapters.at(_index_of_adapter)->get_local_gateway();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//std::string NetAdpInfo::get_system_route(){
|
|
// return get_route_gateway();
|
|
//}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
}// end namespace
|