diff --git a/NetTunnelSDK/UserManager.cpp b/NetTunnelSDK/UserManager.cpp index e31a75b..0d173da 100644 --- a/NetTunnelSDK/UserManager.cpp +++ b/NetTunnelSDK/UserManager.cpp @@ -174,7 +174,7 @@ int LocalWireGuardControl(bool isStart, bool setPrivateMode) { return -ERR_NET_WIREGUARD_ICS; } - // 检查 WireGuard 网络共享状态 + // 检查 WireGuard 网络共享状态 if ((ret = GetNetIntelnetConnectionSharing(ifInetlnetIndex, &chkStatus)) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Call GetNetIntelnetConnectionSharing error: {0}"), ret); return ret; @@ -185,12 +185,17 @@ int LocalWireGuardControl(bool isStart, bool setPrivateMode) { return -ERR_NET_WIREGUARD_ICS; } - // 重设隧道 IP 地址 GetIpV4InfoFromCIDR(GetGlobalCfgInfo()->userCfg.cliConfig.cliAddress, &ipInfo); - if ((ret = SetInterfaceIpAddressWMI(GetGlobalCfgInfo()->userCfg.userName, ipInfo.ip, ipInfo.netmask)) != ERR_SUCCESS) { - SPDLOG_ERROR(TEXT("Call SetInterfaceIpAddressWMI error: {0}"), ret); - return ret; - } + + // 检查 ICS 是否自动添加了其它非法 IP 地址 + if((ret = VerifyInterfaceIpAddr(ifWireGuardIndex, ipInfo.ip, ipInfo.netmask, 1)) != ERR_SUCCESS) { + SPDLOG_WARN(TEXT("Check Windows automatic set another ip to wireguard network interface, force set to {0}/{1}"), ipInfo.ip, ipInfo.netmask); + // 重设隧道 IP 地址 + if ((ret = SetInterfaceIpAddressWMI(GetGlobalCfgInfo()->userCfg.userName, ipInfo.ip, ipInfo.netmask)) != ERR_SUCCESS) { + SPDLOG_ERROR(TEXT("Call SetInterfaceIpAddressWMI error: {0}"), ret); + return ret; + } + } SPDLOG_INFO(TEXT("Net Share Service Work now on ICS mode: {0}"), GetGlobalCfgInfo()->userCfg.userName); } else if (GetCurrentNetShareMode() == NAT_SHARE_MODE) { diff --git a/NetTunnelSDK/include/network.h b/NetTunnelSDK/include/network.h index 1d8e3a6..a42399d 100644 --- a/NetTunnelSDK/include/network.h +++ b/NetTunnelSDK/include/network.h @@ -7,6 +7,21 @@ extern "C" { // we need to export the C interface #endif +/** + * @brief 校验接口 IP 地址 + * @param ifIndex 网卡索引 + * @param pIpAddr 网卡 IP 地址 + * @param pNetMask 网卡子网掩码 + * @param maxIpNumber 网卡最大允许的 IP 地址数 + * @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO + * - -ERR_INPUT_PARAMS 输入参数错误 + * - -ERR_MALLOC_MEMORY 分配内存失败 + * - -ERR_ITEM_UNEXISTS 找不到合适的网卡 + * - -ERR_UN_SUPPORT 系统不支持该操作 + * - ERR_SUCCESS 成功 + */ +int VerifyInterfaceIpAddr(int ifIndex, const TCHAR *pIpAddr, const TCHAR *pNetMask, int maxIpNumber); + /** * @brief 根据网卡 IP地址 获取网卡索引 * @param[in] pIpAddr 网卡IP地址 @@ -33,7 +48,7 @@ int GetInterfaceIfIndexByIpAddr(const TCHAR *pIpAddr, ULONG *pIfIndex); * - -ERR_ITEM_UNEXISTS GUID 不存在 * - ERR_SUCCESS 成功 */ -int GetInterfaceNameByGUID(const TCHAR *pGUID, TCHAR ifName[MAX_NETCARD_NAME], int* pConnStatus); +int GetInterfaceNameByGUID(const TCHAR *pGUID, TCHAR ifName[MAX_NETCARD_NAME], int *pConnStatus); /** * @brief 根据网卡名获取网卡索引 diff --git a/NetTunnelSDK/network/network.cpp b/NetTunnelSDK/network/network.cpp index e2c5fb2..6fff3ba 100644 --- a/NetTunnelSDK/network/network.cpp +++ b/NetTunnelSDK/network/network.cpp @@ -26,6 +26,70 @@ static NIC_CONTENT g_NetAdapterInfo[NET_CARD_MAX]; +int VerifyInterfaceIpAddr(int ifIndex, const TCHAR *pIpAddr, const TCHAR *pNetMask, int maxIpNumber) { + PIP_ADAPTER_INFO pAdapterInfo; + DWORD dwRetVal; + ULONG ulOutBufLen; + int nIp = 0; + bool isMatched = false; + + if (pIpAddr == nullptr || lstrlen(pIpAddr) == 0) { + SPDLOG_ERROR(TEXT("Input pIpAddr error: {0}"), pIpAddr); + return -ERR_INPUT_PARAMS; + } + + ulOutBufLen = sizeof(IP_ADAPTER_INFO); + pAdapterInfo = static_cast(HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO))); + + if (pAdapterInfo == nullptr) { + SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo")); + return -ERR_MALLOC_MEMORY; + } + + if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { + HeapFree(GetProcessHeap(), 0, pAdapterInfo); + pAdapterInfo = static_cast(HeapAlloc(GetProcessHeap(), 0, ulOutBufLen)); + if (pAdapterInfo == nullptr) { + SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo\n")); + return -ERR_MALLOC_MEMORY; + } + } + + if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) { + PIP_ADAPTER_INFO pAdapter = pAdapterInfo; + while (pAdapter) { + PIP_ADDR_STRING ipAddressListPointer = &(pAdapter->IpAddressList); + + while (ipAddressListPointer != nullptr) { + if (pAdapter->Index == static_cast(ifIndex)) { + nIp++; + if (StrCmp((ipAddressListPointer->IpAddress).String, pIpAddr) == 0 && + StrCmp((ipAddressListPointer->IpMask).String, pNetMask) == 0) { + isMatched = true; + } + } + + ipAddressListPointer = ipAddressListPointer->Next; + } + pAdapter = pAdapter->Next; + } + } else { + SPDLOG_ERROR(TEXT("GetAdaptersInfo failed with error: {0}\n"), dwRetVal); + HeapFree(GetProcessHeap(), 0, pAdapterInfo); + return -ERR_SYS_CALL; + } + + if (pAdapterInfo) { + HeapFree(GetProcessHeap(), 0, pAdapterInfo); + } + + if (isMatched == true && nIp == maxIpNumber) { + return ERR_SUCCESS; + } + + return -ERR_ITEM_UNEXISTS; +} + int GetInterfaceIfIndexByIpAddr(const TCHAR *pIpAddr, ULONG *pIfIndex) { PIP_ADAPTER_INFO pAdapterInfo; DWORD dwRetVal; diff --git a/TestNetTunnelSDK/TestNetTunnelSDK.cpp b/TestNetTunnelSDK/TestNetTunnelSDK.cpp index 6af3734..50e89b1 100644 --- a/TestNetTunnelSDK/TestNetTunnelSDK.cpp +++ b/TestNetTunnelSDK/TestNetTunnelSDK.cpp @@ -55,7 +55,7 @@ public: Assert::IsNotNull(pInfo); Assert::AreNotEqual(0, size); - free(pInfo); + //free(pInfo); } TEST_METHOD(TestSetInterfaceIpAddressWMI) { @@ -64,6 +64,11 @@ public: } #if 0 + TEST_METHOD(TestVerifyInterfaceIpAddr) { + const int ret = VerifyInterfaceIpAddr(11, TEXT("10.10.10.251"), TEXT("255.255.255.0"), 2); + Assert::AreEqual(RET_OK, ret); + } + TEST_METHOD(TestSetInterfaceIpAddressFromCIDR) { Assert::AreEqual(RET_OK, SetInterfaceIpAddressFromCIDR(TEXT("wg_server"), TEXT("192.168.100.250/24"))); }