I have some code I'm writing under cygwin (using GCC) that successfully uses gethostbyname(); however when I try to use the resolver directly to retrieve the IP address of the DNS server it fails (all entries in nsaddr_list[] are null and nscount is -1).
If gethostbyname() is working, then obviously it is able to connect to the DNS server.
This code...
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);
}
}
works on unix/linux, but returns nscount=-1 on cygwin. Is there some trick to getting the DNS server when using cygwin/gcc?
As n.m. says, on Cygwin
res_init()
does not populate_res.nsaddr_list
if it is using the Windows resolver. It uses the Windows resolver if either/etc/resolv.conf
does not exist, or/etc/resolv.conf
containsoptions osquery
.In my opinion this is a Cygwin bug - returning a negative
nscount
is bogus - but nonetheless we are stuck with working around it.The solution is to call
GetNetworkParams()
just as Cygwin does itself - here's what I'm doing as a fallback:You need to link against
-liphlpapi
for theGetNetworkParams()
function.This only takes the first Windows DNS address, but if you want the rest of them you can follow the linked list that
GetNetworkParams()
returns.GetNetworkParams()
only returns IPv4 addresses, I'm not sure what you're supposed to do if the machine has an IPv6 DNS server address configured.