how to retrieve IP v6 subnet mask length

2019-04-21 06:56发布

问题:

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:

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.

回答1:

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.



回答2:

Parse the input stream of netsh with arguments:

interface ipv6 show route

Hope this helps!