[moodns-cvs] CVS: moodns/src query.c,1.1,1.2 protocol.h,1.14,1.15 protocol.c,1.20,1.21 protocol-rr.c
Status: Alpha
Brought to you by:
mawolf
From: Michael W. <ma...@us...> - 2002-03-05 02:25:17
|
Update of /cvsroot/moodns/moodns/src In directory usw-pr-cvs1:/tmp/cvs-serv32680/src Modified Files: query.c protocol.h protocol.c protocol-rr.c Log Message: laskjfklasdjfkl aj438rj wkljtf Index: query.c =================================================================== RCS file: /cvsroot/moodns/moodns/src/query.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** query.c 21 Feb 2002 05:29:45 -0000 1.1 --- query.c 5 Mar 2002 02:25:08 -0000 1.2 *************** *** 20,23 **** --- 20,28 ---- /* $Header$ */ + /* Known issues: + + We only check return packets of <= 512 bytes. Will need to deal with larger + ones when we get around to adding TCP support. */ + /* Generalised query sending. */ *************** *** 33,36 **** --- 38,42 ---- #include <netinet/in.h> #include <arpa/inet.h> + #include <assert.h> #include <pthread.h> *************** *** 94,97 **** --- 100,109 ---- } retval = packet_create_from_data(res->data, res->len); + + /* Cast to an int should be safe, since retval->size_in_bytes can't be + more than 512. */ + printf("retval->size_in_bytes = %d, len2 = %d\n", retval->size_in_bytes, + len2); + assert((int) retval->size_in_bytes == len2); if (close(s->fd) == -1) Index: protocol.h =================================================================== RCS file: /cvsroot/moodns/moodns/src/protocol.h,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** protocol.h 21 Feb 2002 05:16:21 -0000 1.14 --- protocol.h 5 Mar 2002 02:25:08 -0000 1.15 *************** *** 104,107 **** --- 104,109 ---- /* IN for internet. Could conceivably be something else...? */ u32 qclass:16; + + size_t size_in_bytes; }; *************** *** 114,117 **** --- 116,124 ---- u16 rdlength; /* Why wasn't this here before? */ byte_array *rdata; + /* This won't be compressed, and isn't included in any size_in_bytes + calculations.*/ + byte_array *rdata_uncompressed; + + size_t size_in_bytes; }; *************** *** 131,146 **** u32 ra, u32 z, u32 rcode); ! packet *packet_create_from_data(u8 * data, u32 len); int packet_add_rr(packet * p, u8 * name, u32 type, u32 class, u32 tll, ! u32 rdlength, u8 * rdata); ! ! int packet_add_rr_from_data(packet * p, u8 * data, int idx); int packet_add_question(packet * p, u8 * qname, u32 qtype, u32 qclass); ! int packet_add_question_from_data(packet * p, u8 * data, int idx); ! int packet_add_answer_from_data(packet * p, u8 * data, int idx); ! int packet_add_authoritive_from_data(packet * p, u8 * data, int idx); ! int packet_add_additional_from_data(packet * p, u8 * data, int idx); byte_array *packet_convert_to_data(packet * p); --- 138,152 ---- u32 ra, u32 z, u32 rcode); ! packet *packet_create_from_data(const u8 * data, u32 len); int packet_add_rr(packet * p, u8 * name, u32 type, u32 class, u32 tll, ! u32 rdlength, u8 * rdata); int packet_add_question(packet * p, u8 * qname, u32 qtype, u32 qclass); ! ! int packet_add_question_from_data(packet * p, const u8 * data, int idx, const u8 *base); ! int packet_add_answer_from_data(packet * p, const u8 * data, int idx, const u8 *base); ! int packet_add_authoritive_from_data(packet * p, const u8 * data, int idx, const u8 *base); ! int packet_add_additional_from_data(packet * p, const u8 * data, int idx, const u8 *base); byte_array *packet_convert_to_data(packet * p); *************** *** 155,163 **** /* FIXME: These are bad names. Should be fixed. And question_arr_to_char should take a byte_array as an argument. */ ! char *question_arr_to_char(char *); ! byte_array *name_to_bytes(char *); byte_array *compress_domain(byte_array *); byte_array *decompress_domain(byte_array *); int query_parse(char *data, int len); --- 161,172 ---- /* FIXME: These are bad names. Should be fixed. And question_arr_to_char should take a byte_array as an argument. */ ! char *question_arr_to_char(const u8 *, const u8 *, int *); ! char *question_arr_to_char_nd(const u8 *, int *); ! byte_array *name_to_bytes(const char *); ! byte_array *decompress2(const u8 *, const u8 *); byte_array *compress_domain(byte_array *); byte_array *decompress_domain(byte_array *); + int query_parse(char *data, int len); Index: protocol.c =================================================================== RCS file: /cvsroot/moodns/moodns/src/protocol.c,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** protocol.c 14 Feb 2002 03:40:46 -0000 1.20 --- protocol.c 5 Mar 2002 02:25:09 -0000 1.21 *************** *** 20,23 **** --- 20,30 ---- /* $Header$ */ + /* Known issues: + + - question_arr_to_char should take a byte_array as its first arg. Maybe + as its second, too. + + */ + /* Based on information presented in RFC 1035, by P Mockapetris. */ *************** *** 42,45 **** --- 49,53 ---- #include <netinet/in.h> #include <arpa/inet.h> + #include <limits.h> #include "record.h" *************** *** 97,105 **** packet * ! packet_create_from_data(u8 *data, u32 len) { packet *p; struct header_packed hp; ! u8 *section; /* Where we are within data. */ size_t ssize; int i; --- 105,113 ---- packet * ! packet_create_from_data(const u8 *data, u32 len) { packet *p; struct header_packed hp; ! const u8 *section; /* Where we are within data. */ size_t ssize; int i; *************** *** 110,158 **** } ! p = (packet *) xcalloc(1, sizeof(packet)); p->h = (struct header *) xcalloc(1, sizeof(struct header)); memset(&hp, 0, sizeof(hp)); memcpy(hp.data, data, sizeof(hp.data)); header_unpack(p->h, &hp); p->size_in_bytes += sizeof(hp.data); ! section = data + sizeof(hp.data); /* Question */ if (p->h->qdcount != 0) p->qd = (struct question **) xcalloc(p->h->qdcount, sizeof(struct question *)); ! ! if (p->h->ancount != 0) ! p->an = (struct resource_record **) ! xcalloc(p->h->ancount, sizeof(struct resorce_record *)); ! ! if (p->h->nscount != 0) ! p->an = (struct resource_record **) ! xcalloc(p->h->nscount, sizeof(struct resource_record *)); ! ! if (p->h->arcount != 0) ! p->an = (struct resource_record **) ! xcalloc(p->h->arcount, sizeof(struct resource_record *)); ! for (i = 0; i < p->h->qdcount; i++) { ! ssize = packet_add_question_from_data(p, section, i); p->size_in_bytes += ssize; section += ssize; } ! for (i = 0; i < p->h->ancount; i++) { ! ssize = packet_add_answer_from_data(p, section, i); p->size_in_bytes += ssize; section += ssize; } ! for (i = 0; i < p->h->nscount; i++) { ! ssize = packet_add_authoritive_from_data(p, section, i); p->size_in_bytes += ssize; section += ssize; } for (i = 0; i < p->h->arcount; i++) { ! ssize = packet_add_additional_from_data(p, section, i); p->size_in_bytes += ssize; section += ssize; --- 118,178 ---- } ! /* allocate packet structure */ p = (packet *) xcalloc(1, sizeof(packet)); + + /* allocate packet's header */ p->h = (struct header *) xcalloc(1, sizeof(struct header)); + + /* place a packet header's size worth of bytes to the packed header */ memset(&hp, 0, sizeof(hp)); memcpy(hp.data, data, sizeof(hp.data)); + + /* unpack those bytes into header structure */ header_unpack(p->h, &hp); p->size_in_bytes += sizeof(hp.data); ! ! section = data + sizeof(hp.data); + /* allocate question */ if (p->h->qdcount != 0) p->qd = (struct question **) xcalloc(p->h->qdcount, sizeof(struct question *)); ! /* convert questions from raw bytes into question structures, place ! question structures into packet */ for (i = 0; i < p->h->qdcount; i++) { ! ssize = packet_add_question_from_data(p, section, i, data); p->size_in_bytes += ssize; section += ssize; } ! ! /* convert answers from raw bytes into rr structures, put ! structures into packet */ ! if (p->h->ancount != 0) ! p->an = (struct resource_record **) ! xcalloc(p->h->ancount, sizeof(struct resorce_record *)); for (i = 0; i < p->h->ancount; i++) { ! ssize = packet_add_answer_from_data(p, section, i, data); p->size_in_bytes += ssize; section += ssize; } ! ! /* convert authorities from raw bytes into rr structures, put ! structures into packet */ ! if (p->h->nscount != 0) ! p->ns = (struct resource_record **) ! xcalloc(p->h->nscount, sizeof(struct resource_record *)); for (i = 0; i < p->h->nscount; i++) { ! ssize = packet_add_authoritive_from_data(p, section, i, data); p->size_in_bytes += ssize; section += ssize; } + /* convert additionals from raw bytes into rr structures, put + structures into packet */ + if (p->h->arcount != 0) + p->ar = (struct resource_record **) + xcalloc(p->h->arcount, sizeof(struct resource_record *)); for (i = 0; i < p->h->arcount; i++) { ! ssize = packet_add_additional_from_data(p, section, i, data); p->size_in_bytes += ssize; section += ssize; *************** *** 203,253 **** } void packet_debug_dump(packet *p) { - int iqd, ian, ins, iar; - printf("printing packet's header:\n"); ! printf("+ id = %d\n+ qr = %d\n+ opcode = %d\n+ aa = %d\n+ tc = %d\n+ rd = %d\n", ! p->h->id, p->h->qr, p->h->opcode, p->h->aa, p->h->tc, p->h->rd); ! printf("+ ra = %d\n+ z = %d\n+ rcode = %d\n+ qdcount = %d\n+ ancount = %d\n", ! p->h->ra, p->h->z, p->h->rcode, p->h->qdcount, p->h->ancount); printf("+ nscount = %d\n+ arcount = %d\n", p->h->nscount, p->h->arcount); ! ! printf("printing packet's query sections:\n"); ! for (iqd = 0; iqd < p->h->qdcount; ++iqd) { ! printf("+ query name: %s\n", p->qd[iqd]->qname); ! assert(p->qd[iqd]->qclass == IN); /* For now, anyway. */ ! printf("+ query type: %d (%s)\n", p->qd[iqd]->qtype, ! record_type_names[p->qd[iqd]->qtype]); ! printf("+ query class: %d (%s)\n", p->qd[iqd]->qclass, ! record_class_names[p->qd[iqd]->qclass]); } ! printf("printing packet's answers:\n"); ! for (ian = 0; ian < p->h->ancount; ++ian) { ! struct in_addr ia; ! printf("name = %s\n", p->an[ian]->name); ! printf("type = %d (%s)\n", p->an[ian]->type, ! record_type_names[p->an[ian]->type]); ! printf("class = %d (%s)\n", p->an[ian]->class, ! record_class_names[p->an[ian]->class]); ! printf("ttl = %u\n", p->an[ian]->ttl); ! ! if (p->an[ian]->type == A) { ! ia.s_addr = *(int *) p->an[ian]->rdata->data; ! printf("rdata is %s\n", inet_ntoa(ia)); } } ! ! for (ins = 0; ins < p->h->nscount; ++ins) { ! ; } ! ! for (iar = 0; iar < p->h->arcount; ++iar) { ! ; } - printf("In serialised form, this packet is %u bytes long.\n", p->size_in_bytes); --- 223,318 ---- } + /* Trivially print out the contents of a packet. */ void packet_debug_dump(packet *p) { printf("printing packet's header:\n"); ! printf("+ id = %d\n+ qr = %d\n+ opcode = %d\n+ aa = %d\n" ! "+ tc = %d\n+ rd = %d\n", p->h->id, p->h->qr, p->h->opcode, ! p->h->aa, p->h->tc, p->h->rd); ! printf("+ ra = %d\n+ z = %d\n+ rcode = %d\n+ qdcount = %d\n" ! "+ ancount = %d\n", p->h->ra, p->h->z, p->h->rcode, p->h->qdcount, ! p->h->ancount); printf("+ nscount = %d\n+ arcount = %d\n", p->h->nscount, p->h->arcount); ! ! { ! int iqd; ! printf("printing packet's query sections:\n"); ! for (iqd = 0; iqd < p->h->qdcount; ++iqd) { ! printf("+ query name: %s\n", p->qd[iqd]->qname); ! assert(p->qd[iqd]->qclass == IN); /* For now, anyway. */ ! printf("+ query type: %d (%s)\n", p->qd[iqd]->qtype, ! record_type_names[p->qd[iqd]->qtype]); ! printf("+ query class: %d (%s)\n", p->qd[iqd]->qclass, ! record_class_names[p->qd[iqd]->qclass]); ! } } ! { ! int ian; ! printf("there are %d records in the answer section\n", p->h->ancount); ! for (ian = 0; ian < p->h->ancount; ++ian) { ! struct in_addr ia; ! printf("answer %d:\n", ian); ! printf(" name = %s\n", p->an[ian]->name); ! printf(" type = %d (%s)\n", p->an[ian]->type, ! record_type_names[p->an[ian]->type]); ! printf(" class = %d (%s)\n", p->an[ian]->class, ! record_class_names[p->an[ian]->class]); ! printf(" ttl = %u\n", p->an[ian]->ttl); ! ! if (p->an[ian]->type == A) { ! ia.s_addr = htonl(*(int *) p->an[ian]->rdata->data); ! printf(" rdata is %s\n", inet_ntoa(ia)); ! } else { ! printf(" sorry, can't print that kind of rdata yet :(\n"); ! } } } ! { ! int ins; ! printf("there are %d records in the ns section\n", p->h->nscount); ! for (ins = 0; ins < p->h->nscount; ++ins) { ! struct in_addr ia; ! printf("answer %d:\n", ins); ! ! printf(" name = %s\n", p->ns[ins]->name); ! printf(" type = %d (%s)\n", p->ns[ins]->type, ! record_type_names[p->ns[ins]->type]); ! printf(" class = %d (%s)\n", p->ns[ins]->class, ! record_class_names[p->ns[ins]->class]); ! printf(" ttl = %u\n", p->ns[ins]->ttl); ! ! if (p->ns[ins]->type == A) { ! ia.s_addr = htonl(*(int *) p->ns[ins]->rdata->data); ! printf(" rdata is %s\n", inet_ntoa(ia)); ! } else { ! printf(" sorry, can't print that kind of rdata yet :(\n"); ! } ; ! } } ! ! { ! int iar; ! printf("there are %d records in the authoritative section\n", p->h->arcount); ! for (iar = 0; iar < p->h->arcount; ++iar) { ! struct in_addr ia; ! printf("answer %d:\n", iar); ! printf(" name = %s\n", p->ar[iar]->name); ! printf(" type = %d (%s)\n", p->ar[iar]->type, ! record_type_names[p->ar[iar]->type]); ! printf(" class = %d (%s)\n", p->ar[iar]->class, ! record_class_names[p->ar[iar]->class]); ! printf(" ttl = %u\n", p->ar[iar]->ttl); ! ! if (p->ar[iar]->type == A) { ! ia.s_addr = htonl(*(int *) p->ar[iar]->rdata->data); ! printf(" rdata is %s\n", inet_ntoa(ia)); ! } else { ! printf(" sorry, can't print that kind of rdata yet :(\n"); ! }; ! } } printf("In serialised form, this packet is %u bytes long.\n", p->size_in_bytes); *************** *** 294,326 **** ! /* Note that the argument here isn't a proper C string. */ char * ! question_arr_to_char(char *bytes) { char *retval; int x, y, z; ! char *c; retval = xcalloc(256, sizeof(char)); c = bytes; x = *c; z = 0; do { for (y = 0; y < x; ++y) { retval[z++] = *(c + 1 + y); } c += (x + 1); x = *c; ! if (x == 0) { break; } retval[z++] = '.'; } while (x != 0); ! return (retval); } ! byte_array * ! name_to_bytes(char *name) { byte_array *retval; char *namecpy; --- 359,473 ---- ! /* Convert a "question array" to an standard '\0'-delimited C string. ! bytes is the raw data we need to convert. When a compression ! pointer is found, the offset is with respect to base. dsize is ! set to the correct size to be added to a size_in_bytes sum, which ! will be less than the size of the question array if compression is ! in fact used. ! ! Use question_arr_to_char_nd when you're sure there will be no ! decompression. */ ! char * ! question_arr_to_char(const u8 *bytes, const u8 *base, int *dsize) { char *retval; int x, y, z; ! const u8 *c; ! u16 base_offset; ! int keep_adding = 1; /* Gross. */ ! int first_part = 1; + assert(bytes != NULL); + assert(dsize != NULL); + + *dsize = 0; retval = xcalloc(256, sizeof(char)); c = bytes; + x = *c; z = 0; do { + /* Check for compression pointer - the first 2 bits will be set */ + if (*c & (128 | 64)) { + puts("compression pointer found"); + /* This is slightly risky, but the assert should catch problems + if they crop up. */ + assert(base != NULL); + /* XXX: Potentially dangerous in the face of bogus input? Change + first argument (at least) to a byte array so we can know for + sure. */ + base_offset = c[1]; + c = &base[base_offset]; + x = *c; + if (keep_adding) + *dsize += 2; + keep_adding = 0; + } + if (!isalpha(*c) && first_part) { + first_part = 0; + if (keep_adding) + ++*dsize; + } for (y = 0; y < x; ++y) { retval[z++] = *(c + 1 + y); + if (keep_adding) + ++*dsize; } c += (x + 1); x = *c; ! if (x == '\0') { ! if (keep_adding) /* XXXXX: May be wrong. */ ! ++*dsize; break; } retval[z++] = '.'; + if (keep_adding) + ++*dsize; } while (x != 0); ! return retval; } ! char * ! question_arr_to_char_nd(const u8 *bytes, int *dsize) { + char *retval; + int x, y, z; + const u8 *c; + int first_part; + + assert(bytes != NULL); + assert(dsize != NULL); + + first_part = 1; + *dsize = 0; + retval = xcalloc(256, sizeof(char)); + c = bytes; + x = *c; + z = 0; + do { + if (!isalpha(*c) && first_part) { + first_part = 0; + ++*dsize; + } + for (y = 0; y < x; ++y) { + retval[z++] = *(c + 1 + y); + ++*dsize; + } + c += (x + 1); + x = *c; + if (x == '\0') { + ++*dsize; + break; + } + retval[z++] = '.'; + ++*dsize; + } while (x != 0); + return retval; + } + + byte_array * + name_to_bytes(const char *name) + { /* XXX: Add compression to this. Will need some more arguments. Hm. */ byte_array *retval; char *namecpy; *************** *** 354,357 **** --- 501,530 ---- } + byte_array * + decompress2(const u8 *pc, const u8 *base) + { + byte_array *retval; + // int x; // , y, z; + const u8 *c; + u16 base_offset; + retval = (byte_array *) xcalloc(1, sizeof(byte_array)); + assert(pc != NULL); + c = pc; + // x = *c; + // z = 0; + while (1) { + if (*c & (128 | 64)) { + puts("compression pointer found"); + base_offset = c[1]; + c = &base[base_offset]; + } + byte_array_catu8(retval, *c); + if (*c == '\0') + break; + ++c; + } + return retval; + } + int _domain_compare(void *a, void *b, void *aux __attribute__((unused))) *************** *** 460,463 **** --- 633,685 ---- return decompressed; } + + + + /* These really belong in misc.c */ + + void + bitprint_u8(u8 c) + { + int i = UCHAR_MAX - 1; + while (i > 0) { + if (i & c) + fputc('1', stdout); + else + fputc('0', stdout); + i >>= 1; + fputc(' ', stdout); + } + puts(""); + } + + void + bitprint_u16(u16 s) + { + int i = USHRT_MAX; + while (i > 0) { + if (i & s) + fputc('1', stdout); + else + fputc('0', stdout); + i >>= 1; + } + puts(""); + } + + void + bitprint_u32(u32 l) + { + unsigned int i = UINT_MAX - 1; + while (i > 0) { + if (i & l) + fputc('1', stdout); + else + fputc('0', stdout); + i >>= 1; + } + puts(""); + } + + Index: protocol-rr.c =================================================================== RCS file: /cvsroot/moodns/moodns/src/protocol-rr.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** protocol-rr.c 21 Feb 2002 05:16:21 -0000 1.2 --- protocol-rr.c 5 Mar 2002 02:25:09 -0000 1.3 *************** *** 20,23 **** --- 20,48 ---- /* $Header$ */ + /* This file is full of tedious code dealing with the conversion of + resource records to an from data. A single error in this file, + when invoked, will propagate throughout conversion. So don't make + errors. + + The functions add_{answer,authoritative,additional}_from_data are + called outside of this file. They in turn call on + build_rr_from_data. That function takes a raw data argument, a + success or failure argument, and a pointer to the base of the + data. The pointer to the base is necessary to perform + decompression since offsets are used throughout. + + The functions record_to_data_* and rr_to_record_* are almost + opposites of each other. */ + + /* Known issues: + + - This file is a fucking mess! + + - Not all record types are handled. + + - Won't compile with -ansi. Definitely won't compile with -pedantic. + + */ + /* Based on information presented in RFC 1035, by P Mockapetris. */ *************** *** 53,56 **** --- 78,82 ---- #endif + static struct resource_record *build_rr_from_data(const u8 *, size_t *, const u8 *); static byte_array *record_to_data_a(record *); *************** *** 83,89 **** out = (byte_array *) xcalloc(1, sizeof(byte_array)); - // for (i = 0; i < p->h->ancount; ++i) { - /* Can we move the name_to_bytes call out of this loop? I - think so, but I'm not sure. */ tmp = name_to_bytes(p->an[idx]->name); byte_array_cat(out, tmp); --- 109,112 ---- *************** *** 91,100 **** byte_array_catu16(out, htons(p->an[idx]->class)); byte_array_catu32(out, htonl(p->an[idx]->ttl)); ! /* XXX: Should use p->an[idx]->rdlength instead of line below. */ ! byte_array_catu16(out, htons((short) p->an[idx]->rdata->len)); ! // byte_array_catu16(out, p->an[idx]->rdlength); byte_array_cat(out, p->an[idx]->rdata); ! // } ! byte_array_destroy(tmp); --- 114,120 ---- byte_array_catu16(out, htons(p->an[idx]->class)); byte_array_catu32(out, htonl(p->an[idx]->ttl)); ! byte_array_catu16(out, htons(p->an[idx]->rdlength)); byte_array_cat(out, p->an[idx]->rdata); ! byte_array_destroy(tmp); *************** *** 140,177 **** } ! int ! packet_add_rr_from_data(packet *p, u8 *data, int idx) { ! int retval; struct resource_record *rr; int offset; ! size_t len; rr = (struct resource_record *) xcalloc(1, sizeof(struct resource_record)); /* Get the name. */ ! rr->name = question_arr_to_char(data); ! offset = 1 + strlen(rr->name) + 1; /* Get the type. */ ! rr->type = ntohs(*(u16 *) &data[offset]); offset += 2; /* Get the class. */ ! rr->class = ntohs(*(u16 *) &data[offset]); offset += 2; /* Get the ttl. */ ! rr->ttl = ntohl(*(u32 *) &data[offset]); offset += 4; - /* Get the rdlength. */ - rr->rdlength = ntohs(*(u16 *) &data[offset]); - offset += 2; ! /* Get the rdata, whose size may be self-determined and may be determined by the type. */ rr->rdata = (byte_array *) xcalloc(1, sizeof(byte_array)); switch (rr->type) { case A: ! // rr->rdata->data = xcalloc(1, sizeof(u32)); ! // memmove(rr->rdata->data, (u32 *) &data[offset], sizeof(u32)); ! byte_array_catu32(rr->rdata, htonl(*(u32 *) &data[offset])); break; case NS: --- 160,207 ---- } ! struct resource_record * ! build_rr_from_data(const u8 *data, size_t *size, const u8 *base) { ! struct resource_record *retval; struct resource_record *rr; int offset; ! u16 len; ! int dsize; ! byte_array *tmp = NULL; rr = (struct resource_record *) xcalloc(1, sizeof(struct resource_record)); + offset = 0; + /* Get the name. */ ! /* XXX: We need to deal with name compression here. */ ! rr->name = question_arr_to_char(data, base, &dsize); ! offset += dsize; ! /* Get the type. */ ! rr->type = ntohs(*(const u16 *) &data[offset]); offset += 2; + /* Get the class. */ ! rr->class = ntohs(*(const u16 *) &data[offset]); offset += 2; + /* Get the ttl. */ ! rr->ttl = ntohl(*(const u32 *) &data[offset]); offset += 4; ! /* Calculate rr->rdlength after rdata's been built. */ ! ! /* Get the rdata, whose size may be self-determined or may be determined by the type. */ rr->rdata = (byte_array *) xcalloc(1, sizeof(byte_array)); + rr->rdata_uncompressed = (byte_array *) xcalloc(1, sizeof(byte_array)); switch (rr->type) { case A: ! len = ntohs(*(const u16 *) &data[offset]); ! assert(len == 4); /* XXX: This will cause failure on bogus input */ offset += 2; ! byte_array_catu32(rr->rdata, htonl(*(const u32 *) &data[offset])); ! /* No compression here. */ ! byte_array_cat(rr->rdata_uncompressed, rr->rdata); break; case NS: *************** *** 181,215 **** /* These cases are handled identically as far as marshalling and unmarshalling are concerned. */ ! len = *(u8 *) &data[offset]; ! byte_array_cats(rr->rdata, (u8 *) &data[offset], len + 1); break; case MX: ! byte_array_catu16(rr->rdata, *(u16 *) &data[offset]); offset += 2; ! len = *(u8 *) &data[offset]; ! byte_array_cats(rr->rdata, (u8 *) &data[offset], len + 1); break; case SOA: ! len = *(u8 *) &data[offset]; ! byte_array_cats(rr->rdata, (u8 *) &data[offset], len + 1); offset += len; ! len = *(u8 *) &data[offset]; ! byte_array_cats(rr->rdata, (u8 *) &data[offset], len); offset += len; ! byte_array_catu32(rr->rdata, *(u32 *) &data[offset]); offset += 4; ! byte_array_catu32(rr->rdata, *(u32 *) &data[offset]); offset += 4; ! byte_array_catu32(rr->rdata, *(u32 *) &data[offset]); offset += 4; ! byte_array_catu32(rr->rdata, *(u32 *) &data[offset]); offset += 4; ! byte_array_catu32(rr->rdata, *(u32 *) &data[offset]); offset += 4; break; --- 211,251 ---- /* These cases are handled identically as far as marshalling and unmarshalling are concerned. */ ! // len = *(u8 *) &data[offset]; ! len = ntohs(*(const u16 *) &data[offset]); ! // byte_array_catu16(rr->rdata, len); ! offset += 2; ! byte_array_cats(rr->rdata, (const u8 *) &data[offset], len); ! tmp = decompress2(&data[offset], base); ! byte_array_cat(rr->rdata_uncompressed, tmp); break; case MX: ! byte_array_catu16(rr->rdata, *(const u16 *) &data[offset]); offset += 2; ! len = *(const u8 *) &data[offset]; ! offset += 2; ! byte_array_cats(rr->rdata, (const u8 *) &data[offset], len + 1); break; case SOA: ! len = *(const u8 *) &data[offset]; ! byte_array_cats(rr->rdata, (const u8 *) &data[offset], len + 1); offset += len; ! len = *(const u8 *) &data[offset]; ! byte_array_cats(rr->rdata, (const u8 *) &data[offset], len); offset += len; ! byte_array_catu32(rr->rdata, *(const u32 *) &data[offset]); offset += 4; ! byte_array_catu32(rr->rdata, *(const u32 *) &data[offset]); offset += 4; ! byte_array_catu32(rr->rdata, *(const u32 *) &data[offset]); offset += 4; ! byte_array_catu32(rr->rdata, *(const u32 *) &data[offset]); offset += 4; ! byte_array_catu32(rr->rdata, *(const u32 *) &data[offset]); offset += 4; break; *************** *** 224,233 **** printf("It's of type %d\n", rr->type); rr->rdlength = rr->rdata->len; ! p->an[idx] = rr; ! ! retval = resource_record_size(p->an[idx]); return retval; } --- 260,273 ---- printf("It's of type %d\n", rr->type); + rr->rdlength = rr->rdata->len; ! retval = rr; + *size = offset + retval->rdlength; + + if (tmp != NULL) + byte_array_destroy(tmp); + return retval; } *************** *** 235,254 **** int ! packet_add_answer_from_data(packet *p, u8 *data, int idx) { ! return packet_add_rr_from_data(p, data, idx); } int ! packet_add_authoritive_from_data(packet *p, u8 *data, int idx) { ! return packet_add_rr_from_data(p, data, idx); } int ! packet_add_additional_from_data(packet *p, u8 *data, int idx) { ! return packet_add_rr_from_data(p, data, idx); } --- 275,309 ---- int ! packet_add_answer_from_data(packet *p, const u8 *data, int idx, const u8 *base) { ! int retval; ! struct resource_record *rr; ! rr = build_rr_from_data(data, &retval, base); ! p->an[idx] = rr; ! // return rr->rdlength; ! return retval; } int ! packet_add_authoritive_from_data(packet *p, const u8 *data, int idx, const u8 *base) { ! int retval; ! struct resource_record *rr; ! rr = build_rr_from_data(data, &retval, base); ! p->ns[idx] = rr; ! // return rr->rdlength; ! return retval; } int ! packet_add_additional_from_data(packet *p, const u8 *data, int idx, const u8 *base) { ! int retval; ! struct resource_record *rr; ! rr = build_rr_from_data(data, &retval, base); ! p->ar[idx] = rr; ! // return rr->rdlength; ! return retval; } *************** *** 315,319 **** strncpy(retval->name, rr->name, 256); retval->ttl = rr->ttl; ! switch (rr->type) { case A: --- 370,375 ---- strncpy(retval->name, rr->name, 256); retval->ttl = rr->ttl; ! retval->type = rr->type; ! switch (rr->type) { case A: *************** *** 321,325 **** break; case NS: ! rr_to_record_ns(retval, rr->rdata); break; case MX: --- 377,381 ---- break; case NS: ! rr_to_record_ns(retval, rr->rdata_uncompressed); break; case MX: *************** *** 363,367 **** rr_to_record_a(record *r, byte_array *rd) { ! r->record.a = *(u32 *) rd->data; } --- 419,423 ---- rr_to_record_a(record *r, byte_array *rd) { ! r->record.a = htonl(*(u32 *) rd->data); } *************** *** 384,388 **** { char *tmp; ! tmp = question_arr_to_char(rd->data); strncpy(r->record.ns, tmp, 256); xfree(tmp); --- 440,450 ---- { char *tmp; ! int size; ! tmp = question_arr_to_char_nd(rd->data, &size); ! if (size == 0) { ! ;/* XXX: Do something */ ! } else { ! ; ! } strncpy(r->record.ns, tmp, 256); xfree(tmp); *************** *** 407,412 **** { char *tmp; r->record.mx.preference = *(u16 *) rd->data; ! tmp = question_arr_to_char(rd->data + sizeof(u16)); strncpy(r->record.mx.exchange, tmp, 256); xfree(tmp); --- 469,480 ---- { char *tmp; + int did_compress; r->record.mx.preference = *(u16 *) rd->data; ! tmp = question_arr_to_char(rd->data + sizeof(u16), NULL, &did_compress); ! if (did_compress == 0) { ! ; /* XXX: do something */ ! } else { ! ; ! } strncpy(r->record.mx.exchange, tmp, 256); xfree(tmp); *************** *** 430,434 **** { char *tmp; ! tmp = question_arr_to_char(rd->data); strncpy(r->record.mx.exchange, tmp, 256); xfree(tmp); --- 498,508 ---- { char *tmp; ! int did_compress; ! tmp = question_arr_to_char(rd->data, NULL, &did_compress); ! if (did_compress == 0) { ! ; /* XXX: do something */ ! } else { ! ; ! } strncpy(r->record.mx.exchange, tmp, 256); xfree(tmp); *************** *** 541,545 **** assert(rr->rdlength == rr->rdata->len); ! retval += 1 + strlen(rr->name) + 1; retval += 2; /* type */ retval += 2; /* class */ --- 615,619 ---- assert(rr->rdlength == rr->rdata->len); ! retval += 1 + strlen(rr->name) + 1; /* first byte, chars + byte per dot, nul terminating byte */ retval += 2; /* type */ retval += 2; /* class */ |