簡體   English   中英

gcc / cygwin如何獲取DNS服務器?

[英]How does gcc/cygwin get the DNS server?

我有一些用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);
        }
    }

在unix / linux上工作,但在cygwin上返回nscount = -1。 使用cygwin / gcc時是否有一些技巧可以獲取DNS服務器?

res_init不一定填充_res.nsaddr_list 而是在Windows上,它指示解析器使用DnsQuery_A除非您具有resolv.conf文件,在這種情況下,將使用該文件中的DNS服務器。

此處查看源文件minires.cminires-os-if.c

如果您需要了解DNS服務器,則可能必須使用DnsQueryConfigGetNetworkParams

注意: _res未記錄,因此不應使用。

UPDATE 顯然,“更新”(約2010及更高版本)的cygwin的版本做填入_res.nsaddr_list ,通過調用get_dns_info然后get_registry_dns 您可能要確保擁有最新的cygwin,並且如果問題仍然存在,請嘗試使用調試版本並跟蹤對上述功能的調用。

更新2不, _res未填充,我的錯。

nm所言 ,在Cygwin上,如果使用Windows解析程序,則res_init()不會填充_res.nsaddr_list 如果/etc/resolv.conf不存在,或/etc/resolv.conf包含options osquery ,它將使用Windows解析器。

在我看來,這是一個Cygwin錯誤-返回負nscount是偽造的-但盡管如此,我們仍堅持解決它。

解決方案是像Cygwin一樣調用GetNetworkParams() -這是我作為后備的做法:

#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);
}

您需要針對GetNetworkParams()函數針對-liphlpapi進行鏈接。

這僅采用第一個Windows DNS地址,但是如果需要其余的Windows DNS地址,則可以遵循GetNetworkParams()返回的鏈接列表。 GetNetworkParams()僅返回IPv4地址,如果計算機配置了IPv6 DNS服務器地址,我不確定您應該怎么做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM