]>
git.ipfire.org Git - people/stevee/aiccu.git/blob - common/resolver.c
1 /**********************************************************
2 SixXS - Automatic IPv6 Connectivity Configuration Utility
3 ***********************************************************
4 Copyright 2003-2005 SixXS - http://www.sixxs.net
5 ***********************************************************
6 common/resolver.c - Simple DNS RR lookup function
7 ***********************************************************
9 $Id: resolver.c,v 1.3 2006-07-23 14:13:57 jeroen Exp $
10 $Date: 2006-07-23 14:13:57 $
11 **********************************************************/
22 #include <netinet/in.h>
23 #include <arpa/nameser.h>
27 int getrrs(const char *label
, int rrtype
, void gotrec(unsigned int num
, int type
, const char *record
))
30 struct __res_state res
;
32 unsigned char answer
[8192];
33 HEADER
*header
= (HEADER
*)answer
;
36 unsigned int i
,j
,k
,rrnum
= 0;
37 unsigned char *startptr
, *endptr
, *ptr
;
38 uint16_t type
= 0, class = 0;
42 memset(&res
, 0, sizeof(res
));
43 res
.options
= RES_DEBUG
;
49 memset(answer
, 0, sizeof(answer
));
51 ret
= res_nquery(&res
, label
, C_IN
, rrtype
, answer
, sizeof(answer
));
53 ret
= res_query(label
, C_IN
, rrtype
, answer
, sizeof(answer
));
55 if (ret
< 0) return -1;
57 /* Our start and end */
58 startptr
= &answer
[0];
59 endptr
= &answer
[ret
];
62 ptr
= startptr
+ HFIXEDSZ
;
65 for (count
= ntohs(header
->qdcount
); count
--; ptr
+= ret
+ QFIXEDSZ
)
67 if ((ret
= dn_skipname(ptr
, endptr
)) < 0) return -1;
70 /* Only look at the Answer section */
71 count
= ntohs(header
->ancount
);
73 /* Go through all the Answer records */
74 while (ptr
< endptr
&& count
> 0)
78 memset(buf
, 0, sizeof(buf
));
79 ret
= dn_expand (startptr
, endptr
, ptr
, buf
, sizeof(buf
));
83 if (ptr
+ INT16SZ
+ INT16SZ
+ INT32SZ
>= endptr
) break;
94 /* Get the RDLength */
97 memset(buf
, 0, sizeof(buf
));
102 for (k
= ret
, j
= 0; j
< k
&& &ptr
[j
] < endptr
; j
+= (i
+1))
105 memcpy(buf
, &ptr
[j
+1], i
> sizeof(buf
) ? sizeof(buf
) : i
);
106 buf
[i
> sizeof(buf
) ? sizeof(buf
) : i
] = '\0';
107 if (rrtype
== type
|| rrtype
== T_ANY
) gotrec(rrnum
, type
, buf
);
112 inet_ntop(AF_INET
, ptr
, buf
, sizeof(buf
));
113 if (rrtype
== type
|| rrtype
== T_ANY
) gotrec(rrnum
, type
, buf
);
117 inet_ntop(AF_INET6
, ptr
, buf
, sizeof(buf
));
118 if (rrtype
== type
|| rrtype
== T_ANY
) gotrec(rrnum
, type
, buf
);
122 /* Get the MX preference */
124 ret
= dn_expand(startptr
, endptr
, ptr
, buf
, sizeof(buf
));
125 if (rrtype
== type
|| rrtype
== T_ANY
) gotrec(rrnum
, type
, buf
);
129 ret
= dn_expand(startptr
, endptr
, ptr
, buf
, sizeof(buf
));
130 if (rrtype
== type
|| rrtype
== T_ANY
) gotrec(rrnum
, type
, buf
);
145 * Windows Resolver Code, as per:
146 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dns/dns/dnsquery.asp
147 * http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B831226
151 int getrrs(const char *label
, int rrtype
, void gotrec(unsigned int num
, int type
, const char *record
))
153 DNS_STATUS status
; /* Return value of DnsQuery_A() function */
154 PDNS_RECORD pResult
, pRec
; /* Pointer to DNS_RECORD structure */
155 unsigned int rrnum
= 0, i
;
158 status
= DnsQuery(label
, /* Pointer to OwnerName */
159 rrtype
, /* Type of the record to be queried */
160 DNS_QUERY_STANDARD
, /* Standard Query */
161 NULL
, /* Contains DNS server IP address */
162 &pResult
, /* Resource record that contains the response */
163 NULL
); /* Reserved for future use */
165 if (status
) return -1;
168 for (pRec
= pResult
; pRec
; pRec
= pRec
->pNext
)
173 if (rrtype
!= type
&& rrtype
!= ns_t_any
) continue;
178 for (i
=0; i
< pRec
->Data
.TXT
.dwStringCount
; i
++)
180 gotrec(rrnum
, type
, pRec
->Data
.TXT
.pStringArray
[i
]);
185 gotrec(rrnum
, type
, (const char *)&pRec
->Data
.A
.IpAddress
);
189 gotrec(rrnum
, type
, (const char *)&pRec
->Data
.AAAA
.Ip6Address
);
193 gotrec(rrnum
, type
, pRec
->Data
.MX
.pNameExchange
);
197 gotrec(rrnum
, type
, pRec
->Data
.NS
.pNameHost
);
203 /* Free memory allocated for DNS records. */
204 DnsRecordListFree(pResult
, DnsFreeRecordListDeep
);