4545. [func] Make dnstap-read output more functionally usable.

[RT #43642]

4544.	[func]		Add message/payload size to dnstap-read YAML output.
			[RT #43622]
This commit is contained in:
wpk
2016-12-28 10:06:40 +01:00
parent 6f94747270
commit e910d18007
10 changed files with 625 additions and 120 deletions

View File

@@ -1,3 +1,9 @@
4545. [func] Make dnstap-read output more functionally usable.
[RT #43642]
4544. [func] Add message/payload size to dnstap-read YAML output.
[RT #43622]
4543. [bug] dns_client_startupdate now delays sending the update
request until isc_app_ctxrun has been called.
[RT #43976]

View File

@@ -18,6 +18,8 @@ ns2.example. A 10.53.0.2
$ORIGIN example.
a A 10.0.0.1
a A 10.0.0.3
a A 10.0.0.5
MX 10 mail.example.
mail A 10.0.0.2

View File

@@ -344,6 +344,18 @@ ret=0
if [ $ret != 0 ]; then echo "I: failed"; fi
status=`expr $status + $ret`
HAS_PYYAML=0
if [ -n "$PYTHON" ] ; then
$PYTHON -c "import yaml" && HAS_PYYAML=1
fi
if [ $HAS_PYYAML ] ; then
echo "I:checking dnstap-read YAML output"
ret=0
$PYTHON ydump.py "$DNSTAPREAD" "ns3/dnstap.out.save" > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I: failed"; fi
status=`expr $status + $ret`
fi
if [ -n "$FSTRM_CAPTURE" ] ; then
$DIG +short @10.53.0.4 -p 5300 a.example > dig.out

View File

@@ -0,0 +1,17 @@
#!/usr/bin/python
try:
import yaml
except:
print "I: No python yaml module, skipping"
exit(1)
import subprocess
import pprint
import sys
DNSTAP_READ=sys.argv[1]
DATAFILE=sys.argv[2]
f = subprocess.Popen([DNSTAP_READ, '-y', DATAFILE], stdout=subprocess.PIPE)
pprint.pprint([l for l in yaml.load_all(f.stdout)])

View File

@@ -83,10 +83,68 @@ usage(void) {
}
static void
print_yaml(dns_dtdata_t *d) {
Dnstap__Dnstap *frame = d->frame;
print_dtdata(dns_dtdata_t *dt) {
isc_result_t result;
isc_buffer_t *b = NULL;
isc_buffer_allocate(mctx, &b, 2048);
if (b == NULL)
fatal("out of memory");
CHECKM(dns_dt_datatotext(dt, &b), "dns_dt_datatotext");
printf("%.*s\n", (int) isc_buffer_usedlength(b),
(char *) isc_buffer_base(b));
cleanup:
if (b != NULL)
isc_buffer_free(&b);
}
static void
print_packet(dns_dtdata_t *dt, const dns_master_style_t *style) {
isc_buffer_t *b = NULL;
isc_result_t result;
if (dt->msg != NULL) {
size_t textlen = 2048;
isc_buffer_allocate(mctx, &b, textlen);
if (b == NULL)
fatal("out of memory");
for (;;) {
isc_buffer_reserve(&b, textlen);
if (b == NULL)
fatal("out of memory");
result = dns_message_totext(dt->msg, style, 0, b);
if (result == ISC_R_NOSPACE) {
textlen *= 2;
continue;
} else if (result == ISC_R_SUCCESS) {
printf("%.*s",
(int) isc_buffer_usedlength(b),
(char *) isc_buffer_base(b));
isc_buffer_free(&b);
} else {
isc_buffer_free(&b);
CHECKM(result, "dns_message_totext");
}
break;
}
}
cleanup:
if (b != NULL)
isc_buffer_free(&b);
}
static void
print_yaml(dns_dtdata_t *dt) {
Dnstap__Dnstap *frame = dt->frame;
Dnstap__Message *m = frame->message;
const ProtobufCEnumValue *ftype, *mtype;
static isc_boolean_t first = ISC_TRUE;
ftype = protobuf_c_enum_descriptor_get_value(
&dnstap__dnstap__type__descriptor,
@@ -94,6 +152,11 @@ print_yaml(dns_dtdata_t *d) {
if (ftype == NULL)
return;
if (!first)
printf("---\n");
else
first = ISC_FALSE;
printf("type: %s\n", ftype->name);
if (frame->has_identity)
@@ -117,18 +180,23 @@ print_yaml(dns_dtdata_t *d) {
printf(" type: %s\n", mtype->name);
if (!isc_time_isepoch(&d->qtime)) {
if (!isc_time_isepoch(&dt->qtime)) {
char buf[100];
isc_time_formatISO8601(&d->qtime, buf, sizeof(buf));
isc_time_formatISO8601(&dt->qtime, buf, sizeof(buf));
printf(" query_time: !!timestamp %s\n", buf);
}
if (!isc_time_isepoch(&d->rtime)) {
if (!isc_time_isepoch(&dt->rtime)) {
char buf[100];
isc_time_formatISO8601(&d->rtime, buf, sizeof(buf));
isc_time_formatISO8601(&dt->rtime, buf, sizeof(buf));
printf(" response_time: !!timestamp %s\n", buf);
}
if (dt->msgdata.base != NULL) {
printf(" message_size: %zdb\n", (size_t) dt->msgdata.length);
} else
printf(" message_size: 0b\n");
if (m->has_socket_family) {
const ProtobufCEnumValue *type =
protobuf_c_enum_descriptor_get_value(
@@ -138,7 +206,7 @@ print_yaml(dns_dtdata_t *d) {
printf(" socket_family: %s\n", type->name);
}
printf(" socket_protocol: %s\n", d->tcp ? "TCP" : "UDP");
printf(" socket_protocol: %s\n", dt->tcp ? "TCP" : "UDP");
if (m->has_query_address) {
ProtobufCBinaryData *ip = &m->query_address;
@@ -186,9 +254,18 @@ print_yaml(dns_dtdata_t *d) {
}
}
if (d->msg != NULL)
printf(" %s: |\n", ((d->type & DNS_DTTYPE_QUERY) != 0)
? "query_message" : "response_message");
if (dt->msg != NULL) {
printf(" %s:\n", ((dt->type & DNS_DTTYPE_QUERY) != 0)
? "query_message_data"
: "response_message_data");
print_packet(dt, &dns_master_style_yaml);
printf(" %s: |\n", ((dt->type & DNS_DTTYPE_QUERY) != 0)
? "query_message"
: "response_message");
print_packet(dt, &dns_master_style_indent);
}
};
int
@@ -197,7 +274,6 @@ main(int argc, char *argv[]) {
dns_message_t *message = NULL;
isc_buffer_t *b = NULL;
dns_dtdata_t *dt = NULL;
const dns_master_style_t *style = &dns_master_style_debug;
dns_dthandle_t *handle = NULL;
int rv = 0, ch;
@@ -212,9 +288,8 @@ main(int argc, char *argv[]) {
break;
case 'y':
yaml = ISC_TRUE;
style = &dns_master_style_indent;
dns_master_indentstr = " ";
printmessage = ISC_TRUE;
dns_master_indentstr = " ";
dns_master_indent = 2;
break;
default:
usage();
@@ -261,44 +336,15 @@ main(int argc, char *argv[]) {
continue;
}
if (yaml)
if (yaml) {
print_yaml(dt);
else {
CHECKM(dns_dt_datatotext(dt, &b), "dns_dt_datatotext");
printf("%.*s\n", (int) isc_buffer_usedlength(b),
(char *) isc_buffer_base(b));
} else if (printmessage) {
print_dtdata(dt);
print_packet(dt, &dns_master_style_debug);
} else {
print_dtdata(dt);
}
if (printmessage && dt->msg != NULL) {
size_t textlen = 2048;
isc_buffer_clear(b);
for (;;) {
isc_buffer_reserve(&b, textlen);
if (b == NULL)
fatal("out of memory");
result = dns_message_totext(dt->msg, style,
0, b);
if (result == ISC_R_NOSPACE) {
textlen *= 2;
continue;
} else if (result == ISC_R_SUCCESS) {
printf("%.*s",
(int) isc_buffer_usedlength(b),
(char *) isc_buffer_base(b));
isc_buffer_free(&b);
} else {
isc_buffer_free(&b);
CHECKM(result, "dns_message_totext");
}
break;
}
}
if (yaml)
printf("---\n");
dns_dtdata_free(&dt);
}

View File

@@ -86,7 +86,7 @@
<listitem>
<para>
Print <command>dnstap</command> data in a detailed YAML
format. Implies <option>-p</option>.
format.
</para>
</listitem>
</varlistentry>

View File

@@ -103,6 +103,9 @@ typedef struct dns_master_style dns_master_style_t;
/*% Indent output. */
#define DNS_STYLEFLAG_INDENT 0x40000000U
/*% Output in YAML style. */
#define DNS_STYLEFLAG_YAML 0x80000000U
ISC_LANG_BEGINDECLS
/***
@@ -167,14 +170,32 @@ LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_indent;
*/
LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_keyzone;
/*%
* YAML-compatible output
*/
LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_yaml;
/*%
* The default indent string to prepend lines with when using
* styleflag DNS_STYLEFLAG_INDENT. This is set to "\t" by default.
* The indent preceeds everything else on the line, including comment
* characters (;).
* styleflag DNS_STYLEFLAG_INDENT or DNS_STYLEFLAG_YAML.
* This is set to "\t" by default. The indent is repeated
* 'dns_master_indent' times. This precedes everything else
* on the line, including comment characters (;).
*
* XXX: Changing this value at runtime is not thread-safe.
*/
LIBDNS_EXTERNAL_DATA extern const char *dns_master_indentstr;
/*%
* The number of copies of the indent string to put at the beginning
* of the line when using DNS_STYLEFLAG_INDENT or DNS_STYLEFLAG_YAML.
* This is set to 1 by default. It is increased and decreased
* to adjust indentation levels when producing YAML output.
*
* XXX: This is not thread-safe.
*/
LIBDNS_EXTERNAL_DATA extern unsigned int dns_master_indent;
/***
*** Functions
***/
@@ -394,6 +415,7 @@ dns_master_stylecreate2(dns_master_style_t **style, unsigned int flags,
unsigned int type_column, unsigned int rdata_column,
unsigned int line_length, unsigned int tab_width,
unsigned int split_width, isc_mem_t *mctx);
void
dns_master_styledestroy(dns_master_style_t **style, isc_mem_t *mctx);

View File

@@ -12,6 +12,7 @@
#include <stdlib.h>
#include <isc/buffer.h>
#include <isc/event.h>
#include <isc/file.h>
#include <isc/magic.h>
@@ -185,11 +186,22 @@ dns_master_style_comment = {
24, 32, 40, 48, 80, 8, UINT_MAX
};
/*%
* YAML style
*/
LIBDNS_EXTERNAL_DATA const dns_master_style_t
dns_master_style_yaml = {
DNS_STYLEFLAG_YAML |
DNS_STYLEFLAG_REL_OWNER |
DNS_STYLEFLAG_INDENT,
24, 32, 40, 48, 80, 8, UINT_MAX
};
/*%
* Default indent string.
*/
LIBDNS_EXTERNAL_DATA const char *dns_master_indentstr = "\t";
LIBDNS_EXTERNAL_DATA unsigned int dns_master_indent = 1;
#define N_SPACES 10
static char spaces[N_SPACES+1] = " ";
@@ -321,14 +333,15 @@ totext_ctx_init(const dns_master_style_t *style, dns_totext_ctx_t *ctx) {
r.base[0] = '\n';
isc_buffer_add(&buf, 1);
if ((ctx->style.flags & DNS_STYLEFLAG_INDENT) != 0) {
unsigned int ilen = strlen(dns_master_indentstr);
isc_buffer_availableregion(&buf, &r);
if (r.length < ilen)
return (DNS_R_TEXTTOOLONG);
isc_buffer_putmem(&buf,
(const isc_uint8_t *) dns_master_indentstr,
(unsigned int)ilen);
if ((ctx->style.flags & DNS_STYLEFLAG_INDENT) != 0 ||
(ctx->style.flags & DNS_STYLEFLAG_YAML) != 0)
{
unsigned int i, len = strlen(dns_master_indentstr);
for (i = 0; i < dns_master_indent; i++) {
if (isc_buffer_availablelength(&buf) < len)
return (DNS_R_TEXTTOOLONG);
isc_buffer_putstr(&buf, dns_master_indentstr);
}
}
if ((ctx->style.flags & DNS_STYLEFLAG_COMMENTDATA) != 0) {
@@ -373,7 +386,11 @@ totext_ctx_init(const dns_master_style_t *style, dns_totext_ctx_t *ctx) {
#define INDENT_TO(col) \
do { \
if ((result = indent(&column, ctx->style.col, \
if ((ctx->style.flags & DNS_STYLEFLAG_YAML) != 0) { \
if ((result = str_totext(" ", target)) \
!= ISC_R_SUCCESS) \
return (result); \
} else if ((result = indent(&column, ctx->style.col, \
ctx->style.tab_width, target)) \
!= ISC_R_SUCCESS) \
return (result); \
@@ -465,6 +482,7 @@ rdataset_totext(dns_rdataset_t *rdataset,
unsigned int type_start;
dns_fixedname_t fixed;
dns_name_t *name = NULL;
unsigned int i;
REQUIRE(DNS_RDATASET_VALID(rdataset));
@@ -487,8 +505,18 @@ rdataset_totext(dns_rdataset_t *rdataset,
/*
* Indent?
*/
if ((ctx->style.flags & DNS_STYLEFLAG_INDENT) != 0)
RETERR(str_totext(dns_master_indentstr, target));
if ((ctx->style.flags & DNS_STYLEFLAG_INDENT) != 0 ||
(ctx->style.flags & DNS_STYLEFLAG_YAML) != 0)
for (i = 0; i < dns_master_indent; i++)
RETERR(str_totext(dns_master_indentstr,
target));
/*
* YAML enumerator?
*/
if ((ctx->style.flags & DNS_STYLEFLAG_YAML) != 0) {
RETERR(str_totext("- ", target));
}
/*
* Comment?
@@ -612,9 +640,13 @@ rdataset_totext(dns_rdataset_t *rdataset,
*/
INDENT_TO(rdata_column);
if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
if ((ctx->style.flags & DNS_STYLEFLAG_INDENT) != 0)
RETERR(str_totext(dns_master_indentstr,
target));
if ((ctx->style.flags & DNS_STYLEFLAG_INDENT) != 0 ||
(ctx->style.flags & DNS_STYLEFLAG_YAML) != 0)
{
for (i = 0; i < dns_master_indent; i++)
RETERR(str_totext(dns_master_indentstr,
target));
}
if (NXDOMAIN(rdataset))
RETERR(str_totext(";-$NXDOMAIN\n", target));
else
@@ -984,11 +1016,16 @@ dump_rdatasets_text(isc_mem_t *mctx, dns_name_t *name,
for (i = 0; i < n; i++) {
dns_rdataset_t *rds = sorted[i];
if (ctx->style.flags & DNS_STYLEFLAG_TRUST)
fprintf(f, "%s; %s\n",
(ctx->style.flags & DNS_STYLEFLAG_INDENT)
? dns_master_indentstr : "",
dns_trust_totext(rds->trust));
if (ctx->style.flags & DNS_STYLEFLAG_TRUST) {
if ((ctx->style.flags & DNS_STYLEFLAG_INDENT) != 0 ||
(ctx->style.flags & DNS_STYLEFLAG_YAML) != 0)
{
unsigned int j;
for (j = 0; j < dns_master_indent; j++)
fprintf(f, "%s", dns_master_indentstr);
}
fprintf(f, "; %s\n", dns_trust_totext(rds->trust));
}
if (((rds->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) &&
(ctx->style.flags & DNS_STYLEFLAG_NCACHE) == 0) {
/* Omit negative cache entries */
@@ -1008,10 +1045,14 @@ dump_rdatasets_text(isc_mem_t *mctx, dns_name_t *name,
memset(buf, 0, sizeof(buf));
isc_buffer_init(&b, buf, sizeof(buf) - 1);
dns_time64_totext((isc_uint64_t)rds->resign, &b);
fprintf(f, "%s; resign=%s\n",
(ctx->style.flags & DNS_STYLEFLAG_INDENT)
? dns_master_indentstr : "",
buf);
if ((ctx->style.flags & DNS_STYLEFLAG_INDENT) != 0 ||
(ctx->style.flags & DNS_STYLEFLAG_YAML) != 0)
{
unsigned int j;
for (j = 0; j < dns_master_indent; j++)
fprintf(f, "%s", dns_master_indentstr);
}
fprintf(f, "; resign=%s\n", buf);
}
dns_rdataset_disassociate(rds);
}
@@ -2066,7 +2107,6 @@ dns_master_stylecreate2(dns_master_style_t **stylep, unsigned int flags,
style->line_length = line_length;
style->tab_width = tab_width;
style->split_width = split_width;
*stylep = style;
return (ISC_R_SUCCESS);
}

View File

@@ -80,8 +80,10 @@ hexdump(const char *msg, const char *msg2, void *base, size_t len) {
#define VALID_SECTION(s) (((s) >= DNS_SECTION_ANY) \
&& ((s) < DNS_SECTION_MAX))
#define ADD_STRING(b, s) {if (strlen(s) >= \
isc_buffer_availablelength(b)) \
return(ISC_R_NOSPACE); else \
isc_buffer_availablelength(b)) { \
result = ISC_R_NOSPACE; \
goto cleanup; \
} else \
isc_buffer_putstr(b, s);}
#define VALID_PSEUDOSECTION(s) (((s) >= DNS_PSEUDOSECTION_ANY) \
&& ((s) < DNS_PSEUDOSECTION_MAX))
@@ -3160,6 +3162,17 @@ dns_message_checksig(dns_message_t *msg, dns_view_t *view) {
}
}
#define INDENT(sp) \
do { \
unsigned int __i, __flags = dns_master_styleflags(sp); \
if ((__flags & DNS_STYLEFLAG_INDENT) == 0 && \
(__flags & DNS_STYLEFLAG_YAML) == 0) \
break; \
for (__i = 0; __i < dns_master_indent; __i++) { \
ADD_STRING(target, dns_master_indentstr); \
} \
} while (0)
isc_result_t
dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
const dns_master_style_t *style,
@@ -3167,20 +3180,29 @@ dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
isc_buffer_t *target) {
dns_name_t *name, empty_name;
dns_rdataset_t *rdataset;
isc_result_t result;
isc_result_t result = ISC_R_SUCCESS;
isc_boolean_t seensoa = ISC_FALSE;
unsigned int sflags = dns_master_styleflags(style);
unsigned int sflags, saveindent;
REQUIRE(DNS_MESSAGE_VALID(msg));
REQUIRE(target != NULL);
REQUIRE(VALID_SECTION(section));
saveindent = dns_master_indent;
sflags = dns_master_styleflags(style);
if (ISC_LIST_EMPTY(msg->sections[section]))
return (ISC_R_SUCCESS);
goto cleanup;
if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) {
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
INDENT(style);
if ((sflags & DNS_STYLEFLAG_YAML) != 0) {
if (msg->opcode != dns_opcode_update) {
ADD_STRING(target, sectiontext[section]);
} else {
ADD_STRING(target, updsectiontext[section]);
}
ADD_STRING(target, "_SECTION:\n");
} else if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) {
ADD_STRING(target, ";; ");
if (msg->opcode != dns_opcode_update) {
ADD_STRING(target, sectiontext[section]);
@@ -3193,7 +3215,10 @@ dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
dns_name_init(&empty_name, NULL);
result = dns_message_firstname(msg, section);
if (result != ISC_R_SUCCESS) {
return (result);
goto cleanup;
}
if ((sflags & DNS_STYLEFLAG_YAML) != 0) {
dns_master_indent++;
}
do {
name = NULL;
@@ -3211,10 +3236,12 @@ dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
seensoa = ISC_TRUE;
}
if (section == DNS_SECTION_QUESTION) {
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target,
dns_master_indentstr);
ADD_STRING(target, ";");
INDENT(style);
if ((sflags & DNS_STYLEFLAG_YAML) != 0) {
ADD_STRING(target, "- ");
} else {
ADD_STRING(target, ";");
}
result = dns_master_questiontotext(name,
rdataset,
style,
@@ -3226,18 +3253,25 @@ dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
target);
}
if (result != ISC_R_SUCCESS)
return (result);
goto cleanup;
}
result = dns_message_nextname(msg, section);
} while (result == ISC_R_SUCCESS);
if ((sflags & DNS_STYLEFLAG_YAML) != 0) {
dns_master_indent--;
}
if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 &&
(flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) {
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
(flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0 &&
(sflags & DNS_STYLEFLAG_YAML) == 0)
{
INDENT(style);
ADD_STRING(target, "\n");
}
if (result == ISC_R_NOMORE)
result = ISC_R_SUCCESS;
cleanup:
dns_master_indent = saveindent;
return (result);
}
@@ -3247,6 +3281,7 @@ render_ecs(isc_buffer_t *ecsbuf, isc_buffer_t *target) {
char addr[16], addr_text[64];
isc_uint16_t family;
isc_uint8_t addrlen, addrbytes, scopelen;
isc_result_t result;
/*
* Note: This routine needs to handle malformed ECS options.
@@ -3293,7 +3328,256 @@ render_ecs(isc_buffer_t *ecsbuf, isc_buffer_t *target) {
ADD_STRING(target, addr_text);
snprintf(addr_text, sizeof(addr_text), "/%d/%d", addrlen, scopelen);
ADD_STRING(target, addr_text);
return (ISC_R_SUCCESS);
result = ISC_R_SUCCESS;
cleanup:
return (result);
}
static isc_result_t
dns_message_pseudosectiontoyaml(dns_message_t *msg,
dns_pseudosection_t section,
const dns_master_style_t *style,
dns_messagetextflag_t flags,
isc_buffer_t *target)
{
dns_rdataset_t *ps = NULL;
dns_name_t *name = NULL;
isc_result_t result = ISC_R_SUCCESS;
char buf[sizeof("1234567890")];
isc_uint32_t mbz;
dns_rdata_t rdata;
isc_buffer_t optbuf;
isc_uint16_t optcode, optlen;
unsigned char *optdata;
unsigned int saveindent = dns_master_indent;
REQUIRE(DNS_MESSAGE_VALID(msg));
REQUIRE(target != NULL);
REQUIRE(VALID_PSEUDOSECTION(section));
switch (section) {
case DNS_PSEUDOSECTION_OPT:
ps = dns_message_getopt(msg);
if (ps == NULL) {
goto cleanup;
}
INDENT(style);
ADD_STRING(target, "OPT_PSEUDOSECTION:\n");
dns_master_indent++;
INDENT(style);
ADD_STRING(target, "EDNS:\n");
dns_master_indent++;
INDENT(style);
ADD_STRING(target, "version: ");
snprintf(buf, sizeof(buf), "%u",
(unsigned int)((ps->ttl & 0x00ff0000) >> 16));
ADD_STRING(target, buf);
ADD_STRING(target, "\n");
INDENT(style);
ADD_STRING(target, "flags:");
if ((ps->ttl & DNS_MESSAGEEXTFLAG_DO) != 0)
ADD_STRING(target, " do");
ADD_STRING(target, "\n");
mbz = ps->ttl & 0xffff;
mbz &= ~DNS_MESSAGEEXTFLAG_DO; /* Known Flags. */
if (mbz != 0) {
INDENT(style);
ADD_STRING(target, "MBZ: ");
snprintf(buf, sizeof(buf), "0x%.4x", mbz);
ADD_STRING(target, buf);
ADD_STRING(target, "\n");
}
INDENT(style);
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) {
result = ISC_R_SUCCESS;
goto cleanup;
}
/*
* Print EDNS info, if any.
*
* WARNING: The option contents may be malformed as
* dig +ednsopt=value:<content> does not validity
* checking.
*/
dns_rdata_init(&rdata);
dns_rdataset_current(ps, &rdata);
isc_buffer_init(&optbuf, rdata.data, rdata.length);
isc_buffer_add(&optbuf, rdata.length);
while (isc_buffer_remaininglength(&optbuf) != 0) {
INSIST(isc_buffer_remaininglength(&optbuf) >= 4U);
optcode = isc_buffer_getuint16(&optbuf);
optlen = isc_buffer_getuint16(&optbuf);
INSIST(isc_buffer_remaininglength(&optbuf) >= optlen);
if (optcode == DNS_OPT_NSID) {
INDENT(style);
ADD_STRING(target, "NSID");
} else if (optcode == DNS_OPT_COOKIE) {
INDENT(style);
ADD_STRING(target, "COOKIE");
} else if (optcode == DNS_OPT_CLIENT_SUBNET) {
isc_buffer_t ecsbuf;
INDENT(style);
ADD_STRING(target, "CLIENT-SUBNET");
isc_buffer_init(&ecsbuf,
isc_buffer_current(&optbuf),
optlen);
isc_buffer_add(&ecsbuf, optlen);
result = render_ecs(&ecsbuf, target);
if (result == ISC_R_NOSPACE)
goto cleanup;
if (result == ISC_R_SUCCESS) {
isc_buffer_forward(&optbuf, optlen);
ADD_STRING(target, "\n");
continue;
}
ADD_STRING(target, "\n");
} else if (optcode == DNS_OPT_EXPIRE) {
if (optlen == 4) {
isc_uint32_t secs;
secs = isc_buffer_getuint32(&optbuf);
INDENT(style);
ADD_STRING(target, "EXPIRE: ");
snprintf(buf, sizeof(buf), "%u", secs);
ADD_STRING(target, buf);
ADD_STRING(target, " (");
result = dns_ttl_totext(secs,
ISC_TRUE,
target);
if (result != ISC_R_SUCCESS)
goto cleanup;
ADD_STRING(target, ")\n");
continue;
}
INDENT(style);
ADD_STRING(target, "EXPIRE");
} else if (optcode == DNS_OPT_PAD) {
INDENT(style);
ADD_STRING(target, "PAD");
} else {
INDENT(style);
ADD_STRING(target, "OPT: ");
snprintf(buf, sizeof(buf), "%u", optcode);
ADD_STRING(target, buf);
ADD_STRING(target, "\n");
}
if (optlen != 0) {
int i;
ADD_STRING(target, ": ");
optdata = isc_buffer_current(&optbuf);
for (i = 0; i < optlen; i++) {
const char *sep;
switch (optcode) {
case DNS_OPT_COOKIE:
sep = "";
break;
default:
sep = " ";
break;
}
snprintf(buf, sizeof(buf), "%02x%s",
optdata[i], sep);
ADD_STRING(target, buf);
}
isc_buffer_forward(&optbuf, optlen);
if (optcode == DNS_OPT_COOKIE) {
/*
* Valid server cookie?
*/
if (msg->cc_ok && optlen >= 16)
ADD_STRING(target, " (good)");
/*
* Server cookie is not valid but
* we had our cookie echoed back.
*/
if (msg->cc_ok && optlen < 16)
ADD_STRING(target, " (echoed)");
/*
* We didn't get our cookie echoed
* back.
*/
if (msg->cc_bad)
ADD_STRING(target, " (bad)");
ADD_STRING(target, "\n");
continue;
}
if (optcode == DNS_OPT_CLIENT_SUBNET) {
ADD_STRING(target, "\n");
continue;
}
/*
* For non-COOKIE options, add a printable
* version
*/
ADD_STRING(target, "(\"");
if (isc_buffer_availablelength(target) < optlen)
{
result = ISC_R_NOSPACE;
goto cleanup;
}
for (i = 0; i < optlen; i++) {
if (isprint(optdata[i]))
isc_buffer_putmem(target,
&optdata[i],
1);
else
isc_buffer_putstr(target, ".");
}
ADD_STRING(target, "\")");
}
ADD_STRING(target, "\n");
}
result = ISC_R_SUCCESS;
goto cleanup;
case DNS_PSEUDOSECTION_TSIG:
ps = dns_message_gettsig(msg, &name);
if (ps == NULL) {
result = ISC_R_SUCCESS;
goto cleanup;
}
INDENT(style);
ADD_STRING(target, "TSIG_PSEUDOSECTION:\n");
result = dns_master_rdatasettotext(name, ps, style, target);
ADD_STRING(target, "\n");
goto cleanup;
case DNS_PSEUDOSECTION_SIG0:
ps = dns_message_getsig0(msg, &name);
if (ps == NULL) {
result = ISC_R_SUCCESS;
goto cleanup;
}
INDENT(style);
ADD_STRING(target, "SIG0_PSEUDOSECTION:\n");
result = dns_master_rdatasettotext(name, ps, style, target);
if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 &&
(flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
ADD_STRING(target, "\n");
goto cleanup;
}
result = ISC_R_UNEXPECTED;
cleanup:
dns_master_indent = saveindent;
return (result);
}
isc_result_t
@@ -3312,25 +3596,25 @@ dns_message_pseudosectiontotext(dns_message_t *msg,
isc_buffer_t optbuf;
isc_uint16_t optcode, optlen;
unsigned char *optdata;
unsigned int sflags = dns_master_styleflags(style);
REQUIRE(DNS_MESSAGE_VALID(msg));
REQUIRE(target != NULL);
REQUIRE(VALID_PSEUDOSECTION(section));
if ((dns_master_styleflags(style) & DNS_STYLEFLAG_YAML) != 0)
return (dns_message_pseudosectiontoyaml(msg, section, style,
flags, target));
switch (section) {
case DNS_PSEUDOSECTION_OPT:
ps = dns_message_getopt(msg);
if (ps == NULL)
return (ISC_R_SUCCESS);
if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) {
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
INDENT(style);
ADD_STRING(target, ";; OPT PSEUDOSECTION:\n");
}
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
INDENT(style);
ADD_STRING(target, "; EDNS: version: ");
snprintf(buf, sizeof(buf), "%u",
(unsigned int)((ps->ttl & 0x00ff0000) >> 16));
@@ -3372,8 +3656,7 @@ dns_message_pseudosectiontotext(dns_message_t *msg,
optlen = isc_buffer_getuint16(&optbuf);
INSIST(isc_buffer_remaininglength(&optbuf) >= optlen);
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
INDENT(style);
if (optcode == DNS_OPT_NSID) {
ADD_STRING(target, "; NSID");
@@ -3493,8 +3776,7 @@ dns_message_pseudosectiontotext(dns_message_t *msg,
ps = dns_message_gettsig(msg, &name);
if (ps == NULL)
return (ISC_R_SUCCESS);
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
INDENT(style);
if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
ADD_STRING(target, ";; TSIG PSEUDOSECTION:\n");
result = dns_master_rdatasettotext(name, ps, style, target);
@@ -3506,8 +3788,7 @@ dns_message_pseudosectiontotext(dns_message_t *msg,
ps = dns_message_getsig0(msg, &name);
if (ps == NULL)
return (ISC_R_SUCCESS);
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
INDENT(style);
if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
ADD_STRING(target, ";; SIG0 PSEUDOSECTION:\n");
result = dns_master_rdatasettotext(name, ps, style, target);
@@ -3516,23 +3797,104 @@ dns_message_pseudosectiontotext(dns_message_t *msg,
ADD_STRING(target, "\n");
return (result);
}
return (ISC_R_UNEXPECTED);
result = ISC_R_UNEXPECTED;
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)
{
unsigned int sflags = dns_master_styleflags(style);
char buf[sizeof("1234567890")];
isc_result_t result;
REQUIRE(DNS_MESSAGE_VALID(msg));
REQUIRE(target != NULL);
if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0) {
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
if (((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0) &&
(dns_master_styleflags(style) & DNS_STYLEFLAG_YAML))
{
INDENT(style);
ADD_STRING(target, "opcode: ");
ADD_STRING(target, opcodetext[msg->opcode]);
ADD_STRING(target, "\n");
INDENT(style);
ADD_STRING(target, "status: ");
result = dns_rcode_totext(msg->rcode, target);
if (result != ISC_R_SUCCESS)
return (result);
ADD_STRING(target, "\n");
INDENT(style);
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)
ADD_STRING(target, " qr");
if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0)
ADD_STRING(target, " aa");
if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0)
ADD_STRING(target, " tc");
if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0)
ADD_STRING(target, " rd");
if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0)
ADD_STRING(target, " ra");
if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0)
ADD_STRING(target, " ad");
if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0)
ADD_STRING(target, " cd");
ADD_STRING(target, "\n");
/*
* The final unnamed flag must be zero.
*/
if ((msg->flags & 0x0040U) != 0) {
INDENT(style);
ADD_STRING(target, "MBZ: 0x4");
ADD_STRING(target, "\n");
}
if (msg->opcode != dns_opcode_update) {
INDENT(style);
ADD_STRING(target, "QUESTION: ");
} else {
ADD_STRING(target, "ZONE: ");
}
snprintf(buf, sizeof(buf), "%1u",
msg->counts[DNS_SECTION_QUESTION]);
ADD_STRING(target, buf);
ADD_STRING(target, "\n");
if (msg->opcode != dns_opcode_update) {
INDENT(style);
ADD_STRING(target, "ANSWER: ");
} else {
INDENT(style);
ADD_STRING(target, "PREREQ: ");
}
snprintf(buf, sizeof(buf), "%1u",
msg->counts[DNS_SECTION_ANSWER]);
ADD_STRING(target, buf);
ADD_STRING(target, "\n");
if (msg->opcode != dns_opcode_update) {
INDENT(style);
ADD_STRING(target, "AUTHORITY: ");
} else {
INDENT(style);
ADD_STRING(target, "UPDATE: ");
}
snprintf(buf, sizeof(buf), "%1u",
msg->counts[DNS_SECTION_AUTHORITY]);
ADD_STRING(target, buf);
ADD_STRING(target, "\n");
INDENT(style);
ADD_STRING(target, "ADDITIONAL: ");
snprintf(buf, sizeof(buf), "%1u",
msg->counts[DNS_SECTION_ADDITIONAL]);
ADD_STRING(target, buf);
ADD_STRING(target, "\n");
} else if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0) {
INDENT(style);
ADD_STRING(target, ";; ->>HEADER<<- opcode: ");
ADD_STRING(target, opcodetext[msg->opcode]);
ADD_STRING(target, ", status: ");
@@ -3543,8 +3905,7 @@ dns_message_totext(dns_message_t *msg, const dns_master_style_t *style,
snprintf(buf, sizeof(buf), "%6u", msg->id);
ADD_STRING(target, buf);
ADD_STRING(target, "\n");
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
INDENT(style);
ADD_STRING(target, ";; flags:");
if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0)
ADD_STRING(target, " qr");
@@ -3564,17 +3925,14 @@ dns_message_totext(dns_message_t *msg, const dns_master_style_t *style,
* The final unnamed flag must be zero.
*/
if ((msg->flags & 0x0040U) != 0) {
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
INDENT(style);
ADD_STRING(target, "; MBZ: 0x4");
}
if (msg->opcode != dns_opcode_update) {
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
INDENT(style);
ADD_STRING(target, "; QUESTION: ");
} else {
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
INDENT(style);
ADD_STRING(target, "; ZONE: ");
}
snprintf(buf, sizeof(buf), "%1u",
@@ -3637,7 +3995,8 @@ dns_message_totext(dns_message_t *msg, const dns_master_style_t *style,
if (result != ISC_R_SUCCESS)
return (result);
return (ISC_R_SUCCESS);
cleanup:
return (result);
}
isc_region_t *

View File

@@ -501,6 +501,7 @@ dns_master_questiontotext
dns_master_rdatasettotext
dns_master_stylecreate
dns_master_stylecreate2
dns_master_stylecreate3
dns_master_styledestroy
dns_master_styleflags
dns_message_addname