From: Jelte Jansen Date: Wed, 15 Dec 2004 14:46:48 +0000 (+0000) Subject: added ldns_wire2dname and ldns_wire2rr (without rdata, but with lots of TODO :p) X-Git-Tag: release-0.50~673 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d85cc88a016c04f1ca9d77e45c2d5b58d051b357;p=thirdparty%2Fldns.git added ldns_wire2dname and ldns_wire2rr (without rdata, but with lots of TODO :p) put a bigger test packet in run-test0.c (response packet to drill www.kanariepiet.com) --- diff --git a/ldns/rr.h b/ldns/rr.h index a118065d..33c81341 100644 --- a/ldns/rr.h +++ b/ldns/rr.h @@ -194,4 +194,9 @@ size_t ldns_rr_descriptor_maximum(ldns_rr_descriptor_type *descriptor); ldns_rdata_field_type ldns_rr_descriptor_field_type( ldns_rr_descriptor_type *descriptor, size_t index); +size_t ldns_wire2dname(uint8_t *dname, const uint8_t *wire, size_t max, + size_t *pos); +size_t ldns_wire2rr(ldns_rr_type *rr, const uint8_t *wire, size_t max, + size_t *pos, int section); + #endif /* _LDNS_RR_H */ diff --git a/packet.c b/packet.c index 46ee2ba7..1c9bf1af 100644 --- a/packet.c +++ b/packet.c @@ -384,16 +384,33 @@ ldns_wire2packet_header(ldns_packet_type *packet, } } +/* TODO: error check, return status (of this and of wire2rrs) */ size_t ldns_wire2packet(ldns_packet_type *packet, const uint8_t *wire, size_t max) { size_t pos = 0; uint16_t i; + ldns_rr_type *rr; + size_t ret; pos += ldns_wire2packet_header(packet, wire, max, &pos); - /* TODO: rrs :) */ + /* TODO: section enum :) */ + for (i = 0; i < packet_qdcount(packet); i++) { + rr = ldns_rr_new(); + ret = ldns_wire2rr(rr, wire, max, &pos, 0); + } for (i = 0; i < packet_ancount(packet); i++) { + rr = ldns_rr_new(); + ret = ldns_wire2rr(rr, wire, max, &pos, 1); + } + for (i = 0; i < packet_nscount(packet); i++) { + rr = ldns_rr_new(); + ret = ldns_wire2rr(rr, wire, max, &pos, 2); + } + for (i = 0; i < packet_arcount(packet); i++) { + rr = ldns_rr_new(); + ret = ldns_wire2rr(rr, wire, max, &pos, 3); } return pos; diff --git a/rr.c b/rr.c index 8d515565..090ae7b9 100644 --- a/rr.c +++ b/rr.c @@ -355,3 +355,149 @@ ldns_rr_descriptor_field_type(ldns_rr_descriptor_type *descriptor, } } +/* TODO: is this a good way? */ +#define READ_INT16(wirebuf) (ntohs(*(uint16_t *) wirebuf)) +#define READ_INT32(wirebuf) (ntohl(*(uint32_t *) wirebuf)) + +/* TODO: general rdata2str or dname2str, with error + checks and return status etc */ +/* this is temp function for debugging wire2rr */ +/* do NOT pass compressed data here :p */ +void +ldns_dname2str(char *dest, uint8_t *dname) +{ + /* can we do with 1 pos var? or without at all? */ + uint8_t src_pos = 0; + uint8_t dest_pos = 0; + uint8_t len; + len = dname[src_pos]; + while (len > 0) { + src_pos++; + memcpy(&dest[dest_pos], &dname[src_pos], len); + dest_pos += len; + src_pos += len; + len = dname[src_pos]; + dest[dest_pos] = '.'; + dest_pos++; + } + dest_pos++; + dest[dest_pos] = '\0'; +} + +/* TODO: is there a better place for this function? + status_type return and remove printfs + #defines */ +size_t +ldns_wire2dname(uint8_t *dname, const uint8_t *wire, size_t max, size_t *pos) +{ + uint8_t label_size; + uint16_t pointer_target; + uint8_t *pointer_target_buf; + size_t dname_pos = 0; + size_t compression_pos = 0; + + if (*pos > max) { + /* TODO set error */ + return 0; + } + + label_size = wire[*pos]; + while (label_size > 0) { + /* compression */ + if (label_size >= 192) { + if (compression_pos == 0) { + compression_pos = *pos + 2; + } + + /* remove first two bits */ + /* TODO: can this be done in a better way? */ + pointer_target_buf = malloc(2); + pointer_target_buf[0] = wire[*pos] & 63; + pointer_target_buf[1] = wire[*pos+1]; + memcpy(&pointer_target, pointer_target_buf, 2); + pointer_target = ntohs(pointer_target); + + if (pointer_target == 0) { + fprintf(stderr, "POINTER TO 0\n"); + exit(0); + } else if (pointer_target > max) { + fprintf(stderr, "POINTER TO OUTSIDE PACKET\n"); + exit(0); + } + *pos = pointer_target; + label_size = wire[*pos]; + } + + if (label_size > MAXLABELLEN) { + /* TODO error: label size too large */ + fprintf(stderr, "LABEL SIZE ERROR: %d\n", + (int) label_size); + return 0; + } + if (*pos + label_size > max) { + /* TODO error: out of packet data */ + fprintf(stderr, "MAX PACKET ERROR: %d\n", + (int) (*pos + label_size)); + } + + dname[dname_pos] = label_size; + dname_pos++; + *pos = *pos + 1; + memcpy(&dname[dname_pos], &wire[*pos], label_size); + dname_pos += label_size; + *pos = *pos + label_size; + label_size = wire[*pos]; + } + + if (compression_pos > 0) { + *pos = compression_pos; + } else { + *pos = *pos + 1; + } + return *pos; +} + +/* TODO: ldns_status_type and error checking + defines for constants? + enum for sections? + remove owner print debug message + can *pos be incremented at READ_INT? or maybe use something like + RR_CLASS(wire)? +*/ +size_t +ldns_wire2rr(ldns_rr_type *rr, const uint8_t *wire, size_t max, + size_t *pos, int section) +{ + uint8_t *owner = malloc(MAXDOMAINLEN); + char *owner_str = malloc(MAXDOMAINLEN); + uint16_t rd_length; + + (void) ldns_wire2dname(owner, wire, max, pos); + + ldns_rr_set_owner(rr, owner); + + ldns_dname2str(owner_str, owner); + printf("owner: %s\n", owner_str); + FREE(owner_str); + + ldns_rr_set_class(rr, READ_INT16(&wire[*pos])); + *pos = *pos + 2; + /* + ldns_rr_set_type(rr, READ_INT16(&wire[*pos])); + */ + *pos = *pos + 2; + + if (section > 0) { + ldns_rr_set_ttl(rr, READ_INT32(&wire[*pos])); + *pos = *pos + 4; + rd_length = READ_INT16(&wire[*pos]); + *pos = *pos + 2; + /* TODO: wire2rdata */ + *pos = *pos + rd_length; + } + + return (size_t) 0; +} + + + diff --git a/run-test0.c b/run-test0.c index a78ab4ef..61d128b7 100644 --- a/run-test0.c +++ b/run-test0.c @@ -9,13 +9,28 @@ #include "util.h" -static const uint8_t wire[] = { +/* 0xc2, 0xb4, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x03, 0x77, 0x77, 0x77, 0x0b, 0x6b, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x70, 0x69, 0x65, 0x74, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01 }; +*/ +static const uint8_t wire[] = { + 0xd0, 0x0e, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x02, 0x03, 0x77, 0x77, 0x77, 0x0b, 0x6b, 0x61, 0x6e, 0x61, 0x72, + 0x69, 0x65, 0x70, 0x69, 0x65, 0x74, 0x03, 0x63, 0x6f, 0x6d, 0x00, + 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x01, 0x45, 0xf2, 0x00, 0x04, 0xd5, 0x85, 0x27, 0xcf, 0xc0, 0x10, + 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x45, 0xf2, 0x00, 0x11, 0x03, + 0x6e, 0x73, 0x32, 0x08, 0x68, 0x65, 0x78, 0x6f, 0x6e, 0x2d, 0x69, + 0x73, 0x02, 0x6e, 0x6c, 0x00, 0xc0, 0x10, 0x00, 0x02, 0x00, 0x01, + 0x00, 0x01, 0x45, 0xf2, 0x00, 0x06, 0x03, 0x6e, 0x73, 0x31, 0xc0, + 0x45, 0xc0, 0x5e, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xfb, 0x2e, + 0x00, 0x04, 0xd5, 0x85, 0x27, 0xcb, 0xc0, 0x41, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x00, 0xfb, 0x2c, 0x00, 0x04, 0xd4, 0xcc, 0xdb, 0x5b +}; int main(void)