1 /* 2 * wire2host.h - from wire conversion routines 3 * 4 * a Net::DNS like library for C 5 * 6 * (c) NLnet Labs, 2005-2006 7 * 8 * See the file LICENSE for the license 9 */ 10 11 /** 12 * \file 13 * 14 * Contains functions that translate dns data from the wire format (as sent 15 * by servers and clients) to the internal structures. 16 */ 17 18 #ifndef LDNS_WIRE2HOST_H 19 #define LDNS_WIRE2HOST_H 20 21 #include <ldns/rdata.h> 22 #include <ldns/common.h> 23 #include <ldns/error.h> 24 #include <ldns/rr.h> 25 #include <ldns/packet.h> 26 27 /* The length of the header */ 28 #define LDNS_HEADER_SIZE 12 29 30 /* First octet of flags */ 31 #define LDNS_RD_MASK 0x01U 32 #define LDNS_RD_SHIFT 0 33 #define LDNS_RD_WIRE(wirebuf) (*(wirebuf+2) & LDNS_RD_MASK) 34 #define LDNS_RD_SET(wirebuf) (*(wirebuf+2) |= LDNS_RD_MASK) 35 #define LDNS_RD_CLR(wirebuf) (*(wirebuf+2) &= ~LDNS_RD_MASK) 36 37 #define LDNS_TC_MASK 0x02U 38 #define LDNS_TC_SHIFT 1 39 #define LDNS_TC_WIRE(wirebuf) (*(wirebuf+2) & LDNS_TC_MASK) 40 #define LDNS_TC_SET(wirebuf) (*(wirebuf+2) |= LDNS_TC_MASK) 41 #define LDNS_TC_CLR(wirebuf) (*(wirebuf+2) &= ~LDNS_TC_MASK) 42 43 #define LDNS_AA_MASK 0x04U 44 #define LDNS_AA_SHIFT 2 45 #define LDNS_AA_WIRE(wirebuf) (*(wirebuf+2) & LDNS_AA_MASK) 46 #define LDNS_AA_SET(wirebuf) (*(wirebuf+2) |= LDNS_AA_MASK) 47 #define LDNS_AA_CLR(wirebuf) (*(wirebuf+2) &= ~LDNS_AA_MASK) 48 49 #define LDNS_OPCODE_MASK 0x78U 50 #define LDNS_OPCODE_SHIFT 3 51 #define LDNS_OPCODE_WIRE(wirebuf) ((*(wirebuf+2) & LDNS_OPCODE_MASK) >> LDNS_OPCODE_SHIFT) 52 #define LDNS_OPCODE_SET(wirebuf, opcode) \ 53 (*(wirebuf+2) = ((*(wirebuf+2)) & ~LDNS_OPCODE_MASK) | ((opcode) << LDNS_OPCODE_SHIFT)) 54 55 #define LDNS_QR_MASK 0x80U 56 #define LDNS_QR_SHIFT 7 57 #define LDNS_QR_WIRE(wirebuf) (*(wirebuf+2) & LDNS_QR_MASK) 58 #define LDNS_QR_SET(wirebuf) (*(wirebuf+2) |= LDNS_QR_MASK) 59 #define LDNS_QR_CLR(wirebuf) (*(wirebuf+2) &= ~LDNS_QR_MASK) 60 61 /* Second octet of flags */ 62 #define LDNS_RCODE_MASK 0x0fU 63 #define LDNS_RCODE_SHIFT 0 64 #define LDNS_RCODE_WIRE(wirebuf) (*(wirebuf+3) & LDNS_RCODE_MASK) 65 #define LDNS_RCODE_SET(wirebuf, rcode) \ 66 (*(wirebuf+3) = ((*(wirebuf+3)) & ~LDNS_RCODE_MASK) | (rcode)) 67 68 #define LDNS_CD_MASK 0x10U 69 #define LDNS_CD_SHIFT 4 70 #define LDNS_CD_WIRE(wirebuf) (*(wirebuf+3) & LDNS_CD_MASK) 71 #define LDNS_CD_SET(wirebuf) (*(wirebuf+3) |= LDNS_CD_MASK) 72 #define LDNS_CD_CLR(wirebuf) (*(wirebuf+3) &= ~LDNS_CD_MASK) 73 74 #define LDNS_AD_MASK 0x20U 75 #define LDNS_AD_SHIFT 5 76 #define LDNS_AD_WIRE(wirebuf) (*(wirebuf+3) & LDNS_AD_MASK) 77 #define LDNS_AD_SET(wirebuf) (*(wirebuf+3) |= LDNS_AD_MASK) 78 #define LDNS_AD_CLR(wirebuf) (*(wirebuf+3) &= ~LDNS_AD_MASK) 79 80 #define LDNS_Z_MASK 0x40U 81 #define LDNS_Z_SHIFT 6 82 #define LDNS_Z_WIRE(wirebuf) (*(wirebuf+3) & LDNS_Z_MASK) 83 #define LDNS_Z_SET(wirebuf) (*(wirebuf+3) |= LDNS_Z_MASK) 84 #define LDNS_Z_CLR(wirebuf) (*(wirebuf+3) &= ~LDNS_Z_MASK) 85 86 #define LDNS_RA_MASK 0x80U 87 #define LDNS_RA_SHIFT 7 88 #define LDNS_RA_WIRE(wirebuf) (*(wirebuf+3) & LDNS_RA_MASK) 89 #define LDNS_RA_SET(wirebuf) (*(wirebuf+3) |= LDNS_RA_MASK) 90 #define LDNS_RA_CLR(wirebuf) (*(wirebuf+3) &= ~LDNS_RA_MASK) 91 92 /* Query ID */ 93 #define LDNS_ID_WIRE(wirebuf) (ldns_read_uint16(wirebuf)) 94 #define LDNS_ID_SET(wirebuf, id) (ldns_write_uint16(wirebuf, id)) 95 96 /* Counter of the question section */ 97 #define LDNS_QDCOUNT_OFF 4 98 /* 99 #define QDCOUNT(wirebuf) (ntohs(*(uint16_t *)(wirebuf+QDCOUNT_OFF))) 100 */ 101 #define LDNS_QDCOUNT(wirebuf) (ldns_read_uint16(wirebuf+LDNS_QDCOUNT_OFF)) 102 103 /* Counter of the answer section */ 104 #define LDNS_ANCOUNT_OFF 6 105 #define LDNS_ANCOUNT(wirebuf) (ldns_read_uint16(wirebuf+LDNS_ANCOUNT_OFF)) 106 107 /* Counter of the authority section */ 108 #define LDNS_NSCOUNT_OFF 8 109 #define LDNS_NSCOUNT(wirebuf) (ldns_read_uint16(wirebuf+LDNS_NSCOUNT_OFF)) 110 111 /* Counter of the additional section */ 112 #define LDNS_ARCOUNT_OFF 10 113 #define LDNS_ARCOUNT(wirebuf) (ldns_read_uint16(wirebuf+LDNS_ARCOUNT_OFF)) 114 115 /** 116 * converts the data on the uint8_t bytearray (in wire format) to a DNS packet. 117 * This function will initialize and allocate memory space for the packet 118 * structure. 119 * 120 * \param[in] packet pointer to the structure to hold the packet 121 * \param[in] data pointer to the buffer with the data 122 * \param[in] len the length of the data buffer (in bytes) 123 * \return LDNS_STATUS_OK if everything succeeds, error otherwise 124 */ 125 ldns_status ldns_wire2pkt(ldns_pkt **packet, const uint8_t *data, size_t len); 126 127 /** 128 * converts the data on the uint8_t bytearray (in wire format) to a DNS packet. 129 * This function will initialize and allocate memory space for the packet 130 * structure. 131 * 132 * \param[in] packet pointer to the structure to hold the packet 133 * \param[in] buffer the buffer with the data 134 * \return LDNS_STATUS_OK if everything succeeds, error otherwise 135 */ 136 ldns_status ldns_buffer2pkt_wire(ldns_pkt **packet, ldns_buffer *buffer); 137 138 /** 139 * converts the data on the uint8_t bytearray (in wire format) to a DNS 140 * dname rdata field. This function will initialize and allocate memory 141 * space for the dname structure. The length of the wiredata of this rdf 142 * is added to the *pos value. 143 * 144 * \param[in] dname pointer to the structure to hold the rdata value 145 * \param[in] wire pointer to the buffer with the data 146 * \param[in] max the length of the data buffer (in bytes) 147 * \param[in] pos the position of the rdf in the buffer (ie. the number of bytes 148 * from the start of the buffer) 149 * \return LDNS_STATUS_OK if everything succeeds, error otherwise 150 */ 151 ldns_status ldns_wire2dname(ldns_rdf **dname, const uint8_t *wire, size_t max, size_t *pos); 152 153 /** 154 * converts the data on the uint8_t bytearray (in wire format) to DNS 155 * rdata fields, and adds them to the list of rdfs of the given rr. 156 * This function will initialize and allocate memory space for the dname 157 * structures. 158 * The length of the wiredata of these rdfs is added to the *pos value. 159 * 160 * All rdfs belonging to the RR are read; the rr should have no rdfs 161 * yet. An error is returned if the format cannot be parsed. 162 * 163 * \param[in] rr pointer to the ldns_rr structure to hold the rdata value 164 * \param[in] wire pointer to the buffer with the data 165 * \param[in] max the length of the data buffer (in bytes) 166 * \param[in] pos the position of the rdf in the buffer (ie. the number of bytes 167 * from the start of the buffer) 168 * \return LDNS_STATUS_OK if everything succeeds, error otherwise 169 */ 170 ldns_status ldns_wire2rdf(ldns_rr *rr, const uint8_t *wire, size_t max, size_t *pos); 171 172 /** 173 * converts the data on the uint8_t bytearray (in wire format) to a DNS 174 * resource record. 175 * This function will initialize and allocate memory space for the rr 176 * structure. 177 * The length of the wiredata of this rr is added to the *pos value. 178 * 179 * \param[in] rr pointer to the structure to hold the rdata value 180 * \param[in] wire pointer to the buffer with the data 181 * \param[in] max the length of the data buffer (in bytes) 182 * \param[in] pos the position of the rr in the buffer (ie. the number of bytes 183 * from the start of the buffer) 184 * \param[in] section the section in the packet the rr is meant for 185 * \return LDNS_STATUS_OK if everything succeeds, error otherwise 186 */ 187 ldns_status ldns_wire2rr(ldns_rr **rr, const uint8_t *wire, size_t max, size_t *pos, ldns_pkt_section section); 188 189 #endif /* LDNS_WIRE2HOST_H */ 190