Open
Description
获取网卡数量
获取虚拟网卡的个数
int GetNetCardNums()
{
int nRet = 0;
CoInitialize(NULL);
INetConnectionManager* pNetManager;
INetConnection* pNetConnection;
IEnumNetConnection* pEnum;
ULONG celtFetched;
std::string strComGuid;
NETCON_PROPERTIES* properties = nullptr;
bool bIsInstalledNcCard = false;
TapReg setRegGuid = get_tap_reg();
NcStatusList ncStausList;
if (setRegGuid.size() == 0)
{
SP_LOGW("%s Reg Not Found, Re Install", __SP_FUNC__);
return 0;
}
if (S_OK != CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionManager, (void**)&pNetManager))
{
SP_LOGW("%s Com Instance Failed, sleep(5s)", __SP_FUNC__);
return 0;
}
pNetManager->EnumConnections(NCME_DEFAULT, &pEnum);
pNetManager->Release();
if (NULL == pEnum)
{
return 0;
}
while (pEnum->Next(1, &pNetConnection, &celtFetched) == S_OK)
{
pNetConnection->GetProperties(&properties);
strComGuid = GUIDToString(properties->guidId);
// 查看当前网卡与注册表的guid一致时的状态
for (auto& it : setRegGuid)
{
// #1 判断是否安装了 虚拟网卡
if (strComGuid.compare(it) == 0)
{
nRet++;
}
}
}
pEnum->Release();
return nRet;
}
网卡保活
声明
/*
* @fn keepAlive
* @brief 网络连接保活
*
* @detail 线程,通过COM组件实现
*/
void keepDeviceTAVnicAlive();
实现
void keepDeviceTAVnicAlive()
{
std::lock_guard<std::mutex> lock(g_mutex);
bool bRet = false;
static int iRePtunFlag = 1; // Nc重连标志
static int iReLoadFlag = 1; // Dll重载标志
// ipc 主要处理nc发送的消息
TrustSpaceIPCUtil m_ncIpc("trustNcToCore");
m_ncIpc.Initialize(&HandleIpcCallBack);
do
{
CoInitialize(NULL);
INetConnectionManager* pNetManager = nullptr;
INetConnection* pNetConnection = nullptr;
IEnumNetConnection* pEnum = nullptr;
ULONG celtFetched;
std::string strComGuid;
bool bIsInstalledNcCard = false;
TapReg setRegGuid = get_tap_reg();
NcStatusList ncStausList;
if (setRegGuid.size() == 0)
{
SP_LOGW("%s Reg Not Found, Re Install", __SP_FUNC__);
goto __REINSTALL;
}
if (S_OK != CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionManager, (void**)&pNetManager))
{
SP_LOGW("%s Com Instance Failed, sleep(5s)", __SP_FUNC__);
std::this_thread::sleep_for(std::chrono::milliseconds(1000 * 5));
continue;
}
pNetManager->EnumConnections(NCME_DEFAULT, &pEnum);
if (pNetManager)
{
pNetManager->Release();
pNetManager = nullptr;
}
if (NULL == pEnum)
{
return;
}
while (pEnum->Next(1, &pNetConnection, &celtFetched) == S_OK)
{
NETCON_PROPERTIES* properties = nullptr;
pNetConnection->GetProperties(&properties);
if (properties != nullptr)
{
strComGuid = GUIDToString(properties->guidId);
// T1 查看当前网卡与注册表的guid一致时的状态
for (auto& it : setRegGuid)
{
// #1 判断是否安装了 虚拟网卡
int minSize = min(strComGuid.size(), it.size());
if (it.compare(0, minSize, strComGuid, 0, minSize) == 0)
{
ncStausList[properties->Status] = properties->pszwDeviceName;
// #2 已安装
bIsInstalledNcCard = true;
// #3 判断是否被禁用
if (NCS_DISCONNECTED == properties->Status)
{
pNetConnection->Connect();
SP_LOGI("%s [NcCard] ReConnect", __SP_FUNC__);
}
}
}
}
if (pNetConnection)
{
pNetConnection->Release();
pNetConnection = nullptr;
}
}
if (pEnum)
{
pEnum->Release();
pEnum = nullptr;
}
// T2 网卡启用时,判断是否有业务需要开启
if (g_sp_trust_model && g_sp_trust_model->Session()->NeedsL3Tunnel() && // 有三层业务
!g_sp_trust_model->Session()->IsTunnelSvrsEmpty() && // 服务不为空
g_sp_trust_model->Session()->IsOnline() && // 会话在线
g_bNetWorkOnline) // 必须联网
{
iRePtunFlag = (iRePtunFlag > 300) ? 0 : ++iRePtunFlag;
if (ncStausList.find(NCS_CONNECTED) == ncStausList.end() && (iRePtunFlag % 30 == 0))
{
SP_LOGI("%s [NcCard] Auto Detect ReConnect PTUN", __SP_FUNC__);
if (iReLoadFlag == 5)
{
SP_LOGI("%s [NcCard] Auto Detect ReConnect PTUN FAILED. RUN TIMES OVER 5, NECT:[NO OPTION]", __SP_FUNC__);
}
handleReStartNc();
Sleep(5 * 1000);
iReLoadFlag++;
}
else if (ncStausList.find(NCS_CONNECTED) != ncStausList.end())
{
iReLoadFlag = 0;
}
}
__REINSTALL:
CoUninitialize();
if (false == bIsInstalledNcCard) // 未安装,重新安装
{
// #1 未安装,重新安装
if (false == bIsInstalledNcCard)
{
SP_DEV_LOGW("[NetCard] Detect Nc Card Not Installed");
// #2 重新安装
bIsInstalledNcCard = true;
std::thread installCardThread([] {
g_sp_trust_model->NotifyUpMessage(SP_TRUST_TOPIC_MSG_NC_INSTALL, SPJSONObject(), 100);
});
installCardThread.detach();
// #3 等待客户端安装
Sleep(15 * 1000);
}
}
else
{
Sleep(1 * 1000); // 每一秒检查一次
}
} while (true);
return;
}
网卡是否存在
bool IsExistNcCard()
{
bool bIsExist = false;
int nNetCardSize = 20;
std::shared_ptr<IP_ADAPTER_INFO> pIpAdapterInfo(new IP_ADAPTER_INFO[nNetCardSize]);
unsigned long stSize = sizeof(IP_ADAPTER_INFO) * nNetCardSize;
//获取所有网卡信息,参数二为输入输出参数
int nRel = GetAdaptersInfo(pIpAdapterInfo.get(), &stSize);
// 空间不足
if (ERROR_BUFFER_OVERFLOW == nRel) {
pIpAdapterInfo.reset(new IP_ADAPTER_INFO[stSize]);
if (GetAdaptersInfo(pIpAdapterInfo.get(), &stSize) != NO_ERROR)
{
std::cout << "Failed to get adapter info" << std::endl;
return false;
}
}
PIP_ADAPTER_INFO cur = pIpAdapterInfo.get();
// 多个网卡 通过链表形式链接起来的
std::string netdesc;
std::string netip;
while (cur) {
netdesc = cur->Description;
switch (cur->Type) {
case MIB_IF_TYPE_OTHER:
break;
case MIB_IF_TYPE_ETHERNET:
{
IP_ADDR_STRING* pIpAddrString = &(cur->IpAddressList);
netip = pIpAddrString->IpAddress.String;
}
break;
case MIB_IF_TYPE_TOKENRING:
break;
case MIB_IF_TYPE_FDDI:
break;
case MIB_IF_TYPE_PPP:
break;
case MIB_IF_TYPE_LOOPBACK:
break;
case MIB_IF_TYPE_SLIP:
break;
default://无线网卡,Unknown type
{
IP_ADDR_STRING* pIpAddrString = &(cur->IpAddressList);
netip = pIpAddrString->IpAddress.String;
}
break;
}
char hex[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
// mac 地址一般6个字节
// mac 二进制转16进制字符串
char macStr[18] = { 0 };//12+5+1
int k = 0;
for (UINT j = 0; j < cur->AddressLength; j++) {
macStr[k++] = hex[(cur->Address[j] & 0xf0) >> 4];
macStr[k++] = hex[cur->Address[j] & 0x0f];
macStr[k++] = '-';
}
if (k < 18 && k > 0)
{
macStr[k - 1] = 0;
}
cur = cur->Next;
// 找到 "TrustAgent VNIC"
if (netdesc.find("TrustAgent VNIC") != std::string::npos)
{
bIsExist = true;
goto _END_;
}
}
_END_:
return bIsExist;
}
blog link 获取网卡数量