c - 如何查询服务器并获取 MX、A、NS 记录

标签 c sockets unix dns libresolv

我正在尝试获取 A、MX 和 NS A 服务器记录,如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <resolv.h>
#include <netdb.h>

#define N 4096

int main (int argc, char *argv[])
{
    u_char nsbuf[N];
    char dispbuf[N];
    ns_msg msg;
    ns_rr rr;
    int i, l;

    if (argc < 2) {
        printf ("Usage: %s <domain>\n", argv[0]);
        exit (1);
    }

    // HEADER
    printf("Domain : %s\n", argv[1]);
    // ------

    // A RECORD
    printf("A records : \n");
    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);
    }
    //------------


    // MX RECORD
    printf("MX records : \n");
    l = res_query(argv[1], ns_c_any, ns_t_mx, nsbuf, sizeof(nsbuf));
    if (l < 0)
    {
      perror(argv[1]);
    }
    else
    {
#ifdef USE_PQUERY
      /* this will give lots of detailed info on the request and reply */
      res_pquery(&_res, nsbuf, l, stdout);
#else
      /* just grab the MX answer info */
      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, i, &rr);
        ns_sprintrr(&msg, &rr, NULL, NULL, dispbuf, sizeof(dispbuf));
        printf ("\t%s\n", dispbuf);
      }
#endif
    }
    // ---------

    // NS RECORD
    printf("NS records : \n");
    l = res_query(argv[1], ns_c_any, ns_t_ns, 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);
    }
    // ---------
    return 0;
}

根据请求收到很多相同的,即相同的 A 记录。与 NS 记录相同。我究竟做错了什么? 示例:

Domain : mail.ru
A records :
        mail.ru.                22S IN A        94.100.191.207
        mail.ru.                22S IN A        94.100.191.207
        mail.ru.                22S IN A        94.100.191.207
        mail.ru.                22S IN A        94.100.191.207
        mail.ru.                22S IN A        94.100.191.207
        mail.ru.                22S IN A        94.100.191.207
        mail.ru.                22S IN A        94.100.191.207
        mail.ru.                22S IN A        94.100.191.207
        mail.ru.                22S IN A        94.100.191.207
        mail.ru.                22S IN A        94.100.191.207
        mail.ru.                22S IN A        94.100.191.207
        mail.ru.                22S IN A        94.100.191.207
        mail.ru.                22S IN A        94.100.191.207
        mail.ru.                22S IN A        94.100.191.207
        mail.ru.                22S IN A        94.100.191.207
        mail.ru.                22S IN A        94.100.191.207
        mail.ru.                22S IN A        94.100.191.207
        mail.ru.                22S IN A        94.100.191.207
        mail.ru.                22S IN A        94.100.191.207
        mail.ru.                22S IN A        94.100.191.207
MX records :
        mail.ru.                1m57s IN MX     10 mxs.mail.ru.
NS records :
        mail.ru.                1m50s IN NS     ns.mail.ru.
        mail.ru.                1m50s IN NS     ns.mail.ru.
        mail.ru.                1m50s IN NS     ns.mail.ru.
        mail.ru.                1m50s IN NS     ns.mail.ru.
        mail.ru.                1m50s IN NS     ns.mail.ru.
        mail.ru.                1m50s IN NS     ns.mail.ru.

请帮忙。

最佳答案

在这个调用中:

  ns_parserr(&msg, ns_s_an, 0, &rr);

第三个参数是要检索的记录的索引。所以在你的情况下应该是:

  ns_parserr(&msg, ns_s_an, i, &rr);

刚刚尝试了您的代码并进行了较小的修复,它按预期工作:

Domain : mail.ru
A records : 
    mail.ru.        5S IN A     94.100.191.248 
    mail.ru.        5S IN A     94.100.191.249 
    mail.ru.        5S IN A     94.100.191.250 
    mail.ru.        5S IN A     94.100.191.201 
    mail.ru.        5S IN A     94.100.191.202 
    mail.ru.        5S IN A     94.100.191.203 
    mail.ru.        5S IN A     94.100.191.204 
    mail.ru.        5S IN A     94.100.191.205 
    mail.ru.        5S IN A     94.100.191.206 
    mail.ru.        5S IN A     94.100.191.207 
    mail.ru.        5S IN A     94.100.191.208 
    mail.ru.        5S IN A     94.100.191.209 
    mail.ru.        5S IN A     94.100.191.210 
    mail.ru.        5S IN A     94.100.191.241 
    mail.ru.        5S IN A     94.100.191.242 
    mail.ru.        5S IN A     94.100.191.243 
    mail.ru.        5S IN A     94.100.191.244 
    mail.ru.        5S IN A     94.100.191.245 
    mail.ru.        5S IN A     94.100.191.246 
    mail.ru.        5S IN A     94.100.191.247 
MX records : 
    mail.ru.        7m14s IN MX 10 mxs.mail.ru.
NS records : 
    mail.ru.        3m35s IN NS ns2.mail.ru. 
    mail.ru.        3m35s IN NS ns.mail.ru. 
    mail.ru.        3m35s IN NS ns4.mail.ru. 
    mail.ru.        3m35s IN NS ns5.mail.ru. 
    mail.ru.        3m35s IN NS ns1.mail.ru. 
    mail.ru.        3m35s IN NS ns3.mail.ru.

关于c - 如何查询服务器并获取 MX、A、NS 记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15476717/

相关文章:

c - 奇怪的控制流程顺序

c - 如何使用 WinAPI 作为另一个用户启动通用应用程序?

c++ - OpenSSL 将消息拆分为两条记录

java - Android中如何处理OutOfMemoryError

c++ - Redis客户端命令错误

linux - SSH 远程命令退出代码

unix - 对 stdin 和 stdout 使用相同的文件进行重定向

c - 从c中的数组中删除偶数

c - 需要解释一下这段代码是如何工作的

php - PDOException : Packets out of order.预期收到0。1.数据包大小= 23