aboutsummaryrefslogtreecommitdiffstats
path: root/drill/drill.c
diff options
context:
space:
mode:
Diffstat (limited to 'drill/drill.c')
-rw-r--r--drill/drill.c181
1 files changed, 110 insertions, 71 deletions
diff --git a/drill/drill.c b/drill/drill.c
index b967ad949c8d..3a9482b38633 100644
--- a/drill/drill.c
+++ b/drill/drill.c
@@ -14,11 +14,22 @@
#include <openssl/err.h>
#endif
-#define IP6_ARPA_MAX_LEN 65
-
/* query debug, 2 hex dumps */
int verbosity;
+static int
+is_ixfr_with_serial(const char* name, uint32_t *serial)
+{
+ char* end;
+ if (strlen(name) > 5 &&
+ strncasecmp(name, "IXFR", 4) == 0 &&
+ name[4] == '=') {
+ *serial = (uint32_t) strtol((name+5), &end, 10);
+ return 1;
+ }
+ return 0;
+}
+
static void
usage(FILE *stream, const char *progname)
{
@@ -31,7 +42,7 @@ usage(FILE *stream, const char *progname)
fprintf(stream, "\t-D\t\tenable DNSSEC (DO bit)\n");
#ifdef HAVE_SSL
fprintf(stream, "\t-T\t\ttrace from the root down to <name>\n");
- fprintf(stream, "\t-S\t\tchase signature(s) from <name> to a know key [*]\n");
+ fprintf(stream, "\t-S\t\tchase signature(s) from <name> to a known key [*]\n");
#endif /*HAVE_SSL*/
fprintf(stream, "\t-I <address>\tsource address to query from\n");
fprintf(stream, "\t-V <number>\tverbosity (0-5)\n");
@@ -106,15 +117,14 @@ main(int argc, char *argv[])
char *serv;
char *src = NULL;
const char *name;
- char *name2;
char *progname;
char *query_file = NULL;
char *answer_file = NULL;
ldns_buffer *query_buffer = NULL;
ldns_rdf *serv_rdf;
ldns_rdf *src_rdf = NULL;
- ldns_rr_type type;
- ldns_rr_class clas;
+ ldns_rr_type type;
+ ldns_rr_class clas;
#if 0
ldns_pkt_opcode opcode = LDNS_PACKET_QUERY;
#endif
@@ -130,7 +140,7 @@ main(int argc, char *argv[])
ldns_rr *axfr_rr;
ldns_status status;
char *type_str;
-
+ uint32_t serial = 0;
/* list of keys used in dnssec operations */
ldns_rr_list *key_list = ldns_rr_list_new();
/* what key verify the current answer */
@@ -153,6 +163,9 @@ main(int argc, char *argv[])
int result = 0;
+ uint8_t s6addr[16];
+ char ip6_arpa_str[74];
+
#ifdef USE_WINSOCK
int r;
WSADATA wsa_data;
@@ -188,12 +201,6 @@ main(int argc, char *argv[])
ldns_init_random(NULL, 0);
- if (argc == 0) {
- usage(stdout, progname);
- result = EXIT_FAILURE;
- goto exit;
- }
-
/* string from orig drill: "i:w:I46Sk:TNp:b:DsvhVcuaq:f:xr" */
/* global first, query opt next, option with parm's last
* and sorted */ /* "46DITSVQf:i:w:q:achuvxzy:so:p:b:k:" */
@@ -363,9 +370,7 @@ main(int argc, char *argv[])
tsig_algorithm[strlen(optarg) - tsig_separator2 - 1] = '\0';
} else {
tsig_separator2 = strlen(optarg);
- tsig_algorithm = xmalloc(26);
- strncpy(tsig_algorithm, "hmac-md5.sig-alg.reg.int.", 25);
- tsig_algorithm[25] = '\0';
+ tsig_algorithm = strdup("hmac-md5.sig-alg.reg.int");
}
tsig_name = xmalloc(tsig_separator + 1);
tsig_data = xmalloc(tsig_separator2 - tsig_separator);
@@ -453,6 +458,10 @@ main(int argc, char *argv[])
if (type != 0) {
int_type = 0;
continue;
+ } else if (is_ixfr_with_serial(argv[i], &serial)) {
+ type = LDNS_RR_TYPE_IXFR;
+ int_type = 0;
+ continue;
}
}
/* if it matches a class, it's a class */
@@ -488,14 +497,20 @@ main(int argc, char *argv[])
if (src) {
src_rdf = ldns_rdf_new_addr_frm_str(src);
if(!src_rdf) {
- fprintf(stderr, "-I must be (or resolve) to a valid IP[v6] address.\n");
+ fprintf(stderr, "-I must be a valid IP[v6] address.\n");
exit(EXIT_FAILURE);
}
+ if (ldns_rdf_size(src_rdf) == 4) {
+ qfamily = LDNS_RESOLV_INET;
+
+ } else if (ldns_rdf_size(src_rdf) == 16) {
+ qfamily = LDNS_RESOLV_INET6;
+ }
}
/* set the nameserver to use */
if (!serv) {
- /* no server given make a resolver from /etc/resolv.conf */
+ /* no server given -- make a resolver from /etc/resolv.conf */
status = ldns_resolver_new_frm_file(&res, resolv_conf_file);
if (status != LDNS_STATUS_OK) {
warning("Could not create a resolver structure: %s (%s)\n"
@@ -516,7 +531,7 @@ main(int argc, char *argv[])
if (!serv_rdf) {
/* try to resolv the name if possible */
status = ldns_resolver_new_frm_file(&cmdline_res, resolv_conf_file);
-
+
if (status != LDNS_STATUS_OK) {
error("%s", "@server ip could not be converted");
}
@@ -554,6 +569,7 @@ main(int argc, char *argv[])
}
}
/* set the resolver options */
+ ldns_resolver_set_ixfr_serial(res, serial);
ldns_resolver_set_port(res, qport);
ldns_resolver_set_source(res, src_rdf);
if (verbosity >= 5) {
@@ -581,6 +597,39 @@ main(int argc, char *argv[])
}
if (tsig_name && tsig_data) {
+ /* With dig TSIG keys are also specified with -y,
+ * but format with drill is: -y <name:key[:algo]>
+ * and with dig: -y [hmac:]name:key
+ *
+ * When we detect an unknown tsig algorithm in algo,
+ * but a known algorithm in name, we cane assume dig
+ * order was used.
+ *
+ * Following if statement is to anticipate and correct dig order
+ */
+ if ( strcasecmp(tsig_algorithm, "hmac-md5.sig-alg.reg.int")
+ && strcasecmp(tsig_algorithm, "hmac-md5")
+ && strcasecmp(tsig_algorithm, "hmac-sha1")
+ && strcasecmp(tsig_algorithm, "hmac-sha256")
+ && (
+ strcasecmp(tsig_name, "hmac-md5.sig-alg.reg.int") == 0
+ || strcasecmp(tsig_name, "hmac-md5") == 0
+ || strcasecmp(tsig_name, "hmac-sha1") == 0
+ || strcasecmp(tsig_name, "hmac-sha256") == 0
+ )) {
+
+ /* Roll options */
+ char *tmp_tsig_algorithm = tsig_name;
+ tsig_name = tsig_data;
+ tsig_data = tsig_algorithm;
+ tsig_algorithm = tmp_tsig_algorithm;
+ }
+
+ if (strcasecmp(tsig_algorithm, "hmac-md5") == 0) {
+ free(tsig_algorithm);
+ tsig_algorithm = strdup("hmac-md5.sig-alg.reg.int");
+ }
+
ldns_resolver_set_tsig_keyname(res, tsig_name);
ldns_resolver_set_tsig_keydata(res, tsig_data);
ldns_resolver_set_tsig_algorithm(res, tsig_algorithm);
@@ -598,7 +647,7 @@ main(int argc, char *argv[])
error("%s", "parsing query name");
}
/* don't care about return packet */
- (void)do_trace(res, qname, type, clas);
+ do_trace(res, qname, type, clas);
clear_root();
break;
case DRILL_SECTRACE:
@@ -650,8 +699,7 @@ main(int argc, char *argv[])
ldns_resolver_set_dnssec_anchors(res, ldns_rr_list_clone(key_list));
result = do_chase(res, qname, type,
clas, key_list,
- pkt, qflags, NULL,
- verbosity);
+ pkt, qflags, NULL);
if (result == LDNS_STATUS_OK) {
if (verbosity != -1) {
mesg("Chase successful");
@@ -682,7 +730,6 @@ main(int argc, char *argv[])
if (!qname) {
error("%s", "making qname");
}
-
status = ldns_resolver_prepare_query_pkt(&qpkt, res, qname, type, clas, qflags);
if(status != LDNS_STATUS_OK) {
error("%s", "making query: %s",
@@ -696,55 +743,48 @@ main(int argc, char *argv[])
case DRILL_REVERSE:
/* ipv4 or ipv6 addr? */
if (strchr(name, ':')) {
- if (strchr(name, '.')) {
- error("Syntax error: both '.' and ':' seen in address\n");
- }
- name2 = malloc(IP6_ARPA_MAX_LEN + 20);
- c = 0;
- for (i=0; i<(int)strlen(name); i++) {
- if (i >= IP6_ARPA_MAX_LEN) {
- error("%s", "reverse argument to long");
- }
- if (name[i] == ':') {
- if (i < (int) strlen(name) && name[i + 1] == ':') {
- error("%s", ":: not supported (yet)");
- } else {
- if (i + 2 == (int) strlen(name) || name[i + 2] == ':') {
- name2[c++] = '0';
- name2[c++] = '.';
- name2[c++] = '0';
- name2[c++] = '.';
- name2[c++] = '0';
- name2[c++] = '.';
- } else if (i + 3 == (int) strlen(name) || name[i + 3] == ':') {
- name2[c++] = '0';
- name2[c++] = '.';
- name2[c++] = '0';
- name2[c++] = '.';
- } else if (i + 4 == (int) strlen(name) || name[i + 4] == ':') {
- name2[c++] = '0';
- name2[c++] = '.';
- }
- }
- } else {
- name2[c++] = name[i];
- name2[c++] = '.';
- }
+ if (!inet_pton(AF_INET6, name, &s6addr)) {
+ error("Syntax error: cannot parse IPv6 address\n");
}
- name2[c++] = '\0';
-
- qname = ldns_dname_new_frm_str(name2);
- qname_tmp = ldns_dname_reverse(qname);
- ldns_rdf_deep_free(qname);
- qname = qname_tmp;
- qname_tmp = ldns_dname_new_frm_str("ip6.arpa.");
- status = ldns_dname_cat(qname, qname_tmp);
- if (status != LDNS_STATUS_OK) {
- error("%s", "could not create reverse address for ip6: %s\n", ldns_get_errorstr_by_id(status));
- }
- ldns_rdf_deep_free(qname_tmp);
+ (void) snprintf(ip6_arpa_str, sizeof(ip6_arpa_str),
+ "%x.%x.%x.%x.%x.%x.%x.%x."
+ "%x.%x.%x.%x.%x.%x.%x.%x."
+ "%x.%x.%x.%x.%x.%x.%x.%x."
+ "%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa.",
+ (unsigned int)(s6addr[15] & 0x0F),
+ (unsigned int)(s6addr[15] >> 4),
+ (unsigned int)(s6addr[14] & 0x0F),
+ (unsigned int)(s6addr[14] >> 4),
+ (unsigned int)(s6addr[13] & 0x0F),
+ (unsigned int)(s6addr[13] >> 4),
+ (unsigned int)(s6addr[12] & 0x0F),
+ (unsigned int)(s6addr[12] >> 4),
+ (unsigned int)(s6addr[11] & 0x0F),
+ (unsigned int)(s6addr[11] >> 4),
+ (unsigned int)(s6addr[10] & 0x0F),
+ (unsigned int)(s6addr[10] >> 4),
+ (unsigned int)(s6addr[9] & 0x0F),
+ (unsigned int)(s6addr[9] >> 4),
+ (unsigned int)(s6addr[8] & 0x0F),
+ (unsigned int)(s6addr[8] >> 4),
+ (unsigned int)(s6addr[7] & 0x0F),
+ (unsigned int)(s6addr[7] >> 4),
+ (unsigned int)(s6addr[6] & 0x0F),
+ (unsigned int)(s6addr[6] >> 4),
+ (unsigned int)(s6addr[5] & 0x0F),
+ (unsigned int)(s6addr[5] >> 4),
+ (unsigned int)(s6addr[4] & 0x0F),
+ (unsigned int)(s6addr[4] >> 4),
+ (unsigned int)(s6addr[3] & 0x0F),
+ (unsigned int)(s6addr[3] >> 4),
+ (unsigned int)(s6addr[2] & 0x0F),
+ (unsigned int)(s6addr[2] >> 4),
+ (unsigned int)(s6addr[1] & 0x0F),
+ (unsigned int)(s6addr[1] >> 4),
+ (unsigned int)(s6addr[0] & 0x0F),
+ (unsigned int)(s6addr[0] >> 4));
- free(name2);
+ qname = ldns_dname_new_frm_str(ip6_arpa_str);
} else {
qname = ldns_dname_new_frm_str(name);
qname_tmp = ldns_dname_reverse(qname);
@@ -974,7 +1014,6 @@ main(int argc, char *argv[])
xfree(tsig_algorithm);
#ifdef HAVE_SSL
- ERR_remove_state(0);
CRYPTO_cleanup_all_ex_data();
ERR_free_strings();
EVP_cleanup();