]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
wire2dname now allocates data itself
authorJelte Jansen <jeltejan@NLnetLabs.nl>
Thu, 16 Dec 2004 13:59:42 +0000 (13:59 +0000)
committerJelte Jansen <jeltejan@NLnetLabs.nl>
Thu, 16 Dec 2004 13:59:42 +0000 (13:59 +0000)
wire2dname now puts dname in ldns_rdf
made start with status returns in wire2 functions
moved wire2packet, wire2rr and wire2dname to wire2host.c
added wire2host to makefile

Makefile.in
ldns/error.h
ldns/ldns.h
ldns/packet.h
ldns/rr.h
packet.c
rdata.c
rr.c
run-test0.c
wire2host.c

index b423a95718eb32d7a2e22ce11a39f97e86233306..5126af0b6b35e7ea030d588ad6ffdb9bda8b2261 100644 (file)
@@ -19,12 +19,13 @@ LINTFLAGS   = +quiet +posixlib -weak -warnposix -unrecog
 #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)
index aecc0b0c428c2800e32cac0d577422fb716cf705..2738c74a73c958fe53cd885760b97d6776d8b518 100644 (file)
  */
 
 #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;
index 7c92256da15376f66bf3665c6de5b98f9f2a785b..78af9bc4442bf1b2e3e0bffb079b7b28daa59599 100644 (file)
@@ -18,5 +18,6 @@
 #include <ldns/rdata.h>
 #include <ldns/rr.h>
 #include <ldns/packet.h>
+#include <ldns/wire2host.h>
 
 #endif /* _LDNS_H */
index dede8389165eaf3a0be69fd5b643a38cd7ef283e..03d1a1cb7292d2cde5ab2fbb171a22a3bb821795 100644 (file)
@@ -13,6 +13,7 @@
 #ifndef _LDNS_PACKET_H
 #define _LDNS_PACKET_H
 
+#include <ldns/error.h>
 #include <ldns/common.h>
 #include <ldns/rr.h>
 
@@ -119,14 +120,4 @@ ldns_pkt *ldns_pkt_new();
  */
 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 */
index ba404f4d45b138e4fb7b11fd1026a182faa9a2e0..91e6026b0d39cbd3d6ca13150497f0d10c834fda 100644 (file)
--- a/ldns/rr.h
+++ b/ldns/rr.h
@@ -17,6 +17,7 @@
 #include <ldns/common.h>
 #include <ldns/rdata.h>
 #include <ldns/rr.h>
+#include <ldns/error.h>
 
 /**
  * The different RR classes.
@@ -213,9 +214,4 @@ size_t ldns_rr_descriptor_minimum(ldns_rr_descriptor *descriptor);
 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 */
index 7b671e76b0bb31d600c7db71eeefaff1c6abb2ae..c30cd6f062e8aea1b3c90eb8c706aa1680d03bc1 100644 (file)
--- a/packet.c
+++ b/packet.c
 #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
  */
@@ -353,68 +239,3 @@ ldns_pkt_free(ldns_pkt *packet)
        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;
-}
diff --git a/rdata.c b/rdata.c
index f93d73dcc6e23459347b4f3806818638c9312fcd..831ade11b48f632d0f1cef45a99d7cc0777ce505 100644 (file)
--- a/rdata.c
+++ b/rdata.c
@@ -114,7 +114,7 @@ _ldns_octet(char *word, size_t *length)
             case '.':
                 if (s[1] == '.') {
                     fprintf(stderr,"Empty label");
-                   return LDNS_E_EMPTY_LABEL;
+                   return LDNS_STATUS_EMPTY_LABEL;
                 }
                 *p = *s;
                 *length++;
@@ -134,7 +134,7 @@ _ldns_octet(char *word, size_t *length)
                         *p = val;
                         *length++;
                     } else {
-                        return LDNS_E_DDD_OVERFLOW;
+                        return LDNS_STATUS_DDD_OVERFLOW;
                     }
                 } else {
                     /* an espaced character, like \<space> ? 
@@ -153,7 +153,7 @@ _ldns_octet(char *word, size_t *length)
                 if ( *s == '\0' ) {
                     /* ok, it was the last one */
                     *p  = '\0'; 
-                   return LDNS_E_OK;
+                   return LDNS_STATUS_OK;
                 }
                 break;
             default:
@@ -163,5 +163,5 @@ _ldns_octet(char *word, size_t *length)
         }
     }
     *p = '\0';
-    return LDNS_E_OK;
+    return LDNS_STATUS_OK;
 }
diff --git a/rr.c b/rr.c
index d895803c1d042163d1c38ec4e4c78757f034d03d..11a07bdcba144cdb565d4e55ad865e0f00a88ed4 100644 (file)
--- a/rr.c
+++ b/rr.c
@@ -355,145 +355,3 @@ ldns_rr_descriptor_field_type(ldns_rr_descriptor *descriptor,
        }
 }
 
-/* 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;
-}
-
-
-
index aab26265814f36e071e1131a016f3530d8daa151..e3fac25dfd9ffea440d2f572549e3e68c032358e 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <config.h>
 
+
 #include <ldns/ldns.h>
 
 #include "util.h"
index c89a63f404e24beac99e3aa789c259a793d3762e..e57b6ff1886499f997df9d90618fd82844b797d5 100644 (file)
  *
  * 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;
@@ -69,4 +190,234 @@ rdata_buf_to_rdf(ldns_rdf *rd, ldns_buf *buffer)
        }       
 
 }
+*/
+
+/* 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;
+}