detect temporary ipv6 address crossplatform
Asked Answered
F

2

8

I want to detect if an address is temporary ipv6 address, i using getifaddrs to get the list of addresses but don't know how to get that info from there. And if possible i want that to work for linux, osx, solaris and windows.

I have seems that in Linux IFA_F_TEMPORARY is set in inet6_ifaddr->ifa_flags, but not sure if how can i get that from the ifaddrs returned by getifaddrs.

Seems that on OSX i need octl with SIOCSIFINFO_FLAGS, and i have no idea about Solaris or Windows.

has any body a sample code that could do that.

Fellah answered 24/7, 2013 at 12:14 Comment(6)
Did you ever find an answer to this, José? I'm curious myself…Fascinating
Nope, it was a bit complex and decided to not implement it.Draper
Bummer. Do you at least have code showing how to use octl on OS X that does the trick?Fascinating
trac.v2.nl/browser/zeroconf/mDNSResponder/mDNSMacOSX/… see the code that checks for IN6_IFF_TEMPORARYDraper
Thanks, very helpful! Works great on OS X and in the iOS simulator, but alas! <netinet6/in6_var.h> is not include in iOS on devices. I suspect Apple does not want anyone to know if IPv6 addresses on iOS are private/temporary.Fascinating
Hi @Fellah , Did you find an answer to - On Linux how to get "IFA_F_TEMPORARY if set in inet6_ifaddr->ifa_flags" from the ifaddrs returned by getifaddrs.Frizette
B
5

Updated (Aug 3, 2016): After searching on and off for the past couple months on this question (because I'm actually in need of this answer myself). I believe I have found the Windows-centric answer. I've only tested this on Windows 10, so I don't know about older versions. But this API shouldn't have changed if someone wants to verify it for me :-)

All _IP_ADAPTER_UNICAST_ADDRESS structures have an enumeration for the address prefix and suffix. I've now bothered to look at them and they are the entire key to solving this issue!

What is a Temporary IPv6 address....it's an address with a RANDOM SUFFIX! So for all IPv6 addresses in a IP_ADAPTER_UNICAST_ADDRESS look at the IP_SUFFIX_ORIGIN see if it is IpSuffixOriginRandom. Thats...it.

I'm really still shocked at how little there on this topic online and this will be a huge issue in a few years for network application developers if no one knows how to solve this issue for server-side applications (even ones running on consumer PCs)

You heard the answer here first!!!


(Original Answer): I've been looking at this exact topic for a cross-platform application as well. I think I've found "a" way to filter IPv6 temporary addresses in Windows. Basically RFC 4941 claims temporary addresses must:

  1. Have a Valid Lifetime less than the "Public" Address
  2. Have a Preferred Lifetime less than the "Public" Address

So for C++, when using a function like GetAdaptersAddresses you can look in the PIP_ADAPTER_ADDRESSES struct for the _IP_ADAPTER_UNICAST_ADDRESS struct and evaluate the ValidLifetime and PreferredLifetime members. After filtering for address type (if you need to know Local-Link vs Public) you can keep a running tally of the largest lifetime. The largest life time (per adapter) should be the public address!

To see the address lifetime info quickly run the Windows terminal command: netsh interface ipv6 show address

You can see all temporary addresses are much smaller than the defaulted SLAAC lifetimes.

I'm working with this assumption for now until testing proves otherwise. All Temporary addresses are based on the public and so cannot out live it.

Hope this helps

Built answered 14/10, 2015 at 5:22 Comment(2)
This does not work on my machine. Both my temporary and the regular IP address show up with the same lifetime: Addr Type DAD State Valid Life Pref. Life Address --------- ----------- ---------- ---------- ------------------------ Public Preferred 1h58m15s 16m36s xxxx:xx:xxxx:2000:71e7:xxxx:xxxx:f4 5b Temporary Preferred 1h58m15s 16m36s xxxx:xx:xxxx:2000:8479:xxxx:xxxx:a7 0a Other Preferred infinite infinite fe80::71e7:xxxx:xxxx:f45b%19Laevorotatory
Well my only thought to that is what you describe would go against RFC 4941 Section 3.3.4 and isn't something I was able to reproduce on testing (using IPv6 DHCP from both Verizon and Comcast) under Windows 8.1 and Windows 10. So I can't speak to what you've posted. If that is in fact true then there are edge cases which don't fit correctly. Hopefully someone else finds a better way.Built
U
0

I use Python 3, it's difficult for me to interactive with Windows API, so

from subprocess import check_output

currentExternalIpAddress = None
rawIpconfigOutput = check_output(["cmd", "/c", "chcp 437 > nul && ipconfig"], universal_newlines=True)
rawTargetInterface = []
targetInterfaceDiscovered = False
for line in rawIpconfigOutput.splitlines():
    if targetInterfaceDiscovered == False:
        isTargetInterface = line.endswith("<Your network adapter name shows in ipconfig>" + ":")
        if isTargetInterface:
            targetInterfaceDiscovered = True
            continue
    if targetInterfaceDiscovered == True:
        isAnotherInterface = ("adapter" in line) and line.endswith(":")
        if (isAnotherInterface):
            break
        rawTargetInterface.append(line)
for line in rawTargetInterface:
    if line.startswith("   IPv6 Address"):
        addressSection = line.split(':', 1)
        addressSection = addressSection[1].strip()
        isPrivateAddress = addressSection.startswith("fd")
        if isPrivateAddress == False:
            currentExternalIpAddress = addressSection
            break
if currentExternalIpAddress is None:
    print("Can't get current external IP address from interface: <Your network adapter name shows in ipconfig>")
else:
    print(currentExternalIpAddress)

The chcp 437 > nul && ipconfig, change code page to prevent output effect by user locale

The idea is get output from ipconfig and parse it line by line, skip Temporary IPv6 Address, and filter out address start with fd, a type of the IPv6 Private address, you may need to filter out other Private address in your environment, because they may also appear under IPv6 Address.

Notice that this code only grab first available address, you need to modify it to get all.

If you carefully wrap it to a function and add a bunch of if not Windows... statement, I think it's capable with cross-platform.

Unspoiled answered 16/8 at 9:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.