4 * Specify some higher level functions that would
5 * be useful to would be developers
7 * a Net::DNS like library for C
9 * (c) NLnet Labs, 2004-2006
11 * See the file LICENSE for the license
14 #include <ldns/config.h>
16 #include <ldns/ldns.h>
19 #include <openssl/ssl.h>
20 #include <openssl/sha.h>
24 ldns_get_rr_list_addr_by_name(ldns_resolver
*res
, const ldns_rdf
*name
,
25 ldns_rr_class c
, uint16_t flags
)
30 ldns_rr_list
*result
= NULL
;
31 ldns_rr_list
*hostsfilenames
;
42 if (ldns_rdf_get_type(name
) != LDNS_RDF_TYPE_DNAME
) {
46 ip6
= ldns_resolver_ip6(res
); /* we use INET_ANY here, save
49 ldns_resolver_set_ip6(res
, LDNS_RESOLV_INETANY
);
51 hostsfilenames
= ldns_get_rr_list_hosts_frm_file(NULL
);
52 for (i
= 0; i
< ldns_rr_list_rr_count(hostsfilenames
); i
++) {
53 if (ldns_rdf_compare(name
,
54 ldns_rr_owner(ldns_rr_list_rr(hostsfilenames
,
57 result
= ldns_rr_list_new();
59 ldns_rr_list_push_rr(result
,
60 ldns_rr_clone(ldns_rr_list_rr(hostsfilenames
, i
)));
63 ldns_rr_list_deep_free(hostsfilenames
);
69 /* add the RD flags, because we want an answer */
70 pkt
= ldns_resolver_query(res
, name
, LDNS_RR_TYPE_AAAA
, c
, flags
| LDNS_RD
);
72 /* extract the data we need */
73 aaaa
= ldns_pkt_rr_list_by_type(pkt
, LDNS_RR_TYPE_AAAA
,
78 pkt
= ldns_resolver_query(res
, name
, LDNS_RR_TYPE_A
, c
, flags
| LDNS_RD
);
80 /* extract the data we need */
81 a
= ldns_pkt_rr_list_by_type(pkt
, LDNS_RR_TYPE_A
, LDNS_SECTION_ANSWER
);
84 ldns_resolver_set_ip6(res
, ip6
);
87 result
= ldns_rr_list_cat_clone(aaaa
, a
);
88 ldns_rr_list_deep_free(aaaa
);
89 ldns_rr_list_deep_free(a
);
94 result
= ldns_rr_list_clone(aaaa
);
98 result
= ldns_rr_list_clone(a
);
101 ldns_rr_list_deep_free(aaaa
);
102 ldns_rr_list_deep_free(a
);
107 ldns_get_rr_list_name_by_addr(ldns_resolver
*res
, const ldns_rdf
*addr
,
108 ldns_rr_class c
, uint16_t flags
)
120 if (ldns_rdf_get_type(addr
) != LDNS_RDF_TYPE_A
&&
121 ldns_rdf_get_type(addr
) != LDNS_RDF_TYPE_AAAA
) {
125 name
= ldns_rdf_address_reverse(addr
);
127 /* add the RD flags, because we want an answer */
128 pkt
= ldns_resolver_query(res
, name
, LDNS_RR_TYPE_PTR
, c
, flags
| LDNS_RD
);
129 ldns_rdf_deep_free(name
);
131 /* extract the data we need */
132 names
= ldns_pkt_rr_list_by_type(pkt
,
133 LDNS_RR_TYPE_PTR
, LDNS_SECTION_ANSWER
);
139 /* read a line, put it in a buffer, parse the buffer */
141 ldns_get_rr_list_hosts_frm_fp(FILE *fp
)
143 return ldns_get_rr_list_hosts_frm_fp_l(fp
, NULL
);
147 ldns_get_rr_list_hosts_frm_fp_l(FILE *fp
, int *line_nr
)
155 ldns_buffer
*linebuf
;
160 ldns_status parse_result
;
162 line
= LDNS_XMALLOC(char, LDNS_MAX_LINELEN
+ 1);
163 word
= LDNS_XMALLOC(char, LDNS_MAX_LINELEN
+ 1);
164 addr
= LDNS_XMALLOC(char, LDNS_MAX_LINELEN
+ 1);
165 rr_str
= LDNS_XMALLOC(char, LDNS_MAX_LINELEN
+ 1);
167 list
= ldns_rr_list_new();
169 if(!line
|| !word
|| !addr
|| !rr_str
|| !list
) {
174 ldns_rr_list_free(list
);
178 for(i
= ldns_fget_token_l(fp
, line
, "\n", LDNS_MAX_LINELEN
, line_nr
);
179 i
> 0; i
= ldns_fget_token_l(fp
, line
, "\n", LDNS_MAX_LINELEN
, line_nr
)) {
181 if (line
[0] == '#') {
184 /* put it in a buffer for further processing */
185 linebuf
= LDNS_MALLOC(ldns_buffer
);
191 ldns_rr_list_deep_free(list
);
195 ldns_buffer_new_frm_data(linebuf
, line
, (size_t) i
);
196 for(cnt
= 0, j
= ldns_bget_token(linebuf
, word
, LDNS_PARSE_NO_NL
, LDNS_MAX_LINELEN
);
198 j
= ldns_bget_token(linebuf
, word
, LDNS_PARSE_NO_NL
, LDNS_MAX_LINELEN
), cnt
++) {
201 if ((tmp
= ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA
,
204 ldns_rdf_deep_free(tmp
);
207 if ((tmp
= ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A
,
210 ldns_rdf_deep_free(tmp
);
217 (void)strlcpy(addr
, word
, LDNS_MAX_LINELEN
+1);
219 /* Stop parsing line when a comment begins. */
224 snprintf(rr_str
, LDNS_MAX_LINELEN
,
225 "%s IN AAAA %s", word
, addr
);
227 snprintf(rr_str
, LDNS_MAX_LINELEN
,
228 "%s IN A %s", word
, addr
);
230 parse_result
= ldns_rr_new_frm_str(&rr
, rr_str
, 0, NULL
, NULL
);
231 if (parse_result
== LDNS_STATUS_OK
&& ldns_rr_owner(rr
) && ldns_rr_rd_count(rr
) > 0) {
232 ldns_rr_list_push_rr(list
, ldns_rr_clone(rr
));
237 ldns_buffer_free(linebuf
);
247 ldns_get_rr_list_hosts_frm_file(char *filename
)
253 fp
= fopen(LDNS_RESOLV_HOSTS
, "r");
256 fp
= fopen(filename
, "r");
262 names
= ldns_get_rr_list_hosts_frm_fp(fp
);
268 ldns_getaddrinfo(ldns_resolver
*res
, const ldns_rdf
*node
,
269 ldns_rr_class c
, ldns_rr_list
**ret
)
272 uint16_t names_found
;
276 t
= ldns_rdf_get_type(node
);
281 /* prepare a new resolver, using /etc/resolv.conf as a guide */
282 s
= ldns_resolver_new_frm_file(&r
, NULL
);
283 if (s
!= LDNS_STATUS_OK
) {
288 if (t
== LDNS_RDF_TYPE_DNAME
) {
289 /* we're asked to query for a name */
290 *ret
= ldns_get_rr_list_addr_by_name(r
, node
, c
, 0);
291 names_found
= ldns_rr_list_rr_count(*ret
);
294 if (t
== LDNS_RDF_TYPE_A
|| t
== LDNS_RDF_TYPE_AAAA
) {
296 *ret
= ldns_get_rr_list_name_by_addr(r
, node
, c
, 0);
297 names_found
= ldns_rr_list_rr_count(*ret
);
301 ldns_resolver_deep_free(r
);
308 ldns_nsec_type_check(const ldns_rr
*nsec
, ldns_rr_type t
)
310 switch (ldns_rr_get_type(nsec
)) {
311 case LDNS_RR_TYPE_NSEC
: if (ldns_rr_rd_count(nsec
) < 2) {
314 return ldns_nsec_bitmap_covers_type(
315 ldns_rr_rdf(nsec
, 1), t
);
317 case LDNS_RR_TYPE_NSEC3
: if (ldns_rr_rd_count(nsec
) < 6) {
320 return ldns_nsec_bitmap_covers_type(
321 ldns_rr_rdf(nsec
, 5), t
);
323 default : return false;
328 ldns_print_rr_rdf(FILE *fp
, ldns_rr
*r
, int rdfnum
, ...)
333 va_start(va_rdf
, rdfnum
);
335 for (rdf
= (int16_t)rdfnum
; rdf
!= -1; rdf
= (int16_t)va_arg(va_rdf
, int))
337 rd
= ldns_rr_rdf(r
, rdf
);
341 ldns_rdf_print(fp
, rd
);
342 fprintf(fp
, " "); /* not sure if we want to do this */