DNS functions (example program)
From SHellium Wiki
DNS functions reference (part 1)
DNS functions reference (part 2)
DNS functions (example program)
DNS functions (example program)
Sorry about this little program. It's not very good, but I made it in a rush. It will find all the MX records for a domain, count them and resolve them, then show what it found:
[eax@valholl ~] ./mx eax.uni.cc ASPMX5.GOOGLEMAIL.COM - 10 ALT1.ASPMX.L.GOOGLE.COM - 5 ALT2.ASPMX.L.GOOGLE.COM - 5 ASPMX.L.GOOGLE.COM - 1 ASPMX2.GOOGLEMAIL.COM - 10 ASPMX3.GOOGLEMAIL.COM - 10 ASPMX4.GOOGLEMAIL.COM - 10 7 66.249.83.27 64.233.171.27 209.85.163.27 74.125.47.27 209.85.135.27 64.233.167.27 66.249.93.27
Well, here's the source:
// $Id: mx.c,v 0.1 2008/04/26 13:51:15 eax/eaxes Exp $ -*- C -*-
// Julian B. <eax@eax.uni.cc>
// gcc -Wall -s -O3 -Os -fexpensive-optimizations mx.c -o mx /usr/lib/libresolv.a
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <resolv.h>
#include <netdb.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#define MAX_MX 10
struct _MX_SERVER
{
int priority;
char MX[MAXDNAME+1];
} MX_SERVER[MAX_MX];
int MX_NUM = 0;
int findMX(char *domain);
int main(int argc, char *argv[])
{
int x;
struct hostent *host;
if (argc != 2)
errx(0, "\rusage: %s [domain]", argv[0]);
if (res_init() == -1)
errx(0, "Couldn't initialize the DNS resolver");
if (findMX(argv[1]) == 1)
exit(EXIT_FAILURE);
else {
printf("%i\n", MX_NUM);
for(x = 0; x < MX_NUM; x++) {
if ((host = gethostbyname(MX_SERVER[x].MX)) == NULL) {
herror("gethostbyname");
errx(1, "Error resolving hostname!");
}
printf("%s\n", inet_ntoa(*((struct in_addr *)host->h_addr)));
}
}
return 0;
}
int findMX(char *domain)
{
unsigned char query_buffer[512];
int query_response, x;
ns_msg query_parse_msg;
ns_rr query_parse_rr;
if ((query_response = res_query(domain, C_IN, T_MX, query_buffer, sizeof(query_buffer))) == -1)
{
if (h_errno == HOST_NOT_FOUND)
warnx("Please choose an existing domain!");
else
herror("res_query");
return 1;
}
if (ns_initparse(query_buffer, query_response, &query_parse_msg) == -1)
{
warnx("Wasn't able to start the DNS query parser.");
return 1;
}
for (x = 0; x < ns_msg_count(query_parse_msg, ns_s_an); x++)
{
if (ns_parserr(&query_parse_msg, ns_s_an, x, &query_parse_rr))
{
warnx("Failed to use ns_parserr.");
return 1;
}
if (ns_rr_type(query_parse_rr) == ns_t_mx)
{
MX_SERVER[x].priority = ns_get16((u_char *)ns_rr_rdata(query_parse_rr));
if (ns_name_uncompress(ns_msg_base(query_parse_msg), ns_msg_end(query_parse_msg), (u_char *)ns_rr_rdata(query_parse_rr)+2, MX_SERVER[x].MX, sizeof(MX_SERVER[x].MX)) < 0)
{
warnx("We can't uncompress the DNS headers!");
return 1;
}
printf("%s - %i\n", MX_SERVER[x].MX, MX_SERVER[x].priority);
MX_NUM++;
}
}
return 0;
}