How to query a server and get the MX, A, NS records

6.2k views Asked by At

I'm trying to get the A, MX and NS A server record as follows:

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

On request receive a lot of the same, that is, the same A records. The same with the NS records. What am I doing wrong? Example :

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.

Please help.

2

There are 2 answers

0
Code Painters On BEST ANSWER

In this call:

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

The third argument is the index of the record you want to retrieve. So in your case it should be:

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

Just tried your code with that minor fix, and it works as expected:

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.
0
Gilles Olivier Vollant On

With Ubuntu 20.04 and more,

 res_query(argv[1], ns_c_any, ns_t_mx, nsbuf, sizeof(nsbuf));

fail. Please replace ns_c_any by ns_c_in

 res_query(argv[1], ns_c_in, ns_t_mx, nsbuf, sizeof(nsbuf));