使用GetAdaptersAddresses查找临时IPv6地址

时间:2016-02-16 20:13:35

标签: c winapi networking winsock

我使用GetAdaptersAddresses查找计算机的所有IPv6地址。

我想区分全局地址和RFC4941临时地址(RFC4941也称为"隐私扩展")。

answer建议使用地址的首选生命周期来查找临时地址,因为它的生命周期会更短。除了这是一个kludge,它也不能在我的机器上工作(使用Windows 7)。 这是netsh接口ipv6显示地址的ouptut

Addr Type  DAD State   Valid Life Pref. Life Address
---------  ----------- ---------- ---------- ------------------------
Public     Preferred     1h58m15s     16m36s xxxx:xx:xxxx:2000:71e7:xxxx:xxxx:f45b
Temporary  Preferred     1h58m15s     16m36s xxxx:xx:xxxx:2000:8479:xxxx:xxxx:a70a
Other      Preferred     infinite   infinite fe80::71e7:xxxx:xxxx:f45b%19

你可以看到两个地址的生命周期是相同的。

那么,如何获得临时地址的标志,或者更具挑衅性地询问ipconfig或netsh如何知道,他们使用的是什么API?

1 个答案:

答案 0 :(得分:0)

我知道现在有点晚了,但是这个问题是我搜索有关如何在Windows中获取临时IPv6地址时的最高结果之一。

我使用了链接问题中给出的指南,并且可以在Windows 10中成功获取临时IPv6地址。如上所述,主要思想是检查SuffixOrigin是否为IpSuffixOriginRandom

IP_ADAPTER_ADDRESSES *adapterAddr = NULL;
DWORD dwSize = 0, dwRet = 0;
DWORD flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;
while (dwRet = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterAddr, &dwSize) == ERROR_BUFFER_OVERFLOW) {
    adapterAddr = (IP_ADAPTER_ADDRESSES *)LocalAlloc(LMEM_ZEROINIT, dwSize);
}
if (adapterAddr != NULL) {
    IP_ADAPTER_ADDRESSES *AI;
    int i;
    for (i = 0, AI = adapterAddr; AI != NULL; AI = AI->Next, i++) {
        if (AI->FirstUnicastAddress != NULL) {
            for (PIP_ADAPTER_UNICAST_ADDRESS unicast = AI->FirstUnicastAddress; unicast; unicast = unicast->Next) {

                if (unicast->SuffixOrigin == IpSuffixOriginRandom) {
                    cout << "This is temporary address!" << endl;
                }
            }
        }
    }
    LocalFree(adapterAddr);
}

希望这会有用