From: Jelte Jansen Date: Tue, 28 Nov 2006 14:05:46 +0000 (+0000) Subject: added -r option for use with the -T[D] trace functionality X-Git-Tag: release-1.2.0~130 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b76bc2b9557c647d3e6c817ea7e548d650859877;p=thirdparty%2Fldns.git added -r option for use with the -T[D] trace functionality fixed rr_compare to exclude TTLs --- diff --git a/drill/chasetrace.c b/drill/chasetrace.c index eca22dbb..936f653a 100644 --- a/drill/chasetrace.c +++ b/drill/chasetrace.c @@ -70,12 +70,15 @@ do_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t, ldns_resolver_set_recursive(res, false); /* setup the root nameserver in the new resolver */ - if (ldns_resolver_push_nameserver_rr_list(res, global_dns_root) != LDNS_STATUS_OK) { + status = ldns_resolver_push_nameserver_rr_list(res, global_dns_root); + if (status != LDNS_STATUS_OK) { + fprintf(stderr, "Error adding root servers to resolver: %s\n", ldns_get_errorstr_by_id(status)); + ldns_rr_list_print(stdout, global_dns_root); return NULL; } /* this must be a real query to local_res */ - status = ldns_resolver_send(&p, local_res, ldns_dname_new_frm_str("."), LDNS_RR_TYPE_NS, c, 0); + status = ldns_resolver_send(&p, res, ldns_dname_new_frm_str("."), LDNS_RR_TYPE_NS, c, 0); /* p can still be NULL */ diff --git a/drill/drill.c b/drill/drill.c index 9ffdcf00..7824da54 100644 --- a/drill/drill.c +++ b/drill/drill.c @@ -54,7 +54,7 @@ usage(FILE *stream, const char *progname) fprintf(stream, "\t-u\t\tsend the query with udp (the default)\n"); fprintf(stream, "\t-x\t\tdo a reverse lookup\n"); fprintf(stream, "\twhen doing a secure trace:\n"); - fprintf(stream, "\t-r \t\tuse file as root servers hint file (NOT IMPLEMENTED YET)\n"); + fprintf(stream, "\t-r \t\tuse file as root servers hint file\n"); fprintf(stream, "\t-d \t\tuse domain as the start point for the trace\n"); fprintf(stream, "\t-y \tspecify named base64 tsig key, and optional an\n\t\t\talgorithm (defaults to hmac-md5.sig-alg.reg.int)\n"); fprintf(stream, "\t-z\t\tdon't randomize the nameservers before use\n"); @@ -214,6 +214,18 @@ main(int argc, char *argv[]) case 'q': query_file = optarg; PURPOSE = DRILL_QTOFILE; + break; + case 'r': + if (global_dns_root) { + fprintf(stderr, "There was already a series of root servers set\n"); + exit(EXIT_FAILURE); + } + global_dns_root = read_root_hints(optarg); + if (!global_dns_root) { + fprintf(stderr, "Unable to read root hints file %s, aborting\n", optarg); + exit(EXIT_FAILURE); + } + break; /* query options */ case 'a': qfail = true; @@ -358,6 +370,7 @@ main(int argc, char *argv[]) } break; case 'h': + version(stdout, progname); usage(stdout, progname); result = EXIT_SUCCESS; goto exit; @@ -528,7 +541,10 @@ main(int argc, char *argv[]) switch(PURPOSE) { case DRILL_TRACE: /* do a trace from the root down */ - init_root(); + if (!global_dns_root) { + + init_root(); + } qname = ldns_dname_new_frm_str(name); if (!qname) { error("%s", "making qname"); @@ -539,7 +555,9 @@ main(int argc, char *argv[]) break; case DRILL_SECTRACE: /* do a secure trace from the root down */ - init_root(); + if (!global_dns_root) { + init_root(); + } qname = ldns_dname_new_frm_str(name); if (!qname) { error("%s", "making qname"); diff --git a/drill/drill.h.in b/drill/drill.h.in index a8801f44..0f5c28c4 100644 --- a/drill/drill.h.in +++ b/drill/drill.h.in @@ -58,6 +58,7 @@ ldns_rr *read_key_file(const char *filename); ldns_pkt *read_hex_pkt(char *filename); ldns_buffer *read_hex_buffer(char *filename); void init_root(void); +ldns_rr_list *read_root_hints(const char *filename); void clear_root(void); void dump_hex(const ldns_pkt *pkt, const char *file); void warning(const char *fmt, ...); diff --git a/drill/root.c b/drill/root.c index dc3a0ba3..97aec3a8 100644 --- a/drill/root.c +++ b/drill/root.c @@ -10,9 +10,10 @@ #include "drill.h" #include +#include /* a global list of the root-servers */ -ldns_rr_list *global_dns_root; +ldns_rr_list *global_dns_root = NULL; /* put a hardcoded list in the root and * init the root rrlist structure */ @@ -51,6 +52,55 @@ init_root(void) ldns_rr_list_push_rr(global_dns_root, r); } +/* + * Read a hints file as root + * + * The file with the given path should contain a list of NS RRs + * for the root zone and A records for those NS RRs. + * Read them, check them, and append the a records to the rr list given. + */ +ldns_rr_list * +read_root_hints(const char *filename) +{ + FILE *fp = NULL; + int line_nr = 0; + ldns_zone *z; + ldns_status status; + ldns_rr_list *addresses = NULL; + ldns_rr *rr; + size_t i; + + fp = fopen(filename, "r"); + if (!fp) { + fprintf(stderr, "Unable to open %s for reading: %s\n", filename, strerror(errno)); + return NULL; + } + + status = ldns_zone_new_frm_fp_l(&z, fp, NULL, 0, 0, &line_nr); + fclose(fp); + if (status != LDNS_STATUS_OK) { + fprintf(stderr, "Error reading root hints file: %s\n", ldns_get_errorstr_by_id(status)); + return NULL; + } else { + addresses = ldns_rr_list_new(); + for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(z)); i++) { + rr = ldns_rr_list_rr(ldns_zone_rrs(z), i); + /*if ((address_family == 0 || address_family == 1) && + */ + if ( ldns_rr_get_type(rr) == LDNS_RR_TYPE_A ) { + ldns_rr_list_push_rr(addresses, ldns_rr_clone(rr)); + } + /*if ((address_family == 0 || address_family == 2) &&*/ + if ( ldns_rr_get_type(rr) == LDNS_RR_TYPE_AAAA) { + ldns_rr_list_push_rr(addresses, ldns_rr_clone(rr)); + } + } + ldns_zone_deep_free(z); + return addresses; + } +} + + void clear_root(void) { diff --git a/drill/securetrace.c b/drill/securetrace.c index 20167831..fc3f46fe 100644 --- a/drill/securetrace.c +++ b/drill/securetrace.c @@ -222,6 +222,13 @@ do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t, ldns_resolver_set_dnssec_cd(res, false); ldns_resolver_set_dnssec(res, true); + /* setup the root nameserver in the new resolver */ + status = ldns_resolver_push_nameserver_rr_list(res, global_dns_root); + if (status != LDNS_STATUS_OK) { + printf("ERRRRR: %s\n", ldns_get_errorstr_by_id(status)); + ldns_rr_list_print(stdout, global_dns_root); + return NULL; + } labels_count = ldns_dname_label_count(name); if (start_name) { if (ldns_dname_is_subdomain(name, start_name)) { diff --git a/rr.c b/rr.c index 4ba38ab1..9949d4e7 100644 --- a/rr.c +++ b/rr.c @@ -1315,15 +1315,21 @@ ldns_rr_compare_no_rdata(const ldns_rr *rr1, const ldns_rr *rr2) int ldns_rr_compare_wire(ldns_buffer *rr1_buf, ldns_buffer *rr2_buf) { - size_t rr1_len, rr2_len, min_len, i; + size_t rr1_len, rr2_len, min_len, i, offset; - rr1_len = ldns_buffer_capacity(rr1_buf); rr2_len = ldns_buffer_capacity(rr2_buf); + /* jump past dname (checked in earlier part) + * and especially past TTL */ + offset = 0; + while (offset < rr1_len && *ldns_buffer_at(rr1_buf, offset) != 0) { + offset += *ldns_buffer_at(rr1_buf, offset); + } + offset += 9; min_len = (rr1_len < rr2_len) ? rr1_len : rr2_len; /* Compare RRs RDATA byte for byte. */ - for(i = 0; i < min_len; i++) { + for(i = offset; i < min_len; i++) { if (*ldns_buffer_at(rr1_buf,i) < *ldns_buffer_at(rr2_buf,i)) { return -1; } else if (*ldns_buffer_at(rr1_buf,i) > *ldns_buffer_at(rr2_buf,i)) { @@ -1375,7 +1381,6 @@ ldns_rr_compare(const ldns_rr *rr1, const ldns_rr *rr2) ldns_buffer_free(rr2_buf); } - return result; }