如何通过GetAdaptersAddresses()获取接口索引与NTEContext以调用Add/DeleteIpAddress()?
使用GetAdaptersAddresses()获取网络接口索引与NTEContext
一、获取接口索引
GetAdaptersAddresses()返回的IP_ADAPTER_ADDRESSES结构体中,IfIndex字段就是对应网络接口的索引值,遍历返回的链表时直接读取该字段即可。
二、获取NTEContext
NTEContext是单IP地址绑定条目的属性,而非接口本身的属性,因此需要结合GetUnicastIpAddressTable()(适配Windows Vista及以上系统,推荐使用)来获取:
- 先用
GetAdaptersAddresses()定位到目标接口的IfIndex; - 调用
GetUnicastIpAddressTable()获取系统所有单播IP地址条目; - 遍历条目,找到与目标
IfIndex匹配的MIB_UNICASTIPADDRESS_ROW,其NteContext字段就是DeleteIpAddress()所需的参数。
若接口绑定了多个IP地址,每个地址对应独立的NTEContext,需根据要删除的IP地址精准筛选。
代码示例
#include <iphlpapi.h> #include <ws2tcpip.h> #include <iostream> #include <cstring> #pragma comment(lib, "iphlpapi.lib") int main() { // 1. 获取目标接口的IfIndex PIP_ADAPTER_ADDRESSES pAdapters = nullptr; ULONG bufSize = 0; // 先调用一次获取缓冲区大小 GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAdapters, &bufSize); pAdapters = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(malloc(bufSize)); if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAdapters, &bufSize) != NO_ERROR) { free(pAdapters); return 1; } DWORD targetIfIndex = 0; PIP_ADAPTER_ADDRESSES currAdapter = pAdapters; while (currAdapter != nullptr) { // 替换为你的目标接口名称(如"以太网"、"WLAN") if (strcmp(currAdapter->FriendlyName, "以太网") == 0) { targetIfIndex = currAdapter->IfIndex; std::cout << "目标接口IfIndex: " << targetIfIndex << std::endl; break; } currAdapter = currAdapter->Next; } free(pAdapters); if (targetIfIndex == 0) { std::cout << "未找到目标接口" << std::endl; return 1; } // 2. 获取该接口的IP地址及对应NTEContext PMIB_UNICASTIPADDRESS_TABLE pIpTable = nullptr; if (GetUnicastIpAddressTable(AF_INET, &pIpTable) != NO_ERROR) { std::cout << "获取IP地址表失败" << std::endl; return 1; } for (DWORD i = 0; i < pIpTable->NumEntries; ++i) { MIB_UNICASTIPADDRESS_ROW& ipRow = pIpTable->Table[i]; if (ipRow.InterfaceIndex == targetIfIndex) { char ipBuf[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &ipRow.Address.Ipv4.sin_addr, ipBuf, INET_ADDRSTRLEN); std::cout << "IP地址: " << ipBuf << " | NTEContext: " << ipRow.NteContext << std::endl; // 调用DeleteIpAddress时传入此NteContext即可删除对应IP // DeleteIpAddress(ipRow.NteContext); } } FreeMibTable(pIpTable); return 0; }
注意事项
- 若需处理IPv6地址,将
AF_INET替换为AF_INET6,并调整IP地址格式化的代码(使用INET6_ADDRSTRLEN); - 调用
AddIPAddress()/DeleteIpAddress()必须以管理员权限运行程序,否则会返回ERROR_ACCESS_DENIED; DeleteIpAddress()删除的是单个IP绑定,而非接口的所有IP,需确保NTEContext与目标IP一一对应。
内容的提问来源于stack exchange,提问作者MichelPeseur
相关产品推荐
相关产品推荐

