1 /* 2 * packet.h -- low-level DNS packet encoding and decoding functions. 3 * 4 * Copyright (c) 2001-2006, NLnet Labs. All rights reserved. 5 * 6 * See LICENSE for the license. 7 * 8 */ 9 10 #ifndef PACKET_H 11 #define PACKET_H 12 13 #include <sys/types.h> 14 15 #include "dns.h" 16 #include "namedb.h" 17 18 struct query; 19 20 /* 21 * Set of macro's to deal with the dns message header as specified 22 * in RFC1035 in portable way. 23 * 24 */ 25 26 /* 27 * 28 * 1 1 1 1 1 1 29 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 30 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 31 * | ID | 32 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 33 * |QR| Opcode |AA|TC|RD|RA| Z|AD|CD| RCODE | 34 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 35 * | QDCOUNT | 36 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 37 * | ANCOUNT | 38 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 39 * | NSCOUNT | 40 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 41 * | ARCOUNT | 42 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 43 * 44 */ 45 46 /* The length of the header */ 47 #define QHEADERSZ 12 48 49 /* First octet of flags */ 50 #define RD_MASK 0x01U 51 #define RD_SHIFT 0 52 #define RD(packet) (*buffer_at((packet), 2) & RD_MASK) 53 #define RD_SET(packet) (*buffer_at((packet), 2) |= RD_MASK) 54 #define RD_CLR(packet) (*buffer_at((packet), 2) &= ~RD_MASK) 55 56 #define TC_MASK 0x02U 57 #define TC_SHIFT 1 58 #define TC(packet) (*buffer_at((packet), 2) & TC_MASK) 59 #define TC_SET(packet) (*buffer_at((packet), 2) |= TC_MASK) 60 #define TC_CLR(packet) (*buffer_at((packet), 2) &= ~TC_MASK) 61 62 #define AA_MASK 0x04U 63 #define AA_SHIFT 2 64 #define AA(packet) (*buffer_at((packet), 2) & AA_MASK) 65 #define AA_SET(packet) (*buffer_at((packet), 2) |= AA_MASK) 66 #define AA_CLR(packet) (*buffer_at((packet), 2) &= ~AA_MASK) 67 68 #define OPCODE_MASK 0x78U 69 #define OPCODE_SHIFT 3 70 #define OPCODE(packet) ((*buffer_at((packet), 2) & OPCODE_MASK) >> OPCODE_SHIFT) 71 #define OPCODE_SET(packet, opcode) \ 72 (*buffer_at((packet), 2) = (*buffer_at((packet), 2) & ~OPCODE_MASK) | ((opcode) << OPCODE_SHIFT)) 73 74 #define QR_MASK 0x80U 75 #define QR_SHIFT 7 76 #define QR(packet) (*buffer_at((packet), 2) & QR_MASK) 77 #define QR_SET(packet) (*buffer_at((packet), 2) |= QR_MASK) 78 #define QR_CLR(packet) (*buffer_at((packet), 2) &= ~QR_MASK) 79 80 /* Second octet of flags */ 81 #define RCODE_MASK 0x0fU 82 #define RCODE_SHIFT 0 83 #define RCODE(packet) (*buffer_at((packet), 3) & RCODE_MASK) 84 #define RCODE_SET(packet, rcode) \ 85 (*buffer_at((packet), 3) = (*buffer_at((packet), 3) & ~RCODE_MASK) | (rcode)) 86 87 #define CD_MASK 0x10U 88 #define CD_SHIFT 4 89 #define CD(packet) (*buffer_at((packet), 3) & CD_MASK) 90 #define CD_SET(packet) (*buffer_at((packet), 3) |= CD_MASK) 91 #define CD_CLR(packet) (*buffer_at((packet), 3) &= ~CD_MASK) 92 93 #define AD_MASK 0x20U 94 #define AD_SHIFT 5 95 #define AD(packet) (*buffer_at((packet), 3) & AD_MASK) 96 #define AD_SET(packet) (*buffer_at((packet), 3) |= AD_MASK) 97 #define AD_CLR(packet) (*buffer_at((packet), 3) &= ~AD_MASK) 98 99 #define Z_MASK 0x40U 100 #define Z_SHIFT 6 101 #define Z(packet) (*buffer_at((packet), 3) & Z_MASK) 102 #define Z_SET(packet) (*buffer_at((packet), 3) |= Z_MASK) 103 #define Z_CLR(packet) (*buffer_at((packet), 3) &= ~Z_MASK) 104 105 #define RA_MASK 0x80U 106 #define RA_SHIFT 7 107 #define RA(packet) (*buffer_at((packet), 3) & RA_MASK) 108 #define RA_SET(packet) (*buffer_at((packet), 3) |= RA_MASK) 109 #define RA_CLR(packet) (*buffer_at((packet), 3) &= ~RA_MASK) 110 111 /* Query ID */ 112 #define ID(packet) (buffer_read_u16_at((packet), 0)) 113 #define ID_SET(packet, id) (buffer_write_u16_at((packet), 0, (id))) 114 115 /* Flags, RCODE, and OPCODE. */ 116 #define FLAGS(packet) (buffer_read_u16_at((packet), 2)) 117 #define FLAGS_SET(packet, f) (buffer_write_u16_at((packet), 2, (f))) 118 119 /* Counter of the question section */ 120 #define QDCOUNT(packet) (buffer_read_u16_at((packet), 4)) 121 #define QDCOUNT_SET(packet, c) (buffer_write_u16_at((packet), 4, (c))) 122 123 /* Counter of the answer section */ 124 #define ANCOUNT(packet) (buffer_read_u16_at((packet), 6)) 125 #define ANCOUNT_SET(packet, c) (buffer_write_u16_at((packet), 6, (c))) 126 127 /* Counter of the authority section */ 128 #define NSCOUNT(packet) (buffer_read_u16_at((packet), 8)) 129 #define NSCOUNT_SET(packet, c) (buffer_write_u16_at((packet), 8, (c))) 130 131 /* Counter of the additional section */ 132 #define ARCOUNT(packet) (buffer_read_u16_at((packet), 10)) 133 #define ARCOUNT_SET(packet, c) (buffer_write_u16_at((packet), 10, (c))) 134 135 /* Miscellaneous limits */ 136 #define MAX_PACKET_SIZE 65535 /* Maximum supported size of DNS packets. */ 137 138 #define QIOBUFSZ (MAX_PACKET_SIZE + MAX_RR_SIZE) 139 140 #define MAXRRSPP 10240 /* Maximum number of rr's per packet */ 141 #define MAX_COMPRESSED_DNAMES MAXRRSPP /* Maximum number of compressed domains. */ 142 #define MAX_COMPRESSION_OFFSET 16383 /* Compression pointers are 14 bit. */ 143 #define IPV4_MINIMAL_RESPONSE_SIZE 1232 /* Recommended minimal edns size for IPv4 */ 144 #define IPV6_MINIMAL_RESPONSE_SIZE 1220 /* Recommended minimal edns size for IPv6 */ 145 146 /* use round robin rotation */ 147 extern int round_robin; 148 /* use minimal responses (more minimal, with additional only for referrals) */ 149 extern int minimal_responses; 150 151 /* 152 * Encode RR with OWNER as owner name into QUERY. Returns the number 153 * of RRs successfully encoded. 154 */ 155 int packet_encode_rr(struct query *query, 156 domain_type *owner, 157 rr_type *rr, 158 uint32_t ttl); 159 160 /* 161 * Encode RRSET with OWNER as the owner name into QUERY. Returns the 162 * number of RRs successfully encoded. If TRUNCATE_RRSET the entire 163 * RRset is truncated in case an RR (or the RRsets signature) does not 164 * fit. 165 */ 166 int packet_encode_rrset(struct query *query, 167 domain_type *owner, 168 rrset_type *rrset, 169 int truncate_rrset, 170 size_t minimal_respsize, 171 int* done); 172 173 /* 174 * Skip the RR at the current position in PACKET. 175 */ 176 int packet_skip_rr(buffer_type *packet, int question_section); 177 178 /* 179 * Skip the dname at the current position in PACKET. 180 */ 181 int packet_skip_dname(buffer_type *packet); 182 183 /* 184 * Read the RR at the current position in PACKET. 185 */ 186 rr_type *packet_read_rr(region_type *region, 187 domain_table_type *owners, 188 buffer_type *packet, 189 int question_section); 190 191 /* 192 * read a query entry from network packet given in buffer. 193 * does not follow compression ptrs, checks for errors (returns 0). 194 * Dest must be at least MAXDOMAINLEN long. 195 */ 196 int packet_read_query_section(buffer_type *packet, 197 uint8_t* dest, 198 uint16_t* qtype, 199 uint16_t* qclass); 200 201 /* read notify SOA serial from packet. buffer position is unmodified on return. 202 * returns false on no-serial found or parse failure. */ 203 int packet_find_notify_serial(buffer_type *packet, uint32_t* serial); 204 205 #endif /* PACKET_H */ 206