如何检索 IP v6 子网掩码长度

Posted

技术标签:

【中文标题】如何检索 IP v6 子网掩码长度【英文标题】:how to retrieve IP v6 subnet mask length 【发布时间】:2012-08-03 18:17:08 【问题描述】:

我正在编写一个应用程序,它必须在 Windows 7 机器上获取网络适配器配置,就像在 Windows 网络适配器配置面板中所做的那样:

到目前为止,我几乎可以从NetworkInterface.GetAllNetworkInterfaces() 获得所需的所有信息除了子网前缀长度

我知道可以通过 OnLinkPrefixLength 从 C++ struc PMIB_UNICASTIPADDRESS_TABLE 检索它,但我正试图留在 .net 中。

我还查看了Win32_NetworkAdapterConfiguration WMI 类,但它似乎只返回 IP v4 子网掩码。

我也知道一些信息(据我所知不是前缀长度)在注册表中:

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

我还使用 SysInternals ProcessMon 在保存网络适配器设置时尝试获取任何有用的信息,但什么也没找到...

那么,是否有任何干净的 .NET 方法来获取此值? (从注册表中获取它不会有问题)

编辑:网关

这与实际问题无关,但对于那些需要检索整个网络适配器 IPv6 配置的人来说,IPInterfaceProperties.GatewayAdresses 属性仅支持 IPv4 网关。正如下面的答案 cmets 中提到的,在 .NET framework 4.5 之前获取整个信息的唯一方法是调用 WMI。

【问题讨论】:

这可能有助于引导您,不确定是否会,但我能够从注册表中提取信息。看看这是否有帮助:***.com/questions/1537908/… 就像我说的,如果我能找到有用的东西,我已经在注册表中查看了,但我没有...... :( 好吧,祝你好运,我想我会插话的。 另外,我相当确定 99.9% 的 ipv6 子网的前缀长度为 /64。 @ jskiles1:好吧,我不是 IP v6 也不是网络专家,我明白,在阅读了 RFC 5375 IPv6 Addressing Considerations 之后,不推荐使用 64 以外的其他值。问题是,我必须开发一个提供与 Windows 相同配置功能的产品! 【参考方案1】:

您可以使用 Win32_NetworkAdapterConfiguration 执行此操作。你可能忽略了它。

IPSubnet 将返回一个字符串数组。使用第二个值。 我没有时间编写一些 C# 代码,但我相信你可以处理它。使用 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 可以有多个地址和子网。对 IPSubnet 数组值使用 Integer.TryParse 以确保它是 IPv6 子网和/或使用最后一项。

【讨论】:

好吧,我确实忽略了 WMI 类。将尝试这个tonigth并将其标记为答案。唯一的缺点是 WMI 并不是一个性能标志,第一次调用需要很长时间...... 好吧,我写这篇文章并没有考虑到速度或搜索特定对象。 Foreach 命令的速度效率不是很高。此外,在我的 WMI 搜索中使用 WHERE 语句会将其范围缩小到正确的网络接口。无论如何,在我的机器上,获取所有对象需要 5 毫秒,遍历每个网络连接(大约 15 个)需要 32 毫秒。我认为您不必担心性能。 提醒一下,一个设备可以有多个 IPv4 地址和多个 IPv4 子网。不保证 IPSubnet 数组中的第二项是 IPv6 子网。您可能应该在子网上执行 Integer.TryParse 和/或使用数组中的最后一项。 .NET 框架 4.5 中似乎有一些修复,IPInterfaceProperties.GatewayAdresses 与 IPv6 不兼容,只会返回 IPv4 网关...... IPv6 看起来像一个半实现的功能......所以目前,我们将从 WMI 获取缺失的信息 另外,请注意 WMI 不会提供有关断开设备的信息!【参考方案2】:

用参数解析netsh的输入流:

interface ipv6 show route

希望这会有所帮助!

【讨论】:

它在 IP 地址的末尾显示 IP v6 前缀长度,这是向前迈出的一步……如果我能从哪里获取该信息并从中访问它,将检查进程/文件监视器.NET 不解析 netsh 输出!

以上是关于如何检索 IP v6 子网掩码长度的主要内容,如果未能解决你的问题,请参考以下文章

子网掩码长度是啥?怎么看?

可变长度子网掩码(VLSM)在子网划分中的应用

IP地址子网掩码网关的关系

IP地址子网掩码网关的关系

子网掩码是啥?

3.子网掩码详解