diff options
Diffstat (limited to 'contrib/bind9/lib/dns/message.c')
-rw-r--r-- | contrib/bind9/lib/dns/message.c | 134 |
1 files changed, 122 insertions, 12 deletions
diff --git a/contrib/bind9/lib/dns/message.c b/contrib/bind9/lib/dns/message.c index 8c56377..b541635 100644 --- a/contrib/bind9/lib/dns/message.c +++ b/contrib/bind9/lib/dns/message.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: message.c,v 1.222.18.16 2008/07/28 23:46:20 tbox Exp $ */ +/* $Id: message.c,v 1.245.50.2 2009/01/18 23:47:40 tbox Exp $ */ /*! \file */ @@ -24,6 +24,7 @@ ***/ #include <config.h> +#include <ctype.h> #include <isc/buffer.h> #include <isc/mem.h> @@ -45,6 +46,35 @@ #include <dns/tsig.h> #include <dns/view.h> +#ifdef SKAN_MSG_DEBUG +static void +hexdump(const char *msg, const char *msg2, void *base, size_t len) { + unsigned char *p; + unsigned int cnt; + + p = base; + cnt = 0; + + printf("*** %s [%s] (%u bytes @ %p)\n", msg, msg2, len, base); + + while (cnt < len) { + if (cnt % 16 == 0) + printf("%p: ", p); + else if (cnt % 8 == 0) + printf(" |"); + printf(" %02x %c", *p, (isprint(*p) ? *p : ' ')); + p++; + cnt++; + + if (cnt % 16 == 0) + printf("\n"); + } + + if (cnt % 16 != 0) + printf("\n"); +} +#endif + #define DNS_MESSAGE_OPCODE_MASK 0x7800U #define DNS_MESSAGE_OPCODE_SHIFT 11 #define DNS_MESSAGE_RCODE_MASK 0x000fU @@ -65,6 +95,8 @@ #define VALID_PSEUDOSECTION(s) (((s) >= DNS_PSEUDOSECTION_ANY) \ && ((s) < DNS_PSEUDOSECTION_MAX)) +#define OPTOUT(x) (((x)->attributes & DNS_RDATASETATTR_OPTOUT) != 0) + /*% * This is the size of each individual scratchpad buffer, and the numbers * of various block allocations used within the server. @@ -138,7 +170,7 @@ static const char *rcodetext[] = { /*% * "helper" type, which consists of a block of some type, and is linkable. * For it to work, sizeof(dns_msgblock_t) must be a multiple of the pointer - * size, or the allocated elements will not be alligned correctly. + * size, or the allocated elements will not be aligned correctly. */ struct dns_msgblock { unsigned int count; @@ -1462,14 +1494,8 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, rdataset->ttl = ttl; } - /* - * XXXMLG Perform a totally ugly hack here to pull - * the rdatalist out of the private field in the rdataset, - * and append this rdata to the rdatalist's linked list - * of rdata. - */ - rdatalist = (dns_rdatalist_t *)(rdataset->private1); - + /* Append this rdata to the rdataset. */ + dns_rdatalist_fromrdataset(rdataset, &rdatalist); ISC_LIST_APPEND(rdatalist->rdata, rdata, link); /* @@ -1934,7 +1960,7 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid, * * XXXMLG Need to change this when * dns_rdataset_towire() can render partial - * sets starting at some arbitary point in the + * sets starting at some arbitrary point in the * set. This will include setting a bit in the * rdataset to indicate that a partial * rendering was done, and some state saved @@ -1964,6 +1990,8 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid, (sectionid == DNS_SECTION_ANSWER || sectionid == DNS_SECTION_AUTHORITY)) msg->flags &= ~DNS_MESSAGEFLAG_AD; + if (OPTOUT(rdataset)) + msg->flags &= ~DNS_MESSAGEFLAG_AD; rdataset->attributes |= DNS_RDATASETATTR_RENDERED; @@ -2899,6 +2927,35 @@ dns_message_rechecksig(dns_message_t *msg, dns_view_t *view) { return (dns_message_checksig(msg, view)); } +#ifdef SKAN_MSG_DEBUG +void +dns_message_dumpsig(dns_message_t *msg, char *txt1) { + dns_rdata_t querytsigrdata = DNS_RDATA_INIT; + dns_rdata_any_tsig_t querytsig; + isc_result_t result; + + if (msg->tsig != NULL) { + result = dns_rdataset_first(msg->tsig); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + dns_rdataset_current(msg->tsig, &querytsigrdata); + result = dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + hexdump(txt1, "TSIG", querytsig.signature, + querytsig.siglen); + } + + if (msg->querytsig != NULL) { + result = dns_rdataset_first(msg->querytsig); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + dns_rdataset_current(msg->querytsig, &querytsigrdata); + result = dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + hexdump(txt1, "QUERYTSIG", querytsig.signature, + querytsig.siglen); + } +} +#endif + isc_result_t dns_message_checksig(dns_message_t *msg, dns_view_t *view) { isc_buffer_t b, msgb; @@ -2907,10 +2964,14 @@ dns_message_checksig(dns_message_t *msg, dns_view_t *view) { if (msg->tsigkey == NULL && msg->tsig == NULL && msg->sig0 == NULL) return (ISC_R_SUCCESS); + INSIST(msg->saved.base != NULL); isc_buffer_init(&msgb, msg->saved.base, msg->saved.length); isc_buffer_add(&msgb, msg->saved.length); if (msg->tsigkey != NULL || msg->tsig != NULL) { +#ifdef SKAN_MSG_DEBUG + dns_message_dumpsig(msg, "dns_message_checksig#1"); +#endif if (view != NULL) return (dns_view_checksig(view, &msgb, msg)); else @@ -2963,6 +3024,7 @@ dns_message_checksig(dns_message_t *msg, dns_view_t *view) { { dst_key_t *key = NULL; + dns_rdata_reset(&rdata); dns_rdataset_current(&keyset, &rdata); isc_buffer_init(&b, rdata.data, rdata.length); isc_buffer_add(&b, rdata.length); @@ -3068,6 +3130,10 @@ dns_message_pseudosectiontotext(dns_message_t *msg, isc_result_t result; char buf[sizeof("1234567890")]; isc_uint32_t mbz; + dns_rdata_t rdata; + isc_buffer_t optbuf; + isc_uint16_t optcode, optlen; + unsigned char *optdata; REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(target != NULL); @@ -3097,6 +3163,50 @@ dns_message_pseudosectiontotext(dns_message_t *msg, ADD_STRING(target, "; udp: "); snprintf(buf, sizeof(buf), "%u\n", (unsigned int)ps->rdclass); ADD_STRING(target, buf); + + result = dns_rdataset_first(ps); + if (result != ISC_R_SUCCESS) + return (ISC_R_SUCCESS); + + /* Print EDNS info, if any */ + dns_rdata_init(&rdata); + dns_rdataset_current(ps, &rdata); + if (rdata.length < 4) + return (ISC_R_SUCCESS); + + isc_buffer_init(&optbuf, rdata.data, rdata.length); + isc_buffer_add(&optbuf, rdata.length); + optcode = isc_buffer_getuint16(&optbuf); + optlen = isc_buffer_getuint16(&optbuf); + + if (optcode == DNS_OPT_NSID) { + ADD_STRING(target, "; NSID"); + } else { + ADD_STRING(target, "; OPT="); + sprintf(buf, "%u", optcode); + ADD_STRING(target, buf); + } + + if (optlen != 0) { + int i; + ADD_STRING(target, ": "); + + optdata = rdata.data + 4; + for (i = 0; i < optlen; i++) { + sprintf(buf, "%02x ", optdata[i]); + ADD_STRING(target, buf); + } + for (i = 0; i < optlen; i++) { + ADD_STRING(target, " ("); + if (isprint(optdata[i])) + isc_buffer_putmem(target, &optdata[i], + 1); + else + isc_buffer_putstr(target, "."); + ADD_STRING(target, ")"); + } + } + ADD_STRING(target, "\n"); return (ISC_R_SUCCESS); case DNS_PSEUDOSECTION_TSIG: ps = dns_message_gettsig(msg, &name); |