Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to retrieve IP v6 subnet mask length

I'm coding an application that has to get the network adapters configuration on a Windows 7 machine just like it's done in the Windows network adapters configuration panel:

enter image description here

So far I can get pretty much all the information I need from NetworkInterface.GetAllNetworkInterfaces() EXCEPT the subnet prefix length.

I'm aware that it can be retrieved from the C++ struc PMIB_UNICASTIPADDRESS_TABLE via OnLinkPrefixLength but I'm trying to stay in .net.

I also took a look at the Win32_NetworkAdapterConfiguration WMI class but it only seems to return the IP v4 subnet mask.

I also know that some information (not the prefix length, as far as I know) are in the registry:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\TCPIP6\Parameters\Interfaces\{CLSID}

I also used SysInternals ProcessMon to try to get anything usefull when saving the network adapter settings but found nothing...

So, is there any clean .NET way to get this value? (getting it from the registry wouldn't be a problem)

EDIT: Gateways

This doesn't concern the actual question, but for those who need to retrieve the entire network adapter IPv6 configuration, the IPInterfaceProperties.GatewayAdresses property only supports the IPv4 gateways. As mentionned in the answer comments below, the only way to get the entire info until .NET framework 4.5 is to call WMI.

like image 567
PhilDulac Avatar asked Aug 06 '12 18:08

PhilDulac


People also ask

How do you determine subnet mask length?

IPv4 addresses are 32 bits made up of four octets of 8 bits each. To calculate the subnet mask, convert an IP address to binary, perform the calculation and then convert back to the IPv4 decimal number representation known as a dotted quad. The same subnetting procedure works for IPv6 addresses.

What is the IPv6 address length?

IPv6 uses 128-bit (2128) addresses, allowing 3.4 x 1038 unique IP addresses. This is equal to 340 trillion trillion trillion IP addresses. IPv6 is written in hexadecimal notation, separated into 8 groups of 16 bits by the colons, thus (8 x 16 = 128) bits in total.

What is the subnet mask of IPv6?

IPv6 doesn't have a subnet mask but instead calls it a Prefix Length, often shortened to “Prefix”. Prefix length and CIDR masking work similarly; The prefix length denotes how many bits of the address define the network in which it exists.

What is my subnet prefix length?

The prefix length determines the size of the subnet and is the number of 1 bits in the netmask. With variable-length subnetting, the prefix length does not have to be a multiple of 8. For example, you can have the IP address 192.168. 123.224, with a netmask = 255.255.


2 Answers

You can do so using Win32_NetworkAdapterConfiguration. You might have overlooked it.

IPSubnet will return an array of strings. Use the second value. I didn't have time to whip up some C# code, but I'm sure you can handle it. Using WBEMTEST, I pulled this:

instance of Win32_NetworkAdapterConfiguration
{
    Caption = "[00000010] Intel(R) 82579V Gigabit Network Connection";
    DatabasePath = "%SystemRoot%\\System32\\drivers\\etc";
    DefaultIPGateway = {"192.168.1.1"};
    Description = "Intel(R) 82579V Gigabit Network Connection";
    DHCPEnabled = TRUE;
    DHCPLeaseExpires = "20120808052416.000000-240";
    DHCPLeaseObtained = "20120807052416.000000-240";
    DHCPServer = "192.168.1.1";
    DNSDomainSuffixSearchOrder = {"*REDACTED*"};
    DNSEnabledForWINSResolution = FALSE;
    DNSHostName = "*REDACTED*";
    DNSServerSearchOrder = {"192.168.1.1"};
    DomainDNSRegistrationEnabled = FALSE;
    FullDNSRegistrationEnabled = TRUE;
    GatewayCostMetric = {0};
    Index = 10;
    InterfaceIndex = 12;
    IPAddress = {"192.168.1.100", "fe80::d53e:b369:629a:7f95"};
    IPConnectionMetric = 10;
    IPEnabled = TRUE;
    IPFilterSecurityEnabled = FALSE;
    IPSecPermitIPProtocols = {};
    IPSecPermitTCPPorts = {};
    IPSecPermitUDPPorts = {};
    IPSubnet = {"255.255.255.0", "64"};
    MACAddress = "*REDACTED*";
    ServiceName = "e1iexpress";
    SettingID = "{B102679F-36AD-4D80-9D3B-D18C7B8FBF24}";
    TcpipNetbiosOptions = 0;
    WINSEnableLMHostsLookup = TRUE;
    WINSScopeID = "";
};

IPSubnet[1] = IPv6 subnet;

Edit: Here's some code.

StringBuilder sBuilder = new StringBuilder();
ManagementObjectCollection objects = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration").Get();
foreach (ManagementObject mObject in objects)
{
    string description = (string)mObject["Description"];
    string[] addresses = (string[])mObject["IPAddress"];
    string[] subnets = (string[])mObject["IPSubnet"];
    if (addresses == null && subnets == null)
        continue;
    sBuilder.AppendLine(description);
    sBuilder.AppendLine(string.Empty.PadRight(description.Length,'-'));
    if (addresses != null)
    {
        sBuilder.Append("IPv4 Address: ");
        sBuilder.AppendLine(addresses[0]);
        if (addresses.Length > 1)
        {
            sBuilder.Append("IPv6 Address: ");
            sBuilder.AppendLine(addresses[1]);
        }
    }
    if (subnets != null)
    {
        sBuilder.Append("IPv4 Subnet:  ");
        sBuilder.AppendLine(subnets[0]);
        if (subnets.Length > 1)
        {
            sBuilder.Append("IPv6 Subnet:  ");
            sBuilder.AppendLine(subnets[1]);
        }
    }
    sBuilder.AppendLine();
    sBuilder.AppendLine();
}
string output = sBuilder.ToString().Trim();
MessageBox.Show(output);

and some output:

Intel(R) 82579V Gigabit Network Connection
------------------------------------------
IPv4 Address: 192.168.1.100
IPv6 Address: fe80::d53e:b369:629a:7f95
IPv4 Subnet:  255.255.255.0
IPv6 Subnet:  64

Edit: I'm just going to clarify in case somebody searches for this later. The second item isn't always the IPv6 value. IPv4 can have multiple addresses and subnets. Use Integer.TryParse on the IPSubnet array value to make sure it's an IPv6 subnet and/or use the last item.

like image 156
ShortFuse Avatar answered Sep 19 '22 16:09

ShortFuse


Parse the input stream of netsh with arguments:

interface ipv6 show route

Hope this helps!

like image 28
hanleyhansen Avatar answered Sep 19 '22 16:09

hanleyhansen