1 /* dns.h - Declarations for dns handling and generic dns functions
2 
3    Copyright (C) 2000, 2001 Thomas Moestl
4    Copyright (C) 2002, 2003, 2004, 2005, 2009, 2011 Paul A. Rombouts
5 
6   This file is part of the pdnsd package.
7 
8   pdnsd is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 3 of the License, or
11   (at your option) any later version.
12 
13   pdnsd is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17 
18   You should have received a copy of the GNU General Public License
19   along with pdnsd; see the file COPYING. If not, see
20   <http://www.gnu.org/licenses/>.
21 */
22 
23 
24 #ifndef DNS_H
25 #define DNS_H
26 
27 #include <config.h>
28 #include <arpa/inet.h>
29 #include <sys/socket.h>
30 #include <net/if.h>
31 #include <sys/types.h>
32 #include <inttypes.h>
33 #include "rr_types.h"
34 #include "list.h"
35 #include "ipvers.h"
36 
37 #if (TARGET==TARGET_BSD)
38 # if !defined(__BIG_ENDIAN)
39 #  if defined(BIG_ENDIAN)
40 #   define __BIG_ENDIAN BIG_ENDIAN
41 #  elif defined(_BIG_ENDIAN)
42 #   define __BIG_ENDIAN _BIG_ENDIAN
43 #  endif
44 # endif
45 # if !defined(__LITTLE_ENDIAN)
46 #  if defined(LITTLE_ENDIAN)
47 #   define __LITTLE_ENDIAN LITTLE_ENDIAN
48 #  elif defined(_LITTLE_ENDIAN)
49 #   define __LITTLE_ENDIAN _LITTLE_ENDIAN
50 #  endif
51 # endif
52 # if !defined(__BYTE_ORDER)
53 #  if defined(BYTE_ORDER)
54 #   define __BYTE_ORDER BYTE_ORDER
55 #  elif defined(_BYTE_ORDER)
56 #   define __BYTE_ORDER _BYTE_ORDER
57 #  endif
58 # endif
59 #endif
60 
61 /* Deal with byte orders */
62 #ifndef __BYTE_ORDER
63 # if defined(__LITTLE_ENDIAN) && defined(__BIG_ENDIAN)
64 #  error Fuzzy endianness system! Both __LITTLE_ENDIAN and __BIG_ENDIAN have been defined!
65 # endif
66 # if !defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN)
67 #  error Strange Endianness-less system! Neither __LITTLE_ENDIAN nor __BIG_ENDIAN has been defined!
68 # endif
69 # if defined(__LITTLE_ENDIAN)
70 #  define __BYTE_ORDER __LITTLE_ENDIAN
71 # elif defined(__BIG_ENDIAN)
72 #  define __BYTE_ORDER __BIG_ENDIAN
73 # endif
74 #endif
75 
76 /* special rr type codes for queries */
77 #define QT_MIN    251
78 #define QT_IXFR   251
79 #define QT_AXFR   252
80 #define QT_MAILB  253
81 #define QT_MAILA  254
82 #define QT_ALL    255
83 #define QT_MAX    255
84 #define QT_NUM      5
85 
86 /* rr classes */
87 #define C_MIN       1
88 #define C_IN        1
89 #define C_CS        2
90 #define C_CH        3
91 #define C_HS        4
92 #define C_MAX       4
93 #define C_NUM       4
94 
95 /* special classes for queries */
96 #define QC_ALL    255
97 
98 /* status codes */
99 #define RC_OK       0
100 #define RC_FORMAT   1
101 #define RC_SERVFAIL 2
102 #define RC_NAMEERR  3
103 #define RC_NOTSUPP  4
104 #define RC_REFUSED  5
105 #define RC_BADVERS 16
106 
107 /*
108  * special internal retvals
109  */
110 #define RC_NOTCACHED  0xfffa
111 #define RC_CACHED     0xfffb
112 #define RC_STALE      0xfffc
113 #define RC_TCPREFUSED 0xfffd
114 #define RC_TRUNC      0xfffe
115 #define RC_FATALERR   0xffff
116 
117 /* query/response */
118 #define QR_QUERY    0
119 #define QR_RESP     1
120 
121 /*opcodes */
122 #define OP_QUERY    0
123 #define OP_IQUERY   1
124 #define OP_STATUS   2
125 
126 #if 0
127 typedef struct {
128 	/* the name is the first field. It has variable length, so it can't be put in the struct */
129 	uint16_t type;
130 	uint16_t class;
131 	uint32_t ttl;
132 	uint16_t rdlength;
133 	/* rdata follows */
134 } __attribute__((packed)) rr_hdr_t;
135 
136 #define sizeof_rr_hdr_t (sizeof rr_hdr_t)
137 #else
138 
139 /* We will not actually use the rr_hdr_t type, only its size:
140    sizeof(rr_hdr_t) = 2 + 2 + 4 + 2 */
141 #define sizeof_rr_hdr_t 10
142 #endif
143 
144 #define sizeof_opt_pseudo_rr  (1+sizeof_rr_hdr_t)
145 
146 #if 0
147 typedef struct {
148 	/* The server name and maintainer mailbox are the first two fields. It has variable length, */
149 	/* so they can't be put in the struct */
150 	uint32_t serial;
151 	uint32_t refresh;
152 	uint32_t retry;
153 	uint32_t expire;
154 	uint32_t minimum;
155 } __attribute__((packed)) soa_r_t;
156 
157 
158 typedef struct {
159 /*	char           qname[];*/
160 	uint16_t qtype;
161 	uint16_t qclass;
162 } __attribute__((packed)) std_query_t;
163 #endif
164 
165 
166 typedef struct {
167 	uint16_t id;
168 #if __BYTE_ORDER == __LITTLE_ENDIAN
169 	unsigned int   rd:1;
170 	unsigned int   tc:1;
171 	unsigned int   aa:1;
172 	unsigned int   opcode:4;
173 	unsigned int   qr:1;
174 	unsigned int   rcode:4;
175 	unsigned int   cd:1;
176 	unsigned int   ad:1;
177 	unsigned int   z :1;
178 	unsigned int   ra:1;
179 #elif __BYTE_ORDER == __BIG_ENDIAN
180 	unsigned int   qr:1;
181 	unsigned int   opcode:4;
182 	unsigned int   aa:1;
183 	unsigned int   tc:1;
184 	unsigned int   rd:1;
185 	unsigned int   ra:1;
186 	unsigned int   z :1;
187 	unsigned int   ad:1;
188 	unsigned int   cd:1;
189 	unsigned int   rcode:4;
190 #else
191 # error	"Please define __BYTE_ORDER to be __LITTLE_ENDIAN or __BIG_ENDIAN"
192 #endif
193 	uint16_t qdcount;
194 	uint16_t ancount;
195 	uint16_t nscount;
196 	uint16_t arcount;
197 } __attribute__((packed)) dns_hdr_t;
198 
199 
200 /* A structure that can also be used for DNS messages over TCP. */
201 typedef struct {
202 #ifndef NO_TCP_QUERIES
203 	uint16_t len;
204 #endif
205 	dns_hdr_t hdr;
206 } __attribute__((packed)) dns_msg_t;
207 
208 #ifdef NO_TCP_QUERIES
209 # define dnsmsghdroffset 0
210 #else
211 # define dnsmsghdroffset 2
212 #endif
213 
214 
215 /* Structure for storing EDNS (Extension mechanisms for DNS) information. */
216 typedef struct {
217 	unsigned short udpsize;
218 	unsigned short rcode;
219 	unsigned short version;
220 	unsigned char  do_flg;
221 } edns_info_t;
222 
223 
224 /* Macros to retrieve or store integer data that is not necessarily aligned.
225    Also takes care of network to host byte order.
226    The pointer cp is advanced and should be of type void* or char*.
227    These are actually adapted versions of the NS_GET16 and NS_GET32
228    macros in the arpa/nameser.h include file in the BIND 9 source.
229 */
230 
231 #define GETINT16(s,cp) do {							\
232 	register uint16_t t_s;							\
233 	register const unsigned char *t_cp = (const unsigned char *)(cp);	\
234 	t_s = (uint16_t)*t_cp++ << 8;						\
235 	t_s |= (uint16_t)*t_cp++;						\
236 	(s) = t_s;								\
237 	(cp) = (void *)t_cp;							\
238 } while (0)
239 
240 #define GETINT32(l,cp) do {							\
241 	register uint32_t t_l;							\
242 	register const unsigned char *t_cp = (const unsigned char *)(cp);	\
243 	t_l = (uint32_t)*t_cp++ << 24;						\
244 	t_l |= (uint32_t)*t_cp++ << 16;						\
245 	t_l |= (uint32_t)*t_cp++ << 8;						\
246 	t_l |= (uint32_t)*t_cp++;						\
247 	(l) = t_l;								\
248 	(cp) = (void *)t_cp;							\
249 } while (0)
250 
251 #define PUTINT16(s,cp) do {					\
252 	register uint16_t t_s = (uint16_t)(s);			\
253 	register unsigned char *t_cp = (unsigned char *)(cp);	\
254 	*t_cp++ = t_s >> 8;					\
255 	*t_cp++ = t_s;						\
256 	(cp) = (void *)t_cp;					\
257 } while (0)
258 
259 #define PUTINT32(l,cp) do {					\
260 	register uint32_t t_l = (uint32_t)(l);			\
261 	register unsigned char *t_cp = (unsigned char *)(cp);	\
262 	*t_cp++ = t_l >> 24;					\
263 	*t_cp++ = t_l >> 16;					\
264 	*t_cp++ = t_l >> 8;					\
265 	*t_cp++ = t_l;						\
266 	(cp) = (void *)t_cp;					\
267 } while (0)
268 
269 
270 /* Size (number of bytes) of buffers used to hold domain names. */
271 #define DNSNAMEBUFSIZE 256
272 
273 /* Recursion depth. */
274 #define MAX_HOPS 20
275 
276 /*
277  * Types for compression buffers.
278  */
279 typedef struct {
280 	unsigned int  index;
281 	unsigned char s[0];
282 } compel_t;
283 
284 
285 
286 int decompress_name(unsigned char *msg, size_t msgsz, unsigned char **src, size_t *sz, unsigned char *tgt, unsigned int *len);
287 /* int domain_name_match(const unsigned char *ms, const unsigned char *md, int *os, int *od); */
288 unsigned int domain_match(const unsigned char *ms, const unsigned char *md, unsigned int *os, unsigned int *od);
289 unsigned int compress_name(unsigned char *in, unsigned char *out, unsigned int offs, dlist *cb);
290 int a2ptrstr(pdnsd_ca *a, int tp, unsigned char *buf);
291 int read_hosts(const char *fn, unsigned char *rns, time_t ttl, unsigned flags, int aliases, char **errstr);
292 
293 const char *getrrtpname(int tp);
294 #if DEBUG>0
295 const char *get_cname(int id);
296 const char *get_tname(int id);
297 const char *get_ename(int id);
298 #define DNSFLAGSMAXSTRSIZE (7*3+1)
299 char *dnsflags2str(dns_hdr_t *hdr, char *buf);
300 #endif
301 
302 #if DEBUG>=9
303 void debug_dump_dns_msg(void *data, size_t len);
304 #define DEBUG_DUMP_DNS_MSG(d,l) {if(debug_p && global.verbosity>=9) debug_dump_dns_msg(d,l);}
305 #else
306 #define DEBUG_DUMP_DNS_MSG(d,l)
307 #endif
308 
309 #endif
310