How to set DNS lookup type for getaddrinfo()?

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 could try the res_query functions for interfacing to the systems resolver.

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