Philipp
Philipp

Reputation: 987

find temporary IPv6 address using GetAdaptersAddresses

I'm using GetAdaptersAddresses to find all IPv6 addresses of a machine.

I want to distinguish between the global address and the RFC4941 temporary address (RFC4941 is also known as "privacy extensions").

This answer suggests using the preferred lifetime of the address to find the temporary address, because it would have a shorter lifetime. Besides this being a kludge, it also doesn't work on my Machine (using Windows 7). This is the ouptut of netsh interface ipv6 show address

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

Where you can see the lifetimes of both addresses are identical.

So, how is it possible to get the flag for the temporary address, or, more provocatively asked, how does the ipconfig or netsh know, what is the API they are using?

Upvotes: 7

Views: 1285

Answers (1)

miradham
miradham

Reputation: 2345

I know it is a bit late, but this question was one of top results while I searched regarding how to get temporary IPv6 address in windows.

I used guide given in the linked question and could successfully get temporary IPv6 address in Windows 10. As it is mentioned, main idea is to check SuffixOrigin is 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);
}

Hope this is gonna be useful

Upvotes: 5

Related Questions