From: Evan Hunt Date: Wed, 17 Jul 2019 06:44:20 +0000 (-0700) Subject: add "dig +yaml" output format X-Git-Tag: v9.15.4~29^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=71325852f1a52fcd0875d152344373eed87f56b5;p=thirdparty%2Fbind9.git add "dig +yaml" output format --- diff --git a/bin/dig/dig.c b/bin/dig/dig.c index 1c425fddf66..51b52b6ba6b 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -64,7 +64,8 @@ static char hexcookie[81]; static bool short_form = false, printcmd = true, plusquest = false, pluscomm = false, - ipv4only = false, ipv6only = false, digrc = true; + ipv4only = false, ipv6only = false, digrc = true, + yaml = false; static uint32_t splitwidth = 0xffffffff; /*% opcode text */ @@ -262,7 +263,11 @@ received(unsigned int bytes, isc_sockaddr_t *from, dig_query_t *query) { isc_sockaddr_format(from, fromtext, sizeof(fromtext)); - if (query->lookup->stats && !short_form) { + if (short_form || yaml) { + return; + } + + if (query->lookup->stats) { diff = isc_time_microdiff(&query->time_recv, &query->time_sent); if (query->lookup->use_usec) printf(";; Query time: %ld usec\n", (long) diff); @@ -283,11 +288,15 @@ received(unsigned int bytes, isc_sockaddr_t *from, dig_query_t *query) { */ if (wcsftime(time_str, sizeof(time_str)/sizeof(time_str[0]), L"%a %b %d %H:%M:%S %Z %Y", &tmnow) > 0U) + { printf(";; WHEN: %ls\n", time_str); + } #else if (strftime(time_str, sizeof(time_str), "%a %b %d %H:%M:%S %Z %Y", &tmnow) > 0U) + { printf(";; WHEN: %s\n", time_str); + } #endif if (query->lookup->doing_xfr) { printf(";; XFR size: %u records (messages %u, " @@ -298,30 +307,32 @@ received(unsigned int bytes, isc_sockaddr_t *from, dig_query_t *query) { printf(";; MSG SIZE rcvd: %u\n", bytes); } if (tsigkey != NULL) { - if (!validated) + if (!validated) { puts(";; WARNING -- Some TSIG could not " "be validated"); + } } if ((tsigkey == NULL) && (keysecret[0] != 0)) { puts(";; WARNING -- TSIG key was not used."); } puts(""); - } else if (query->lookup->identify && !short_form) { + } else if (query->lookup->identify) { diff = isc_time_microdiff(&query->time_recv, &query->time_sent); - if (query->lookup->use_usec) + if (query->lookup->use_usec) { printf(";; Received %" PRIu64 " bytes " "from %s(%s) in %ld us\n\n", query->lookup->doing_xfr ? query->byte_count : (uint64_t)bytes, fromtext, query->userarg, (long) diff); - else + } else { printf(";; Received %" PRIu64 " bytes " "from %s(%s) in %ld ms\n\n", query->lookup->doing_xfr ? query->byte_count : (uint64_t)bytes, fromtext, query->userarg, (long) diff / 1000); + } } } @@ -364,18 +375,20 @@ say_message(dns_rdata_t *rdata, dig_query_t *query, isc_buffer_t *buf) { styleflags |= DNS_STYLEFLAG_EXPANDAAAA; result = dns_rdata_tofmttext(rdata, NULL, styleflags, 0, splitwidth, " ", buf); - if (result == ISC_R_NOSPACE) + if (result == ISC_R_NOSPACE) { return (result); + } check_result(result, "dns_rdata_totext"); if (query->lookup->identify) { - diff = isc_time_microdiff(&query->time_recv, &query->time_sent); ADD_STRING(buf, " from server "); ADD_STRING(buf, query->servname); if (query->lookup->use_usec) { - snprintf(store, sizeof(store), " in %" PRIu64 " us.", diff); + snprintf(store, sizeof(store), + " in %" PRIu64 " us.", diff); } else { - snprintf(store, sizeof(store), " in %" PRIu64 " ms.", diff / 1000); + snprintf(store, sizeof(store), + " in %" PRIu64 " ms.", diff / 1000); } ADD_STRING(buf, store); } @@ -415,8 +428,7 @@ short_answer(dns_message_t *msg, dns_messagetextflag_t flags, loopresult = dns_rdataset_first(rdataset); while (loopresult == ISC_R_SUCCESS) { dns_rdataset_current(rdataset, &rdata); - result = say_message(&rdata, query, - buf); + result = say_message(&rdata, query, buf); if (result == ISC_R_NOSPACE) return (result); check_result(result, "say_message"); @@ -458,63 +470,85 @@ isdotlocal(dns_message_t *msg) { * Callback from dighost.c to print the reply from a server */ static isc_result_t -printmessage(dig_query_t *query, dns_message_t *msg, bool headers) { +printmessage(dig_query_t *query, const isc_buffer_t *msgbuf, + dns_message_t *msg, bool headers) +{ isc_result_t result; dns_messagetextflag_t flags; isc_buffer_t *buf = NULL; unsigned int len = OUTPUTBUF; dns_master_style_t *style = NULL; unsigned int styleflags = 0; + bool isquery = (msg == query->lookup->sendmsg); + + UNUSED(msgbuf); styleflags |= DNS_STYLEFLAG_REL_OWNER; - if (query->lookup->comments) - styleflags |= DNS_STYLEFLAG_COMMENT; - if (query->lookup->print_unknown_format) - styleflags |= DNS_STYLEFLAG_UNKNOWNFORMAT; - /* Turn on rrcomments if explicitly enabled */ - if (query->lookup->rrcomments > 0) - styleflags |= DNS_STYLEFLAG_RRCOMMENT; - if (query->lookup->ttlunits) - styleflags |= DNS_STYLEFLAG_TTL_UNITS; - if (query->lookup->nottl) - styleflags |= DNS_STYLEFLAG_NO_TTL; - if (query->lookup->noclass) - styleflags |= DNS_STYLEFLAG_NO_CLASS; - if (query->lookup->nocrypto) - styleflags |= DNS_STYLEFLAG_NOCRYPTO; - if (query->lookup->expandaaaa) - styleflags |= DNS_STYLEFLAG_EXPANDAAAA; - if (query->lookup->multiline) { - styleflags |= DNS_STYLEFLAG_OMIT_OWNER; - styleflags |= DNS_STYLEFLAG_OMIT_CLASS; - styleflags |= DNS_STYLEFLAG_REL_DATA; - styleflags |= DNS_STYLEFLAG_OMIT_TTL; - styleflags |= DNS_STYLEFLAG_TTL; - styleflags |= DNS_STYLEFLAG_MULTILINE; - /* Turn on rrcomments unless explicitly disabled */ - if (query->lookup->rrcomments >= 0) + if (yaml) { + dns_master_indentstr = " "; + dns_master_indent = 3; + styleflags |= DNS_STYLEFLAG_YAML; + } else { + if (query->lookup->comments) { + styleflags |= DNS_STYLEFLAG_COMMENT; + } + if (query->lookup->print_unknown_format) { + styleflags |= DNS_STYLEFLAG_UNKNOWNFORMAT; + } + /* Turn on rrcomments if explicitly enabled */ + if (query->lookup->rrcomments > 0) { styleflags |= DNS_STYLEFLAG_RRCOMMENT; + } + if (query->lookup->ttlunits) { + styleflags |= DNS_STYLEFLAG_TTL_UNITS; + } + if (query->lookup->nottl) { + styleflags |= DNS_STYLEFLAG_NO_TTL; + } + if (query->lookup->noclass) { + styleflags |= DNS_STYLEFLAG_NO_CLASS; + } + if (query->lookup->nocrypto) { + styleflags |= DNS_STYLEFLAG_NOCRYPTO; + } + if (query->lookup->expandaaaa) { + styleflags |= DNS_STYLEFLAG_EXPANDAAAA; + } + if (query->lookup->multiline) { + styleflags |= DNS_STYLEFLAG_OMIT_OWNER; + styleflags |= DNS_STYLEFLAG_OMIT_CLASS; + styleflags |= DNS_STYLEFLAG_REL_DATA; + styleflags |= DNS_STYLEFLAG_OMIT_TTL; + styleflags |= DNS_STYLEFLAG_TTL; + styleflags |= DNS_STYLEFLAG_MULTILINE; + /* Turn on rrcomments unless explicitly disabled */ + if (query->lookup->rrcomments >= 0) { + styleflags |= DNS_STYLEFLAG_RRCOMMENT; + } + } } if (query->lookup->multiline || (query->lookup->nottl && query->lookup->noclass)) + { result = dns_master_stylecreate(&style, styleflags, 24, 24, 24, 32, 80, 8, splitwidth, mctx); - else if (query->lookup->nottl || query->lookup->noclass) + } else if (query->lookup->nottl || query->lookup->noclass) { result = dns_master_stylecreate(&style, styleflags, 24, 24, 32, 40, 80, 8, splitwidth, mctx); - else + } else { result = dns_master_stylecreate(&style, styleflags, 24, 32, 40, 48, 80, 8, splitwidth, mctx); + } check_result(result, "dns_master_stylecreate"); if (query->lookup->cmdline[0] != 0) { if (!short_form && printcmd) { fputs(query->lookup->cmdline, stdout); } - query->lookup->cmdline[0]=0; + query->lookup->cmdline[0] = '\0'; } debug("printmessage(%s %s %s)", headers ? "headers" : "noheaders", query->lookup->comments ? "comments" : "nocomments", @@ -535,13 +569,110 @@ printmessage(dig_query_t *query, dns_message_t *msg, bool headers) { result = isc_buffer_allocate(mctx, &buf, len); check_result(result, "isc_buffer_allocate"); - if (query->lookup->comments && !short_form) { - if (query->lookup->cmdline[0] != 0 && printcmd) + if (yaml) { + enum { Q = 0x1, R = 0x2 }; /* Q:query; R:ecursive */ + unsigned int tflag = 0; + isc_sockaddr_t saddr; + char sockstr[ISC_SOCKADDR_FORMATSIZE]; + uint16_t sport; + char *hash; + int pf; + + printf("-\n"); + printf(" type: MESSAGE\n"); + printf(" message:\n"); + + if (isquery) { + tflag |= Q; + if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0) { + tflag |= R; + } + } else if (((msg->flags & DNS_MESSAGEFLAG_RD) != 0) && + ((msg->flags & DNS_MESSAGEFLAG_RA) != 0)) + { + tflag |= R; + } + + if (tflag == (Q|R)) { + printf(" type: RECURSIVE_QUERY\n"); + } else if (tflag == Q) { + printf(" type: AUTH_QUERY\n"); + } else if (tflag == R) { + printf(" type: RECURSIVE_RESPONSE\n"); + } else { + printf(" type: AUTH_RESPONSE\n"); + } + + if (!isc_time_isepoch(&query->time_sent)) { + char tbuf[100]; + isc_time_formatISO8601ms(&query->time_sent, + tbuf, sizeof(tbuf)); + printf(" query_time: !!timestamp %s\n", tbuf); + } + + if (!isquery && !isc_time_isepoch(&query->time_recv)) { + char tbuf[100]; + isc_time_formatISO8601ms(&query->time_recv, + tbuf, sizeof(tbuf)); + printf(" response_time: !!timestamp %s\n", tbuf); + } + + printf(" message_size: %ub\n", + isc_buffer_usedlength(msgbuf)); + + pf = isc_sockaddr_pf(&query->sockaddr); + if (pf == PF_INET || pf == PF_INET6) { + printf(" socket_family: %s\n", + pf == PF_INET ? "INET" : "INET6"); + + printf(" socket_protocol: %s\n", + query->lookup->tcp_mode ? "TCP" : "UDP"); + + sport = isc_sockaddr_getport(&query->sockaddr); + isc_sockaddr_format(&query->sockaddr, + sockstr, sizeof(sockstr)); + hash = strchr(sockstr, '#'); + if (hash != NULL) { + *hash = '\0'; + } + if (strcmp(sockstr, "::") == 0) { + strlcat(sockstr, "0", sizeof(sockstr)); + } + + printf(" response_address: %s\n", sockstr); + printf(" response_port: %u\n", sport); + } + + if (query->sock != NULL && + isc_socket_getsockname(query->sock, &saddr) + == ISC_R_SUCCESS) + { + sport = isc_sockaddr_getport(&saddr); + isc_sockaddr_format(&saddr, sockstr, sizeof(sockstr)); + hash = strchr(sockstr, '#'); + if (hash != NULL) { + *hash = '\0'; + } + if (strcmp(sockstr, "::") == 0) { + strlcat(sockstr, "0", sizeof(sockstr)); + } + + printf(" query_address: %s\n", sockstr); + printf(" query_port: %u\n", sport); + } + + printf(" %s:\n", isquery ? "query_message_data" + : "response_message_data"); + result = dns_message_headertotext(msg, style, flags, buf); + } else if (query->lookup->comments && !short_form) { + if (query->lookup->cmdline[0] != '\0' && printcmd) { printf("; %s\n", query->lookup->cmdline); - if (msg == query->lookup->sendmsg) + } + if (msg == query->lookup->sendmsg) { printf(";; Sending:\n"); - else + } else { printf(";; Got answer:\n"); + } if (headers) { if (isdotlocal(msg)) { @@ -686,8 +817,9 @@ buftoosmall: } } - if (headers && query->lookup->comments && !short_form) + if (headers && query->lookup->comments && !short_form && !yaml) { printf("\n"); + } printf("%.*s", (int)isc_buffer_usedlength(buf), (char *)isc_buffer_base(buf)); @@ -1545,6 +1677,15 @@ plus_option(char *option, bool is_batchfile, lookup->tcp_mode_set = true; } break; + case 'y': /* yaml */ + FULLCHECK("yaml"); + yaml = state; + if (state) { + printcmd = false; + lookup->stats = false; + lookup->rrcomments = -1; + } + break; case 'z': /* zflag */ FULLCHECK("zflag"); lookup->zflag = state; @@ -2257,8 +2398,37 @@ query_finished(void) { } } -void dig_setup(int argc, char **argv) -{ +static void +dig_error(const char *format, ...) { + va_list args; + + if (yaml) { + printf("-\n"); + printf(" type: DIG_ERROR\n"); + + /* + * Print an indent before a literal block quote. + * Note: this will break if used to print more than + * one line of text as only the first line would be + * indented. + */ + printf(" message: |\n"); + printf(" "); + } else { + printf(";; "); + } + + va_start(args, format); + vprintf(format, args); + va_end(args); + + if (!yaml) { + printf("\n"); + } +} + +void +dig_setup(int argc, char **argv) { isc_result_t result; ISC_LIST_INIT(lookup_list); @@ -2272,6 +2442,7 @@ void dig_setup(int argc, char **argv) dighost_received = received; dighost_trying = trying; dighost_shutdown = query_finished; + dighost_error = dig_error; progname = argv[0]; preparse_args(argc, argv); diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index b20cb05c9c6..d9ee70bcf12 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -193,11 +193,15 @@ dig_lookup_t *current_lookup = NULL; /* dynamic callbacks */ isc_result_t -(*dighost_printmessage)(dig_query_t *query, dns_message_t *msg, - bool headers); +(*dighost_printmessage)(dig_query_t *query, const isc_buffer_t *msgbuf, + dns_message_t *msg, bool headers); void -(*dighost_received)(unsigned int bytes, isc_sockaddr_t *from, dig_query_t *query); +(*dighost_error)(const char *format, ...); + +void +(*dighost_received)(unsigned int bytes, isc_sockaddr_t *from, + dig_query_t *query); void (*dighost_trying)(char *frm, dig_lookup_t *lookup); @@ -2501,6 +2505,9 @@ setup_lookup(dig_lookup_t *lookup) { COMMSIZE); query->sendbuf = lookup->renderbuf; + isc_time_settoepoch(&query->time_sent); + isc_time_settoepoch(&query->time_recv); + ISC_LINK_INIT(query, clink); ISC_LINK_INIT(query, link); @@ -2509,16 +2516,6 @@ setup_lookup(dig_lookup_t *lookup) { ISC_LIST_ENQUEUE(lookup->q, query, link); } - /* XXX qrflag, print_query, etc... */ - if (!ISC_LIST_EMPTY(lookup->q) && lookup->qr) { - extrabytes = 0; - dighost_printmessage(ISC_LIST_HEAD(lookup->q), - lookup->sendmsg, true); - if (lookup->stats) { - printf(";; QUERY SIZE: %u\n\n", - isc_buffer_usedlength(&lookup->renderbuf)); - } - } return (true); } @@ -2856,6 +2853,18 @@ send_udp(dig_query_t *query) { sevent, ISC_SOCKFLAG_NORETRY); check_result(result, "isc_socket_sendto2"); sendcount++; + + /* XXX qrflag, print_query, etc... */ + if (!ISC_LIST_EMPTY(query->lookup->q) && query->lookup->qr) { + extrabytes = 0; + dighost_printmessage(ISC_LIST_HEAD(query->lookup->q), + &query->lookup->renderbuf, + query->lookup->sendmsg, true); + if (query->lookup->stats) { + printf(";; QUERY SIZE: %u\n\n", + isc_buffer_usedlength(&query->lookup->renderbuf)); + } + } } /*% @@ -2955,11 +2964,11 @@ connect_timeout(isc_task_t *task, isc_event_t *event) { isc_netaddr_fromsockaddr(&netaddr, &query->sockaddr); isc_netaddr_format(&netaddr, buf, sizeof(buf)); - printf(";; no response from %s\n", buf); + dighost_error("no response from %s\n", buf); } else { fputs(l->cmdline, stdout); - printf(";; connection timed out; no servers could be " - "reached\n"); + dighost_error("connection timed out; " + "no servers could be reached\n"); } cancel_lookup(l); check_next_lookup(l); @@ -3031,8 +3040,8 @@ tcp_length_done(isc_task_t *task, isc_event_t *event) { char sockstr[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(&query->sockaddr, sockstr, sizeof(sockstr)); - printf(";; communications error to %s: %s\n", - sockstr, isc_result_totext(sevent->result)); + dighost_error("communications error to %s: %s\n", + sockstr, isc_result_totext(sevent->result)); if (keep != NULL) isc_socket_detach(&keep); l = query->lookup; @@ -3131,6 +3140,19 @@ launch_next_query(dig_query_t *query, bool include_question) { check_result(result, "isc_socket_send"); sendcount++; debug("sendcount=%d", sendcount); + + /* XXX qrflag, print_query, etc... */ + if (!ISC_LIST_EMPTY(query->lookup->q) && query->lookup->qr) { + extrabytes = 0; + dighost_printmessage(ISC_LIST_HEAD(query->lookup->q), + &query->lookup->renderbuf, + query->lookup->sendmsg, true); + if (query->lookup->stats) { + printf(";; QUERY SIZE: %u\n\n", + isc_buffer_usedlength( + &query->lookup->renderbuf)); + } + } } query->waiting_connect = false; #if 0 @@ -3505,7 +3527,6 @@ recv_done(isc_task_t *task, isc_event_t *event) { query = event->ev_arg; TIME_NOW(&query->time_recv); - debug("lookup=%p, query=%p", query->lookup, query); l = query->lookup; @@ -3534,8 +3555,8 @@ recv_done(isc_task_t *task, isc_event_t *event) { debug("in recv cancel handler"); query->waiting_connect = false; } else { - printf(";; communications error: %s\n", - isc_result_totext(sevent->result)); + dighost_error("communications error: %s\n", + isc_result_totext(sevent->result)); if (keep != NULL) isc_socket_detach(&keep); isc_socket_detach(&query->sock); @@ -3886,19 +3907,19 @@ recv_done(isc_task_t *task, isc_event_t *event) { if (msg->rcode == dns_rcode_nxdomain && (l->origin != NULL || l->need_search)) { if (!next_origin(query->lookup) || showsearch) { - dighost_printmessage(query, msg, true); + dighost_printmessage(query, &b, msg, true); dighost_received(isc_buffer_usedlength(&b), &sevent->address, query); } } else if (!l->trace && !l->ns_search_only) { - dighost_printmessage(query, msg, true); + dighost_printmessage(query, &b, msg, true); } else if (l->trace) { int nl = 0; int count = msg->counts[DNS_SECTION_ANSWER]; debug("in TRACE code"); if (!l->ns_search_only) - dighost_printmessage(query, msg, true); + dighost_printmessage(query, &b, msg, true); l->rdtype = l->qrdtype; if (l->trace_root || (l->ns_search_only && count > 0)) { @@ -3929,7 +3950,7 @@ recv_done(isc_task_t *task, isc_event_t *event) { l->trace_root = false; usesearch = false; } else { - dighost_printmessage(query, msg, true); + dighost_printmessage(query, &b, msg, true); } } } diff --git a/bin/dig/host.c b/bin/dig/host.c index 7e9b6c57540..aa7cb8473eb 100644 --- a/bin/dig/host.c +++ b/bin/dig/host.c @@ -400,13 +400,16 @@ chase_cnamechain(dns_message_t *msg, dns_name_t *qname) { } static isc_result_t -printmessage(dig_query_t *query, dns_message_t *msg, bool headers) { +printmessage(dig_query_t *query, const isc_buffer_t *msgbuf, + dns_message_t *msg, bool headers) +{ bool did_flag = false; dns_rdataset_t *opt, *tsig = NULL; const dns_name_t *tsigname; isc_result_t result = ISC_R_SUCCESS; int force_error; + UNUSED(msgbuf); UNUSED(headers); /* @@ -854,6 +857,17 @@ parse_args(bool is_batchfile, int argc, char **argv) { ISC_LIST_APPEND(lookup_list, lookup, link); } +static void +host_error(const char *format, ...) { + va_list args; + + printf(";; "); + va_start(args, format); + vfprintf(stdout, format, args); + va_end(args); + printf("\n"); +} + int main(int argc, char **argv) { isc_result_t result; @@ -871,6 +885,7 @@ main(int argc, char **argv) { dighost_received = received; dighost_trying = trying; dighost_shutdown = host_shutdown; + dighost_error = host_error; debug("main()"); progname = argv[0]; diff --git a/bin/dig/include/dig/dig.h b/bin/dig/include/dig/dig.h index 41cc31a3a4f..34327559cea 100644 --- a/bin/dig/include/dig/dig.h +++ b/bin/dig/include/dig/dig.h @@ -380,13 +380,22 @@ set_search_domain(char *domain); * then assigned to the appropriate function pointer */ extern isc_result_t -(*dighost_printmessage)(dig_query_t *query, dns_message_t *msg, bool headers); +(*dighost_printmessage)(dig_query_t *query, const isc_buffer_t *msgbuf, + dns_message_t *msg, bool headers); + +/* + * Print an error message in the appropriate format. + */ +void +(*dighost_error)(const char *format, ...); + /*%< * Print the final result of the lookup. */ extern void -(*dighost_received)(unsigned int bytes, isc_sockaddr_t *from, dig_query_t *query); +(*dighost_received)(unsigned int bytes, isc_sockaddr_t *from, + dig_query_t *query); /*%< * Print a message about where and when the response * was received from, like the final comment in the diff --git a/bin/dig/nslookup.c b/bin/dig/nslookup.c index 2363903e9d5..f343fec7bc2 100644 --- a/bin/dig/nslookup.c +++ b/bin/dig/nslookup.c @@ -429,16 +429,21 @@ chase_cnamechain(dns_message_t *msg, dns_name_t *qname) { } static isc_result_t -printmessage(dig_query_t *query, dns_message_t *msg, bool headers) { +printmessage(dig_query_t *query, const isc_buffer_t *msgbuf, + dns_message_t *msg, bool headers) +{ char servtext[ISC_SOCKADDR_FORMATSIZE]; + UNUSED(msgbuf); + /* I've we've gotten this far, we've reached a server. */ query_error = 0; debug("printmessage()"); if(!default_lookups || query->lookup->rdtype == dns_rdatatype_a) { - isc_sockaddr_format(&query->sockaddr, servtext, sizeof(servtext)); + isc_sockaddr_format(&query->sockaddr, servtext, + sizeof(servtext)); printf("Server:\t\t%s\n", query->userarg); printf("Address:\t%s\n", servtext); @@ -978,6 +983,17 @@ getinput(isc_task_t *task, isc_event_t *event) { isc_app_shutdown(); } +static void +nsl_error(const char *format, ...) { + va_list args; + + printf(";; "); + va_start(args, format); + vfprintf(stdout, format, args); + va_end(args); + printf("\n"); +} + int main(int argc, char **argv) { isc_result_t result; @@ -995,6 +1011,7 @@ main(int argc, char **argv) { dighost_received = received; dighost_trying = trying; dighost_shutdown = query_finished; + dighost_error = nsl_error; result = isc_app_start(); check_result(result, "isc_app_start"); diff --git a/lib/dns/include/dns/message.h b/lib/dns/include/dns/message.h index 1f793b48099..af6af7d1c7b 100644 --- a/lib/dns/include/dns/message.h +++ b/lib/dns/include/dns/message.h @@ -384,6 +384,37 @@ dns_message_pseudosectiontotext(dns_message_t *msg, *\li Note: On error return, *target may be partially filled with data. */ +isc_result_t +dns_message_headertotext(dns_message_t *msg, const dns_master_style_t *style, + dns_messagetextflag_t flags, isc_buffer_t *target); +/*%< + * Convert the header section of message 'msg' to a cleartext + * representation. This is called from dns_message_totext(). + * + * Notes on flags: + *\li If #DNS_MESSAGETEXTFLAG_NOHEADERS is set, header lines will be + * suppressed and this function is a no-op. + * + * Requires: + * + *\li 'msg' is a valid message. + * + *\li 'target' is a valid buffer. + * + * Ensures: + * + *\li If the result is success: + * The used space in 'target' is updated. + * + * Returns: + * + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOSPACE + *\li #ISC_R_NOMORE + * + *\li Note: On error return, *target may be partially filled with data. + */ + isc_result_t dns_message_totext(dns_message_t *msg, const dns_master_style_t *style, dns_messagetextflag_t flags, isc_buffer_t *target); diff --git a/lib/dns/message.c b/lib/dns/message.c index a3f9a5187d5..a3e8189a238 100644 --- a/lib/dns/message.c +++ b/lib/dns/message.c @@ -4001,8 +4001,8 @@ dns_message_pseudosectiontotext(dns_message_t *msg, } isc_result_t -dns_message_totext(dns_message_t *msg, const dns_master_style_t *style, - dns_messagetextflag_t flags, isc_buffer_t *target) +dns_message_headertotext(dns_message_t *msg, const dns_master_style_t *style, + dns_messagetextflag_t flags, isc_buffer_t *target) { char buf[sizeof("1234567890")]; isc_result_t result; @@ -4010,9 +4010,11 @@ dns_message_totext(dns_message_t *msg, const dns_master_style_t *style, REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(target != NULL); - if (((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0) && - (dns_master_styleflags(style) & DNS_STYLEFLAG_YAML)) - { + if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) != 0) { + return (ISC_R_SUCCESS); + } + + if (dns_master_styleflags(style) & DNS_STYLEFLAG_YAML) { INDENT(style); ADD_STRING(target, "opcode: "); ADD_STRING(target, opcodetext[msg->opcode]); @@ -4020,30 +4022,38 @@ dns_message_totext(dns_message_t *msg, const dns_master_style_t *style, INDENT(style); ADD_STRING(target, "status: "); result = dns_rcode_totext(msg->rcode, target); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } ADD_STRING(target, "\n"); INDENT(style); ADD_STRING(target, "id: "); - snprintf(buf, sizeof(buf), "%6u", msg->id); + snprintf(buf, sizeof(buf), "%u", msg->id); ADD_STRING(target, buf); ADD_STRING(target, "\n"); INDENT(style); ADD_STRING(target, "flags:"); - if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) + if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) { ADD_STRING(target, " qr"); - if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0) + } + if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0) { ADD_STRING(target, " aa"); - if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) + } + if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { ADD_STRING(target, " tc"); - if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0) + } + if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0) { ADD_STRING(target, " rd"); - if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0) + } + if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0) { ADD_STRING(target, " ra"); - if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0) + } + if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0) { ADD_STRING(target, " ad"); - if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0) + } + if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0) { ADD_STRING(target, " cd"); + } ADD_STRING(target, "\n"); /* * The final unnamed flag must be zero. @@ -4091,34 +4101,42 @@ dns_message_totext(dns_message_t *msg, const dns_master_style_t *style, msg->counts[DNS_SECTION_ADDITIONAL]); ADD_STRING(target, buf); ADD_STRING(target, "\n"); - } else if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0) { + } else { INDENT(style); ADD_STRING(target, ";; ->>HEADER<<- opcode: "); ADD_STRING(target, opcodetext[msg->opcode]); ADD_STRING(target, ", status: "); result = dns_rcode_totext(msg->rcode, target); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } ADD_STRING(target, ", id: "); snprintf(buf, sizeof(buf), "%6u", msg->id); ADD_STRING(target, buf); ADD_STRING(target, "\n"); INDENT(style); ADD_STRING(target, ";; flags:"); - if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) + if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) { ADD_STRING(target, " qr"); - if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0) + } + if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0) { ADD_STRING(target, " aa"); - if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) + } + if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { ADD_STRING(target, " tc"); - if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0) + } + if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0) { ADD_STRING(target, " rd"); - if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0) + } + if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0) { ADD_STRING(target, " ra"); - if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0) + } + if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0) { ADD_STRING(target, " ad"); - if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0) + } + if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0) { ADD_STRING(target, " cd"); + } /* * The final unnamed flag must be zero. */ @@ -4158,42 +4176,63 @@ dns_message_totext(dns_message_t *msg, const dns_master_style_t *style, ADD_STRING(target, buf); ADD_STRING(target, "\n"); } - result = dns_message_pseudosectiontotext(msg, - DNS_PSEUDOSECTION_OPT, + + cleanup: + return (result); +} + +isc_result_t +dns_message_totext(dns_message_t *msg, const dns_master_style_t *style, + dns_messagetextflag_t flags, isc_buffer_t *target) +{ + isc_result_t result; + + REQUIRE(DNS_MESSAGE_VALID(msg)); + REQUIRE(target != NULL); + + result = dns_message_headertotext(msg, style, flags, target); + if (result != ISC_R_SUCCESS) { + return (result); + } + + result = dns_message_pseudosectiontotext(msg, DNS_PSEUDOSECTION_OPT, style, flags, target); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } result = dns_message_sectiontotext(msg, DNS_SECTION_QUESTION, style, flags, target); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } + result = dns_message_sectiontotext(msg, DNS_SECTION_ANSWER, style, flags, target); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } + result = dns_message_sectiontotext(msg, DNS_SECTION_AUTHORITY, style, flags, target); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } + result = dns_message_sectiontotext(msg, DNS_SECTION_ADDITIONAL, style, flags, target); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } - result = dns_message_pseudosectiontotext(msg, - DNS_PSEUDOSECTION_TSIG, + result = dns_message_pseudosectiontotext(msg, DNS_PSEUDOSECTION_TSIG, style, flags, target); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } - result = dns_message_pseudosectiontotext(msg, - DNS_PSEUDOSECTION_SIG0, + result = dns_message_pseudosectiontotext(msg, DNS_PSEUDOSECTION_SIG0, style, flags, target); - if (result != ISC_R_SUCCESS) - return (result); - - cleanup: return (result); } diff --git a/lib/dns/win32/libdns.def.in b/lib/dns/win32/libdns.def.in index f0645696c0a..2eb382c28ab 100644 --- a/lib/dns/win32/libdns.def.in +++ b/lib/dns/win32/libdns.def.in @@ -496,6 +496,7 @@ dns_message_gettemprdataset dns_message_gettimeadjust dns_message_gettsig dns_message_gettsigkey +dns_message_headertotext dns_message_logfmtpacket dns_message_logpacket dns_message_movename