Как получить длину маски подсети IP v6

Я кодирую приложение, которое должно получить конфигурацию сетевых адаптеров на компьютере под управлением Windows 7, как это было сделано на панели конфигурации сетевых адаптеров Windows:

enter image description here

До сих пор я могу получить практически всю необходимую мне информацию из NetworkInterface.GetAllNetworkInterfaces() ИСКЛЮЧИТЬ длину префикса подсети.

Я знаю, что его можно извлечь из С++ struc PMIB_UNICASTIPADDRESS_TABLE через OnLinkPrefixLength, но я пытаюсь остаться в .net.

Я также рассмотрел класс Win32_NetworkAdapterConfiguration WMI, но он возвращает только маску подсети IP v4.

Я также знаю, что некоторая информация (а не длина префикса, насколько я знаю) находится в реестре:

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

Я также использовал SysInternals ProcessMon, чтобы попытаться получить что-нибудь полезное при сохранении настроек сетевого адаптера, но ничего не нашел...

Итак, есть ли какой-либо чистый способ .NET, чтобы получить это значение? (получение его из реестра не будет проблемой)

РЕДАКТИРОВАТЬ: Шлюзы

Это не касается фактического вопроса, но для тех, кому необходимо получить всю конфигурацию IPv6 для сетевого адаптера, свойство IPInterfaceProperties.GatewayAdresses поддерживает только шлюзы IPv4. Как упоминалось в комментариях ниже, единственный способ получить всю информацию до тех пор, пока .NET framework 4.5 не вызовет WMI.

Ответ 1

Вы можете сделать это с помощью Win32_NetworkAdapterConfiguration. Возможно, вы его не заметили.

IPSubnet вернет массив строк. Используйте второе значение. У меня не было времени взломать код С#, но я уверен, что вы справитесь с этим. Используя WBEMTEST, я вытащил это:

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;

Изменить: здесь некоторый код.

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);

и некоторый вывод:

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

Изменить: я просто хочу уточнить, если кто-то ищет это позже. Второй элемент - это не всегда значение IPv6. IPv4 может иметь несколько адресов и подсетей. Используйте Integer.TryParse для значения массива IPSubnet, чтобы убедиться, что он является подсети IPv6 и/или использует последний элемент.

Ответ 2

Разберите входной поток netsh с аргументами:

interface ipv6 show route

Надеюсь, это поможет!