gcc/cygwin如何获得DNS服务器?

Ed.*_*Ed. 8 c dns networking cygwin libresolv

我有一些代码我在cygwin(使用GCC)下编写成功使用gethostbyname(); 但是当我尝试直接使用解析器来检索DNS服务器的IP地址时,它失败了(nsaddr_list []中的所有条目都为null,nscount为-1​​).如果gethostbyname()正在工作,那么显然它能够连接到DNS服务器.
这段代码......

    if (res_init() == -1) {
        fprintf(stderr,"res_init() failed\n");
        exit(1);
    }

    if (_res.nscount <= 0) {
        fprintf(stderr,"nscount = %d\n",_res.nscount);
    }
    else {
        for(i=0;i<_res.nscount;i++) {
            fprintf(stderr, "dnssrvr: %d.%d.%d.%d\n",
                (_res.nsaddr_list[i].sin_addr.s_addr & 0xff) >> 0,
                (_res.nsaddr_list[i].sin_addr.s_addr & 0xff00) >> 8,
                (_res.nsaddr_list[i].sin_addr.s_addr & 0xff0000) >> 16,
                (_res.nsaddr_list[i].sin_addr.s_addr & 0xff000000) >> 24);
        }
    }
Run Code Online (Sandbox Code Playgroud)

适用于unix/linux,但在cygwin上返回nscount = -1.使用cygwin/gcc时获取DNS服务器有什么技巧吗?

caf*_*caf 2

正如nm 所说,如果使用 Windows 解析器,则Cygwin 上res_init()不会填充。_res.nsaddr_list如果/etc/resolv.conf不存在或/etc/resolv.conf包含options osquery.

在我看来,这是一个 Cygwin 错误 - 返回负值nscount是伪造的 - 但尽管如此,我们仍坚持解决它。

解决方案是GetNetworkParams()像 Cygwin 本身一样进行调用 - 这是我正在做的后备措施:

#include <windows.h>
#include <iphlpapi.h>
#include <netinet/in.h>
#include <arpa/inet.h>

if (_res.nscount < 0)
{
    ULONG buflen = 0;
    FIXED_INFO *buf = NULL;

    if (GetNetworkParams(NULL, &buflen) == ERROR_BUFFER_OVERFLOW)
        buf = malloc(buflen);

    if (buf && GetNetworkParams(buf, &buflen) == NO_ERROR)
    {
        _res.nscount = 1;
        _res.nsaddr_list[0].sin_family = AF_INET;
        _res.nsaddr_list[0].sin_addr.s_addr = inet_addr(buf->DnsServerList.IpAddress.String);
        _res.nsaddr_list[0].sin_port = htons(53);
    }

    free(buf);
}
Run Code Online (Sandbox Code Playgroud)

您需要链接-liphlpapi该GetNetworkParams()功能。

这只需要第一个 Windows DNS 地址,但如果您想要其余的,可以按照GetNetworkParams()返回的链接列表进行操作。 GetNetworkParams()只返回 IPv4 地址,我不确定如果机器配置了 IPv6 DNS 服务器地址,您应该做什么。