使用 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::88882001:4860:4860::8844 .如果我输入这些地址作为我的 IPv4 DNS 服务器地址,代码 returns ::2001:4860:4860:0:0.

有人知道我在这段代码中可能有什么问题吗?

您向 inet_ntop 传递了错误的数据。您应该根据协议传递 sin_addrsin6_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);