#INSTALL = $(srcdir)/install-sh -c
#INSTALL_PROGRAM = $(INSTALL)
-LIBDNS_SOURCES = rdata.c util.c rr.c packet.c
+LIBDNS_SOURCES = rdata.c util.c rr.c packet.c wire2host.c
LIBDNS_HEADERS = ldns/error.h \
ldns/packet.h \
ldns/prototype.h \
ldns/rdata.h \
ldns/rr.h \
+ ldns/wire2host.h \
util.h \
buf.h
LIBDNS_OBJECTS = $(LIBDNS_SOURCES:.c=.o)
*/
#ifndef _ERROR_H
-#define _ERORR_H
+#define _ERROR_H
/* we do negative error codes? */
#define __X -1
enum ldns_enum_status
{
- LDNS_E_OK = 0,
- LDNS_E_EMPTY_LABEL = 1 * __X,
- LDNS_E_DDD_OVERFLOW = 2 * __X
+ LDNS_STATUS_OK = 0,
+ LDNS_STATUS_EMPTY_LABEL = 1 * __X,
+ LDNS_STATUS_LABEL_OVERFLOW = 2 * __X,
+ LDNS_STATUS_DOMAINNAME_OVERFLOW = 3 * __X,
+ LDNS_STATUS_DDD_OVERFLOW = 4 * __X,
+ LDNS_PACKET_OVERFLOW = 5 * __X
};
typedef enum ldns_enum_status ldns_status;
#include <ldns/rdata.h>
#include <ldns/rr.h>
#include <ldns/packet.h>
+#include <ldns/wire2host.h>
#endif /* _LDNS_H */
#ifndef _LDNS_PACKET_H
#define _LDNS_PACKET_H
+#include <ldns/error.h>
#include <ldns/common.h>
#include <ldns/rr.h>
*/
void ldns_pkt_free(ldns_pkt *packet);
-/**
- * Converts the data on the uint8_t bytearray (in wire format) to a DNS packet
- *
- * @param data pointer to the buffer with the data
- * @param len the length of the data buffer (in bytes)
- * @param packet pointer to the structure to hold the packet
- * @return the number of bytes read from the wire
- */
-size_t ldns_wire2pkt(ldns_pkt *packet, const uint8_t *data, size_t len);
-
#endif /* !_LDNS_PACKET_H */
#include <ldns/common.h>
#include <ldns/rdata.h>
#include <ldns/rr.h>
+#include <ldns/error.h>
/**
* The different RR classes.
size_t ldns_rr_descriptor_maximum(ldns_rr_descriptor *descriptor);
ldns_rdf_type ldns_rr_descriptor_field_type(ldns_rr_descriptor *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 *rr, const uint8_t *wire, size_t max,
- size_t *pos, int section);
-
#endif /* _LDNS_RR_H */
#include <config.h>
#include <ldns/packet.h>
-
#include "util.h"
-/*
- * Set of macro's to deal with the dns message header as specified
- * in RFC1035 in portable way.
- *
- */
-
-/*
- *
- * 1 1 1 1 1 1
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | ID |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * |QR| Opcode |AA|TC|RD|RA| Z|AD|CD| RCODE |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | QDCOUNT |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | ANCOUNT |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | NSCOUNT |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | ARCOUNT |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- *
- */
-
-/* The length of the header */
-#define QHEADERSZ 12
-
-/* First octet of flags */
-#define RD_MASK 0x01U
-#define RD_SHIFT 0
-#define RD(wirebuf) (*(wirebuf+2) & RD_MASK)
-#define RD_SET(wirebuf) (*(wirebuf+2) |= RD_MASK)
-#define RD_CLR(wirebuf) (*(wirebuf+2) &= ~RD_MASK)
-
-#define TC_MASK 0x02U
-#define TC_SHIFT 1
-#define TC(wirebuf) (*(wirebuf+2) & TC_MASK)
-#define TC_SET(wirebuf) (*(wirebuf+2) |= TC_MASK)
-#define TC_CLR(wirebuf) (*(wirebuf+2) &= ~TC_MASK)
-
-#define AA_MASK 0x04U
-#define AA_SHIFT 2
-#define AA(wirebuf) (*(wirebuf+2) & AA_MASK)
-#define AA_SET(wirebuf) (*(wirebuf+2) |= AA_MASK)
-#define AA_CLR(wirebuf) (*(wirebuf+2) &= ~AA_MASK)
-
-#define OPCODE_MASK 0x78U
-#define OPCODE_SHIFT 3
-#define OPCODE(wirebuf) ((*(wirebuf+2) & OPCODE_MASK) >> OPCODE_SHIFT)
-#define OPCODE_SET(wirebuf, opcode) \
- (*(wirebuf+2) = ((*(wirebuf+2)) & ~OPCODE_MASK) | ((opcode) << OPCODE_SHIFT))
-
-#define QR_MASK 0x80U
-#define QR_SHIFT 7
-#define QR(wirebuf) (*(wirebuf+2) & QR_MASK)
-#define QR_SET(wirebuf) (*(wirebuf+2) |= QR_MASK)
-#define QR_CLR(wirebuf) (*(wirebuf+2) &= ~QR_MASK)
-
-/* Second octet of flags */
-#define RCODE_MASK 0x0fU
-#define RCODE_SHIFT 0
-#define RCODE(wirebuf) (*(wirebuf+3) & RCODE_MASK)
-#define RCODE_SET(wirebuf, rcode) \
- (*(wirebuf+3) = ((*(wirebuf+3)) & ~RCODE_MASK) | (rcode))
-
-#define CD_MASK 0x10U
-#define CD_SHIFT 4
-#define CD(wirebuf) (*(wirebuf+3) & CD_MASK)
-#define CD_SET(wirebuf) (*(wirebuf+3) |= CD_MASK)
-#define CD_CLR(wirebuf) (*(wirebuf+3) &= ~CD_MASK)
-
-#define AD_MASK 0x20U
-#define AD_SHIFT 5
-#define AD(wirebuf) (*(wirebuf+3) & AD_MASK)
-#define AD_SET(wirebuf) (*(wirebuf+3) |= AD_MASK)
-#define AD_CLR(wirebuf) (*(wirebuf+3) &= ~AD_MASK)
-
-#define Z_MASK 0x40U
-#define Z_SHIFT 6
-#define Z(wirebuf) (*(wirebuf+3) & Z_MASK)
-#define Z_SET(wirebuf) (*(wirebuf+3) |= Z_MASK)
-#define Z_CLR(wirebuf) (*(wirebuf+3) &= ~Z_MASK)
-
-#define RA_MASK 0x80U
-#define RA_SHIFT 7
-#define RA(wirebuf) (*(wirebuf+3) & RA_MASK)
-#define RA_SET(wirebuf) (*(wirebuf+3) |= RA_MASK)
-#define RA_CLR(wirebuf) (*(wirebuf+3) &= ~RA_MASK)
-
-/* Query ID */
-#define ID(wirebuf) (ntohs(*(uint16_t *)(wirebuf)))
-
-/* Counter of the question section */
-#define QDCOUNT_OFF 4
-/*
-#define QDCOUNT(wirebuf) (ntohs(*(uint16_t *)(wirebuf+QDCOUNT_OFF)))
-*/
-#define QDCOUNT(wirebuf) (read_uint16(wirebuf+QDCOUNT_OFF))
-
-/* Counter of the answer section */
-#define ANCOUNT_OFF 6
-#define ANCOUNT(wirebuf) (read_uint16(wirebuf+ANCOUNT_OFF))
-
-/* Counter of the authority section */
-#define NSCOUNT_OFF 8
-#define NSCOUNT(wirebuf) (read_uint16(wirebuf+NSCOUNT_OFF))
-
-/* Counter of the additional section */
-#define ARCOUNT_OFF 10
-#define ARCOUNT(wirebuf) (read_uint16(wirebuf+ARCOUNT_OFF))
-
/* Access functions
* do this as functions to get type checking
*/
FREE(packet);
}
-static size_t
-ldns_wire2pkt_hdr(ldns_pkt *packet,
- const uint8_t *wire,
- size_t max,
- size_t *pos)
-{
- if (*pos + QHEADERSZ >= max) {
- /* TODO: set t_status error. */
- return 0;
- } else {
-
- pkt_set_id(packet, ID(wire));
-
- pkt_set_qr(packet, QR(wire));
- pkt_set_opcode(packet, OPCODE(wire));
- pkt_set_aa(packet, AA(wire));
- pkt_set_tc(packet, TC(wire));
- pkt_set_rd(packet, RD(wire));
- pkt_set_ra(packet, RA(wire));
- pkt_set_ad(packet, AD(wire));
- pkt_set_cd(packet, CD(wire));
- pkt_set_rcode(packet, RCODE(wire));
-
- pkt_set_qdcount(packet, QDCOUNT(wire));
- pkt_set_ancount(packet, ANCOUNT(wire));
- pkt_set_nscount(packet, NSCOUNT(wire));
- pkt_set_arcount(packet, ARCOUNT(wire));
-
- *pos += QHEADERSZ;
- /* TODO t_status succ. */
- return 0;
- }
-}
-
-/* TODO: error check, return status (of this and of wire2rrs) */
-size_t
-ldns_wire2pkt(ldns_pkt *packet, const uint8_t *wire, size_t max)
-{
- size_t pos = 0;
- uint16_t i;
- ldns_rr *rr;
- size_t ret;
-
- pos += ldns_wire2pkt_hdr(packet, wire, max, &pos);
-
- /* TODO: section enum :) */
- for (i = 0; i < pkt_qdcount(packet); i++) {
- rr = ldns_rr_new();
- ret = ldns_wire2rr(rr, wire, max, &pos, 0);
- }
- for (i = 0; i < pkt_ancount(packet); i++) {
- rr = ldns_rr_new();
- ret = ldns_wire2rr(rr, wire, max, &pos, 1);
- }
- for (i = 0; i < pkt_nscount(packet); i++) {
- rr = ldns_rr_new();
- ret = ldns_wire2rr(rr, wire, max, &pos, 2);
- }
- for (i = 0; i < pkt_arcount(packet); i++) {
- rr = ldns_rr_new();
- ret = ldns_wire2rr(rr, wire, max, &pos, 3);
- }
-
- return pos;
-}
case '.':
if (s[1] == '.') {
fprintf(stderr,"Empty label");
- return LDNS_E_EMPTY_LABEL;
+ return LDNS_STATUS_EMPTY_LABEL;
}
*p = *s;
*length++;
*p = val;
*length++;
} else {
- return LDNS_E_DDD_OVERFLOW;
+ return LDNS_STATUS_DDD_OVERFLOW;
}
} else {
/* an espaced character, like \<space> ?
if ( *s == '\0' ) {
/* ok, it was the last one */
*p = '\0';
- return LDNS_E_OK;
+ return LDNS_STATUS_OK;
}
break;
default:
}
}
*p = '\0';
- return LDNS_E_OK;
+ return LDNS_STATUS_OK;
}
}
}
-/* 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");
- return 0;
- } else if (pointer_target > max) {
- fprintf(stderr, "POINTER TO OUTSIDE PACKET\n");
- return 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 *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_uint16(&wire[*pos]));
- *pos = *pos + 2;
- /*
- ldns_rr_set_type(rr, read_uint16(&wire[*pos]));
- */
- *pos = *pos + 2;
-
- if (section > 0) {
- ldns_rr_set_ttl(rr, read_uint32(&wire[*pos]));
- *pos = *pos + 4;
- rd_length = read_uint16(&wire[*pos]);
- *pos = *pos + 2;
- /* TODO: wire2rdata */
- *pos = *pos + rd_length;
- }
-
- return (size_t) 0;
-}
-
-
-
#include <config.h>
+
#include <ldns/ldns.h>
#include "util.h"
*
* See the file LICENSE for the license
*/
+#include <config.h>
+
+#include <limits.h>
+
+#include <ldns/wire2host.h>
+
+#include "util.h"
+
+
+/*
+ * Set of macro's to deal with the dns message header as specified
+ * in RFC1035 in portable way.
+ *
+ */
+
+/*
+ *
+ * 1 1 1 1 1 1
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ * | ID |
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ * |QR| Opcode |AA|TC|RD|RA| Z|AD|CD| RCODE |
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ * | QDCOUNT |
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ * | ANCOUNT |
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ * | NSCOUNT |
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ * | ARCOUNT |
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *
+ */
+
+/* The length of the header */
+#define QHEADERSZ 12
+
+/* First octet of flags */
+#define RD_MASK 0x01U
+#define RD_SHIFT 0
+#define RD(wirebuf) (*(wirebuf+2) & RD_MASK)
+#define RD_SET(wirebuf) (*(wirebuf+2) |= RD_MASK)
+#define RD_CLR(wirebuf) (*(wirebuf+2) &= ~RD_MASK)
+
+#define TC_MASK 0x02U
+#define TC_SHIFT 1
+#define TC(wirebuf) (*(wirebuf+2) & TC_MASK)
+#define TC_SET(wirebuf) (*(wirebuf+2) |= TC_MASK)
+#define TC_CLR(wirebuf) (*(wirebuf+2) &= ~TC_MASK)
+
+#define AA_MASK 0x04U
+#define AA_SHIFT 2
+#define AA(wirebuf) (*(wirebuf+2) & AA_MASK)
+#define AA_SET(wirebuf) (*(wirebuf+2) |= AA_MASK)
+#define AA_CLR(wirebuf) (*(wirebuf+2) &= ~AA_MASK)
+
+#define OPCODE_MASK 0x78U
+#define OPCODE_SHIFT 3
+#define OPCODE(wirebuf) ((*(wirebuf+2) & OPCODE_MASK) >> OPCODE_SHIFT)
+#define OPCODE_SET(wirebuf, opcode) \
+ (*(wirebuf+2) = ((*(wirebuf+2)) & ~OPCODE_MASK) | ((opcode) << OPCODE_SHIFT))
+
+#define QR_MASK 0x80U
+#define QR_SHIFT 7
+#define QR(wirebuf) (*(wirebuf+2) & QR_MASK)
+#define QR_SET(wirebuf) (*(wirebuf+2) |= QR_MASK)
+#define QR_CLR(wirebuf) (*(wirebuf+2) &= ~QR_MASK)
+
+/* Second octet of flags */
+#define RCODE_MASK 0x0fU
+#define RCODE_SHIFT 0
+#define RCODE(wirebuf) (*(wirebuf+3) & RCODE_MASK)
+#define RCODE_SET(wirebuf, rcode) \
+ (*(wirebuf+3) = ((*(wirebuf+3)) & ~RCODE_MASK) | (rcode))
+
+#define CD_MASK 0x10U
+#define CD_SHIFT 4
+#define CD(wirebuf) (*(wirebuf+3) & CD_MASK)
+#define CD_SET(wirebuf) (*(wirebuf+3) |= CD_MASK)
+#define CD_CLR(wirebuf) (*(wirebuf+3) &= ~CD_MASK)
+
+#define AD_MASK 0x20U
+#define AD_SHIFT 5
+#define AD(wirebuf) (*(wirebuf+3) & AD_MASK)
+#define AD_SET(wirebuf) (*(wirebuf+3) |= AD_MASK)
+#define AD_CLR(wirebuf) (*(wirebuf+3) &= ~AD_MASK)
+
+#define Z_MASK 0x40U
+#define Z_SHIFT 6
+#define Z(wirebuf) (*(wirebuf+3) & Z_MASK)
+#define Z_SET(wirebuf) (*(wirebuf+3) |= Z_MASK)
+#define Z_CLR(wirebuf) (*(wirebuf+3) &= ~Z_MASK)
+
+#define RA_MASK 0x80U
+#define RA_SHIFT 7
+#define RA(wirebuf) (*(wirebuf+3) & RA_MASK)
+#define RA_SET(wirebuf) (*(wirebuf+3) |= RA_MASK)
+#define RA_CLR(wirebuf) (*(wirebuf+3) &= ~RA_MASK)
+
+/* Query ID */
+#define ID(wirebuf) (ntohs(*(uint16_t *)(wirebuf)))
+
+/* Counter of the question section */
+#define QDCOUNT_OFF 4
+/*
+#define QDCOUNT(wirebuf) (ntohs(*(uint16_t *)(wirebuf+QDCOUNT_OFF)))
+*/
+#define QDCOUNT(wirebuf) (read_uint16(wirebuf+QDCOUNT_OFF))
+
+/* Counter of the answer section */
+#define ANCOUNT_OFF 6
+#define ANCOUNT(wirebuf) (read_uint16(wirebuf+ANCOUNT_OFF))
+
+/* Counter of the authority section */
+#define NSCOUNT_OFF 8
+#define NSCOUNT(wirebuf) (read_uint16(wirebuf+NSCOUNT_OFF))
+
+/* Counter of the additional section */
+#define ARCOUNT_OFF 10
+#define ARCOUNT(wirebuf) (read_uint16(wirebuf+ARCOUNT_OFF))
+
/**
* transform a wireformatted rdata to our
* internal representation. We need to the
* length, and the type and put the data in
*/
+/*
ssize_t
-rdata_buf_to_rdf(ldns_rdf *rd, ldns_buf *buffer)
+rdata_buf_to_rdf(ldns_rdf *rd, ldns_rdf *buffer)
{
- /* TODO TODO */
switch(RDATA_TYPESS) {
case RDF_TYPE_NONE:
break;
case RDF_TYPE_DNAME:
- /* can be compressed or not */
break;
case RDF_TYPE_INT8:
break;
}
}
+*/
+
+/* 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, ldns_rdf *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->_data[src_pos];
+ while (len > 0) {
+ src_pos++;
+ memcpy(&dest[dest_pos], &(dname->_data[src_pos]), len);
+ dest_pos += len;
+ src_pos += len;
+ len = dname->_data[src_pos];
+ dest[dest_pos] = '.';
+ dest_pos++;
+ }
+ dest[dest_pos] = '\0';
+}
+
+/* TODO: is there a better place for this function?
+ status_type return and remove printfs
+ #defines */
+/* allocates memory to *dname! */
+ldns_status
+ldns_wire2dname(ldns_rdf **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 uncompressed_length = 0;
+ size_t compression_pos = 0;
+ uint8_t *tmp_dname = XMALLOC(uint8_t, MAXDOMAINLEN);
+
+ 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");
+ return 0;
+ } else if (pointer_target > max) {
+ fprintf(stderr, "POINTER TO OUTSIDE PACKET\n");
+ return 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));
+ }
+
+ tmp_dname[dname_pos] = label_size;
+ dname_pos++;
+ *pos = *pos + 1;
+ memcpy(&tmp_dname[dname_pos], &wire[*pos], label_size);
+ uncompressed_length += label_size + 1;
+ dname_pos += label_size;
+ *pos = *pos + label_size;
+ label_size = wire[*pos];
+ }
+
+ if (compression_pos > 0) {
+ *pos = compression_pos;
+ } else {
+ *pos = *pos + 1;
+ }
+
+ tmp_dname[dname_pos] = 0;
+
+ *dname = MALLOC(ldns_rdf);
+ (*dname)->_type = LDNS_RDF_TYPE_DNAME;
+ (*dname)->_size = (uint16_t) dname_pos;
+ (*dname)->_data = XMALLOC(uint8_t, dname_pos);
+ memcpy((*dname)->_data, tmp_dname, dname_pos);
+ FREE(tmp_dname);
+
+ return LDNS_STATUS_OK;
+}
+
+/* maybe make this a goto error so data can be freed or something/ */
+#define STATUS_CHECK_RETURN(st) {if (st != LDNS_STATUS_OK) { return st; }}
+
+/* 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)?
+*/
+ldns_status
+ldns_wire2rr(ldns_rr *rr, const uint8_t *wire, size_t max,
+ size_t *pos, int section)
+{
+ ldns_rdf *owner;
+ char *owner_str = malloc(MAXDOMAINLEN);
+ uint16_t rd_length;
+ ldns_status status = LDNS_STATUS_OK;
+
+ status = 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_uint16(&wire[*pos]));
+ *pos = *pos + 2;
+ /*
+ ldns_rr_set_type(rr, read_uint16(&wire[*pos]));
+ */
+ *pos = *pos + 2;
+
+ if (section > 0) {
+ ldns_rr_set_ttl(rr, read_uint32(&wire[*pos]));
+ *pos = *pos + 4;
+ rd_length = read_uint16(&wire[*pos]);
+ *pos = *pos + 2;
+ /* TODO: wire2rdata */
+ *pos = *pos + rd_length;
+ }
+
+ return (size_t) 0;
+}
+
+static ldns_status
+ldns_wire2pkt_hdr(ldns_pkt *packet,
+ const uint8_t *wire,
+ size_t max,
+ size_t *pos)
+{
+ if (*pos + QHEADERSZ >= max) {
+ /* TODO: set t_status error. */
+ return LDNS_PACKET_OVERFLOW;
+ } else {
+
+ pkt_set_id(packet, ID(wire));
+
+ pkt_set_qr(packet, QR(wire));
+ pkt_set_opcode(packet, OPCODE(wire));
+ pkt_set_aa(packet, AA(wire));
+ pkt_set_tc(packet, TC(wire));
+ pkt_set_rd(packet, RD(wire));
+ pkt_set_ra(packet, RA(wire));
+ pkt_set_ad(packet, AD(wire));
+ pkt_set_cd(packet, CD(wire));
+ pkt_set_rcode(packet, RCODE(wire));
+
+ pkt_set_qdcount(packet, QDCOUNT(wire));
+ pkt_set_ancount(packet, ANCOUNT(wire));
+ pkt_set_nscount(packet, NSCOUNT(wire));
+ pkt_set_arcount(packet, ARCOUNT(wire));
+
+ *pos += QHEADERSZ;
+ /* TODO t_status succ. */
+ return LDNS_STATUS_OK;
+ }
+}
+
+/* TODO: error check, return status (of this and of wire2rrs) */
+ldns_status
+ldns_wire2pkt(ldns_pkt *packet, const uint8_t *wire, size_t max)
+{
+ size_t pos = 0;
+ uint16_t i;
+ ldns_rr *rr;
+ ldns_status status = LDNS_STATUS_OK;
+
+ status = ldns_wire2pkt_hdr(packet, wire, max, &pos);
+ STATUS_CHECK_RETURN(status);
+
+ /* TODO: section enum :) */
+ for (i = 0; i < pkt_qdcount(packet); i++) {
+ rr = ldns_rr_new();
+ status = ldns_wire2rr(rr, wire, max, &pos, 0);
+ STATUS_CHECK_RETURN(status);
+ }
+ for (i = 0; i < pkt_ancount(packet); i++) {
+ rr = ldns_rr_new();
+ status = ldns_wire2rr(rr, wire, max, &pos, 1);
+
+ STATUS_CHECK_RETURN(status);
+ }
+ for (i = 0; i < pkt_nscount(packet); i++) {
+ rr = ldns_rr_new();
+ status = ldns_wire2rr(rr, wire, max, &pos, 2);
+ STATUS_CHECK_RETURN(status);
+ }
+ for (i = 0; i < pkt_arcount(packet); i++) {
+ rr = ldns_rr_new();
+ status = ldns_wire2rr(rr, wire, max, &pos, 3);
+ STATUS_CHECK_RETURN(status);
+ }
+
+ return status;
+}