2
0
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:
Michael Graff
1999-04-30 00:17:15 +00:00
parent 1d11db66fa
commit fccf7905e8
3 changed files with 217 additions and 389 deletions

View File

@@ -27,6 +27,7 @@
#include <isc/assertions.h>
#include <isc/boolean.h>
#include <isc/region.h>
#include <isc/types.h>
#include <dns/message.h>
#include <dns/rdataset.h>
@@ -74,6 +75,7 @@ struct dns_msgblock {
static inline void
msgblock_free(isc_mem_t *, dns_msgblock_t *);
#define msgblock_get(block, type) \
((type *)msgblock_internalget(block, sizeof(type)))
@@ -375,6 +377,7 @@ msgreset(dns_message_t *msg, isc_boolean_t everything)
dns_rdataset_disassociate(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);
if (msgblock == NULL)
goto cleanup4;
ISC_LIST_APPEND(m->rdatas, msgblock, link);
ISC_LIST_APPEND(m->rdatasets, msgblock, link);
if (intent == DNS_MESSAGE_INTENT_PARSE) {
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);
}
*msg = m;
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;
printf("-----\n");
for (curr = ISC_LIST_TAIL(*section) ;
curr != NULL ;
curr = ISC_LIST_PREV(curr, link)) {
printf("curr = %p\n", curr);
if (dns_name_compare(curr, target) == 0) {
if (foundname != NULL)
*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 */
}
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
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.
*/
isc_buffer_remaining(source, &r);
isc_buffer_setactive(source, r.length);
result = getname(name, source, msg, dctx);
if (result != DNS_R_SUCCESS)
return (result);
@@ -679,17 +722,24 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx)
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
* FORMERR. In the future, check the opcode to see if
* this should be legal or not. In either case we no longer
* need this name pointer.
*/
releasename(msg, name);
if (result != DNS_R_SUCCESS)
return (DNS_R_FORMERR);
name = name2;
ISC_LIST_APPEND(*section, name, link);
if (result != DNS_R_SUCCESS) {
if (ISC_LIST_EMPTY(*section)) {
ISC_LIST_APPEND(*section, name, link);
} else {
return (DNS_R_FORMERR);
}
} else {
name = name2;
}
/*
* Get type and class.
@@ -734,6 +784,7 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx)
rdatalist->ttl = 0;
ISC_LIST_INIT(rdatalist->rdata);
dns_rdataset_init(rdataset);
result = dns_rdatalist_tordataset(rdatalist, rdataset);
if (result != DNS_R_SUCCESS)
return (result);
@@ -758,6 +809,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
dns_result_t result;
dns_rdatatype_t rdtype;
dns_rdataclass_t rdclass;
dns_rdata_t *rdata;
dns_ttl_t ttl;
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.
*/
isc_buffer_remaining(source, &r);
isc_buffer_setactive(source, r.length);
result = getname(name, source, msg, dctx);
if (result != DNS_R_SUCCESS)
return (result);
@@ -789,10 +843,9 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
if (result == DNS_R_SUCCESS) {
releasename(msg, name);
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
@@ -831,42 +884,51 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
result = findtype(&rdataset, name, rdtype);
/*
* Oh hurt me... I need to add this name to the rdatalist,
* but I have to cheat to get at that given the rdataset...
*
* This sucks. XXXMLG stop point, code below probably wrong.
* If we found an rdataset that matches, we need to
* append this rdata to that set. If we did not, we need
* to create a new rdatalist, store the important bits there,
* convert it to an rdataset, and link the latter to the name.
* Yuck.
*/
#if 0
if (result != DNS_R_SUCCESS) {
rdataset = newrdataset(msg);
if (rdataset == NULL)
return (DNS_R_NOMEMORY);
rdatalist = newrdatalist(msg);
if (rdatalist == NULL)
return (DNS_R_NOMEMORY);
ISC_LIST_APPEND(section, rdataset,
return (DNS_R_FORMERR);
#endif
rdatalist->type = rdtype;
rdatalist->rdclass = rdclass;
rdatalist->ttl = ttl;
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);
rdataset = newrdataset(msg);
/*
* Convert rdatalist to rdataset, and attach the latter to
* the name.
*/
rdatalist->type = rdtype;
rdatalist->rdclass = rdclass;
rdatalist->ttl = 0;
ISC_LIST_INIT(rdatalist->rdata);
result = dns_rdatalist_tordataset(rdatalist, rdataset);
rdata = newrdata(msg);
if (rdata == NULL)
return (DNS_R_NOMEMORY);
result = getrdata(name, source, msg, dctx,
rdclass, rdtype, rdatalen, rdata);
if (result != DNS_R_SUCCESS)
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);
@@ -878,16 +940,21 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source)
isc_region_t r;
dns_decompress_t dctx;
dns_result_t ret;
isc_uint16_t tmpflags;
REQUIRE(VALID_MESSAGE(msg));
REQUIRE(source != NULL);
isc_buffer_remaining(source, &r);
if (r.length >= DNS_MESSAGE_HEADER_LEN)
if (r.length < DNS_MESSAGE_HEADER_LEN)
return (DNS_R_UNEXPECTEDEND);
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_ANSWER] = 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)
return (ret);
isc_buffer_remaining(source, &r);
if (r.length != 0)
return (DNS_R_FORMERR);
/*
* 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_NAMED_SECTION(section));
REQUIRE(name != NULL && name == NULL);
REQUIRE(name != NULL && *name == NULL);
REQUIRE(msg->cursors[section] != NULL);
*name = msg->cursors[section];