4 * Specify some higher level functions that would
5 * be usefull 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
, ldns_rdf
*name
, ldns_rr_class c
,
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
, ldns_rdf
*addr
, ldns_rr_class c
,
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
);
138 /* read a line, put it in a buffer, parse the buffer */
140 ldns_get_rr_list_hosts_frm_fp(FILE *fp
)
142 return ldns_get_rr_list_hosts_frm_fp_l(fp
, NULL
);
146 ldns_get_rr_list_hosts_frm_fp_l(FILE *fp
, int *line_nr
)
154 ldns_buffer
*linebuf
;
159 ldns_status parse_result
;
161 line
= LDNS_XMALLOC(char, LDNS_MAX_LINELEN
+ 1);
162 word
= LDNS_XMALLOC(char, LDNS_MAX_LINELEN
+ 1);
163 addr
= LDNS_XMALLOC(char, LDNS_MAX_LINELEN
+ 1);
164 rr_str
= LDNS_XMALLOC(char, LDNS_MAX_LINELEN
+ 1);
166 list
= ldns_rr_list_new();
168 if(!line
|| !word
|| !addr
|| !rr_str
|| !list
) {
173 ldns_rr_list_free(list
);
177 for(i
= ldns_fget_token_l(fp
, line
, "\n", LDNS_MAX_LINELEN
, line_nr
);
178 i
> 0; i
= ldns_fget_token_l(fp
, line
, "\n", LDNS_MAX_LINELEN
, line_nr
)) {
180 if (line
[0] == '#') {
183 /* put it in a buffer for further processing */
184 linebuf
= LDNS_MALLOC(ldns_buffer
);
190 ldns_rr_list_deep_free(list
);
194 ldns_buffer_new_frm_data(linebuf
, line
, (size_t) i
);
195 for(cnt
= 0, j
= ldns_bget_token(linebuf
, word
, LDNS_PARSE_NO_NL
, LDNS_MAX_LINELEN
);
197 j
= ldns_bget_token(linebuf
, word
, LDNS_PARSE_NO_NL
, LDNS_MAX_LINELEN
), cnt
++) {
200 if ((tmp
= ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA
,
203 ldns_rdf_deep_free(tmp
);
206 if ((tmp
= ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A
,
209 ldns_rdf_deep_free(tmp
);
216 (void)strlcpy(addr
, word
, LDNS_MAX_LINELEN
+1);
220 snprintf(rr_str
, LDNS_MAX_LINELEN
,
221 "%s IN AAAA %s", word
, addr
);
223 snprintf(rr_str
, LDNS_MAX_LINELEN
,
224 "%s IN A %s", word
, addr
);
226 parse_result
= ldns_rr_new_frm_str(&rr
, rr_str
, 0, NULL
, NULL
);
227 if (parse_result
== LDNS_STATUS_OK
&& ldns_rr_owner(rr
) && ldns_rr_rd_count(rr
) > 0) {
228 ldns_rr_list_push_rr(list
, ldns_rr_clone(rr
));
233 ldns_buffer_free(linebuf
);
243 ldns_get_rr_list_hosts_frm_file(char *filename
)
249 fp
= fopen(LDNS_RESOLV_HOSTS
, "r");
252 fp
= fopen(filename
, "r");
258 names
= ldns_get_rr_list_hosts_frm_fp(fp
);
264 ldns_getaddrinfo(ldns_resolver
*res
, ldns_rdf
*node
, ldns_rr_class c
,
268 uint16_t names_found
;
272 t
= ldns_rdf_get_type(node
);
277 /* prepare a new resolver, using /etc/resolv.conf as a guide */
278 s
= ldns_resolver_new_frm_file(&r
, NULL
);
279 if (s
!= LDNS_STATUS_OK
) {
284 if (t
== LDNS_RDF_TYPE_DNAME
) {
285 /* we're asked to query for a name */
286 *ret
= ldns_get_rr_list_addr_by_name(r
, node
, c
, 0);
287 names_found
= ldns_rr_list_rr_count(*ret
);
290 if (t
== LDNS_RDF_TYPE_A
|| t
== LDNS_RDF_TYPE_AAAA
) {
292 *ret
= ldns_get_rr_list_name_by_addr(r
, node
, c
, 0);
293 names_found
= ldns_rr_list_rr_count(*ret
);
297 ldns_resolver_deep_free(r
);
304 ldns_nsec_type_check(ldns_rr
*nsec
, ldns_rr_type t
)
306 /* does the nsec cover the t given? */
307 /* copied from host2str.c line 465: ldns_rdf2buffer_str_nsec */
308 uint8_t window_block_nr
;
309 uint8_t bitmap_length
;
313 ldns_rdf
*nsec_type_list
= ldns_rr_rdf(nsec
, 1);
316 if (nsec_type_list
== NULL
) {
319 data
= ldns_rdf_data(nsec_type_list
);
321 while(pos
< ldns_rdf_size(nsec_type_list
)) {
322 window_block_nr
= data
[pos
];
323 bitmap_length
= data
[pos
+ 1];
326 for (bit_pos
= 0; bit_pos
< (bitmap_length
) * 8; bit_pos
++) {
327 if (ldns_get_bit(&data
[pos
], bit_pos
)) {
328 type
= 256 * (uint16_t) window_block_nr
+ bit_pos
;
330 if ((ldns_rr_type
)type
== t
) {
331 /* we have a winner */
336 pos
+= (uint16_t) bitmap_length
;
342 ldns_print_rr_rdf(FILE *fp
, ldns_rr
*r
, int rdfnum
, ...)
347 va_start(va_rdf
, rdfnum
);
349 for (rdf
= (int16_t)rdfnum
; rdf
!= -1; rdf
= (int16_t)va_arg(va_rdf
, int))
351 rd
= ldns_rr_rdf(r
, rdf
);
355 ldns_rdf_print(fp
, rd
);
356 fprintf(fp
, " "); /* not sure if we want to do this */