1

I'm trying to get the list of all DNS servers in c through the resolver library, but I can't get the list of ipv6 DNS servers, please help me.

OS: Debian GNU/Linux 10 (buster)

here is the test code:

#include <stdio.h>
#include <arpa/inet.h>
#include <resolv.h>

int main(int argc, char **argv)
{
    struct __res_state statp;
    char addr_str[80];
    if(res_ninit(&statp) < 0)
    {
        fprintf(stderr, "init resolver failed\n");
        return 1;
    }
    //ipv6 dns server
    for(int i =  0; i < statp._u._ext.nscount; i++)
    {
        if(statp._u._ext.nsaddrs[i]->sin6_family == AF_INET6)
        {
            if(inet_ntop(AF_INET6, &statp._u._ext.nsaddrs[i]->sin6_addr, addr_str, 80) != NULL)
            {
                printf("ipv6 dns server = %s\n", addr_str);
            }
        }
    }
    //ipv4 dns server
    for(int i =  0; i < statp.nscount; i++)
    {
        if(statp.nsaddr_list[i].sin_family == AF_INET)
        {
            if(inet_ntop(AF_INET, &statp.nsaddr_list[i].sin_addr, addr_str, 80) != NULL)
            {
                printf("ipv4 dns server = %s\n", addr_str);
            }
        }
    }
    res_nclose(&statp);
    return 0;
}

/etc/resolv.conf:

# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 2001:19f0:300:1704::6
nameserver 108.61.10.10

Debugging code in gdb:

(gdb) p statp._u._ext 
$2 = {nscount = 0, nsmap = {0, 77, 0}, nssocks = {-1, -1, -134331088}, nscount6 = 32767, nsinit = 0, 
  nsaddrs = {0x555555559630, 0x0, 0x555555555090 <_start>}, __glibc_reserved = {1219461217, 648608350}}
(gdb) p *statp._u._ext.nsaddrs[0]
$3 = {sin6_family = 10, sin6_port = 13568, sin6_flowinfo = 0, sin6_addr = {__in6_u = {
      __u6_addr8 = " \001\031\360\003\000\027\004\000\000\000\000\000\000\000\006", __u6_addr16 = {288, 
        61465, 3, 1047, 0, 0, 0, 1536}, __u6_addr32 = {4028170528, 68616195, 0, 100663296}}}, 
  sin6_scope_id = 0}

statp._u._ext.nscount is 0, but statp._u._ext.nsaddrs[0] is the correct ipv6 dns server sockaddr.

Pejman Kheyri
  • 4,044
  • 9
  • 32
  • 39
shenw
  • 91
  • 7
  • Is there something wrong with the code presented? Is the debugging output anyhow relevant? – KamilCuk Mar 01 '21 at 23:28
  • What glibc version are you using? [This looks like the calculation](https://github.com/psi-im/iris/blob/master/src/jdns/src/jdns/jdns_sys.c#L803). Looks like in `__GLIBC_` you just iterate up to `MAXNS` and check if `._u._ext.nsaddrs[i]` is not NULL. – KamilCuk Mar 01 '21 at 23:35
  • glibc version is 2.28-10, and check if ._u._ext.nsaddrs[i] is not NULL may worked, I'll try it, thanks. – shenw Mar 02 '21 at 02:30
  • @KamilCuk After I changed the test code `for(int i = 0; i < statp._u._ext.nscount; i++)` to `for(int i = 0; i < MAXNS && statp._u._ext.nsaddrs[i] != NULL; i++)`, it worked, thank you so much. – shenw Mar 02 '21 at 02:52
  • No, it's not `for (;...statp._u._ext.nsaddrs[i] != NULL;)` it's `for (... MAXNS ...) { if (statp._u._ext.nsaddrs[i] == NULL) continue; ... }`. Don't iterate until NULL, just omit elements with NULL. – KamilCuk Mar 02 '21 at 09:09

0 Answers0