]>
Commit | Line | Data |
---|---|---|
12c86877 BH |
1 | /* |
2 | PowerDNS Versatile Database Driven Nameserver | |
213cc78f | 3 | Copyright (C) 2002 - 2011 PowerDNS.COM BV |
12c86877 BH |
4 | |
5 | This program is free software; you can redistribute it and/or modify | |
22dc646a BH |
6 | it under the terms of the GNU General Public License version 2 |
7 | as published by the Free Software Foundation | |
f782fe38 MH |
8 | |
9 | Additionally, the license of this program contains a special | |
10 | exception which allows to distribute the program in binary form when | |
11 | it is linked against OpenSSL. | |
12c86877 BH |
12 | |
13 | This program 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 this program; if not, write to the Free Software | |
06bd9ccf | 20 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
12c86877 | 21 | */ |
092f210a | 22 | // $Id$ |
12c86877 BH |
23 | /* (C) 2002 POWERDNS.COM BV */ |
24 | #ifndef DNS_HH | |
25 | #define DNS_HH | |
5f8fcf64 BH |
26 | #include <boost/multi_index_container.hpp> |
27 | #include <boost/multi_index/ordered_index.hpp> | |
28 | #include <boost/tuple/tuple_comparison.hpp> | |
29 | #include <boost/multi_index/key_extractors.hpp> | |
30 | #include <boost/multi_index/sequenced_index.hpp> | |
cb433f9c BH |
31 | #include <boost/serialization/string.hpp> |
32 | #include <boost/serialization/version.hpp> | |
33 | ||
34 | ||
12c86877 BH |
35 | #include "utility.hh" |
36 | #include "qtype.hh" | |
37 | #include <time.h> | |
38 | #include <sys/types.h> | |
39 | class DNSBackend; | |
40 | ||
41 | struct SOAData | |
42 | { | |
aff67420 | 43 | SOAData() : db(0), scopeMask(0) {}; |
998a2450 | 44 | |
12c86877 BH |
45 | string qname; |
46 | string nameserver; | |
47 | string hostmaster; | |
092f210a BH |
48 | uint32_t ttl; |
49 | uint32_t serial; | |
50 | uint32_t refresh; | |
51 | uint32_t retry; | |
52 | uint32_t expire; | |
53 | uint32_t default_ttl; | |
12c86877 BH |
54 | int domain_id; |
55 | DNSBackend *db; | |
af7d3ea6 | 56 | uint8_t scopeMask; |
12c86877 BH |
57 | }; |
58 | ||
59 | ||
60 | class RCode | |
61 | { | |
62 | public: | |
751ccfff | 63 | enum rcodes_ { NoError=0, FormErr=1, ServFail=2, NXDomain=3, NotImp=4, Refused=5, YXDomain=6, YXRRSet=7, NXRRSet=8, NotAuth=9, NotZone=10}; |
12c86877 BH |
64 | }; |
65 | ||
66 | class Opcode | |
67 | { | |
68 | public: | |
69 | enum { Query=0, IQuery=1, Status=2, Notify=4, Update=5 }; | |
70 | }; | |
71 | ||
12c86877 BH |
72 | //! This class represents a resource record |
73 | class DNSResourceRecord | |
74 | { | |
75 | public: | |
794c2f92 | 76 | DNSResourceRecord() : qclass(1), priority(0), signttl(0), last_modified(0), d_place(ANSWER), auth(1), scopeMask(0) {}; |
f7a69a4c | 77 | DNSResourceRecord(const struct DNSRecord&); |
12c86877 BH |
78 | ~DNSResourceRecord(){}; |
79 | ||
f7a69a4c RA |
80 | void setContent(const string& content); |
81 | string getZoneRepresentation(); | |
82 | ||
12c86877 BH |
83 | // data |
84 | ||
85 | QType qtype; //!< qtype of this record, ie A, CNAME, MX etc | |
a9af3782 | 86 | uint16_t qclass; //!< class of this record |
12c86877 | 87 | string qname; //!< the name of this record, for example: www.powerdns.com |
702b226d | 88 | string wildcardname; |
12c86877 | 89 | string content; //!< what this record points to. Example: 10.1.2.3 |
cb433f9c | 90 | uint16_t priority; //!< For qtypes that support a priority or preference (MX, SRV) |
092f210a | 91 | uint32_t ttl; //!< Time To Live of this record |
794c2f92 | 92 | uint32_t signttl; //!< If non-zero, use this TTL as original TTL in the RRSIG |
12c86877 BH |
93 | int domain_id; //!< If a backend implements this, the domain_id of the zone this record is in |
94 | time_t last_modified; //!< For autocalculating SOA serial numbers - the backend needs to fill this in | |
95 | enum Place {QUESTION=0, ANSWER=1, AUTHORITY=2, ADDITIONAL=3}; //!< Type describing the positioning of a DNSResourceRecord within, say, a DNSPacket | |
96 | Place d_place; //!< This specifies where a record goes within the packet | |
97 | ||
702b226d | 98 | bool auth; |
af7d3ea6 | 99 | uint8_t scopeMask; |
702b226d | 100 | |
cb433f9c BH |
101 | template<class Archive> |
102 | void serialize(Archive & ar, const unsigned int version) | |
103 | { | |
104 | ar & qtype; | |
105 | ar & qclass; | |
106 | ar & qname; | |
107 | ar & wildcardname; | |
108 | ar & content; | |
109 | ar & priority; | |
110 | ar & ttl; | |
111 | ar & domain_id; | |
112 | ar & last_modified; | |
113 | ar & d_place; | |
114 | ar & auth; | |
115 | } | |
914353ca | 116 | |
f7a69a4c | 117 | bool operator==(const DNSResourceRecord& rhs); |
cb433f9c | 118 | |
728485ca BH |
119 | bool operator<(const DNSResourceRecord &b) const |
120 | { | |
c536ca8d | 121 | if(qname < b.qname) |
728485ca | 122 | return true; |
c536ca8d BH |
123 | if(qname == b.qname) |
124 | return(content < b.content); | |
728485ca BH |
125 | return false; |
126 | } | |
12c86877 BH |
127 | }; |
128 | ||
76473b92 KM |
129 | #define GCCPACKATTRIBUTE __attribute__((packed)) |
130 | ||
5a57d2ea BH |
131 | struct dnsrecordheader |
132 | { | |
133 | uint16_t d_type; | |
134 | uint16_t d_class; | |
135 | uint32_t d_ttl; | |
136 | uint16_t d_clen; | |
009f9f55 BH |
137 | } GCCPACKATTRIBUTE; |
138 | ||
139 | struct EDNS0Record | |
140 | { | |
4957a608 BH |
141 | uint8_t extRCode, version; |
142 | uint16_t Z; | |
009f9f55 | 143 | } GCCPACKATTRIBUTE; |
009f9f55 | 144 | |
8b3cfcd3 | 145 | enum { |
5a57d2ea BH |
146 | ns_t_invalid = 0, /* Cookie. */ |
147 | ns_t_a = 1, /* Host address. */ | |
148 | ns_t_ns = 2, /* Authoritative server. */ | |
149 | ns_t_md = 3, /* Mail destination. */ | |
150 | ns_t_mf = 4, /* Mail forwarder. */ | |
151 | ns_t_cname = 5, /* Canonical name. */ | |
152 | ns_t_soa = 6, /* Start of authority zone. */ | |
153 | ns_t_mb = 7, /* Mailbox domain name. */ | |
154 | ns_t_mg = 8, /* Mail group member. */ | |
155 | ns_t_mr = 9, /* Mail rename name. */ | |
156 | ns_t_null = 10, /* Null resource record. */ | |
157 | ns_t_wks = 11, /* Well known service. */ | |
158 | ns_t_ptr = 12, /* Domain name pointer. */ | |
159 | ns_t_hinfo = 13, /* Host information. */ | |
160 | ns_t_minfo = 14, /* Mailbox information. */ | |
161 | ns_t_mx = 15, /* Mail routing information. */ | |
162 | ns_t_txt = 16, /* Text strings. */ | |
163 | ns_t_rp = 17, /* Responsible person. */ | |
164 | ns_t_afsdb = 18, /* AFS cell database. */ | |
165 | ns_t_x25 = 19, /* X_25 calling address. */ | |
166 | ns_t_isdn = 20, /* ISDN calling address. */ | |
8b3cfcd3 | 167 | ns_t_rt = 21, /* Router. */ |
5a57d2ea BH |
168 | ns_t_nsap = 22, /* NSAP address. */ |
169 | ns_t_nsap_ptr = 23, /* Reverse NSAP lookup (deprecated). */ | |
170 | ns_t_sig = 24, /* Security signature. */ | |
171 | ns_t_key = 25, /* Security key. */ | |
172 | ns_t_px = 26, /* X.400 mail mapping. */ | |
173 | ns_t_gpos = 27, /* Geographical position (withdrawn). */ | |
174 | ns_t_aaaa = 28, /* Ip6 Address. */ | |
175 | ns_t_loc = 29, /* Location Information. */ | |
176 | ns_t_nxt = 30, /* Next domain (security). */ | |
177 | ns_t_eid = 31, /* Endpoint identifier. */ | |
178 | ns_t_nimloc = 32, /* Nimrod Locator. */ | |
179 | ns_t_srv = 33, /* Server Selection. */ | |
180 | ns_t_atma = 34, /* ATM Address */ | |
181 | ns_t_naptr = 35, /* Naming Authority PoinTeR */ | |
182 | ns_t_kx = 36, /* Key Exchange */ | |
183 | ns_t_cert = 37, /* Certification record */ | |
184 | ns_t_a6 = 38, /* IPv6 address (deprecates AAAA) */ | |
185 | ns_t_dname = 39, /* Non-terminal DNAME (for IPv6) */ | |
abc1d928 | 186 | ns_t_sink = 40, /* Kitchen sink (experimental) */ |
5a57d2ea | 187 | ns_t_opt = 41, /* EDNS0 option (meta-RR) */ |
59a11942 | 188 | ns_t_ds = 43, /* Delegation signer */ |
7c56383a | 189 | ns_t_ipseckey = 45, /* IPSEC Key */ |
59a11942 PD |
190 | ns_t_rrsig = 46, /* Resoure Record signature */ |
191 | ns_t_nsec = 47, /* Next Record */ | |
192 | ns_t_dnskey = 48, /* DNSKEY record */ | |
193 | ns_t_nsec3 = 50, /* Next Record v3 */ | |
194 | ns_t_nsec3param = 51, /* NSEC Parameters */ | |
195 | ns_t_tlsa = 52, /* TLSA */ | |
1708f778 AT |
196 | ns_t_eui48 = 108, /* EUI-48 */ |
197 | ns_t_eui64 = 109, /* EUI-64 */ | |
5a57d2ea BH |
198 | ns_t_tsig = 250, /* Transaction signature. */ |
199 | ns_t_ixfr = 251, /* Incremental zone transfer. */ | |
200 | ns_t_axfr = 252, /* Transfer zone of authority. */ | |
201 | ns_t_mailb = 253, /* Transfer mailbox records. */ | |
202 | ns_t_maila = 254, /* Transfer mail agent records. */ | |
203 | ns_t_any = 255, /* Wildcard match. */ | |
204 | }; | |
205 | ||
76473b92 | 206 | #if __FreeBSD__ || __APPLE__ || __OpenBSD__ |
009f9f55 | 207 | #include <machine/endian.h> |
a1a344bf BH |
208 | #elif __linux__ |
209 | # include <endian.h> | |
210 | ||
211 | #else // with thanks to <arpa/nameser.h> | |
212 | ||
213 | # define LITTLE_ENDIAN 1234 /* least-significant byte first (vax, pc) */ | |
214 | # define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */ | |
215 | # define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp) */ | |
216 | ||
217 | #if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \ | |
218 | defined(__i386) || defined(__ia64) || defined(__amd64) || \ | |
219 | defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \ | |
220 | defined(__alpha__) || defined(__alpha) || \ | |
221 | (defined(__Lynx__) && defined(__x86__)) | |
222 | # define BYTE_ORDER LITTLE_ENDIAN | |
223 | #endif | |
224 | ||
225 | #if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \ | |
226 | defined(__sparc) || \ | |
227 | defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \ | |
228 | defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\ | |
229 | defined(apollo) || defined(__convex__) || defined(_CRAY) || \ | |
230 | defined(__hppa) || defined(__hp9000) || \ | |
231 | defined(__hp9000s300) || defined(__hp9000s700) || \ | |
232 | defined(__hp3000s900) || defined(MPE) || \ | |
233 | defined(BIT_ZERO_ON_LEFT) || defined(m68k) || \ | |
234 | (defined(__Lynx__) && \ | |
235 | (defined(__68k__) || defined(__sparc__) || defined(__powerpc__))) | |
236 | # define BYTE_ORDER BIG_ENDIAN | |
237 | #endif | |
238 | ||
5a57d2ea BH |
239 | #endif |
240 | ||
241 | struct dnsheader { | |
242 | unsigned id :16; /* query identification number */ | |
243 | #if BYTE_ORDER == BIG_ENDIAN | |
244 | /* fields in third byte */ | |
245 | unsigned qr: 1; /* response flag */ | |
246 | unsigned opcode: 4; /* purpose of message */ | |
7c696097 | 247 | unsigned aa: 1; /* authoritative answer */ |
5a57d2ea BH |
248 | unsigned tc: 1; /* truncated message */ |
249 | unsigned rd: 1; /* recursion desired */ | |
250 | /* fields in fourth byte */ | |
251 | unsigned ra: 1; /* recursion available */ | |
252 | unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */ | |
253 | unsigned ad: 1; /* authentic data from named */ | |
254 | unsigned cd: 1; /* checking disabled by resolver */ | |
255 | unsigned rcode :4; /* response code */ | |
256 | #endif | |
257 | #if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN | |
258 | /* fields in third byte */ | |
259 | unsigned rd :1; /* recursion desired */ | |
260 | unsigned tc :1; /* truncated message */ | |
7c696097 | 261 | unsigned aa :1; /* authoritative answer */ |
5a57d2ea BH |
262 | unsigned opcode :4; /* purpose of message */ |
263 | unsigned qr :1; /* response flag */ | |
264 | /* fields in fourth byte */ | |
265 | unsigned rcode :4; /* response code */ | |
266 | unsigned cd: 1; /* checking disabled by resolver */ | |
267 | unsigned ad: 1; /* authentic data from named */ | |
268 | unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */ | |
269 | unsigned ra :1; /* recursion available */ | |
270 | #endif | |
271 | /* remaining bytes */ | |
272 | unsigned qdcount :16; /* number of question entries */ | |
273 | unsigned ancount :16; /* number of answer entries */ | |
274 | unsigned nscount :16; /* number of authority entries */ | |
275 | unsigned arcount :16; /* number of resource entries */ | |
276 | }; | |
277 | ||
278 | ||
12c86877 BH |
279 | #define L theL() |
280 | extern time_t s_starttime; | |
3ea54bf0 | 281 | std::string questionExpand(const char* packet, uint16_t len, uint16_t& type); |
3d40879b | 282 | bool dnspacketLessThan(const std::string& a, const std::string& b); |
213cc78f BH |
283 | |
284 | /** helper function for both DNSPacket and addSOARecord() - converts a line into a struct, for easier parsing */ | |
285 | void fillSOAData(const string &content, SOAData &data); | |
286 | ||
287 | /** for use by DNSPacket, converts a SOAData class to a ascii line again */ | |
288 | string serializeSOAData(const SOAData &data); | |
289 | string &attodot(string &str); //!< for when you need to insert an email address in the SOA | |
67672ba6 | 290 | string strrcode(unsigned char rcode); |
12c86877 | 291 | #endif |