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