xref: /openbsd/usr.sbin/nsd/packet.h (revision 3efee2e1)
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