diff options
author | Jakob Schlyter <jakob@cvs.openbsd.org> | 2007-12-09 13:39:46 +0000 |
---|---|---|
committer | Jakob Schlyter <jakob@cvs.openbsd.org> | 2007-12-09 13:39:46 +0000 |
commit | 1173d5eff8dc423c129f442023419436ee94db23 (patch) | |
tree | 57c2bcdc1429b2e80b91a387cd1dc561dab988eb /usr.sbin/bind/bin/dig/dig.c | |
parent | e4a92ccc5f8c866478b32a346c71150a2cdf5001 (diff) |
resolve conflicts
Diffstat (limited to 'usr.sbin/bind/bin/dig/dig.c')
-rw-r--r-- | usr.sbin/bind/bin/dig/dig.c | 321 |
1 files changed, 225 insertions, 96 deletions
diff --git a/usr.sbin/bind/bin/dig/dig.c b/usr.sbin/bind/bin/dig/dig.c index 14a5c4a0105..ae9f8721049 100644 --- a/usr.sbin/bind/bin/dig/dig.c +++ b/usr.sbin/bind/bin/dig/dig.c @@ -1,8 +1,8 @@ /* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $ISC: dig.c,v 1.157.2.13.2.31 2006/07/22 23:52:57 marka Exp $ */ +/* $ISC: dig.c,v 1.186.18.29 2007/08/28 07:19:55 tbox Exp $ */ + +/*! \file */ #include <config.h> #include <stdlib.h> @@ -40,6 +42,7 @@ #include <dns/rdatatype.h> #include <dns/rdataclass.h> #include <dns/result.h> +#include <dns/tsig.h> #include <bind9/getaddresses.h> @@ -67,6 +70,7 @@ static isc_boolean_t short_form = ISC_FALSE, printcmd = ISC_TRUE, ip6_int = ISC_FALSE, plusquest = ISC_FALSE, pluscomm = ISC_FALSE, multiline = ISC_FALSE, nottl = ISC_FALSE, noclass = ISC_FALSE; +/*% opcode text */ static const char *opcodetext[] = { "QUERY", "IQUERY", @@ -86,6 +90,7 @@ static const char *opcodetext[] = { "RESERVED15" }; +/*% return code text */ static const char *rcodetext[] = { "NOERROR", "FORMERR", @@ -106,6 +111,7 @@ static const char *rcodetext[] = { "BADVERS" }; +/*% print usage */ static void print_usage(FILE *fp) { fputs( @@ -122,11 +128,13 @@ usage(void) { exit(1); } +/*% version */ static void version(void) { fputs("DiG " VERSION "\n", stderr); } +/*% help */ static void help(void) { print_usage(stdout); @@ -141,10 +149,11 @@ help(void) { " -f filename (batch mode)\n" " -b address[#port] (bind to source address/port)\n" " -p port (specify port number)\n" +" -q name (specify query name)\n" " -t type (specify query type)\n" " -c class (specify query class)\n" " -k keyfile (specify tsig key file)\n" -" -y name:key (specify named base64 tsig key)\n" +" -y [hmac:]name:key (specify named base64 tsig key)\n" " -4 (use IPv4 query transport only)\n" " -6 (use IPv6 query transport only)\n" " d-opt is of the form +keyword[=value], where keyword is:\n" @@ -156,7 +165,9 @@ help(void) { " +domain=### (Set default domainname)\n" " +bufsize=### (Set EDNS0 Max UDP packet size)\n" " +ndots=### (Set NDOTS value)\n" +" +edns=### (Set EDNS version)\n" " +[no]search (Set whether to use searchlist)\n" +" +[no]showsearch (Search with intermediate results)\n" " +[no]defname (Ditto)\n" " +[no]recurse (Recursive mode)\n" " +[no]ignore (Don't revert to TCP for TC responses.)" @@ -198,7 +209,7 @@ help(void) { stdout); } -/* +/*% * Callback from dighost.c to print the received message. */ void @@ -219,10 +230,12 @@ received(int bytes, isc_sockaddr_t *from, dig_query_t *query) { time(&tnow); printf(";; WHEN: %s", ctime(&tnow)); if (query->lookup->doing_xfr) { - printf(";; XFR size: %u records (messages %u)\n", - query->rr_count, query->msg_count); + printf(";; XFR size: %u records (messages %u, " + "bytes %" ISC_PRINT_QUADFORMAT "u)\n", + query->rr_count, query->msg_count, + query->byte_count); } else { - printf(";; MSG SIZE rcvd: %d\n", bytes); + printf(";; MSG SIZE rcvd: %u\n", bytes); } if (key != NULL) { @@ -236,8 +249,11 @@ received(int bytes, isc_sockaddr_t *from, dig_query_t *query) { puts(""); } else if (query->lookup->identify && !short_form) { diff = isc_time_microdiff(&now, &query->time_sent); - printf(";; Received %u bytes from %s(%s) in %d ms\n\n", - bytes, fromtext, query->servname, + printf(";; Received %" ISC_PRINT_QUADFORMAT "u bytes " + "from %s(%s) in %d ms\n\n", + query->lookup->doing_xfr ? + query->byte_count : (isc_uint64_t)bytes, + fromtext, query->servname, (int)diff/1000); } } @@ -253,7 +269,7 @@ trying(char *frm, dig_lookup_t *lookup) { UNUSED(lookup); } -/* +/*% * Internal print routine used to print short form replies. */ static isc_result_t @@ -283,7 +299,7 @@ say_message(dns_rdata_t *rdata, dig_query_t *query, isc_buffer_t *buf) { return (ISC_R_SUCCESS); } -/* +/*% * short_form message print handler. Calls above say_message() */ static isc_result_t @@ -475,7 +491,16 @@ printmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers) { msg->counts[DNS_SECTION_ANSWER], msg->counts[DNS_SECTION_AUTHORITY], msg->counts[DNS_SECTION_ADDITIONAL]); + + if (msg != query->lookup->sendmsg && + (msg->flags & DNS_MESSAGEFLAG_RD) != 0 && + (msg->flags & DNS_MESSAGEFLAG_RA) == 0) + printf(";; WARNING: recursion requested " + "but not available\n"); } + if (msg != query->lookup->sendmsg && extrabytes != 0U) + printf(";; WARNING: Messages has %u extra byte%s at " + "end\n", extrabytes, extrabytes != 0 ? "s" : ""); } repopulate_buffer: @@ -578,7 +603,7 @@ cleanup: return (result); } -/* +/*% * print the greeting message when the program first starts up. */ static void @@ -616,42 +641,6 @@ printgreeting(int argc, char **argv, dig_lookup_t *lookup) { } } -/* - * Reorder an argument list so that server names all come at the end. - * This is a bit of a hack, to allow batch-mode processing to properly - * handle the server options. - */ -static void -reorder_args(int argc, char *argv[]) { - int i, j; - char *ptr; - int end; - - debug("reorder_args()"); - end = argc - 1; - while (argv[end][0] == '@') { - end--; - if (end == 0) - return; - } - debug("arg[end]=%s", argv[end]); - for (i = 1; i < end - 1; i++) { - if (argv[i][0] == '@') { - debug("arg[%d]=%s", i, argv[i]); - ptr = argv[i]; - for (j = i + 1; j < end; j++) { - debug("Moving %s to %d", argv[j], j - 1); - argv[j - 1] = argv[j]; - } - debug("moving %s to end, %d", ptr, end - 1); - argv[end - 1] = ptr; - end--; - if (end < 1) - return; - } - } -} - static isc_uint32_t parse_uint(char *arg, const char *desc, isc_uint32_t max) { isc_result_t result; @@ -665,7 +654,7 @@ parse_uint(char *arg, const char *desc, isc_uint32_t max) { return (tmp); } -/* +/*% * We're not using isc_commandline_parse() here since the command line * syntax of dig is quite a bit different from that which can be described * by that routine. @@ -804,6 +793,8 @@ plus_option(char *option, isc_boolean_t is_batchfile, break; case 'n': /* dnssec */ FULLCHECK("dnssec"); + if (state && lookup->edns == -1) + lookup->edns = 0; lookup->dnssec = state; break; case 'o': /* domain */ @@ -818,6 +809,16 @@ plus_option(char *option, isc_boolean_t is_batchfile, goto invalid_option; } break; + case 'e': + FULLCHECK("edns"); + if (!state) { + lookup->edns = -1; + break; + } + if (value == NULL) + goto need_value; + lookup->edns = (isc_int16_t) parse_uint(value, "edns", 255); + break; case 'f': /* fail */ FULLCHECK("fail"); lookup->servfail_stops = state; @@ -917,17 +918,30 @@ plus_option(char *option, isc_boolean_t is_batchfile, FULLCHECK("search"); usesearch = state; break; - case 'h': /* short */ - FULLCHECK("short"); - short_form = state; - if (state) { - printcmd = ISC_FALSE; - lookup->section_additional = ISC_FALSE; - lookup->section_answer = ISC_TRUE; - lookup->section_authority = ISC_FALSE; - lookup->section_question = ISC_FALSE; - lookup->comments = ISC_FALSE; - lookup->stats = ISC_FALSE; + case 'h': + if (cmd[2] != 'o') + goto invalid_option; + switch (cmd[3]) { + case 'r': /* short */ + FULLCHECK("short"); + short_form = state; + if (state) { + printcmd = ISC_FALSE; + lookup->section_additional = ISC_FALSE; + lookup->section_answer = ISC_TRUE; + lookup->section_authority = ISC_FALSE; + lookup->section_question = ISC_FALSE; + lookup->comments = ISC_FALSE; + lookup->stats = ISC_FALSE; + } + break; + case 'w': /* showsearch */ + FULLCHECK("showsearch"); + showsearch = state; + usesearch = state; + break; + default: + goto invalid_option; } break; #ifdef DIG_SIGCHASE @@ -1036,16 +1050,18 @@ plus_option(char *option, isc_boolean_t is_batchfile, return; } -/* - * ISC_TRUE returned if value was used +/*% + * #ISC_TRUE returned if value was used */ static const char *single_dash_opts = "46dhimnv"; static const char *dash_opts = "46bcdfhikmnptvyx"; static isc_boolean_t dash_option(char *option, char *next, dig_lookup_t **lookup, - isc_boolean_t *open_type_class) + isc_boolean_t *open_type_class, isc_boolean_t *need_clone, + isc_boolean_t config_only, int argc, char **argv, + isc_boolean_t *firstarg) { - char opt, *value, *ptr; + char opt, *value, *ptr, *ptr2, *ptr3; isc_result_t result; isc_boolean_t value_from_next; isc_textregion_t tr; @@ -1177,6 +1193,26 @@ dash_option(char *option, char *next, dig_lookup_t **lookup, case 'p': port = (in_port_t) parse_uint(value, "port number", MAXPORT); return (value_from_next); + case 'q': + if (!config_only) { + if (*need_clone) + (*lookup) = clone_lookup(default_lookup, + ISC_TRUE); + *need_clone = ISC_TRUE; + strncpy((*lookup)->textname, value, + sizeof((*lookup)->textname)); + (*lookup)->textname[sizeof((*lookup)->textname)-1]=0; + (*lookup)->trace_root = ISC_TF((*lookup)->trace || + (*lookup)->ns_search_only); + (*lookup)->new_search = ISC_TRUE; + if (*firstarg) { + printgreeting(argc, argv, *lookup); + *firstarg = ISC_FALSE; + } + ISC_LIST_APPEND(lookup_list, (*lookup), link); + debug("looking up %s", (*lookup)->textname); + } + return (value_from_next); case 't': *open_type_class = ISC_FALSE; if (strncasecmp(value, "ixfr=", 5) == 0) { @@ -1220,18 +1256,89 @@ dash_option(char *option, char *next, dig_lookup_t **lookup, value); return (value_from_next); case 'y': - ptr = next_token(&value,":"); + ptr = next_token(&value,":"); /* hmac type or name */ if (ptr == NULL) { usage(); } - strlcpy(keynametext, ptr, sizeof(keynametext)); - ptr = next_token(&value, ""); - if (ptr == NULL) + ptr2 = next_token(&value, ":"); /* name or secret */ + if (ptr2 == NULL) usage(); - strlcpy(keysecret, ptr, sizeof(keysecret)); + ptr3 = next_token(&value,":"); /* secret or NULL */ + if (ptr3 != NULL) { + if (strcasecmp(ptr, "hmac-md5") == 0) { + hmacname = DNS_TSIG_HMACMD5_NAME; + digestbits = 0; + } else if (strncasecmp(ptr, "hmac-md5-", 9) == 0) { + hmacname = DNS_TSIG_HMACMD5_NAME; + digestbits = parse_uint(&ptr[9], + "digest-bits [0..128]", + 128); + digestbits = (digestbits + 7) & ~0x7U; + } else if (strcasecmp(ptr, "hmac-sha1") == 0) { + hmacname = DNS_TSIG_HMACSHA1_NAME; + digestbits = 0; + } else if (strncasecmp(ptr, "hmac-sha1-", 10) == 0) { + hmacname = DNS_TSIG_HMACSHA1_NAME; + digestbits = parse_uint(&ptr[10], + "digest-bits [0..160]", + 160); + digestbits = (digestbits + 7) & ~0x7U; + } else if (strcasecmp(ptr, "hmac-sha224") == 0) { + hmacname = DNS_TSIG_HMACSHA224_NAME; + digestbits = 0; + } else if (strncasecmp(ptr, "hmac-sha224-", 12) == 0) { + hmacname = DNS_TSIG_HMACSHA224_NAME; + digestbits = parse_uint(&ptr[12], + "digest-bits [0..224]", + 224); + digestbits = (digestbits + 7) & ~0x7U; + } else if (strcasecmp(ptr, "hmac-sha256") == 0) { + hmacname = DNS_TSIG_HMACSHA256_NAME; + digestbits = 0; + } else if (strncasecmp(ptr, "hmac-sha256-", 12) == 0) { + hmacname = DNS_TSIG_HMACSHA256_NAME; + digestbits = parse_uint(&ptr[12], + "digest-bits [0..256]", + 256); + digestbits = (digestbits + 7) & ~0x7U; + } else if (strcasecmp(ptr, "hmac-sha384") == 0) { + hmacname = DNS_TSIG_HMACSHA384_NAME; + digestbits = 0; + } else if (strncasecmp(ptr, "hmac-sha384-", 12) == 0) { + hmacname = DNS_TSIG_HMACSHA384_NAME; + digestbits = parse_uint(&ptr[12], + "digest-bits [0..384]", + 384); + digestbits = (digestbits + 7) & ~0x7U; + } else if (strcasecmp(ptr, "hmac-sha512") == 0) { + hmacname = DNS_TSIG_HMACSHA512_NAME; + digestbits = 0; + } else if (strncasecmp(ptr, "hmac-sha512-", 12) == 0) { + hmacname = DNS_TSIG_HMACSHA512_NAME; + digestbits = parse_uint(&ptr[12], + "digest-bits [0..512]", + 512); + digestbits = (digestbits + 7) & ~0x7U; + } else { + fprintf(stderr, ";; Warning, ignoring " + "invalid TSIG algorithm %s\n", ptr); + return (value_from_next); + } + ptr = ptr2; + ptr2 = ptr3; + } else { + hmacname = DNS_TSIG_HMACMD5_NAME; + digestbits = 0; + } + strlcpy(keynametext, ptr, sizeof(keynametext)); + keynametext[sizeof(keynametext)-1]=0; + strlcpy(keysecret, ptr2, sizeof(keysecret)); + keysecret[sizeof(keysecret)-1]=0; return (value_from_next); case 'x': - *lookup = clone_lookup(default_lookup, ISC_TRUE); + if (*need_clone) + *lookup = clone_lookup(default_lookup, ISC_TRUE); + *need_clone = ISC_TRUE; if (get_reverse(textname, sizeof(textname), value, ip6_int, ISC_FALSE) == ISC_R_SUCCESS) { strlcpy((*lookup)->textname, textname, @@ -1245,6 +1352,10 @@ dash_option(char *option, char *next, dig_lookup_t **lookup, if (!(*lookup)->rdclassset) (*lookup)->rdclass = dns_rdataclass_in; (*lookup)->new_search = ISC_TRUE; + if (*firstarg) { + printgreeting(argc, argv, *lookup); + *firstarg = ISC_FALSE; + } ISC_LIST_APPEND(lookup_list, *lookup, link); } else { fprintf(stderr, "Invalid IP address %s\n", value); @@ -1259,10 +1370,11 @@ dash_option(char *option, char *next, dig_lookup_t **lookup, return (ISC_FALSE); } -/* +/*% * Because we may be trying to do memory allocation recording, we're going * to need to parse the arguments for the -m *before* we start the main * argument parsing routine. + * * I'd prefer not to have to do this, but I am not quite sure how else to * fix the problem. Argument parsing in dig involves memory allocation * by its nature, so it can't be done in the main argument parser. @@ -1335,6 +1447,8 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only, char rcfile[256]; #endif char *input; + int i; + isc_boolean_t need_clone = ISC_TRUE; /* * The semantics for parsing the args is a bit complex; if @@ -1382,7 +1496,9 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only, bargv[0] = argv[0]; argv0 = argv[0]; - reorder_args(bargc, (char **)bargv); + for(i = 0; i < bargc; i++) + debug(".digrc argv %d: %s", + i, bargv[i]); parse_args(ISC_TRUE, ISC_TRUE, bargc, (char **)bargv); } @@ -1391,7 +1507,12 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only, #endif } - lookup = default_lookup; + if (is_batchfile && !config_only) { + /* Processing '-f batchfile'. */ + lookup = clone_lookup(default_lookup, ISC_TRUE); + need_clone = ISC_FALSE; + } else + lookup = default_lookup; rc = argc; rv = argv; @@ -1407,13 +1528,17 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only, } else if (rv[0][0] == '-') { if (rc <= 1) { if (dash_option(&rv[0][1], NULL, - &lookup, &open_type_class)) { + &lookup, &open_type_class, + &need_clone, config_only, + argc, argv, &firstarg)) { rc--; rv++; } } else { if (dash_option(&rv[0][1], rv[1], - &lookup, &open_type_class)) { + &lookup, &open_type_class, + &need_clone, config_only, + argc, argv, &firstarg)) { rc--; rv++; } @@ -1481,20 +1606,28 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only, continue; } } + if (!config_only) { - lookup = clone_lookup(default_lookup, - ISC_TRUE); + if (need_clone) + lookup = clone_lookup(default_lookup, + ISC_TRUE); + need_clone = ISC_TRUE; strlcpy(lookup->textname, rv[0], sizeof(lookup->textname)); lookup->trace_root = ISC_TF(lookup->trace || lookup->ns_search_only); lookup->new_search = ISC_TRUE; + if (firstarg) { + printgreeting(argc, argv, lookup); + firstarg = ISC_FALSE; + } ISC_LIST_APPEND(lookup_list, lookup, link); debug("looking up %s", lookup->textname); } /* XXX Error message */ } } + /* * If we have a batchfile, seed the lookup list with the * first entry, then trust the callback in dighost_shutdown @@ -1529,15 +1662,20 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only, bargv[0] = argv[0]; argv0 = argv[0]; - reorder_args(bargc, (char **)bargv); + for(i = 0; i < bargc; i++) + debug("batch argv %d: %s", i, bargv[i]); parse_args(ISC_TRUE, ISC_FALSE, bargc, (char **)bargv); + return; } + return; } /* * If no lookup specified, search for root */ if ((lookup_list.head == NULL) && !config_only) { - lookup = clone_lookup(default_lookup, ISC_TRUE); + if (need_clone) + lookup = clone_lookup(default_lookup, ISC_TRUE); + need_clone = ISC_TRUE; lookup->trace_root = ISC_TF(lookup->trace || lookup->ns_search_only); lookup->new_search = ISC_TRUE; @@ -1549,10 +1687,9 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only, firstarg = ISC_FALSE; } ISC_LIST_APPEND(lookup_list, lookup, link); - } else if (!config_only && firstarg) { - printgreeting(argc, argv, lookup); - firstarg = ISC_FALSE; } + if (!need_clone) + destroy_lookup(lookup); } /* @@ -1566,7 +1703,7 @@ dighost_shutdown(void) { int bargc; char *bargv[16]; char *input; - + int i; if (batchname == NULL) { isc_app_shutdown(); @@ -1594,7 +1731,8 @@ dighost_shutdown(void) { bargv[0] = argv0; - reorder_args(bargc, (char **)bargv); + for(i = 0; i < bargc; i++) + debug("batch argv %d: %s", i, bargv[i]); parse_args(ISC_TRUE, ISC_FALSE, bargc, (char **)bargv); start_lookup(); } else { @@ -1606,10 +1744,10 @@ dighost_shutdown(void) { } } +/*% Main processing routine for dig */ int main(int argc, char **argv) { isc_result_t result; - dig_server_t *s, *s2; ISC_LIST_INIT(lookup_list); ISC_LIST_INIT(server_list); @@ -1630,16 +1768,7 @@ main(int argc, char **argv) { result = isc_app_onrun(mctx, global_task, onrun_callback, NULL); check_result(result, "isc_app_onrun"); isc_app_run(); - s = ISC_LIST_HEAD(default_lookup->my_server_list); - while (s != NULL) { - debug("freeing server %p belonging to %p", - s, default_lookup); - s2 = s; - s = ISC_LIST_NEXT(s, link); - ISC_LIST_DEQUEUE(default_lookup->my_server_list, s2, link); - isc_mem_free(mctx, s2); - } - isc_mem_free(mctx, default_lookup); + destroy_lookup(default_lookup); if (batchname != NULL) { if (batchfp != stdin) fclose(batchfp); |