1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
/*
* mxget.c -- fetch MX records for given DNS name
*
* Copyright 1996 by Eric S. Raymond
* All rights reserved.
* For license terms, see the file COPYING in this directory.
*/
#include "config.h"
#ifdef HAVE_RES_SEARCH
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include "mx.h"
/*
* This ought to be in the bind library. It's adapted from sendmail.
*/
/*
* These are defined in RFC833. Some bind interface headers don't declare them.
* Ghod help us if they're ever actually incompatible with what's in
* the arpa/nameser.h header.
*/
#ifndef PACKETSZ
#define PACKETSZ 512 /* maximum packet size */
#endif
#ifndef HFIXEDSZ
#define HFIXEDSZ 12 /* #/bytes of fixed data in header */
#endif
#ifndef INT32SZ
#define INT32SZ 4 /* for systems without 32-bit ints */
#endif
#ifndef INT16SZ
#define INT16SZ 2 /* for systems without 16-bit ints */
#endif
/* minimum possible size of MX record in packet */
#define MIN_MX_SIZE 8 /* corresp to "a.com 0" w/ terminating space */
struct mxentry *getmxrecords(const char *name)
/* get MX records for given host */
{
unsigned char answer[PACKETSZ], *eom, *cp, *bp;
int n, ancount, qdcount, buflen, type, pref, ind;
static struct mxentry pmx[(PACKETSZ - HFIXEDSZ) / MIN_MX_SIZE];
static char MXHostBuf[PACKETSZ - HFIXEDSZ];
HEADER *hp;
n = res_search(name,C_IN,T_MX,(unsigned char*)&answer, sizeof(answer));
if (n == -1)
return((struct mxentry *)NULL);
hp = (HEADER *)&answer;
cp = answer + HFIXEDSZ;
eom = answer + n;
h_errno = 0;
for (qdcount = ntohs(hp->qdcount); qdcount--; cp += n + QFIXEDSZ)
if ((n = dn_skipname(cp, eom)) < 0)
return((struct mxentry *)NULL);
buflen = sizeof(MXHostBuf) - 1;
bp = MXHostBuf;
ind = 0;
ancount = ntohs(hp->ancount);
while (--ancount >= 0 && cp < eom)
{
if ((n = dn_expand(answer, eom, cp, bp, buflen)) < 0)
break;
cp += n;
GETSHORT(type, cp);
cp += INT16SZ + INT32SZ;
GETSHORT(n, cp);
if (type != T_MX)
{
cp += n;
continue;
}
GETSHORT(pref, cp);
if ((n = dn_expand(answer, eom, cp, bp, buflen)) < 0)
break;
cp += n;
pmx[ind].name = bp;
pmx[ind].pref = pref;
++ind;
n = strlen(bp);
bp += n;
*bp++ = '\0';
buflen -= n + 1;
}
pmx[ind].name = (char *)NULL;
pmx[ind].pref = -1;
return(pmx);
}
#endif /* HAVE_RES_SEARCH */
#ifdef TESTMAIN
main(int argc, char *argv[])
{
int count, i;
struct mxentry *responses;
responses = getmxrecords(argv[1]);
if (responses == (struct mxentry *)NULL)
puts("No MX records found");
else
do {
printf("%s %d\n", responses->name, responses->pref);
} while
((++responses)->name);
}
#endif /* TESTMAIN */
/* mxget.c ends here */
|