列出适配器地址和 mask/prefix,包括 IPv4 和 IPv6 (GetAdaptersAddresses)
list adapters addresses and mask/prefix, both IPv4 and IPv6 (GetAdaptersAddresses)
我的任务是列出本地计算机上的所有单播接口(通过网络掩码 (IPv4) 或前缀长度 (IPv6) 的 IP 地址和子网)。作为 win32 的新手 API,我正在阅读 GetAdaptersAddress docs。有一个例子很清楚:
- 调用
GetAdaptersAddresses
增加缓冲区大小,直到结果适合分配的内存块
- 遍历 PIP_ADAPTER_ADDRESSES (
pCurrAddresses
) 的返回链表:
- 遍历 PIP_ADAPTER_UNICAST_ADDRESS*
pCurrAddresses->FirstUnicastAddresses
linked list to retrieve all IP addresses (SOCKET_ADDRESS and its LPSOCKADDR Address->lpSockAddr
成员);它是 sockaddr_in*
或 sockaddr_in6*
取决于 lpSockAddr.sa_family
(AF_INET
或 AF_INET6
)
此刻,我有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 前缀长度,如果你需要的话。
我的任务是列出本地计算机上的所有单播接口(通过网络掩码 (IPv4) 或前缀长度 (IPv6) 的 IP 地址和子网)。作为 win32 的新手 API,我正在阅读 GetAdaptersAddress docs。有一个例子很清楚:
- 调用
GetAdaptersAddresses
增加缓冲区大小,直到结果适合分配的内存块 - 遍历 PIP_ADAPTER_ADDRESSES (
pCurrAddresses
) 的返回链表:- 遍历 PIP_ADAPTER_UNICAST_ADDRESS*
pCurrAddresses->FirstUnicastAddresses
linked list to retrieve all IP addresses (SOCKET_ADDRESS and its LPSOCKADDRAddress->lpSockAddr
成员);它是sockaddr_in*
或sockaddr_in6*
取决于lpSockAddr.sa_family
(AF_INET
或AF_INET6
)
- 遍历 PIP_ADAPTER_UNICAST_ADDRESS*
此刻,我有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 前缀长度,如果你需要的话。