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 1480 /* 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 149 /* 150 * Encode RR with OWNER as owner name into QUERY. Returns the number 151 * of RRs successfully encoded. 152 */ 153 int packet_encode_rr(struct query *query, 154 domain_type *owner, 155 rr_type *rr, 156 uint32_t ttl); 157 158 /* 159 * Encode RRSET with OWNER as the owner name into QUERY. Returns the 160 * number of RRs successfully encoded. If TRUNCATE_RRSET the entire 161 * RRset is truncated in case an RR (or the RRsets signature) does not 162 * fit. 163 */ 164 int packet_encode_rrset(struct query *query, 165 domain_type *owner, 166 rrset_type *rrset, 167 int truncate_rrset, 168 size_t minimal_respsize, 169 int* done); 170 171 /* 172 * Skip the RR at the current position in PACKET. 173 */ 174 int packet_skip_rr(buffer_type *packet, int question_section); 175 176 /* 177 * Skip the dname at the current position in PACKET. 178 */ 179 int packet_skip_dname(buffer_type *packet); 180 181 /* 182 * Read the RR at the current position in PACKET. 183 */ 184 rr_type *packet_read_rr(region_type *region, 185 domain_table_type *owners, 186 buffer_type *packet, 187 int question_section); 188 189 /* 190 * read a query entry from network packet given in buffer. 191 * does not follow compression ptrs, checks for errors (returns 0). 192 * Dest must be at least MAXDOMAINLEN long. 193 */ 194 int packet_read_query_section(buffer_type *packet, 195 uint8_t* dest, 196 uint16_t* qtype, 197 uint16_t* qclass); 198 199 /* read notify SOA serial from packet. buffer position is unmodified on return. 200 * returns false on no-serial found or parse failure. */ 201 int packet_find_notify_serial(buffer_type *packet, uint32_t* serial); 202 203 #endif /* _PACKET_H_ */ 204