使用 GetAdaptersAddresses() 获取 IPv6 DNS 服务器地址
Get IPv6 DNS Server Addresses using GetAdaptersAddresses()
我试图在 C++ 中获取 DNS 服务器 IPv6 地址,我发现这篇文章展示了如何使用 GetAdaptersAddresses() 获取信息:GetAdaptersAddresses function (iphlpapi.h)。本文还提供示例代码。通过说明,它说 IP_ADAPTER_ADDRESSES 结构的 FirstDnsServerAddress 成员是指向 IP_ADAPTER_DNS_SERVER_ADDRESS 结构的链表的指针。在IP_ADAPTER_DNS_SERVER_ADDRESS结构中使用了SOCKET_ADDRESS结构。 lpSockaddr 成员指向的 SOCKADDR 结构因所选的协议或地址族而异。例如,sockaddr_in6 结构用于 IPv6 套接字地址,而 sockaddr_in4 结构用于 IPv4 套接字地址。根据这些说明,我修改了示例代码以获取 IP 地址,如下所示:
pDnServer = pCurrAddresses->FirstDnsServerAddress;
if (pDnServer) {
for (i = 0; pDnServer != NULL; i++) {
switch (pDnServer->Address.lpSockaddr->sa_family) {
case AF_INET:
if (pDnServer->Address.lpSockaddr) {
char* ipv4_addrstr = (char*)malloc(INET_ADDRSTRLEN * sizeof(char));
inet_ntop(AF_INET, (struct sockaddr_in*)pDnServer->Address.lpSockaddr->sa_data, ipv4_addrstr, INET_ADDRSTRLEN);
printf("IPv4 Address: %s\n", ipv4_addrstr);
free(ipv4_addrstr);
}
break;
case AF_INET6:
if (pDnServer->Address.lpSockaddr) {
char* ipv6_addrstr = (char*)malloc(INET6_ADDRSTRLEN * sizeof(char));
memset(ipv6_addrstr, 0, sizeof(char) * INET6_ADDRSTRLEN);
inet_ntop(AF_INET6, (struct sockaddr_in6*)pDnServer->Address.lpSockaddr->sa_data, ipv6_addrstr, INET6_ADDRSTRLEN);
printf("IPv6 Address: %s\n", ipv6_addrstr);
free(ipv6_addrstr);
}
break;
default:
printf("\tAddress Family Name: Unknown\n");
break;
} // End switch
pDnServer = pDnServer->Next;
} // End for loop
printf("\tNumber of DNS Server Addresses: %d\n", i);
}
代码正确获取 IPv4 DNS 服务器地址。但是,代码返回不正确的 IPv6 地址。例如,Google DNS 服务器地址是 2001:4860:4860::8888 和 2001:4860:4860::8844 .如果我输入这些地址作为我的 IPv4 DNS 服务器地址,代码 returns ::2001:4860:4860:0:0.
有人知道我在这段代码中可能有什么问题吗?
您向 inet_ntop
传递了错误的数据。您应该根据协议传递 sin_addr
或 sin6_addr
成员。
inet_ntop(AF_INET, &((struct sockaddr_in*)pDnServer->Address.lpSockaddr)->sin_addr, ipv4_addrstr, INET_ADDRSTRLEN);
inet_ntop(AF_INET6, &((struct sockaddr_in6*)pDnServer->Address.lpSockaddr)->sin6_addr, ipv6_addrstr, INET6_ADDRSTRLEN);
我试图在 C++ 中获取 DNS 服务器 IPv6 地址,我发现这篇文章展示了如何使用 GetAdaptersAddresses() 获取信息:GetAdaptersAddresses function (iphlpapi.h)。本文还提供示例代码。通过说明,它说 IP_ADAPTER_ADDRESSES 结构的 FirstDnsServerAddress 成员是指向 IP_ADAPTER_DNS_SERVER_ADDRESS 结构的链表的指针。在IP_ADAPTER_DNS_SERVER_ADDRESS结构中使用了SOCKET_ADDRESS结构。 lpSockaddr 成员指向的 SOCKADDR 结构因所选的协议或地址族而异。例如,sockaddr_in6 结构用于 IPv6 套接字地址,而 sockaddr_in4 结构用于 IPv4 套接字地址。根据这些说明,我修改了示例代码以获取 IP 地址,如下所示:
pDnServer = pCurrAddresses->FirstDnsServerAddress;
if (pDnServer) {
for (i = 0; pDnServer != NULL; i++) {
switch (pDnServer->Address.lpSockaddr->sa_family) {
case AF_INET:
if (pDnServer->Address.lpSockaddr) {
char* ipv4_addrstr = (char*)malloc(INET_ADDRSTRLEN * sizeof(char));
inet_ntop(AF_INET, (struct sockaddr_in*)pDnServer->Address.lpSockaddr->sa_data, ipv4_addrstr, INET_ADDRSTRLEN);
printf("IPv4 Address: %s\n", ipv4_addrstr);
free(ipv4_addrstr);
}
break;
case AF_INET6:
if (pDnServer->Address.lpSockaddr) {
char* ipv6_addrstr = (char*)malloc(INET6_ADDRSTRLEN * sizeof(char));
memset(ipv6_addrstr, 0, sizeof(char) * INET6_ADDRSTRLEN);
inet_ntop(AF_INET6, (struct sockaddr_in6*)pDnServer->Address.lpSockaddr->sa_data, ipv6_addrstr, INET6_ADDRSTRLEN);
printf("IPv6 Address: %s\n", ipv6_addrstr);
free(ipv6_addrstr);
}
break;
default:
printf("\tAddress Family Name: Unknown\n");
break;
} // End switch
pDnServer = pDnServer->Next;
} // End for loop
printf("\tNumber of DNS Server Addresses: %d\n", i);
}
代码正确获取 IPv4 DNS 服务器地址。但是,代码返回不正确的 IPv6 地址。例如,Google DNS 服务器地址是 2001:4860:4860::8888 和 2001:4860:4860::8844 .如果我输入这些地址作为我的 IPv4 DNS 服务器地址,代码 returns ::2001:4860:4860:0:0.
有人知道我在这段代码中可能有什么问题吗?
您向 inet_ntop
传递了错误的数据。您应该根据协议传递 sin_addr
或 sin6_addr
成员。
inet_ntop(AF_INET, &((struct sockaddr_in*)pDnServer->Address.lpSockaddr)->sin_addr, ipv4_addrstr, INET_ADDRSTRLEN);
inet_ntop(AF_INET6, &((struct sockaddr_in6*)pDnServer->Address.lpSockaddr)->sin6_addr, ipv6_addrstr, INET6_ADDRSTRLEN);