1 /*
2 ** Copyright (C) 2006 Olivier DEMBOUR
3 ** $Id: dns.h,v 1.16.4.2 2010/06/01 16:05:05 collignon Exp $
4 **
5 **
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License as published by
8 ** the Free Software Foundation; either version 2 of the License, or
9 ** (at your option) any later version.
10 **
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 ** GNU General Public License for more details.
15 **
16 ** You should have received a copy of the GNU General Public License
17 ** along with This program; if not, write to the Free Software
18 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20 
21 #ifndef __DNS_H__
22 #define __DNS_H__
23 
24 #include "config.h"
25 
26 #ifndef _WIN32
27 #include <unistd.h>
28 #include <arpa/inet.h>
29 #else
30 #include "mywin32.h"
31 #endif
32 #include "base64.h"
33 
34 #define MAX_DNS_LEN			512
35 #define MAX_EDNS_LEN			4096
36 
37 #define EDNS_HEADER			11
38 
39 #define MAX_HOST_NAME_ENCODED		200 /* need space for reply */
40 #define MAX_HOST_NAME_DECODED		DECODED_LEN((MAX_HOST_NAME_ENCODED))
41 
42 #define ENCODED_LEN(len)		(((len) + (((len) / 63) + 1)))
43 #define DECODED_LEN(len)		( ((len)>0) ? (((len) - (((len) / 63) + 1))) : 0)
44 
45 /* USE EDNS or std DNS */
46 #define MAX_ENCODE_DATA(len, dns_size)	\
47 	( \
48 		 (((len)+RR_HDR_SIZE) > (dns_size - AUTHORITATIVE_SIZE)) ? 0 :		\
49 			DECODED_LEN(DECODED_BASE64_SIZE(\
50 			( (dns_size - AUTHORITATIVE_SIZE) - (len) - (RR_HDR_SIZE)) ) \
51 				    ))
52 
53 #define MAX_RAW_DATA(len, dns_size)	\
54 	( \
55 		 (((len)+RR_HDR_SIZE) > (dns_size - AUTHORITATIVE_SIZE)) ? 0 :	\
56 			DECODED_BASE64_SIZE(\
57 		    ( (dns_size - AUTHORITATIVE_SIZE) - (len) - (RR_HDR_SIZE) ) ) \
58 	  )
59 
60 
61 #define AUTHORITATIVE_SIZE 50 /* should be better defined ... */
62 /* Additional record + Authoritative nameserver */
63 
64 
65 #define ENCODE_DATA_AVAILABLE(len, query_len, dns_size)  (client && (client->control.use_compress)) ? \
66 				((MAX_ENCODE_DATA((len + 2), (dns_size)))) :				\
67 				((MAX_ENCODE_DATA((len + query_len), (dns_size))))
68 
69 #define RAW_DATA_AVAILABLE(len, query_len, dns_size)  (client && (client->control.use_compress)) ? \
70 				((MAX_RAW_DATA((len + 2), (dns_size)))) :				\
71 				((MAX_RAW_DATA((len + query_len), (dns_size))))
72 
73 /*
74 #define ENCODE_DATA_AVAILABLE(len, query_len, dns_size)  (client && (client->control.use_compress)) ? \
75 				((MAX_ENCODE_DATA((len) + 2, (dns_size + 1)))) : \
76 				((MAX_ENCODE_DATA((len) + (query_len), (dns_size))))
77 
78 #define RAW_DATA_AVAILABLE(len, query_len, dns_size)  (client && (client->control.use_compress)) ? \
79 				((MAX_RAW_DATA((len) + 2, (dns_size + 1)))) : \
80 				((MAX_RAW_DATA((len) + (query_len), (dns_size))))
81 */
82 #define	MAX_QNAME_DATA(domain)		(DECODED_BASE64_SIZE(MAX_HOST_NAME_DECODED - strlen(domain) - 1))
83 
84 /* GCC alignement padding workaround */
85 
86 #define DNS_HDR_SIZE			12
87 #define	RR_HDR_SIZE			10
88 #define	REQ_HDR_SIZE			4
89 
90 #define	JUMP_DNS_HDR(hdr)		((char *)hdr + DNS_HDR_SIZE)
91 #define	JUMP_RR_HDR(hdr)		((char *)hdr + RR_HDR_SIZE)
92 #define	JUMP_REQ_HDR(hdr)		((char *)hdr + REQ_HDR_SIZE)
93 
94 #define COMPRESS_FLAG_CHAR		0xC0
95 #define COMPRESS_FLAG			0xC000
96 #define	GET_DECOMPRESS_OFFSET(offset)	((ntohs(offset)) & ~(COMPRESS_FLAG))
97 
98 /* Why not */
99 #define	MAX_COMPRESS_DEPTH		10
100 
101 
102 /* Network order */
103 #define PUT_16(dst, src) do \
104 	{\
105 		((unsigned char *)(dst))[0] = (uint8_t) ((src ) >> 8) ;       \
106 		((unsigned char *)(dst))[1] = (uint8_t) (src) ;		\
107 	} while (0)
108 
109 #define PUT_32(dst, src) do \
110 	{\
111 	  ((unsigned char *)(dst))[0] = (uint8_t) ((src ) >> 24) ;      \
112 	  ((unsigned char *)(dst))[1] = (uint8_t) ((src ) >> 16) ;      \
113 	  ((unsigned char *)(dst))[2] = (uint8_t) ((src ) >> 8) ;       \
114 	  ((unsigned char *)(dst))[3] = (uint8_t) (src) ;	       \
115 	} while (0)
116 
117 /* Host order */
118 #define GET_16(src) ((((unsigned char *)(src))[0] << 8) | (((unsigned char *)(src))[1]) )
119 #define GET_32(src) (\
120 			  (((unsigned char *)(src))[0] << 24) |		\
121 			  (((unsigned char *)(src))[1] << 16) |		\
122 			  (((unsigned char *)(src))[2] << 8) |		\
123 			  (((unsigned char *)(src))[3] )		\
124 		     )
125 
126 /* FIXME hardcoded '=' is bad ! (check base64_padding ...) */
127 #define RESOURCE	"=resource."
128 #define AUTH		"=auth."
129 #define CONNECT		"=connect."
130 
131 
132 
133 struct				dns_hdr {
134   uint16_t			id;
135 #ifndef WORDS_BIGENDIAN
136   uint16_t			rd:1, /* recurse demand */
137 				tc:1, /* truncated */
138 				aa:1, /* authorative */
139 				opcode:4,
140 				qr:1,
141 				rcode:4,
142 				z:3,
143 				ra:1; /* recurse available */
144 #else
145   uint16_t			qr:1,
146 				opcode:4,
147 				aa:1,
148 				tc:1,
149 				rd:1,
150 				ra:1,
151 				z:3,
152 				rcode:4;
153 #endif
154 #define RCODE_NO_ERR		0x0
155 #define RCODE_FORMAT_ERR	0x1
156 #define RCODE_SRV_FAILURE	0x2
157 #define RCODE_NAME_ERR		0x3
158 #define RCODE_NOT_IMPLEMENTED	0x4
159 #define RCODE_REFUSED		0x3
160   uint16_t			qdcount; /* nb queries */
161   uint16_t			ancount; /* nb answers */
162   uint16_t			nscount; /* authority records */
163   uint16_t			arcount; /* additional records */
164 }  __attribute__((packed));
165 
166 
167 #define MAX_DNS_ERROR	6
168 extern const char *dns_error[MAX_DNS_ERROR];
169 
170 struct		req_hdr {
171   uint16_t	qtype; /* TXT */
172   uint16_t	qclass; /* IN | CHAOS */
173 } __attribute__((packed));
174 
175 struct		rr_hdr {
176   uint16_t	type;
177 #define TYPE_TXT 16
178 #define TYPE_KEY 25
179   uint16_t	klass;
180 #define CLASS_IN 1
181   uint32_t	ttl;
182   uint16_t	rdlength;
183 } __attribute__((packed));
184 
185 struct		add_record {
186   uint8_t	name;
187   uint16_t	type;
188 #define TYPE_EDNS 41
189   uint16_t	payload_size;
190   uint8_t	rcode;
191   uint8_t	version;
192   uint16_t	z;
193   uint16_t	length;
194 } __attribute__((packed));
195 
196 void    dns_simple_decode(char *input, char *output, int max_len);
197 void	dns_simple_decode_strip_dot(char *input, char *output, int max_len);
198 void	dns_encode(char *);
199 void	*jump_end_query(void *, int, int);
200 void   *jump_qname(void *, int);
201 void	*jump_end_answer(void *buffer, int max_len);
202 void	*jump_edns(void *buffer, int max_len);
203 
204 #endif
205