Hi there,
I'm trying to do an MX type lookup using getaddrinfo(), but I can't work out how to change the lookup type to MX from the standard A - can anybody tell me how to do this?
Thanks very much
John G
Hi there,
I'm trying to do an MX type lookup using getaddrinfo(), but I can't work out how to change the lookup type to MX from the standard A - can anybody tell me how to do this?
Thanks very much
John G
You cannot use getaddrinfo() to look up MX records. By design, it only queries A (or AAAA if configured) records.
Thanks both very much!
I found a helpful O'Rielly chapter about res_query et al here and followed it quite well, up until the last bit where we uncompress a domain name. When I uncompress it, I appear to get garbage.
The program below is a test I'm using to look for an MX record of a domain specified on the command-line. Basically I'm looking for anything I can use as the hostname of a mail server so I can open a port and start an SMTP session.
It doesn't output the name directly (as the names I get are unprintable!) but it outputs the hex value of each character in the uncompressed name.
I'm compiling with
gcc -std=gnu99 -Wall -Werror get-host.c -o get-host -lbind9
and here's a sample of my output:
Got answer of length: 219
Got 5 answers
name:
0x2e, 0x0, 0xffffffb5, 0xffffff83, 0xffffffb7, 0xfffffff8, 0xffffff98, 0xffffffe6, 0xffffffbf, 0x17, 0x0, 0x0, 0x0, 0xffffffda, 0xffffff9e, 0xffffffe4, 0x0, 0xffffffe0, 0x47, 0xc, 0xffffffb7, 0x57, 0xffffffdb, 0xffffff93, 0x1c, 0x17, 0x0, 0x0, 0x0, 0x0,
name:
0x2e, 0x0, 0xffffffb5, 0xffffff83, 0xffffffb7, 0xfffffff8, 0xffffff98, 0xffffffe6, 0xffffffbf, 0x17, 0x0, 0x0, 0x0, 0xffffffda, 0xffffff9e, 0xffffffe4, 0x0, 0xffffffe0, 0x47, 0xc, 0xffffffb7, 0x57, 0xffffffdb, 0xffffff93, 0x1c, 0x17, 0x0, 0x0, 0x0, 0x0,
name:
0x2e, 0x0, 0xffffffb5, 0xffffff83, 0xffffffb7, 0xfffffff8, 0xffffff98, 0xffffffe6, 0xffffffbf, 0x17, 0x0, 0x0, 0x0, 0xffffffda, 0xffffff9e, 0xffffffe4, 0x0, 0xffffffe0, 0x47, 0xc, 0xffffffb7, 0x57, 0xffffffdb, 0xffffff93, 0x1c, 0x17, 0x0, 0x0, 0x0, 0x0,
name:
0x2e, 0x0, 0xffffffb5, 0xffffff83, 0xffffffb7, 0xfffffff8, 0xffffff98, 0xffffffe6, 0xffffffbf, 0x17, 0x0, 0x0, 0x0, 0xffffffda, 0xffffff9e, 0xffffffe4, 0x0, 0xffffffe0, 0x47, 0xc, 0xffffffb7, 0x57, 0xffffffdb, 0xffffff93, 0x1c, 0x17, 0x0, 0x0, 0x0, 0x0,
name:
0x2e, 0x0, 0xffffffb5, 0xffffff83, 0xffffffb7, 0xfffffff8, 0xffffff98, 0xffffffe6, 0xffffffbf, 0x17, 0x0, 0x0, 0x0, 0xffffffda, 0xffffff9e, 0xffffffe4, 0x0, 0xffffffe0, 0x47, 0xc, 0xffffffb7, 0x57, 0xffffffdb, 0xffffff93, 0x1c, 0x17, 0x0, 0x0, 0x0, 0x0,
I tested each stage up until the decompression, and I was getting what I expect.
I'd be grateful if anyone has any idea what I'm doing wrong...?
#include <stdio.h>
#include <stdlib.h>
// for resolver routines
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
// for ns routines
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/nameser.h>
#include <resolv.h>
int main ( int argc, char **argv )
{
if (argc != 2)
printf("usage: %s [addr]\n", argv[0]), exit(0);
if (res_init() != 0)
{
puts("error in init\n");
exit(1);
}
const char *dname = argv[1];
int class = C_IN;
int type = T_MX;
int anslen = 5000;
unsigned char answer[anslen];
/* make query */
int len = res_search(dname, class, type, answer, anslen);
if (len == -1)
{
printf("Error making query\n");
exit(1);
}
else
{
printf("Got answer of length: %d\n", len);
}
/* parse response */
ns_msg msg;
if (ns_initparse(answer, len, &msg) != 0)
printf("Error parsing response\n"), exit(1);
uint16_t msg_count = ns_msg_count(msg, ns_s_an);
printf("Got %d answers\n", msg_count);
if (msg_count == 0)
exit(0);
ns_rr rr;
for ( int i = 0 ; i < msg_count ; i++ )
{
if (ns_parserr(&msg, ns_s_an, i, &rr))
printf("Error parsing record\n"), exit(1);
char buf[MAXDNAME];
int size = ns_name_uncompress(ns_msg_base(msg), ns_msg_end(msg), ns_rr_rdata(rr), buf, MAXDNAME);
if (size < 0)
puts("Error uncompressing response name"), exit(1);
puts("name:");
for (int j = 0 ; j < 30 ; j++)
printf("0x%x(%c), ", buf[j], buf[j]);
printf("\n");
}
exit(0);
}