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 /* 103 #define QDCOUNT(wirebuf) (ntohs(*(uint16_t *)(wirebuf+QDCOUNT_OFF))) 104 */ 105 #define LDNS_QDCOUNT(wirebuf) (ldns_read_uint16(wirebuf+LDNS_QDCOUNT_OFF)) 106 107 /* Counter of the answer section */ 108 #define LDNS_ANCOUNT_OFF 6 109 #define LDNS_ANCOUNT(wirebuf) (ldns_read_uint16(wirebuf+LDNS_ANCOUNT_OFF)) 110 111 /* Counter of the authority section */ 112 #define LDNS_NSCOUNT_OFF 8 113 #define LDNS_NSCOUNT(wirebuf) (ldns_read_uint16(wirebuf+LDNS_NSCOUNT_OFF)) 114 115 /* Counter of the additional section */ 116 #define LDNS_ARCOUNT_OFF 10 117 #define LDNS_ARCOUNT(wirebuf) (ldns_read_uint16(wirebuf+LDNS_ARCOUNT_OFF)) 118 119 /** 120 * converts the data on the uint8_t bytearray (in wire format) to a DNS packet. 121 * This function will initialize and allocate memory space for the packet 122 * structure. 123 * 124 * \param[in] packet pointer to the structure to hold the packet 125 * \param[in] data pointer to the buffer with the data 126 * \param[in] len the length of the data buffer (in bytes) 127 * \return LDNS_STATUS_OK if everything succeeds, error otherwise 128 */ 129 ldns_status ldns_wire2pkt(ldns_pkt **packet, const uint8_t *data, size_t len); 130 131 /** 132 * converts the data on the uint8_t bytearray (in wire format) to a DNS packet. 133 * This function will initialize and allocate memory space for the packet 134 * structure. 135 * 136 * \param[in] packet pointer to the structure to hold the packet 137 * \param[in] buffer the buffer with the data 138 * \return LDNS_STATUS_OK if everything succeeds, error otherwise 139 */ 140 ldns_status ldns_buffer2pkt_wire(ldns_pkt **packet, ldns_buffer *buffer); 141 142 /** 143 * converts the data on the uint8_t bytearray (in wire format) to a DNS 144 * dname rdata field. This function will initialize and allocate memory 145 * space for the dname structure. The length of the wiredata of this rdf 146 * is added to the *pos value. 147 * 148 * \param[in] dname pointer to the structure to hold the rdata value 149 * \param[in] wire pointer to the buffer with the data 150 * \param[in] max the length of the data buffer (in bytes) 151 * \param[in] pos the position of the rdf in the buffer (ie. the number of bytes 152 * from the start of the buffer) 153 * \return LDNS_STATUS_OK if everything succeeds, error otherwise 154 */ 155 ldns_status ldns_wire2dname(ldns_rdf **dname, const uint8_t *wire, size_t max, size_t *pos); 156 157 /** 158 * converts the data on the uint8_t bytearray (in wire format) to DNS 159 * rdata fields, and adds them to the list of rdfs of the given rr. 160 * This function will initialize and allocate memory space for the dname 161 * structures. 162 * The length of the wiredata of these rdfs is added to the *pos value. 163 * 164 * All rdfs belonging to the RR are read; the rr should have no rdfs 165 * yet. An error is returned if the format cannot be parsed. 166 * 167 * \param[in] rr pointer to the ldns_rr structure to hold the rdata value 168 * \param[in] wire pointer to the buffer with the data 169 * \param[in] max the length of the data buffer (in bytes) 170 * \param[in] pos the position of the rdf in the buffer (ie. the number of bytes 171 * from the start of the buffer) 172 * \return LDNS_STATUS_OK if everything succeeds, error otherwise 173 */ 174 ldns_status ldns_wire2rdf(ldns_rr *rr, const uint8_t *wire, size_t max, size_t *pos); 175 176 /** 177 * converts the data on the uint8_t bytearray (in wire format) to a DNS 178 * resource record. 179 * This function will initialize and allocate memory space for the rr 180 * structure. 181 * The length of the wiredata of this rr is added to the *pos value. 182 * 183 * \param[in] rr pointer to the structure to hold the rdata value 184 * \param[in] wire pointer to the buffer with the data 185 * \param[in] max the length of the data buffer (in bytes) 186 * \param[in] pos the position of the rr in the buffer (ie. the number of bytes 187 * from the start of the buffer) 188 * \param[in] section the section in the packet the rr is meant for 189 * \return LDNS_STATUS_OK if everything succeeds, error otherwise 190 */ 191 ldns_status ldns_wire2rr(ldns_rr **rr, const uint8_t *wire, size_t max, size_t *pos, ldns_pkt_section section); 192 193 #ifdef __cplusplus 194 } 195 #endif 196 197 #endif /* LDNS_WIRE2HOST_H */ 198