3 * Where all the hard work concerning chasing
5 * (c) 2005, 2006 NLnet Labs
7 * See the file LICENSE for the license
12 #include <ldns/ldns.h>
15 * trace down from the root to name
18 /* same naive method as in drill0.9
19 * We resolver _ALL_ the names, which is ofcourse not needed
20 * We _do_ use the local resolver to do that, so it still is
21 * fast, but it can be made to run much faster
24 do_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
29 ldns_rr_list *new_nss_a;
30 ldns_rr_list *new_nss_aaaa;
31 ldns_rr_list *final_answer;
32 ldns_rr_list *new_nss;
33 ldns_rr_list *hostnames;
34 ldns_rr_list *ns_addr;
47 res = ldns_resolver_new();
50 error("Memory allocation failed");
54 /* transfer some properties of local_res to res,
55 * because they were given on the commandline */
56 ldns_resolver_set_ip6(res,
57 ldns_resolver_ip6(local_res));
58 ldns_resolver_set_port(res,
59 ldns_resolver_port(local_res));
60 ldns_resolver_set_debug(res,
61 ldns_resolver_debug(local_res));
62 ldns_resolver_set_dnssec(res,
63 ldns_resolver_dnssec(local_res));
64 ldns_resolver_set_fail(res,
65 ldns_resolver_fail(local_res));
66 ldns_resolver_set_usevc(res,
67 ldns_resolver_usevc(local_res));
68 ldns_resolver_set_random(res,
69 ldns_resolver_random(local_res));
70 ldns_resolver_set_recursive(res, false);
72 /* setup the root nameserver in the new resolver */
73 status = ldns_resolver_push_nameserver_rr_list(res, global_dns_root);
74 if (status != LDNS_STATUS_OK) {
75 fprintf(stderr, "Error adding root servers to resolver: %s\n", ldns_get_errorstr_by_id(status));
76 ldns_rr_list_print(stdout, global_dns_root);
80 /* this must be a real query to local_res */
81 status = ldns_resolver_send(&p, res, ldns_dname_new_frm_str("."), LDNS_RR_TYPE_NS, c, 0);
82 /* p can still be NULL */
85 if (ldns_pkt_empty(p)) {
86 warning("No root server information received");
89 if (status == LDNS_STATUS_OK) {
90 if (!ldns_pkt_empty(p)) {
91 drill_pkt_print(stdout, local_res, p);
94 error("cannot use local resolver");
98 status = ldns_resolver_send(&p, res, name, t, c, 0);
100 while(status == LDNS_STATUS_OK &&
101 ldns_pkt_reply_type(p) == LDNS_PACKET_REFERRAL) {
104 /* some error occurred, bail out */
108 new_nss_a = ldns_pkt_rr_list_by_type(p,
109 LDNS_RR_TYPE_A, LDNS_SECTION_ADDITIONAL);
110 new_nss_aaaa = ldns_pkt_rr_list_by_type(p,
111 LDNS_RR_TYPE_AAAA, LDNS_SECTION_ADDITIONAL);
112 new_nss = ldns_pkt_rr_list_by_type(p,
113 LDNS_RR_TYPE_NS, LDNS_SECTION_AUTHORITY);
115 if (verbosity != -1) {
116 ldns_rr_list_print(stdout, new_nss);
118 /* checks itself for verbosity */
119 drill_pkt_print_footer(stdout, local_res, p);
121 /* remove the old nameserver from the resolver */
122 while((pop = ldns_resolver_pop_nameserver(res))) { /* do it */ }
124 /* also check for new_nss emptyness */
126 if (!new_nss_aaaa && !new_nss_a) {
128 * no nameserver found!!!
129 * try to resolve the names we do got
131 for(i = 0; i < ldns_rr_list_rr_count(new_nss); i++) {
132 /* get the name of the nameserver */
133 pop = ldns_rr_rdf(ldns_rr_list_rr(new_nss, i), 0);
138 ldns_rr_list_print(stdout, new_nss);
139 ldns_rdf_print(stdout, pop);
140 /* retrieve it's addresses */
141 ns_addr = ldns_rr_list_cat_clone(ns_addr,
142 ldns_get_rr_list_addr_by_name(local_res, pop, c, 0));
146 if (ldns_resolver_push_nameserver_rr_list(res, ns_addr) !=
148 error("Error adding new nameservers");
152 ldns_rr_list_free(ns_addr);
154 ldns_rr_list_print(stdout, ns_addr);
155 error("Could not find the nameserver ip addr; abort");
161 /* add the new ones */
163 if (ldns_resolver_push_nameserver_rr_list(res, new_nss_aaaa) !=
165 error("adding new nameservers");
171 if (ldns_resolver_push_nameserver_rr_list(res, new_nss_a) !=
173 error("adding new nameservers");
179 if (loop_count++ > 20) {
180 /* unlikely that we are doing something usefull */
181 error("Looks like we are looping");
186 status = ldns_resolver_send(&p, res, name, t, c, 0);
192 status = ldns_resolver_send(&p, res, name, t, c, 0);
198 hostnames = ldns_get_rr_list_name_by_addr(local_res,
199 ldns_pkt_answerfrom(p), 0, 0);
201 new_nss = ldns_pkt_authority(p);
202 final_answer = ldns_pkt_answer(p);
204 if (verbosity != -1) {
205 ldns_rr_list_print(stdout, final_answer);
206 ldns_rr_list_print(stdout, new_nss);
209 drill_pkt_print_footer(stdout, local_res, p);
216 * Chase the given rr to a known and trusted key
220 * the last argument prev_key_list, if not null, and type == DS, then the ds
221 * rr list we have must all be a ds for the keys in this list
225 do_chase(ldns_resolver *res,
229 ldns_rr_list *trusted_keys,
232 ldns_rr_list *prev_key_list,
235 ldns_rr_list *rrset = NULL;
237 ldns_rr *orig_rr = NULL;
239 bool cname_followed = false;
247 ldns_status tree_result;
248 ldns_dnssec_data_chain *chain;
249 ldns_dnssec_trust_tree *tree;
251 const ldns_rr_descriptor *descriptor;
252 descriptor = ldns_rr_descript(type);
254 ldns_dname2canonical(name);
256 pkt = ldns_pkt_clone(pkt_o);
258 mesg("No name to chase");
260 return LDNS_STATUS_EMPTY_LABEL;
262 if (verbosity != -1) {
263 printf(";; Chasing: ");
264 ldns_rdf_print(stdout, name);
265 if (descriptor && descriptor->_name) {
266 printf(" %s\n", descriptor->_name);
268 printf(" type %d\n", type);
272 if (!trusted_keys || ldns_rr_list_rr_count(trusted_keys) < 1) {
273 warning("No trusted keys specified");
277 rrset = ldns_pkt_rr_list_by_name_and_type(pkt,
283 /* nothing in answer, try authority */
284 rrset = ldns_pkt_rr_list_by_name_and_type(pkt,
287 LDNS_SECTION_AUTHORITY
290 /* answer might be a cname, chase that first, then chase
291 cname target? (TODO) */
293 cname_followed = true;
294 rrset = ldns_pkt_rr_list_by_name_and_type(pkt,
300 /* nothing in answer, try authority */
301 rrset = ldns_pkt_rr_list_by_name_and_type(pkt,
304 LDNS_SECTION_AUTHORITY
310 if (verbosity >= 0) {
311 fprintf(stderr, "%s", ldns_get_errorstr_by_id(LDNS_STATUS_MEM_ERR));
312 fprintf(stderr, "\n");
314 return LDNS_STATUS_MEM_ERR;
318 /* not found in original packet, try again */
321 pkt = ldns_resolver_query(res, name, type, c, qflags);
324 if (verbosity >= 0) {
325 fprintf(stderr, "%s", ldns_get_errorstr_by_id(LDNS_STATUS_NETWORK_ERR));
326 fprintf(stderr, "\n");
328 return LDNS_STATUS_NETWORK_ERR;
330 if (verbosity >= 5) {
331 ldns_pkt_print(stdout, pkt);
334 rrset = ldns_pkt_rr_list_by_name_and_type(pkt,
341 orig_rr = ldns_rr_new();
343 /* if the answer had no answer section, we need to construct our own rr (for instance if
344 * the rr qe asked for doesn't exist. This rr will be destroyed when the chain is freed */
345 if (ldns_pkt_ancount(pkt) < 1) {
346 ldns_rr_set_type(orig_rr, type);
347 ldns_rr_set_owner(orig_rr, ldns_rdf_clone(name));
349 chain = ldns_dnssec_build_data_chain(res, qflags, rrset, pkt, ldns_rr_clone(orig_rr));
351 /* chase the first answer */
352 chain = ldns_dnssec_build_data_chain(res, qflags, rrset, pkt, NULL);
355 if (verbosity >= 4) {
356 printf("\n\nDNSSEC Data Chain:\n");
357 ldns_dnssec_data_chain_print(stdout, chain);
360 result = LDNS_STATUS_OK;
362 tree = ldns_dnssec_derive_trust_tree(chain, NULL);
364 if (verbosity >= 2) {
365 printf("\n\nDNSSEC Trust tree:\n");
366 ldns_dnssec_trust_tree_print(stdout, tree, 0, true);
369 if (ldns_rr_list_rr_count(trusted_keys) > 0) {
370 tree_result = ldns_dnssec_trust_tree_contains_keys(tree, trusted_keys);
372 if (tree_result == LDNS_STATUS_DNSSEC_EXISTENCE_DENIED) {
373 if (verbosity >= 1) {
374 printf("Existence denied or verifiably insecure\n");
376 result = LDNS_STATUS_OK;
377 } else if (tree_result != LDNS_STATUS_OK) {
378 if (verbosity >= 1) {
379 printf("No trusted keys found in tree: first error was: %s\n", ldns_get_errorstr_by_id(tree_result));
381 result = tree_result;
385 if (verbosity >= 0) {
386 printf("You have not provided any trusted keys.\n");
390 ldns_rr_free(orig_rr);
391 ldns_dnssec_trust_tree_free(tree);
392 ldns_dnssec_data_chain_deep_free(chain);
394 ldns_rr_list_deep_free(rrset);
396 /* ldns_rr_free(orig_rr);*/
400 #endif /* HAVE_SSL */