2

我正在做一些 dns 的事情,我需要对 SRV 进行 A 记录查找并从中提取 ttl 和 ip 地址:

我可以使用以下代码提取 ip,但是如何提取 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);
    }

输出:

./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
4

1 回答 1

3

主要遵循您的代码,您可以通过这种方式检索 IP 和 TTL(我修复了您的ns_parserr()调用,以便它正确地遍历响应中的多个条目):

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

它产生以下输出:

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

我无法在该libresolv库上找到很多文档,而且共享库libresolv.so似乎不包含链接程序所需的所有符号。所以,我不得不像这样编译程序:

$ gcc test_resolv.c -static -lresolv -dynamic
于 2013-09-12T21:06:51.373 回答