Extracting TTL value of a DNS A record

1.9k Views Asked by At

I am doing some dns stuff and I require to do an A record lookup for an SRV and extract ttl and ip address from it:

I was able to extract ip using the following code, but how do I extract TTL?

 l = res_query(argv[1], ns_c_any, ns_t_a, nsbuf, sizeof(nsbuf));
    if (l < 0)
    {
      perror(argv[1]);
    }
    ns_initparse(nsbuf, l, &msg);
    l = ns_msg_count(msg, ns_s_an);
    for (i = 0; i < l; i++)
    {
      ns_parserr(&msg, ns_s_an, 0, &rr);
      ns_sprintrr(&msg, &rr, NULL, NULL, dispbuf, sizeof(dispbuf));
      printf("\t%s \n", dispbuf);
      inet_ntop(AF_INET, ns_rr_rdata(rr), debuf, sizeof(debuf));
      printf("\t%s \n", debuf);
    }

Output:

./a.out sip-anycast-1.voice.google.com
        sip-anycast-1.voice.google.com.  21h55m46s IN A  216.239.32.1
        216.239.32.1
1

There are 1 best solutions below

0
On BEST ANSWER

Following mostly your code, you can retrieve the IP and TTL in this way (I fixed up your ns_parserr() call so that it iterates through multiple entries in the response properly):

    l = res_query(argv[1], ns_c_any, ns_t_a, nsbuf, sizeof(nsbuf));
    if (l < 0) {
        perror(argv[1]);
        exit(EXIT_FAILURE);
    }
    ns_initparse(nsbuf, l, &msg);
    c = ns_msg_count(msg, ns_s_an);
    for (i = 0; i < c; ++i) {
        ns_parserr(&msg, ns_s_an, i, &rr);
        ns_sprintrr(&msg, &rr, NULL, NULL, dispbuf, sizeof(dispbuf));
        printf("%s\n", dispbuf);
        if (ns_rr_type(rr) == ns_t_a) {
            uint8_t ip[4];
            uint32_t ttl = ns_rr_ttl(rr);
            memcpy(ip, ns_rr_rdata(rr), sizeof(ip));
            printf("ip: %u.%u.%u.%u\n", ip[0], ip[1], ip[2], ip[3]);
            printf("ttl: %u\n", ttl);
        }
    }

It produces the following output:

$ ./a.out myserver.mydomain.com
myserver.mydomain.com.  1H IN A         172.16.1.21
ip: 172.16.1.21
ttl: 3600

I was not able to find very much documentation on the libresolv library, and it seems that the shared library libresolv.so does not include all the symbols needed to link the program. So, I had to compile the program like this:

$ gcc test_resolv.c -static -lresolv -dynamic