put a bigger test packet in run-test0.c (response packet to drill www.kanariepiet.com)
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 */
}
}
+/* 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;
}
}
+/* 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;
+}
+
+
+
#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)