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,
122 if (ldns_rdf_get_type(addr) != LDNS_RDF_TYPE_A &&
123 ldns_rdf_get_type(addr) != LDNS_RDF_TYPE_AAAA) {
127 name = ldns_rdf_address_reverse(addr);
129 /* add the RD flags, because we want an answer */
130 pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_PTR, c, flags | LDNS_RD);
132 /* extract the data we need */
133 names = ldns_pkt_rr_list_by_type(pkt,
134 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();
170 for(i = ldns_fget_token_l(fp, line, "\n", 0, line_nr);
171 i > 0; i = ldns_fget_token_l(fp, line, "\n", 0, line_nr)) {
173 if (line[0] == '#') {
176 /* put it in a buffer for further processing */
177 linebuf = LDNS_MALLOC(ldns_buffer);
179 ldns_buffer_new_frm_data(linebuf, line, (size_t) i);
180 for(cnt = 0, j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, 0);
182 j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, 0), cnt++) {
185 if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA,
188 ldns_rdf_deep_free(tmp);
191 if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A,
194 ldns_rdf_deep_free(tmp);
201 strlcpy(addr, word, LDNS_MAX_LINELEN+1);
205 snprintf(rr_str, LDNS_MAX_LINELEN,
206 "%s IN AAAA %s", word, addr);
208 snprintf(rr_str, LDNS_MAX_LINELEN,
209 "%s IN A %s", word, addr);
211 parse_result = ldns_rr_new_frm_str(&rr, rr_str, 0, NULL, NULL);
212 if (parse_result == LDNS_STATUS_OK && ldns_rr_owner(rr) && ldns_rr_rd_count(rr) > 0) {
213 ldns_rr_list_push_rr(list, ldns_rr_clone(rr));
218 ldns_buffer_free(linebuf);
228 ldns_get_rr_list_hosts_frm_file(char *filename)
234 fp = fopen(LDNS_RESOLV_HOSTS, "r");
237 fp = fopen(filename, "r");
243 names = ldns_get_rr_list_hosts_frm_fp(fp);
249 ldns_getaddrinfo(ldns_resolver *res, ldns_rdf *node, ldns_rr_class c,
253 uint16_t names_found;
257 t = ldns_rdf_get_type(node);
262 /* prepare a new resolver, using /etc/resolv.conf as a guide */
263 s = ldns_resolver_new_frm_file(&r, NULL);
264 if (s != LDNS_STATUS_OK) {
269 if (t == LDNS_RDF_TYPE_DNAME) {
270 /* we're asked to query for a name */
271 *ret = ldns_get_rr_list_addr_by_name(r, node, c, 0);
272 names_found = ldns_rr_list_rr_count(*ret);
275 if (t == LDNS_RDF_TYPE_A || t == LDNS_RDF_TYPE_AAAA) {
277 *ret = ldns_get_rr_list_name_by_addr(r, node, c, 0);
278 names_found = ldns_rr_list_rr_count(*ret);
282 ldns_resolver_deep_free(r);
289 ldns_nsec_type_check(ldns_rr *nsec, ldns_rr_type t)
291 /* does the nsec cover the t given? */
292 /* copied from host2str.c line 465: ldns_rdf2buffer_str_nsec */
293 uint8_t window_block_nr;
294 uint8_t bitmap_length;
298 ldns_rdf *nsec_type_list = ldns_rr_rdf(nsec, 1);
299 uint8_t *data = ldns_rdf_data(nsec_type_list);
301 while(pos < ldns_rdf_size(nsec_type_list)) {
302 window_block_nr = data[pos];
303 bitmap_length = data[pos + 1];
306 for (bit_pos = 0; bit_pos < (bitmap_length) * 8; bit_pos++) {
307 if (ldns_get_bit(&data[pos], bit_pos)) {
308 type = 256 * (uint16_t) window_block_nr + bit_pos;
310 if ((ldns_rr_type)type == t) {
311 /* we have a winner */
316 pos += (uint16_t) bitmap_length;
322 ldns_print_rr_rdf(FILE *fp, ldns_rr *r, int rdfnum, ...)
327 va_start(va_rdf, rdfnum);
329 for (rdf = (int16_t)rdfnum; rdf != -1; rdf = (int16_t)va_arg(va_rdf, int))
331 rd = ldns_rr_rdf(r, rdf);
335 ldns_rdf_print(fp, rd);
336 fprintf(fp, " "); /* not sure if we want to do this */