root/trunk/pdns/pdns/dnsrecords.hh @ 2338

Revision 2338, 15.7 KB (checked in by peter, 2 years ago)

Update DANE/TLSA support to comply with newer drafts. Spotted by James Cloos

Line 
1/*
2    PowerDNS Versatile Database Driven Nameserver
3    Copyright (C) 2005 - 2010  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 as
7    published by the Free Software Foundation
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17*/
18
19#ifndef PDNS_DNSRECORDS_HH
20#define PDNS_DNSRECORDS_HH
21
22#include "dnsparser.hh"
23#include "dnswriter.hh"
24#include "rcpgenerator.hh"
25#include <boost/lexical_cast.hpp>
26#include <set>
27#include <bitset>
28
29#include "namespaces.hh"
30#include "namespaces.hh"
31
32#define includeboilerplate(RNAME)   RNAME##RecordContent(const DNSRecord& dr, PacketReader& pr); \
33  RNAME##RecordContent(const string& zoneData);                                                  \
34  static void report(void);                                                                      \
35  static void unreport(void);                                                                    \
36  static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);                          \
37  static DNSRecordContent* make(const string& zonedata);                                         \
38  string getZoneRepresentation() const;                                                          \
39  void toPacket(DNSPacketWriter& pw);                                                            \
40  template<class Convertor> void xfrPacket(Convertor& conv);                             
41
42class NAPTRRecordContent : public DNSRecordContent
43{
44public:
45  NAPTRRecordContent(uint16_t order, uint16_t preference, string flags, string services, string regexp, string replacement);
46
47  includeboilerplate(NAPTR);
48  template<class Convertor> void xfrRecordContent(Convertor& conv);
49private:
50  uint16_t d_order, d_preference;
51  string d_flags, d_services, d_regexp, d_replacement;
52};
53
54
55class ARecordContent : public DNSRecordContent
56{
57public:
58  explicit ARecordContent(uint32_t ip);
59  includeboilerplate(A);
60  void doRecordCheck(const DNSRecord& dr);
61  uint32_t getIP() const;
62
63private:
64  uint32_t d_ip;
65};
66
67class MXRecordContent : public DNSRecordContent
68{
69public:
70  MXRecordContent(uint16_t preference, const string& mxname);
71
72  includeboilerplate(MX)
73
74private:
75  uint16_t d_preference;
76  string d_mxname;
77};
78
79class KXRecordContent : public DNSRecordContent
80{
81public:
82  KXRecordContent(uint16_t preference, const string& exchanger);
83
84  includeboilerplate(KX)
85
86private:
87  uint16_t d_preference;
88  string d_exchanger;
89};
90
91class IPSECKEYRecordContent : public DNSRecordContent
92{
93public:
94  IPSECKEYRecordContent(uint16_t preference, uint8_t gatewaytype, uint8_t algo, const std::string& gateway, const std::string &publickey);
95
96  includeboilerplate(IPSECKEY)
97
98private:
99  uint8_t d_preference, d_gatewaytype, d_algorithm;
100  string d_gateway, d_publickey;
101};
102
103class DHCIDRecordContent : public DNSRecordContent
104{
105public:
106  includeboilerplate(DHCID)
107
108private:
109  string d_content;
110};
111
112
113class SRVRecordContent : public DNSRecordContent
114{
115public:
116  SRVRecordContent(uint16_t preference, uint16_t weight, uint16_t port, const string& target);
117
118  includeboilerplate(SRV)
119
120private:
121  uint16_t d_preference, d_weight, d_port;
122  string d_target;
123};
124
125class TSIGRecordContent : public DNSRecordContent
126{
127public:
128  includeboilerplate(TSIG)
129  TSIGRecordContent() : DNSRecordContent(QType::TSIG) {}
130
131  string d_algoName;
132  uint64_t d_time; // 48 bits
133  uint16_t d_fudge;
134  //  uint16_t d_macSize;
135  string d_mac;
136  uint16_t d_origID;
137  uint16_t d_eRcode;
138  // uint16_t d_otherLen
139  string d_otherData;
140};
141
142
143class TXTRecordContent : public DNSRecordContent
144{
145public:
146  includeboilerplate(TXT)
147
148private:
149  string d_text;
150};
151
152class SPFRecordContent : public DNSRecordContent
153{
154public:
155  includeboilerplate(SPF)
156
157private:
158  string d_text;
159};
160
161
162class NSRecordContent : public DNSRecordContent
163{
164public:
165  includeboilerplate(NS)
166
167private:
168  string d_content;
169};
170
171class PTRRecordContent : public DNSRecordContent
172{
173public:
174  includeboilerplate(PTR)
175
176private:
177  string d_content;
178};
179
180class CNAMERecordContent : public DNSRecordContent
181{
182public:
183  includeboilerplate(CNAME)
184
185private:
186  string d_content;
187};
188
189class MRRecordContent : public DNSRecordContent
190{
191public:
192  includeboilerplate(MR)
193
194private:
195  string d_alias;
196};
197
198
199class OPTRecordContent : public DNSRecordContent
200{
201public:
202  includeboilerplate(OPT)
203  void getData(vector<pair<uint16_t, string> > &opts);
204private:
205  string d_data;
206};
207
208
209class HINFORecordContent : public DNSRecordContent
210{
211public:
212  includeboilerplate(HINFO)
213
214private:
215  string d_cpu, d_host;
216};
217
218class RPRecordContent : public DNSRecordContent
219{
220public:
221  includeboilerplate(RP)
222
223private:
224  string d_mbox, d_info;
225};
226
227
228class DNSKEYRecordContent : public DNSRecordContent
229{
230public:
231  DNSKEYRecordContent();
232  includeboilerplate(DNSKEY)
233  uint16_t getTag();
234
235  uint16_t d_flags;
236  uint8_t d_protocol;
237  uint8_t d_algorithm;
238  string d_key;
239};
240
241class DSRecordContent : public DNSRecordContent
242{
243public:
244  DSRecordContent();
245  includeboilerplate(DS)
246
247  uint16_t d_tag;
248  uint8_t d_algorithm, d_digesttype;
249  string d_digest;
250};
251
252class DLVRecordContent : public DNSRecordContent
253{
254public:
255  DLVRecordContent();
256  includeboilerplate(DLV)
257
258  uint16_t d_tag;
259  uint8_t d_algorithm, d_digesttype;
260  string d_digest;
261};
262
263
264class SSHFPRecordContent : public DNSRecordContent
265{
266public:
267  includeboilerplate(SSHFP)
268
269private:
270  uint8_t d_algorithm, d_fptype;
271  string d_fingerprint;
272};
273
274class KEYRecordContent : public DNSRecordContent
275{
276public:
277  includeboilerplate(KEY)
278
279private:
280  uint16_t d_flags;
281  uint8_t d_protocol, d_algorithm;
282  string d_certificate;
283};
284
285class AFSDBRecordContent : public DNSRecordContent
286{
287public:
288  includeboilerplate(AFSDB)
289
290private:
291  uint16_t d_subtype;
292  string d_hostname;
293};
294
295
296class CERTRecordContent : public DNSRecordContent
297{
298public:
299  includeboilerplate(CERT)
300
301private:
302  uint16_t d_type, d_tag;
303  uint8_t d_algorithm;
304  string d_certificate;
305};
306
307class TLSARecordContent : public DNSRecordContent
308{
309public:
310  includeboilerplate(TLSA)
311
312private:
313  uint8_t d_certusage, d_selector, d_matchtype;
314  string d_cert;
315};
316
317
318class RRSIGRecordContent : public DNSRecordContent
319{
320public:
321  RRSIGRecordContent(); 
322  includeboilerplate(RRSIG)
323
324  uint16_t d_type;
325  uint8_t d_algorithm, d_labels;
326  uint32_t d_originalttl, d_sigexpire, d_siginception;
327  uint16_t d_tag;
328  string d_signer, d_signature;
329};
330
331
332
333//namespace {
334  struct soatimes
335  {
336    uint32_t serial;
337    uint32_t refresh;
338    uint32_t retry;
339    uint32_t expire;
340    uint32_t minimum;
341  };
342//}
343
344
345class SOARecordContent : public DNSRecordContent
346{
347public:
348  includeboilerplate(SOA)
349  SOARecordContent(const string& mname, const string& rname, const struct soatimes& st);
350
351  string d_mname;
352  string d_rname;
353  struct soatimes d_st;
354};
355
356class NSECRecordContent : public DNSRecordContent
357{
358public:
359  static void report(void);
360  NSECRecordContent() : DNSRecordContent(47)
361  {}
362  NSECRecordContent(const string& content, const string& zone="");
363
364  static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
365  static DNSRecordContent* make(const string& content);
366  string getZoneRepresentation() const;
367  void toPacket(DNSPacketWriter& pw);
368  string d_next;
369  std::set<uint16_t> d_set;
370private:
371};
372
373class NSEC3RecordContent : public DNSRecordContent
374{
375public:
376  static void report(void);
377  NSEC3RecordContent() : DNSRecordContent(50)
378  {}
379  NSEC3RecordContent(const string& content, const string& zone="");
380
381  static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
382  static DNSRecordContent* make(const string& content);
383  string getZoneRepresentation() const;
384  void toPacket(DNSPacketWriter& pw);
385
386  uint8_t d_algorithm, d_flags;
387  uint16_t d_iterations;
388  uint8_t d_saltlength;
389  string d_salt;
390  uint8_t d_nexthashlength;
391  string d_nexthash;
392  std::set<uint16_t> d_set;
393
394private:
395};
396
397
398class NSEC3PARAMRecordContent : public DNSRecordContent
399{
400public:
401  static void report(void);
402  NSEC3PARAMRecordContent() : DNSRecordContent(51)
403  {}
404  NSEC3PARAMRecordContent(const string& content, const string& zone="");
405
406  static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
407  static DNSRecordContent* make(const string& content);
408  string getZoneRepresentation() const;
409  void toPacket(DNSPacketWriter& pw);
410
411
412  uint8_t d_algorithm, d_flags;
413  uint16_t d_iterations;
414  uint8_t d_saltlength;
415  string d_salt;
416};
417
418
419class LOCRecordContent : public DNSRecordContent
420{
421public:
422  static void report(void);
423  LOCRecordContent() : DNSRecordContent(ns_t_loc)
424  {}
425  LOCRecordContent(const string& content, const string& zone="");
426
427  static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
428  static DNSRecordContent* make(const string& content);
429  string getZoneRepresentation() const;
430  void toPacket(DNSPacketWriter& pw);
431
432  uint8_t d_version, d_size, d_horizpre, d_vertpre;
433  uint32_t d_latitude, d_longitude, d_altitude;
434 
435private:
436};
437
438
439class WKSRecordContent : public DNSRecordContent
440{
441public:
442  static void report(void);
443  WKSRecordContent() : DNSRecordContent(ns_t_wks)
444  {}
445  WKSRecordContent(const string& content, const string& zone="");
446
447  static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
448  static DNSRecordContent* make(const string& content);
449  string getZoneRepresentation() const;
450  void toPacket(DNSPacketWriter& pw);
451
452  uint32_t d_ip;
453  std::bitset<65535> d_services;
454private:
455};
456
457
458class URLRecordContent : public DNSRecordContent // Fake, 'fancy record' with type 256
459{
460public:
461  includeboilerplate(URL)
462private:
463  string d_url;
464};
465
466class MBOXFWRecordContent : public DNSRecordContent // Fake, 'fancy record' with type 256
467{
468public:
469  includeboilerplate(MBOXFW)
470private:
471  string d_mboxfw;
472};
473
474
475#define boilerplate(RNAME, RTYPE)                                                                         \
476RNAME##RecordContent::DNSRecordContent* RNAME##RecordContent::make(const DNSRecord& dr, PacketReader& pr) \
477{                                                                                                  \
478  return new RNAME##RecordContent(dr, pr);                                                         \
479}                                                                                                  \
480                                                                                                   \
481RNAME##RecordContent::RNAME##RecordContent(const DNSRecord& dr, PacketReader& pr) : DNSRecordContent(RTYPE) \
482{                                                                                                  \
483  doRecordCheck(dr);                                                                               \
484  xfrPacket(pr);                                                                                   \
485}                                                                                                  \
486                                                                                                   \
487RNAME##RecordContent::DNSRecordContent* RNAME##RecordContent::make(const string& zonedata)         \
488{                                                                                                  \
489  return new RNAME##RecordContent(zonedata);                                                       \
490}                                                                                                  \
491                                                                                                   \
492void RNAME##RecordContent::toPacket(DNSPacketWriter& pw)                                           \
493{                                                                                                  \
494  this->xfrPacket(pw);                                                                             \
495}                                                                                                  \
496                                                                                                   \
497void RNAME##RecordContent::report(void)                                                            \
498{                                                                                                  \
499  regist(1, RTYPE, &RNAME##RecordContent::make, &RNAME##RecordContent::make, #RNAME);              \
500}                                                                                                  \
501void RNAME##RecordContent::unreport(void)                                                          \
502{                                                                                                  \
503  unregist(1, RTYPE);                                                                              \
504}                                                                                                  \
505                                                                                                   \
506RNAME##RecordContent::RNAME##RecordContent(const string& zoneData) : DNSRecordContent(RTYPE)       \
507{                                                                                                  \
508  try {                                                                                            \
509    RecordTextReader rtr(zoneData);                                                                \
510    xfrPacket(rtr);                                                                                \
511  }                                                                                                \
512  catch(RecordTextException& rtr) {                                                                \
513    throw MOADNSException("Parsing record content: "+string(rtr.what()));                          \
514  }                                                                                                \
515}                                                                                                  \
516                                                                                                   \
517string RNAME##RecordContent::getZoneRepresentation() const                                         \
518{                                                                                                  \
519  string ret;                                                                                      \
520  RecordTextWriter rtw(ret);                                                                       \
521  const_cast<RNAME##RecordContent*>(this)->xfrPacket(rtw);                                         \
522  return ret;                                                                                      \
523}                                                                                                 
524                                                                                           
525
526#define boilerplate_conv(RNAME, TYPE, CONV)                       \
527boilerplate(RNAME, TYPE)                                          \
528template<class Convertor>                                         \
529void RNAME##RecordContent::xfrPacket(Convertor& conv)             \
530{                                                                 \
531  CONV;                                                           \
532}                                                                 \
533
534struct EDNSOpts
535{
536  uint16_t d_packetsize;
537  uint8_t d_extRCode, d_version;
538  uint16_t d_Z;
539  vector<pair<uint16_t, string> > d_options;
540  enum zFlags { DNSSECOK=32768 };
541};
542//! Convenience function that fills out EDNS0 options, and returns true if there are any
543
544class MOADNSParser;
545bool getEDNSOpts(const MOADNSParser& mdp, EDNSOpts* eo);
546
547void reportBasicTypes();
548void reportOtherTypes();
549void reportAllTypes();
550void reportFancyTypes();
551
552#endif
Note: See TracBrowser for help on using the browser.