mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
snapshot working message parsing
This commit is contained in:
@@ -23,6 +23,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <isc/assertions.h>
|
#include <isc/assertions.h>
|
||||||
|
#include <isc/error.h>
|
||||||
#include <isc/boolean.h>
|
#include <isc/boolean.h>
|
||||||
#include <isc/region.h>
|
#include <isc/region.h>
|
||||||
|
|
||||||
@@ -35,42 +36,26 @@
|
|||||||
#include <dns/rdatalist.h>
|
#include <dns/rdatalist.h>
|
||||||
#include <dns/rdataset.h>
|
#include <dns/rdataset.h>
|
||||||
#include <dns/compress.h>
|
#include <dns/compress.h>
|
||||||
|
#include <dns/message.h>
|
||||||
#define DNS_FLAG_QR 0x8000U
|
|
||||||
#define DNS_FLAG_AA 0x0400U
|
|
||||||
#define DNS_FLAG_TC 0x0200U
|
|
||||||
#define DNS_FLAG_RD 0x0100U
|
|
||||||
#define DNS_FLAG_RA 0x0080U
|
|
||||||
|
|
||||||
#define DNS_OPCODE_MASK 0x7000U
|
|
||||||
#define DNS_OPCODE_SHIFT 11
|
|
||||||
#define DNS_RCODE_MASK 0x000FU
|
|
||||||
|
|
||||||
typedef struct dns_message {
|
|
||||||
unsigned int id;
|
|
||||||
unsigned int flags;
|
|
||||||
unsigned int qcount;
|
|
||||||
unsigned int ancount;
|
|
||||||
unsigned int aucount;
|
|
||||||
unsigned int adcount;
|
|
||||||
dns_namelist_t question;
|
|
||||||
dns_namelist_t answer;
|
|
||||||
dns_namelist_t authority;
|
|
||||||
dns_namelist_t additional;
|
|
||||||
} dns_message_t;
|
|
||||||
|
|
||||||
#define MAX_PREALLOCATED 100
|
|
||||||
|
|
||||||
dns_decompress_t dctx;
|
dns_decompress_t dctx;
|
||||||
unsigned int rdcount, rlcount, ncount;
|
unsigned int rdcount, rlcount, ncount;
|
||||||
dns_name_t names[MAX_PREALLOCATED];
|
|
||||||
dns_rdata_t rdatas[MAX_PREALLOCATED];
|
|
||||||
dns_rdatalist_t lists[MAX_PREALLOCATED];
|
|
||||||
|
|
||||||
void getmessage(dns_message_t *message, isc_buffer_t *source,
|
void getmessage(dns_message_t *message, isc_buffer_t *source,
|
||||||
isc_buffer_t *target);
|
isc_buffer_t *target);
|
||||||
dns_result_t printmessage(dns_message_t *message);
|
dns_result_t printmessage(dns_message_t *message);
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
CHECKRESULT(dns_result_t result, char *msg)
|
||||||
|
{
|
||||||
|
if (result != DNS_R_SUCCESS) {
|
||||||
|
printf("%s: %s\n", msg, dns_result_totext(result));
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef NOISY
|
#ifdef NOISY
|
||||||
static void
|
static void
|
||||||
print_wirename(isc_region_t *name) {
|
print_wirename(isc_region_t *name) {
|
||||||
@@ -98,232 +83,6 @@ fromhex(char c) {
|
|||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
static isc_uint16_t
|
|
||||||
getshort(isc_buffer_t *buffer) {
|
|
||||||
isc_region_t r;
|
|
||||||
|
|
||||||
isc_buffer_remaining(buffer, &r);
|
|
||||||
if (r.length < 2) {
|
|
||||||
printf("not enough input\n");
|
|
||||||
exit(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (isc_buffer_getuint16(buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int
|
|
||||||
getname(dns_name_t *name, isc_buffer_t *source, isc_buffer_t *target) {
|
|
||||||
unsigned char c[255];
|
|
||||||
dns_result_t result;
|
|
||||||
isc_buffer_t text;
|
|
||||||
unsigned int current;
|
|
||||||
#ifdef NOISY
|
|
||||||
isc_region_t r;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
isc_buffer_init(&text, c, 255, ISC_BUFFERTYPE_TEXT);
|
|
||||||
dns_name_init(name, NULL);
|
|
||||||
|
|
||||||
current = source->current;
|
|
||||||
if (dns_decompress_edns(&dctx) > 1 || !dns_decompress_strict(&dctx))
|
|
||||||
dns_decompress_setmethods(&dctx, DNS_COMPRESS_GLOBAL);
|
|
||||||
else
|
|
||||||
dns_decompress_setmethods(&dctx, DNS_COMPRESS_GLOBAL14);
|
|
||||||
result = dns_name_fromwire(name, source, &dctx, ISC_FALSE, target);
|
|
||||||
|
|
||||||
#ifdef NOISY
|
|
||||||
if (result == DNS_R_SUCCESS) {
|
|
||||||
dns_name_toregion(name, &r);
|
|
||||||
print_wirename(&r);
|
|
||||||
printf("%u labels, %u bytes.\n",
|
|
||||||
dns_name_countlabels(name),
|
|
||||||
r.length);
|
|
||||||
result = dns_name_totext(name, ISC_FALSE, &text);
|
|
||||||
if (result == DNS_R_SUCCESS) {
|
|
||||||
isc_buffer_used(&text, &r);
|
|
||||||
printf("%.*s\n", (int)r.length, r.base);
|
|
||||||
} else
|
|
||||||
printf("%s\n", dns_result_totext(result));
|
|
||||||
} else
|
|
||||||
printf("%s\n", dns_result_totext(result));
|
|
||||||
#else
|
|
||||||
if (result != DNS_R_SUCCESS)
|
|
||||||
printf("%s\n", dns_result_totext(result));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return (source->current - current);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
getquestions(isc_buffer_t *source, dns_namelist_t *section, unsigned int count,
|
|
||||||
isc_buffer_t *target)
|
|
||||||
{
|
|
||||||
unsigned int type, rdclass;
|
|
||||||
dns_name_t *name, *curr;
|
|
||||||
dns_rdatalist_t *rdatalist;
|
|
||||||
isc_region_t r;
|
|
||||||
|
|
||||||
ISC_LIST_INIT(*section);
|
|
||||||
while (count > 0) {
|
|
||||||
count--;
|
|
||||||
|
|
||||||
if (ncount == MAX_PREALLOCATED) {
|
|
||||||
printf("out of names\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
name = &names[ncount++];
|
|
||||||
|
|
||||||
isc_buffer_remaining(source, &r);
|
|
||||||
isc_buffer_setactive(source, r.length);
|
|
||||||
(void)getname(name, source, target);
|
|
||||||
for (curr = ISC_LIST_HEAD(*section);
|
|
||||||
curr != NULL;
|
|
||||||
curr = ISC_LIST_NEXT(curr, link)) {
|
|
||||||
if (dns_name_compare(curr, name) == 0) {
|
|
||||||
ncount--;
|
|
||||||
name = curr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (name != curr)
|
|
||||||
ISC_LIST_APPEND(*section, name, link);
|
|
||||||
type = getshort(source);
|
|
||||||
rdclass = getshort(source);
|
|
||||||
for (rdatalist = ISC_LIST_HEAD(name->list);
|
|
||||||
rdatalist != NULL;
|
|
||||||
rdatalist = ISC_LIST_NEXT(rdatalist, link)) {
|
|
||||||
if (rdatalist->rdclass == rdclass &&
|
|
||||||
rdatalist->type == type)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (rdatalist == NULL) {
|
|
||||||
if (rlcount == MAX_PREALLOCATED) {
|
|
||||||
printf("out of rdatalists\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
rdatalist = &lists[rlcount++];
|
|
||||||
rdatalist->rdclass = rdclass;
|
|
||||||
rdatalist->type = type;
|
|
||||||
rdatalist->ttl = 0;
|
|
||||||
ISC_LIST_INIT(rdatalist->rdata);
|
|
||||||
ISC_LIST_APPEND(name->list, rdatalist, link);
|
|
||||||
} else
|
|
||||||
printf(";; duplicate question\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
getsection(isc_buffer_t *source, dns_namelist_t *section, unsigned int count,
|
|
||||||
isc_buffer_t *target)
|
|
||||||
{
|
|
||||||
unsigned int type, rdclass, ttl, rdlength;
|
|
||||||
isc_region_t r;
|
|
||||||
dns_name_t *name, *curr;
|
|
||||||
dns_rdata_t *rdata;
|
|
||||||
dns_rdatalist_t *rdatalist;
|
|
||||||
dns_result_t result;
|
|
||||||
|
|
||||||
ISC_LIST_INIT(*section);
|
|
||||||
while (count > 0) {
|
|
||||||
count--;
|
|
||||||
|
|
||||||
if (ncount == MAX_PREALLOCATED) {
|
|
||||||
printf("out of names\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
name = &names[ncount++];
|
|
||||||
isc_buffer_remaining(source, &r);
|
|
||||||
isc_buffer_setactive(source, r.length);
|
|
||||||
(void)getname(name, source, target);
|
|
||||||
for (curr = ISC_LIST_HEAD(*section);
|
|
||||||
curr != NULL;
|
|
||||||
curr = ISC_LIST_NEXT(curr, link)) {
|
|
||||||
if (dns_name_compare(curr, name) == 0) {
|
|
||||||
ncount--;
|
|
||||||
name = curr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (name != curr)
|
|
||||||
ISC_LIST_APPEND(*section, name, link);
|
|
||||||
type = getshort(source);
|
|
||||||
rdclass = getshort(source);
|
|
||||||
ttl = getshort(source);
|
|
||||||
ttl *= 65536;
|
|
||||||
ttl += getshort(source);
|
|
||||||
rdlength = getshort(source);
|
|
||||||
isc_buffer_remaining(source, &r);
|
|
||||||
if (r.length < rdlength) {
|
|
||||||
printf("unexpected end of rdata\n");
|
|
||||||
exit(7);
|
|
||||||
}
|
|
||||||
isc_buffer_setactive(source, rdlength);
|
|
||||||
if (rdcount == MAX_PREALLOCATED) {
|
|
||||||
printf("out of rdata\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
rdata = &rdatas[rdcount++];
|
|
||||||
dns_decompress_localinit(&dctx, name, source);
|
|
||||||
result = dns_rdata_fromwire(rdata, rdclass, type,
|
|
||||||
source, &dctx, ISC_FALSE,
|
|
||||||
target);
|
|
||||||
dns_decompress_localinvalidate(&dctx);
|
|
||||||
if (result != DNS_R_SUCCESS) {
|
|
||||||
printf("%s\n", dns_result_totext(result));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
for (rdatalist = ISC_LIST_HEAD(name->list);
|
|
||||||
rdatalist != NULL;
|
|
||||||
rdatalist = ISC_LIST_NEXT(rdatalist, link)) {
|
|
||||||
if (rdatalist->rdclass == rdclass &&
|
|
||||||
rdatalist->type == type)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (rdatalist == NULL) {
|
|
||||||
if (rlcount == MAX_PREALLOCATED) {
|
|
||||||
printf("out of rdatalists\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
rdatalist = &lists[rlcount++];
|
|
||||||
rdatalist->rdclass = rdclass;
|
|
||||||
rdatalist->type = type;
|
|
||||||
rdatalist->ttl = ttl;
|
|
||||||
ISC_LIST_INIT(rdatalist->rdata);
|
|
||||||
ISC_LIST_APPEND(name->list, rdatalist, link);
|
|
||||||
} else {
|
|
||||||
if (ttl < rdatalist->ttl)
|
|
||||||
rdatalist->ttl = ttl;
|
|
||||||
}
|
|
||||||
|
|
||||||
ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
getmessage(dns_message_t *message, isc_buffer_t *source,
|
|
||||||
isc_buffer_t *target)
|
|
||||||
{
|
|
||||||
isc_region_t r;
|
|
||||||
|
|
||||||
message->id = getshort(source);
|
|
||||||
message->flags = getshort(source);
|
|
||||||
message->qcount = getshort(source);
|
|
||||||
message->ancount = getshort(source);
|
|
||||||
message->aucount = getshort(source);
|
|
||||||
message->adcount = getshort(source);
|
|
||||||
|
|
||||||
dns_decompress_init(&dctx, -1, ISC_FALSE);
|
|
||||||
getquestions(source, &message->question, message->qcount, target);
|
|
||||||
getsection(source, &message->answer, message->ancount, target);
|
|
||||||
getsection(source, &message->authority, message->aucount, target);
|
|
||||||
getsection(source, &message->additional, message->adcount, target);
|
|
||||||
dns_decompress_invalidate(&dctx);
|
|
||||||
|
|
||||||
isc_buffer_remaining(source, &r);
|
|
||||||
if (r.length != 0)
|
|
||||||
printf("extra data at end of packet.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *opcodetext[] = {
|
static char *opcodetext[] = {
|
||||||
"QUERY",
|
"QUERY",
|
||||||
"IQUERY",
|
"IQUERY",
|
||||||
@@ -362,85 +121,50 @@ static char *rcodetext[] = {
|
|||||||
"RESERVED15"
|
"RESERVED15"
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
|
||||||
printquestions(dns_namelist_t *section) {
|
|
||||||
dns_name_t *name;
|
|
||||||
dns_rdatalist_t *rdatalist;
|
|
||||||
char t[1000];
|
|
||||||
isc_buffer_t target;
|
|
||||||
dns_result_t result;
|
|
||||||
|
|
||||||
printf(";; QUERY SECTION:\n");
|
|
||||||
for (name = ISC_LIST_HEAD(*section);
|
|
||||||
name != NULL;
|
|
||||||
name = ISC_LIST_NEXT(name, link)) {
|
|
||||||
isc_buffer_init(&target, t, sizeof t, ISC_BUFFERTYPE_TEXT);
|
|
||||||
result = dns_name_totext(name, ISC_FALSE, &target);
|
|
||||||
if (result != DNS_R_SUCCESS) {
|
|
||||||
printf("%s\n", dns_result_totext(result));
|
|
||||||
exit(15);
|
|
||||||
}
|
|
||||||
for (rdatalist = ISC_LIST_HEAD(name->list);
|
|
||||||
rdatalist != NULL;
|
|
||||||
rdatalist = ISC_LIST_NEXT(rdatalist, link)) {
|
|
||||||
printf(";;\t%.*s, type = ", (int)target.used,
|
|
||||||
(char *)target.base);
|
|
||||||
isc_buffer_clear(&target);
|
|
||||||
result = dns_rdatatype_totext(rdatalist->type,
|
|
||||||
&target);
|
|
||||||
if (result != DNS_R_SUCCESS) {
|
|
||||||
printf("%s\n",
|
|
||||||
dns_result_totext(result));
|
|
||||||
exit(16);
|
|
||||||
}
|
|
||||||
printf("%.*s, class = ", (int)target.used,
|
|
||||||
(char *)target.base);
|
|
||||||
isc_buffer_clear(&target);
|
|
||||||
result = dns_rdataclass_totext(rdatalist->rdclass,
|
|
||||||
&target);
|
|
||||||
if (result != DNS_R_SUCCESS) {
|
|
||||||
printf("%s\n", dns_result_totext(result));
|
|
||||||
exit(17);
|
|
||||||
}
|
|
||||||
printf("%.*s\n", (int)target.used,
|
|
||||||
(char *)target.base);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static dns_result_t
|
static dns_result_t
|
||||||
printsection(dns_namelist_t *section, char *section_name) {
|
printsection(dns_message_t *msg, dns_section_t sectionid, char *section_name)
|
||||||
|
{
|
||||||
dns_name_t *name, *print_name;
|
dns_name_t *name, *print_name;
|
||||||
dns_rdatalist_t *rdatalist;
|
dns_rdataset_t *rdataset;
|
||||||
dns_rdataset_t rdataset;
|
|
||||||
isc_buffer_t target;
|
isc_buffer_t target;
|
||||||
dns_result_t result;
|
dns_result_t result;
|
||||||
isc_region_t r;
|
isc_region_t r;
|
||||||
dns_name_t empty_name;
|
dns_name_t empty_name;
|
||||||
char t[1000];
|
char t[1000];
|
||||||
isc_boolean_t first;
|
isc_boolean_t first;
|
||||||
|
isc_boolean_t no_rdata;
|
||||||
|
|
||||||
|
if (sectionid == DNS_SECTION_QUESTION)
|
||||||
|
no_rdata = ISC_TRUE;
|
||||||
|
else
|
||||||
|
no_rdata = ISC_FALSE;
|
||||||
|
|
||||||
dns_rdataset_init(&rdataset);
|
|
||||||
dns_name_init(&empty_name, NULL);
|
|
||||||
printf("\n;; %s SECTION:\n", section_name);
|
printf("\n;; %s SECTION:\n", section_name);
|
||||||
for (name = ISC_LIST_HEAD(*section);
|
|
||||||
name != NULL;
|
dns_name_init(&empty_name, NULL);
|
||||||
name = ISC_LIST_NEXT(name, link)) {
|
|
||||||
|
result = dns_message_firstname(msg, sectionid);
|
||||||
|
if (result == DNS_R_NOMORE)
|
||||||
|
return (DNS_R_SUCCESS);
|
||||||
|
else if (result != DNS_R_SUCCESS)
|
||||||
|
return (result);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
name = NULL;
|
||||||
|
dns_message_currentname(msg, sectionid, &name);
|
||||||
|
|
||||||
isc_buffer_init(&target, t, sizeof t, ISC_BUFFERTYPE_TEXT);
|
isc_buffer_init(&target, t, sizeof t, ISC_BUFFERTYPE_TEXT);
|
||||||
first = ISC_TRUE;
|
first = ISC_TRUE;
|
||||||
print_name = name;
|
print_name = name;
|
||||||
for (rdatalist = ISC_LIST_HEAD(name->list);
|
|
||||||
rdatalist != NULL;
|
for (rdataset = ISC_LIST_HEAD(name->list);
|
||||||
rdatalist = ISC_LIST_NEXT(rdatalist, link)) {
|
rdataset != NULL;
|
||||||
result = dns_rdatalist_tordataset(rdatalist,
|
rdataset = ISC_LIST_NEXT(rdataset, link)) {
|
||||||
&rdataset);
|
result = dns_rdataset_totext(rdataset, print_name,
|
||||||
|
ISC_FALSE, &target,
|
||||||
|
no_rdata);
|
||||||
if (result != DNS_R_SUCCESS)
|
if (result != DNS_R_SUCCESS)
|
||||||
return (result);
|
return (result);
|
||||||
result = dns_rdataset_totext(&rdataset, print_name,
|
|
||||||
ISC_FALSE, &target);
|
|
||||||
if (result != DNS_R_SUCCESS)
|
|
||||||
return (result);
|
|
||||||
dns_rdataset_disassociate(&rdataset);
|
|
||||||
#ifdef USEINITALWS
|
#ifdef USEINITALWS
|
||||||
if (first) {
|
if (first) {
|
||||||
print_name = &empty_name;
|
print_name = &empty_name;
|
||||||
@@ -450,53 +174,75 @@ printsection(dns_namelist_t *section, char *section_name) {
|
|||||||
}
|
}
|
||||||
isc_buffer_used(&target, &r);
|
isc_buffer_used(&target, &r);
|
||||||
printf("%.*s", (int)r.length, (char *)r.base);
|
printf("%.*s", (int)r.length, (char *)r.base);
|
||||||
|
|
||||||
|
result = dns_message_nextname(msg, sectionid);
|
||||||
|
if (result == DNS_R_NOMORE)
|
||||||
|
break;
|
||||||
|
else if (result != DNS_R_SUCCESS)
|
||||||
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (DNS_R_SUCCESS);
|
return (DNS_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
dns_result_t
|
dns_result_t
|
||||||
printmessage(dns_message_t *message) {
|
printmessage(dns_message_t *msg) {
|
||||||
isc_boolean_t did_flag = ISC_FALSE;
|
isc_boolean_t did_flag = ISC_FALSE;
|
||||||
unsigned int opcode, rcode;
|
|
||||||
dns_result_t result;
|
dns_result_t result;
|
||||||
|
|
||||||
opcode = (message->flags & DNS_OPCODE_MASK) >> DNS_OPCODE_SHIFT;
|
result = DNS_R_UNEXPECTED;
|
||||||
rcode = message->flags & DNS_RCODE_MASK;
|
|
||||||
printf(";; ->>HEADER<<- opcode: %s, status: %s, id: %u\n",
|
printf(";; ->>HEADER<<- opcode: %s, status: %s, id: %u\n",
|
||||||
opcodetext[opcode], rcodetext[rcode], message->id);
|
opcodetext[msg->opcode], rcodetext[msg->rcode], msg->id);
|
||||||
|
|
||||||
printf(";; flags: ");
|
printf(";; flags: ");
|
||||||
if ((message->flags & DNS_FLAG_QR) != 0) {
|
if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) {
|
||||||
printf("qr");
|
printf("qr");
|
||||||
did_flag = ISC_TRUE;
|
did_flag = ISC_TRUE;
|
||||||
}
|
}
|
||||||
if ((message->flags & DNS_FLAG_AA) != 0) {
|
if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0) {
|
||||||
printf("%saa", did_flag ? " " : "");
|
printf("%saa", did_flag ? " " : "");
|
||||||
did_flag = ISC_TRUE;
|
did_flag = ISC_TRUE;
|
||||||
}
|
}
|
||||||
if ((message->flags & DNS_FLAG_TC) != 0) {
|
if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
|
||||||
printf("%stc", did_flag ? " " : "");
|
printf("%stc", did_flag ? " " : "");
|
||||||
did_flag = ISC_TRUE;
|
did_flag = ISC_TRUE;
|
||||||
}
|
}
|
||||||
if ((message->flags & DNS_FLAG_RD) != 0) {
|
if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0) {
|
||||||
printf("%srd", did_flag ? " " : "");
|
printf("%srd", did_flag ? " " : "");
|
||||||
did_flag = ISC_TRUE;
|
did_flag = ISC_TRUE;
|
||||||
}
|
}
|
||||||
if ((message->flags & DNS_FLAG_RA) != 0) {
|
if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0) {
|
||||||
printf("%sra", did_flag ? " " : "");
|
printf("%sra", did_flag ? " " : "");
|
||||||
did_flag = ISC_TRUE;
|
did_flag = ISC_TRUE;
|
||||||
}
|
}
|
||||||
printf("; QUERY: %u, ANSWER: %u, AUTHORITY: %u, ADDITIONAL: %u\n",
|
printf("; QUERY: %u, ANSWER: %u, AUTHORITY: %u, ADDITIONAL: %u\n",
|
||||||
message->qcount, message->ancount, message->aucount,
|
msg->counts[DNS_SECTION_QUESTION],
|
||||||
message->adcount);
|
msg->counts[DNS_SECTION_ANSWER],
|
||||||
printquestions(&message->question);
|
msg->counts[DNS_SECTION_AUTHORITY],
|
||||||
result = printsection(&message->answer, "ANSWER");
|
msg->counts[DNS_SECTION_ADDITIONAL]);
|
||||||
|
printf("; PSEUDOSECTIONS: OPT: %u, TSIG: %u\n",
|
||||||
|
msg->counts[DNS_SECTION_OPT],
|
||||||
|
msg->counts[DNS_SECTION_TSIG]);
|
||||||
|
|
||||||
|
result = printsection(msg, DNS_SECTION_QUESTION, "QUESTION");
|
||||||
if (result != DNS_R_SUCCESS)
|
if (result != DNS_R_SUCCESS)
|
||||||
return (result);
|
return (result);
|
||||||
result = printsection(&message->authority, "AUTHORITY");
|
result = printsection(msg, DNS_SECTION_ANSWER, "ANSWER");
|
||||||
|
if (result != DNS_R_SUCCESS)
|
||||||
|
return (result);
|
||||||
|
result = printsection(msg, DNS_SECTION_AUTHORITY, "AUTHORITY");
|
||||||
|
if (result != DNS_R_SUCCESS)
|
||||||
|
return (result);
|
||||||
|
result = printsection(msg, DNS_SECTION_ADDITIONAL, "ADDITIONAL");
|
||||||
|
if (result != DNS_R_SUCCESS)
|
||||||
|
return (result);
|
||||||
|
result = printsection(msg, DNS_SECTION_OPT, "PSEUDOSECTION OPT");
|
||||||
|
if (result != DNS_R_SUCCESS)
|
||||||
|
return (result);
|
||||||
|
result = printsection(msg, DNS_SECTION_TSIG, "PSEUDOSECTION TSIG");
|
||||||
if (result != DNS_R_SUCCESS)
|
if (result != DNS_R_SUCCESS)
|
||||||
return (result);
|
return (result);
|
||||||
result = printsection(&message->additional, "ADDITIONAL");
|
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
@@ -506,16 +252,19 @@ int
|
|||||||
main(int argc, char *argv[]) {
|
main(int argc, char *argv[]) {
|
||||||
char *rp, *wp;
|
char *rp, *wp;
|
||||||
unsigned char *bp;
|
unsigned char *bp;
|
||||||
isc_buffer_t source, target;
|
isc_buffer_t source;
|
||||||
size_t len, i;
|
size_t len, i;
|
||||||
int n;
|
int n;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
isc_boolean_t need_close = ISC_FALSE;
|
isc_boolean_t need_close = ISC_FALSE;
|
||||||
unsigned char b[1000];
|
unsigned char b[1000];
|
||||||
char s[1000];
|
char s[1000];
|
||||||
char t[5000];
|
dns_message_t *message;
|
||||||
dns_message_t message;
|
dns_message_t *message2;
|
||||||
dns_result_t result;
|
dns_result_t result;
|
||||||
|
isc_mem_t *mctx;
|
||||||
|
|
||||||
|
RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
f = fopen(argv[1], "r");
|
f = fopen(argv[1], "r");
|
||||||
@@ -562,19 +311,26 @@ main(int argc, char *argv[]) {
|
|||||||
if (need_close)
|
if (need_close)
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
rdcount = 0;
|
f = fopen("foo", "w");
|
||||||
rlcount = 0;
|
fwrite(b, bp - b, 1, f);
|
||||||
ncount = 0;
|
fclose(f);
|
||||||
|
|
||||||
|
|
||||||
isc_buffer_init(&source, b, sizeof b, ISC_BUFFERTYPE_BINARY);
|
isc_buffer_init(&source, b, sizeof b, ISC_BUFFERTYPE_BINARY);
|
||||||
isc_buffer_add(&source, bp - b);
|
isc_buffer_add(&source, bp - b);
|
||||||
isc_buffer_init(&target, t, sizeof t, ISC_BUFFERTYPE_BINARY);
|
|
||||||
getmessage(&message, &source, &target);
|
result = dns_message_create(mctx, &message, DNS_MESSAGE_INTENT_PARSE);
|
||||||
result = printmessage(&message);
|
CHECKRESULT(result, "dns_message_create failed");
|
||||||
if (result != DNS_R_SUCCESS)
|
|
||||||
printf("printmessage() failed: %s\n",
|
result = dns_message_parse(message, &source);
|
||||||
dns_result_totext(result));
|
CHECKRESULT(result, "dns_message_parse failed");
|
||||||
|
|
||||||
|
result = printmessage(message);
|
||||||
|
CHECKRESULT(result, "printmessage() failed");
|
||||||
|
|
||||||
|
dns_message_destroy(&message);
|
||||||
|
|
||||||
|
isc_mem_stats(mctx, stdout);
|
||||||
|
isc_mem_destroy(&mctx);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@@ -56,15 +56,16 @@
|
|||||||
|
|
||||||
ISC_LANG_BEGINDECLS
|
ISC_LANG_BEGINDECLS
|
||||||
|
|
||||||
#define DNS_MESSAGE_QR 0x8000U
|
#define DNS_MESSAGEFLAG_QR 0x8000U
|
||||||
#define DNS_MESSAGE_AA 0x0400U
|
#define DNS_MESSAGEFLAG_AA 0x0400U
|
||||||
#define DNS_MESSAGE_TC 0x0200U
|
#define DNS_MESSAGEFLAG_TC 0x0200U
|
||||||
#define DNS_MESSAGE_RD 0x0100U
|
#define DNS_MESSAGEFLAG_RD 0x0100U
|
||||||
#define DNS_MESSAGE_RA 0x0080U
|
#define DNS_MESSAGEFLAG_RA 0x0080U
|
||||||
|
|
||||||
#define DNS_MESSAGE_OPCODE_MASK 0x7000U
|
#define DNS_MESSAGE_OPCODE_MASK 0x7000U
|
||||||
#define DNS_MESSAGE_OPCODE_SHIFT 11
|
#define DNS_MESSAGE_OPCODE_SHIFT 11
|
||||||
#define DNS_MESSAGE_RCODE_MASK 0x000fU
|
#define DNS_MESSAGE_RCODE_MASK 0x000fU
|
||||||
|
#define DNS_MESSAGE_FLAG_MASK 0x1ff0U
|
||||||
|
|
||||||
#define DNS_MESSAGE_HEADER_LEN 12 /* 6 u_int16_t's */
|
#define DNS_MESSAGE_HEADER_LEN 12 /* 6 u_int16_t's */
|
||||||
|
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
#include <isc/assertions.h>
|
#include <isc/assertions.h>
|
||||||
#include <isc/boolean.h>
|
#include <isc/boolean.h>
|
||||||
#include <isc/region.h>
|
#include <isc/region.h>
|
||||||
|
#include <isc/types.h>
|
||||||
|
|
||||||
#include <dns/message.h>
|
#include <dns/message.h>
|
||||||
#include <dns/rdataset.h>
|
#include <dns/rdataset.h>
|
||||||
@@ -74,6 +75,7 @@ struct dns_msgblock {
|
|||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
msgblock_free(isc_mem_t *, dns_msgblock_t *);
|
msgblock_free(isc_mem_t *, dns_msgblock_t *);
|
||||||
|
|
||||||
#define msgblock_get(block, type) \
|
#define msgblock_get(block, type) \
|
||||||
((type *)msgblock_internalget(block, sizeof(type)))
|
((type *)msgblock_internalget(block, sizeof(type)))
|
||||||
|
|
||||||
@@ -375,6 +377,7 @@ msgreset(dns_message_t *msg, isc_boolean_t everything)
|
|||||||
dns_rdataset_disassociate(rds);
|
dns_rdataset_disassociate(rds);
|
||||||
rds = next_rds;
|
rds = next_rds;
|
||||||
}
|
}
|
||||||
|
name = next_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -508,7 +511,7 @@ dns_message_create(isc_mem_t *mctx, dns_message_t **msg, unsigned int intent)
|
|||||||
RDATASET_COUNT);
|
RDATASET_COUNT);
|
||||||
if (msgblock == NULL)
|
if (msgblock == NULL)
|
||||||
goto cleanup4;
|
goto cleanup4;
|
||||||
ISC_LIST_APPEND(m->rdatas, msgblock, link);
|
ISC_LIST_APPEND(m->rdatasets, msgblock, link);
|
||||||
|
|
||||||
if (intent == DNS_MESSAGE_INTENT_PARSE) {
|
if (intent == DNS_MESSAGE_INTENT_PARSE) {
|
||||||
msgblock = msgblock_allocate(mctx, sizeof(dns_rdatalist_t),
|
msgblock = msgblock_allocate(mctx, sizeof(dns_rdatalist_t),
|
||||||
@@ -518,6 +521,7 @@ dns_message_create(isc_mem_t *mctx, dns_message_t **msg, unsigned int intent)
|
|||||||
ISC_LIST_APPEND(m->rdatalists, msgblock, link);
|
ISC_LIST_APPEND(m->rdatalists, msgblock, link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*msg = m;
|
||||||
return (DNS_R_SUCCESS);
|
return (DNS_R_SUCCESS);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -569,9 +573,11 @@ findname(dns_name_t **foundname, dns_name_t *target, dns_namelist_t *section)
|
|||||||
{
|
{
|
||||||
dns_name_t *curr;
|
dns_name_t *curr;
|
||||||
|
|
||||||
|
printf("-----\n");
|
||||||
for (curr = ISC_LIST_TAIL(*section) ;
|
for (curr = ISC_LIST_TAIL(*section) ;
|
||||||
curr != NULL ;
|
curr != NULL ;
|
||||||
curr = ISC_LIST_PREV(curr, link)) {
|
curr = ISC_LIST_PREV(curr, link)) {
|
||||||
|
printf("curr = %p\n", curr);
|
||||||
if (dns_name_compare(curr, target) == 0) {
|
if (dns_name_compare(curr, target) == 0) {
|
||||||
if (foundname != NULL)
|
if (foundname != NULL)
|
||||||
*foundname = curr;
|
*foundname = curr;
|
||||||
@@ -641,6 +647,41 @@ getname(dns_name_t *name, isc_buffer_t *source, dns_message_t *msg,
|
|||||||
return (DNS_R_UNEXPECTED); /* should never get here... XXXMLG */
|
return (DNS_R_UNEXPECTED); /* should never get here... XXXMLG */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static dns_result_t
|
||||||
|
getrdata(dns_name_t *name, isc_buffer_t *source, dns_message_t *msg,
|
||||||
|
dns_decompress_t *dctx, dns_rdataclass_t rdclass,
|
||||||
|
dns_rdatatype_t rdtype, unsigned int rdatalen, dns_rdata_t *rdata)
|
||||||
|
{
|
||||||
|
isc_buffer_t *scratch;
|
||||||
|
dns_result_t result;
|
||||||
|
unsigned int tries;
|
||||||
|
|
||||||
|
scratch = currentbuffer(msg);
|
||||||
|
|
||||||
|
isc_buffer_setactive(source, rdatalen);
|
||||||
|
dns_decompress_localinit(dctx, name, source);
|
||||||
|
|
||||||
|
tries = 0;
|
||||||
|
while (tries < 2) {
|
||||||
|
result = dns_rdata_fromwire(rdata, rdclass, rdtype,
|
||||||
|
source, dctx, ISC_FALSE,
|
||||||
|
scratch);
|
||||||
|
|
||||||
|
if (result == DNS_R_NOSPACE) {
|
||||||
|
tries++;
|
||||||
|
|
||||||
|
result = newbuffer(msg);
|
||||||
|
if (result != DNS_R_SUCCESS)
|
||||||
|
return (result);
|
||||||
|
|
||||||
|
scratch = currentbuffer(msg);
|
||||||
|
} else {
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (DNS_R_UNEXPECTED); /* should never get here... XXXMLG */
|
||||||
|
}
|
||||||
|
|
||||||
static dns_result_t
|
static dns_result_t
|
||||||
getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx)
|
getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx)
|
||||||
@@ -666,6 +707,8 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx)
|
|||||||
/*
|
/*
|
||||||
* Parse the name out of this packet.
|
* Parse the name out of this packet.
|
||||||
*/
|
*/
|
||||||
|
isc_buffer_remaining(source, &r);
|
||||||
|
isc_buffer_setactive(source, r.length);
|
||||||
result = getname(name, source, msg, dctx);
|
result = getname(name, source, msg, dctx);
|
||||||
if (result != DNS_R_SUCCESS)
|
if (result != DNS_R_SUCCESS)
|
||||||
return (result);
|
return (result);
|
||||||
@@ -679,17 +722,24 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx)
|
|||||||
result = findname(&name2, name, section);
|
result = findname(&name2, name, section);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If it is a new name, append to the section. Note that
|
* If it is the first name in the section, accept it.
|
||||||
|
*
|
||||||
|
* If it is not, but is not the same as the name already
|
||||||
|
* in the question section, append to the section. Note that
|
||||||
* here in the question section this is illegal, so return
|
* here in the question section this is illegal, so return
|
||||||
* FORMERR. In the future, check the opcode to see if
|
* FORMERR. In the future, check the opcode to see if
|
||||||
* this should be legal or not. In either case we no longer
|
* this should be legal or not. In either case we no longer
|
||||||
* need this name pointer.
|
* need this name pointer.
|
||||||
*/
|
*/
|
||||||
releasename(msg, name);
|
if (result != DNS_R_SUCCESS) {
|
||||||
if (result != DNS_R_SUCCESS)
|
if (ISC_LIST_EMPTY(*section)) {
|
||||||
return (DNS_R_FORMERR);
|
ISC_LIST_APPEND(*section, name, link);
|
||||||
name = name2;
|
} else {
|
||||||
ISC_LIST_APPEND(*section, name, link);
|
return (DNS_R_FORMERR);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
name = name2;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get type and class.
|
* Get type and class.
|
||||||
@@ -734,6 +784,7 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx)
|
|||||||
rdatalist->ttl = 0;
|
rdatalist->ttl = 0;
|
||||||
ISC_LIST_INIT(rdatalist->rdata);
|
ISC_LIST_INIT(rdatalist->rdata);
|
||||||
|
|
||||||
|
dns_rdataset_init(rdataset);
|
||||||
result = dns_rdatalist_tordataset(rdatalist, rdataset);
|
result = dns_rdatalist_tordataset(rdatalist, rdataset);
|
||||||
if (result != DNS_R_SUCCESS)
|
if (result != DNS_R_SUCCESS)
|
||||||
return (result);
|
return (result);
|
||||||
@@ -758,6 +809,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||||||
dns_result_t result;
|
dns_result_t result;
|
||||||
dns_rdatatype_t rdtype;
|
dns_rdatatype_t rdtype;
|
||||||
dns_rdataclass_t rdclass;
|
dns_rdataclass_t rdclass;
|
||||||
|
dns_rdata_t *rdata;
|
||||||
dns_ttl_t ttl;
|
dns_ttl_t ttl;
|
||||||
dns_namelist_t *section;
|
dns_namelist_t *section;
|
||||||
|
|
||||||
@@ -771,6 +823,8 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||||||
/*
|
/*
|
||||||
* Parse the name out of this packet.
|
* Parse the name out of this packet.
|
||||||
*/
|
*/
|
||||||
|
isc_buffer_remaining(source, &r);
|
||||||
|
isc_buffer_setactive(source, r.length);
|
||||||
result = getname(name, source, msg, dctx);
|
result = getname(name, source, msg, dctx);
|
||||||
if (result != DNS_R_SUCCESS)
|
if (result != DNS_R_SUCCESS)
|
||||||
return (result);
|
return (result);
|
||||||
@@ -789,10 +843,9 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||||||
if (result == DNS_R_SUCCESS) {
|
if (result == DNS_R_SUCCESS) {
|
||||||
releasename(msg, name);
|
releasename(msg, name);
|
||||||
name = name2;
|
name = name2;
|
||||||
|
} else {
|
||||||
|
ISC_LIST_APPEND(*section, name, link);
|
||||||
}
|
}
|
||||||
name = name2;
|
|
||||||
ISC_LIST_APPEND(msg->sections[DNS_SECTION_QUESTION],
|
|
||||||
name, link);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get type, class, ttl, and rdatalen. Verify that at least
|
* Get type, class, ttl, and rdatalen. Verify that at least
|
||||||
@@ -831,42 +884,51 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||||||
result = findtype(&rdataset, name, rdtype);
|
result = findtype(&rdataset, name, rdtype);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Oh hurt me... I need to add this name to the rdatalist,
|
* If we found an rdataset that matches, we need to
|
||||||
* but I have to cheat to get at that given the rdataset...
|
* append this rdata to that set. If we did not, we need
|
||||||
*
|
* to create a new rdatalist, store the important bits there,
|
||||||
* This sucks. XXXMLG stop point, code below probably wrong.
|
* convert it to an rdataset, and link the latter to the name.
|
||||||
|
* Yuck.
|
||||||
*/
|
*/
|
||||||
#if 0
|
|
||||||
if (result != DNS_R_SUCCESS) {
|
if (result != DNS_R_SUCCESS) {
|
||||||
rdataset = newrdataset(msg);
|
rdataset = newrdataset(msg);
|
||||||
if (rdataset == NULL)
|
if (rdataset == NULL)
|
||||||
return (DNS_R_NOMEMORY);
|
return (DNS_R_NOMEMORY);
|
||||||
|
rdatalist = newrdatalist(msg);
|
||||||
|
if (rdatalist == NULL)
|
||||||
|
return (DNS_R_NOMEMORY);
|
||||||
|
|
||||||
ISC_LIST_APPEND(section, rdataset,
|
rdatalist->type = rdtype;
|
||||||
|
rdatalist->rdclass = rdclass;
|
||||||
return (DNS_R_FORMERR);
|
rdatalist->ttl = ttl;
|
||||||
#endif
|
ISC_LIST_INIT(rdatalist->rdata);
|
||||||
|
|
||||||
|
dns_rdataset_init(rdataset);
|
||||||
|
dns_rdatalist_tordataset(rdatalist, rdataset);
|
||||||
|
|
||||||
|
ISC_LIST_APPEND(name->list, rdataset, link);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate a new rdatalist, rdata.
|
* Read the rdata from the wire format.
|
||||||
*/
|
*/
|
||||||
rdatalist = newrdatalist(msg);
|
rdata = newrdata(msg);
|
||||||
rdataset = newrdataset(msg);
|
if (rdata == NULL)
|
||||||
|
return (DNS_R_NOMEMORY);
|
||||||
/*
|
result = getrdata(name, source, msg, dctx,
|
||||||
* Convert rdatalist to rdataset, and attach the latter to
|
rdclass, rdtype, rdatalen, rdata);
|
||||||
* the name.
|
|
||||||
*/
|
|
||||||
rdatalist->type = rdtype;
|
|
||||||
rdatalist->rdclass = rdclass;
|
|
||||||
rdatalist->ttl = 0;
|
|
||||||
ISC_LIST_INIT(rdatalist->rdata);
|
|
||||||
|
|
||||||
result = dns_rdatalist_tordataset(rdatalist, rdataset);
|
|
||||||
if (result != DNS_R_SUCCESS)
|
if (result != DNS_R_SUCCESS)
|
||||||
return (result);
|
return (result);
|
||||||
|
|
||||||
ISC_LIST_APPEND(name->list, rdataset, link);
|
/*
|
||||||
|
* XXX 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);
|
||||||
|
|
||||||
|
ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (DNS_R_SUCCESS);
|
return (DNS_R_SUCCESS);
|
||||||
@@ -878,16 +940,21 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source)
|
|||||||
isc_region_t r;
|
isc_region_t r;
|
||||||
dns_decompress_t dctx;
|
dns_decompress_t dctx;
|
||||||
dns_result_t ret;
|
dns_result_t ret;
|
||||||
|
isc_uint16_t tmpflags;
|
||||||
|
|
||||||
REQUIRE(VALID_MESSAGE(msg));
|
REQUIRE(VALID_MESSAGE(msg));
|
||||||
REQUIRE(source != NULL);
|
REQUIRE(source != NULL);
|
||||||
|
|
||||||
isc_buffer_remaining(source, &r);
|
isc_buffer_remaining(source, &r);
|
||||||
if (r.length >= DNS_MESSAGE_HEADER_LEN)
|
if (r.length < DNS_MESSAGE_HEADER_LEN)
|
||||||
return (DNS_R_UNEXPECTEDEND);
|
return (DNS_R_UNEXPECTEDEND);
|
||||||
|
|
||||||
msg->id = isc_buffer_getuint16(source);
|
msg->id = isc_buffer_getuint16(source);
|
||||||
msg->flags = isc_buffer_getuint16(source);
|
tmpflags = isc_buffer_getuint16(source);
|
||||||
|
msg->opcode = ((tmpflags & DNS_MESSAGE_OPCODE_MASK)
|
||||||
|
>> DNS_MESSAGE_OPCODE_SHIFT);
|
||||||
|
msg->rcode = (tmpflags & DNS_MESSAGE_RCODE_MASK);
|
||||||
|
msg->flags = (tmpflags & ~DNS_MESSAGE_FLAG_MASK);
|
||||||
msg->counts[DNS_SECTION_QUESTION] = isc_buffer_getuint16(source);
|
msg->counts[DNS_SECTION_QUESTION] = isc_buffer_getuint16(source);
|
||||||
msg->counts[DNS_SECTION_ANSWER] = isc_buffer_getuint16(source);
|
msg->counts[DNS_SECTION_ANSWER] = isc_buffer_getuint16(source);
|
||||||
msg->counts[DNS_SECTION_AUTHORITY] = isc_buffer_getuint16(source);
|
msg->counts[DNS_SECTION_AUTHORITY] = isc_buffer_getuint16(source);
|
||||||
@@ -911,6 +978,10 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source)
|
|||||||
if (ret != DNS_R_SUCCESS)
|
if (ret != DNS_R_SUCCESS)
|
||||||
return (ret);
|
return (ret);
|
||||||
|
|
||||||
|
isc_buffer_remaining(source, &r);
|
||||||
|
if (r.length != 0)
|
||||||
|
return (DNS_R_FORMERR);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXXMLG Need to check the tsig(s) here...
|
* XXXMLG Need to check the tsig(s) here...
|
||||||
*/
|
*/
|
||||||
@@ -1024,7 +1095,7 @@ dns_message_currentname(dns_message_t *msg, dns_section_t section,
|
|||||||
{
|
{
|
||||||
REQUIRE(VALID_MESSAGE(msg));
|
REQUIRE(VALID_MESSAGE(msg));
|
||||||
REQUIRE(VALID_NAMED_SECTION(section));
|
REQUIRE(VALID_NAMED_SECTION(section));
|
||||||
REQUIRE(name != NULL && name == NULL);
|
REQUIRE(name != NULL && *name == NULL);
|
||||||
REQUIRE(msg->cursors[section] != NULL);
|
REQUIRE(msg->cursors[section] != NULL);
|
||||||
|
|
||||||
*name = msg->cursors[section];
|
*name = msg->cursors[section];
|
||||||
|
Reference in New Issue
Block a user