| 1 | /* |
|---|
| 2 | PowerDNS Versatile Database Driven Nameserver |
|---|
| 3 | Copyright (C) 2002 PowerDNS.COM BV |
|---|
| 4 | |
|---|
| 5 | This program is free software; you can redistribute it and/or modify |
|---|
| 6 | it under the terms of the GNU General Public License version 2 |
|---|
| 7 | as published by the Free Software Foundation |
|---|
| 8 | |
|---|
| 9 | |
|---|
| 10 | This program is distributed in the hope that it will be useful, |
|---|
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 13 | GNU General Public License for more details. |
|---|
| 14 | |
|---|
| 15 | You should have received a copy of the GNU General Public License |
|---|
| 16 | along with this program; if not, write to the Free Software |
|---|
| 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|---|
| 18 | */ |
|---|
| 19 | // $Id$ |
|---|
| 20 | /* (C) 2002 POWERDNS.COM BV */ |
|---|
| 21 | #ifndef DNS_HH |
|---|
| 22 | #define DNS_HH |
|---|
| 23 | #include <boost/multi_index_container.hpp> |
|---|
| 24 | #include <boost/multi_index/ordered_index.hpp> |
|---|
| 25 | #include <boost/tuple/tuple_comparison.hpp> |
|---|
| 26 | #include <boost/multi_index/key_extractors.hpp> |
|---|
| 27 | #include <boost/multi_index/sequenced_index.hpp> |
|---|
| 28 | #include "utility.hh" |
|---|
| 29 | #include "qtype.hh" |
|---|
| 30 | #include <time.h> |
|---|
| 31 | #include <sys/types.h> |
|---|
| 32 | class DNSBackend; |
|---|
| 33 | |
|---|
| 34 | struct SOAData |
|---|
| 35 | { |
|---|
| 36 | string qname; |
|---|
| 37 | string nameserver; |
|---|
| 38 | string hostmaster; |
|---|
| 39 | uint32_t ttl; |
|---|
| 40 | uint32_t serial; |
|---|
| 41 | uint32_t refresh; |
|---|
| 42 | uint32_t retry; |
|---|
| 43 | uint32_t expire; |
|---|
| 44 | uint32_t default_ttl; |
|---|
| 45 | int domain_id; |
|---|
| 46 | DNSBackend *db; |
|---|
| 47 | }; |
|---|
| 48 | |
|---|
| 49 | |
|---|
| 50 | class RCode |
|---|
| 51 | { |
|---|
| 52 | public: |
|---|
| 53 | enum rcodes_ { NoError=0, FormErr=1, ServFail=2, NXDomain=3, NotImp=4, Refused=5 }; |
|---|
| 54 | }; |
|---|
| 55 | |
|---|
| 56 | class Opcode |
|---|
| 57 | { |
|---|
| 58 | public: |
|---|
| 59 | enum { Query=0, IQuery=1, Status=2, Notify=4, Update=5 }; |
|---|
| 60 | }; |
|---|
| 61 | |
|---|
| 62 | //! This class represents a resource record |
|---|
| 63 | class DNSResourceRecord |
|---|
| 64 | { |
|---|
| 65 | public: |
|---|
| 66 | DNSResourceRecord() : qclass(1), priority(0), d_place(ANSWER) {}; |
|---|
| 67 | ~DNSResourceRecord(){}; |
|---|
| 68 | |
|---|
| 69 | string serialize() const; |
|---|
| 70 | int unSerialize(const string &str); |
|---|
| 71 | |
|---|
| 72 | // data |
|---|
| 73 | |
|---|
| 74 | QType qtype; //!< qtype of this record, ie A, CNAME, MX etc |
|---|
| 75 | uint16_t qclass; //!< class of this record |
|---|
| 76 | string qname; //!< the name of this record, for example: www.powerdns.com |
|---|
| 77 | string wildcardname; |
|---|
| 78 | string content; //!< what this record points to. Example: 10.1.2.3 |
|---|
| 79 | uint16_t priority; //!< For qtype's that support a priority or preference. Currently only MX |
|---|
| 80 | uint32_t ttl; //!< Time To Live of this record |
|---|
| 81 | int domain_id; //!< If a backend implements this, the domain_id of the zone this record is in |
|---|
| 82 | time_t last_modified; //!< For autocalculating SOA serial numbers - the backend needs to fill this in |
|---|
| 83 | enum Place {QUESTION=0, ANSWER=1, AUTHORITY=2, ADDITIONAL=3}; //!< Type describing the positioning of a DNSResourceRecord within, say, a DNSPacket |
|---|
| 84 | Place d_place; //!< This specifies where a record goes within the packet |
|---|
| 85 | |
|---|
| 86 | bool auth; |
|---|
| 87 | |
|---|
| 88 | bool operator<(const DNSResourceRecord &b) const |
|---|
| 89 | { |
|---|
| 90 | if(qname < b.qname) |
|---|
| 91 | return true; |
|---|
| 92 | if(qname == b.qname) |
|---|
| 93 | return(content < b.content); |
|---|
| 94 | return false; |
|---|
| 95 | } |
|---|
| 96 | |
|---|
| 97 | private: |
|---|
| 98 | string escape(const string &str) const; |
|---|
| 99 | }; |
|---|
| 100 | |
|---|
| 101 | #ifdef _MSC_VER |
|---|
| 102 | # pragma pack ( push ) |
|---|
| 103 | # pragma pack ( 1 ) |
|---|
| 104 | # define GCCPACKATTRIBUTE |
|---|
| 105 | #else |
|---|
| 106 | # define GCCPACKATTRIBUTE __attribute__((packed)) |
|---|
| 107 | #endif |
|---|
| 108 | struct dnsrecordheader |
|---|
| 109 | { |
|---|
| 110 | uint16_t d_type; |
|---|
| 111 | uint16_t d_class; |
|---|
| 112 | uint32_t d_ttl; |
|---|
| 113 | uint16_t d_clen; |
|---|
| 114 | } GCCPACKATTRIBUTE; |
|---|
| 115 | |
|---|
| 116 | struct EDNS0Record |
|---|
| 117 | { |
|---|
| 118 | uint8_t extRCode, version; |
|---|
| 119 | uint16_t Z; |
|---|
| 120 | } GCCPACKATTRIBUTE; |
|---|
| 121 | #ifdef _MSC_VER |
|---|
| 122 | #pragma pack (pop) |
|---|
| 123 | #endif |
|---|
| 124 | |
|---|
| 125 | enum { |
|---|
| 126 | ns_t_invalid = 0, /* Cookie. */ |
|---|
| 127 | ns_t_a = 1, /* Host address. */ |
|---|
| 128 | ns_t_ns = 2, /* Authoritative server. */ |
|---|
| 129 | ns_t_md = 3, /* Mail destination. */ |
|---|
| 130 | ns_t_mf = 4, /* Mail forwarder. */ |
|---|
| 131 | ns_t_cname = 5, /* Canonical name. */ |
|---|
| 132 | ns_t_soa = 6, /* Start of authority zone. */ |
|---|
| 133 | ns_t_mb = 7, /* Mailbox domain name. */ |
|---|
| 134 | ns_t_mg = 8, /* Mail group member. */ |
|---|
| 135 | ns_t_mr = 9, /* Mail rename name. */ |
|---|
| 136 | ns_t_null = 10, /* Null resource record. */ |
|---|
| 137 | ns_t_wks = 11, /* Well known service. */ |
|---|
| 138 | ns_t_ptr = 12, /* Domain name pointer. */ |
|---|
| 139 | ns_t_hinfo = 13, /* Host information. */ |
|---|
| 140 | ns_t_minfo = 14, /* Mailbox information. */ |
|---|
| 141 | ns_t_mx = 15, /* Mail routing information. */ |
|---|
| 142 | ns_t_txt = 16, /* Text strings. */ |
|---|
| 143 | ns_t_rp = 17, /* Responsible person. */ |
|---|
| 144 | ns_t_afsdb = 18, /* AFS cell database. */ |
|---|
| 145 | ns_t_x25 = 19, /* X_25 calling address. */ |
|---|
| 146 | ns_t_isdn = 20, /* ISDN calling address. */ |
|---|
| 147 | ns_t_rt = 21, /* Router. */ |
|---|
| 148 | ns_t_nsap = 22, /* NSAP address. */ |
|---|
| 149 | ns_t_nsap_ptr = 23, /* Reverse NSAP lookup (deprecated). */ |
|---|
| 150 | ns_t_sig = 24, /* Security signature. */ |
|---|
| 151 | ns_t_key = 25, /* Security key. */ |
|---|
| 152 | ns_t_px = 26, /* X.400 mail mapping. */ |
|---|
| 153 | ns_t_gpos = 27, /* Geographical position (withdrawn). */ |
|---|
| 154 | ns_t_aaaa = 28, /* Ip6 Address. */ |
|---|
| 155 | ns_t_loc = 29, /* Location Information. */ |
|---|
| 156 | ns_t_nxt = 30, /* Next domain (security). */ |
|---|
| 157 | ns_t_eid = 31, /* Endpoint identifier. */ |
|---|
| 158 | ns_t_nimloc = 32, /* Nimrod Locator. */ |
|---|
| 159 | ns_t_srv = 33, /* Server Selection. */ |
|---|
| 160 | ns_t_atma = 34, /* ATM Address */ |
|---|
| 161 | ns_t_naptr = 35, /* Naming Authority PoinTeR */ |
|---|
| 162 | ns_t_kx = 36, /* Key Exchange */ |
|---|
| 163 | ns_t_cert = 37, /* Certification record */ |
|---|
| 164 | ns_t_a6 = 38, /* IPv6 address (deprecates AAAA) */ |
|---|
| 165 | ns_t_dname = 39, /* Non-terminal DNAME (for IPv6) */ |
|---|
| 166 | ns_t_sink = 40, /* Kitchen sink (experimentatl) */ |
|---|
| 167 | ns_t_opt = 41, /* EDNS0 option (meta-RR) */ |
|---|
| 168 | ns_t_tsig = 250, /* Transaction signature. */ |
|---|
| 169 | ns_t_ixfr = 251, /* Incremental zone transfer. */ |
|---|
| 170 | ns_t_axfr = 252, /* Transfer zone of authority. */ |
|---|
| 171 | ns_t_mailb = 253, /* Transfer mailbox records. */ |
|---|
| 172 | ns_t_maila = 254, /* Transfer mail agent records. */ |
|---|
| 173 | ns_t_any = 255, /* Wildcard match. */ |
|---|
| 174 | }; |
|---|
| 175 | |
|---|
| 176 | #ifdef WIN32 |
|---|
| 177 | #define BYTE_ORDER 1 |
|---|
| 178 | #define LITTLE_ENDIAN 1 |
|---|
| 179 | #elif __FreeBSD__ || __APPLE__ |
|---|
| 180 | #include <machine/endian.h> |
|---|
| 181 | #elif __linux__ |
|---|
| 182 | # include <endian.h> |
|---|
| 183 | |
|---|
| 184 | #else // with thanks to <arpa/nameser.h> |
|---|
| 185 | |
|---|
| 186 | # define LITTLE_ENDIAN 1234 /* least-significant byte first (vax, pc) */ |
|---|
| 187 | # define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */ |
|---|
| 188 | # define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp) */ |
|---|
| 189 | |
|---|
| 190 | #if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \ |
|---|
| 191 | defined(__i386) || defined(__ia64) || defined(__amd64) || \ |
|---|
| 192 | defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \ |
|---|
| 193 | defined(__alpha__) || defined(__alpha) || \ |
|---|
| 194 | (defined(__Lynx__) && defined(__x86__)) |
|---|
| 195 | # define BYTE_ORDER LITTLE_ENDIAN |
|---|
| 196 | #endif |
|---|
| 197 | |
|---|
| 198 | #if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \ |
|---|
| 199 | defined(__sparc) || \ |
|---|
| 200 | defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \ |
|---|
| 201 | defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\ |
|---|
| 202 | defined(apollo) || defined(__convex__) || defined(_CRAY) || \ |
|---|
| 203 | defined(__hppa) || defined(__hp9000) || \ |
|---|
| 204 | defined(__hp9000s300) || defined(__hp9000s700) || \ |
|---|
| 205 | defined(__hp3000s900) || defined(MPE) || \ |
|---|
| 206 | defined(BIT_ZERO_ON_LEFT) || defined(m68k) || \ |
|---|
| 207 | (defined(__Lynx__) && \ |
|---|
| 208 | (defined(__68k__) || defined(__sparc__) || defined(__powerpc__))) |
|---|
| 209 | # define BYTE_ORDER BIG_ENDIAN |
|---|
| 210 | #endif |
|---|
| 211 | |
|---|
| 212 | #endif |
|---|
| 213 | |
|---|
| 214 | struct dnsheader { |
|---|
| 215 | unsigned id :16; /* query identification number */ |
|---|
| 216 | #if BYTE_ORDER == BIG_ENDIAN |
|---|
| 217 | /* fields in third byte */ |
|---|
| 218 | unsigned qr: 1; /* response flag */ |
|---|
| 219 | unsigned opcode: 4; /* purpose of message */ |
|---|
| 220 | unsigned aa: 1; /* authoritive answer */ |
|---|
| 221 | unsigned tc: 1; /* truncated message */ |
|---|
| 222 | unsigned rd: 1; /* recursion desired */ |
|---|
| 223 | /* fields in fourth byte */ |
|---|
| 224 | unsigned ra: 1; /* recursion available */ |
|---|
| 225 | unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */ |
|---|
| 226 | unsigned ad: 1; /* authentic data from named */ |
|---|
| 227 | unsigned cd: 1; /* checking disabled by resolver */ |
|---|
| 228 | unsigned rcode :4; /* response code */ |
|---|
| 229 | #endif |
|---|
| 230 | #if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN |
|---|
| 231 | /* fields in third byte */ |
|---|
| 232 | unsigned rd :1; /* recursion desired */ |
|---|
| 233 | unsigned tc :1; /* truncated message */ |
|---|
| 234 | unsigned aa :1; /* authoritive answer */ |
|---|
| 235 | unsigned opcode :4; /* purpose of message */ |
|---|
| 236 | unsigned qr :1; /* response flag */ |
|---|
| 237 | /* fields in fourth byte */ |
|---|
| 238 | unsigned rcode :4; /* response code */ |
|---|
| 239 | unsigned cd: 1; /* checking disabled by resolver */ |
|---|
| 240 | unsigned ad: 1; /* authentic data from named */ |
|---|
| 241 | unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */ |
|---|
| 242 | unsigned ra :1; /* recursion available */ |
|---|
| 243 | #endif |
|---|
| 244 | /* remaining bytes */ |
|---|
| 245 | unsigned qdcount :16; /* number of question entries */ |
|---|
| 246 | unsigned ancount :16; /* number of answer entries */ |
|---|
| 247 | unsigned nscount :16; /* number of authority entries */ |
|---|
| 248 | unsigned arcount :16; /* number of resource entries */ |
|---|
| 249 | }; |
|---|
| 250 | |
|---|
| 251 | |
|---|
| 252 | #define L theL() |
|---|
| 253 | extern time_t s_starttime; |
|---|
| 254 | std::string questionExpand(const char* packet, uint16_t len, uint16_t& type); |
|---|
| 255 | bool dnspacketLessThan(const std::string& a, const std::string& b); |
|---|
| 256 | #endif |
|---|