列出适配器地址和 mask/prefix,包括 IPv4 和 IPv6 (GetAdaptersAddresses)

list adapters addresses and mask/prefix, both IPv4 and IPv6 (GetAdaptersAddresses)

我的任务是列出本地计算机上的所有单播接口(通过网络掩码 (IPv4) 或前缀长度 (IPv6) 的 IP 地址和子网)。作为 win32 的新手 API,我正在阅读 GetAdaptersAddress docs。有一个例子很清楚:

此刻,我有IP地址。

netmask/prefix怎么样?这似乎就是 PIP_ADAPTER_PREFIX_XP(及其 SOCKET_ADDRESS Address 字段)的意义所在。这是另一个链表,可从 PIP_ADAPTER_ADDRESSES->FirstPrefix.

访问

毫无帮助,the docs state 前缀的顺序可能与地址不同:

In addition, the linked IP_ADAPTER_UNICAST_ADDRESS structures pointed to by the FirstUnicastAddress member and the linked IP_ADAPTER_PREFIX structures pointed to by the FirstPrefix member are maintained as separate internal linked lists by the operating system. As a result, the order of linked IP_ADAPTER_UNICAST_ADDRESS structures pointed to by the FirstUnicastAddress member does not have any relationship with the order of linked IP_ADAPTER_PREFIX structures pointed to by the FirstPrefix member.

有什么解决办法?我是否漏掉了一些明显的东西?

一些代码(例如zeroMQ)只为每个适配器使用第一个单播地址和第一个前缀。这种方法安全吗?我会错过界面吗?

IP_ADAPTER_ADDRESSES::FirstPrefix 字段为您提供分配给适配器的 subnets/prefixes 列表,但正如文档所述,GetAdaptersAddresses() 不会告诉您哪个特定 IP 地址适配器对应于 subnet/prefix。因此,要确定每个 IP 地址的特定 subnet/prefix,您必须查看 IP_ADAPTER_ADDRESSES::FirstUnicastAddresses 列表中的各个条目。

在 Windows Vista 及更高版本中,IP_ADAPTER_UNICAST_ADDRESS::OnLinkPrefixLength 字段提供 AF_INET 地址的 IPv4 子网掩码长度,以及 AF_INET6 地址。对于 IPv4,如果需要实际的子网掩码,可以将长度传递给 ConvertLengthToIpv4Mask() 函数。

在 Windows XP 上,OnLinkPrefixLength 字段不存在。幸运的是,AF_INET 地址的 IPv4 子网掩码可以通过调用 GetIpAddrTable() 函数然后在 table 中查找 IP 地址(在 MIB_IPADDRROW::dwAddr 字段中 - 子网掩码将在 MIB_IPADDRROW::dwMask 字段中)。

我不知道如何在 XP 上获取 AF_INET6 地址的 IPv6 前缀长度,如果你需要的话。