2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
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.
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
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #ifndef PDNS_DNSRECORDS_HH
23 #define PDNS_DNSRECORDS_HH
25 #include "dnsparser.hh"
26 #include "dnswriter.hh"
27 #include "rcpgenerator.hh"
30 #include "namespaces.hh"
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(bool noDot=false) const override; \
39 void toPacket(DNSPacketWriter& pw) override; \
40 uint16_t getType() const override { return QType::RNAME; } \
41 template<class Convertor> void xfrPacket(Convertor& conv, bool noDot=false);
43 class NAPTRRecordContent : public DNSRecordContent
46 NAPTRRecordContent(uint16_t order, uint16_t preference, string flags, string services, string regexp, DNSName replacement);
48 includeboilerplate(NAPTR);
49 template<class Convertor> void xfrRecordContent(Convertor& conv);
51 uint16_t d_order, d_preference;
52 string d_flags, d_services, d_regexp;
53 DNSName d_replacement;
57 class ARecordContent : public DNSRecordContent
60 explicit ARecordContent(const ComboAddress& ca);
61 explicit ARecordContent(uint32_t ip);
62 includeboilerplate(A);
63 void doRecordCheck(const DNSRecord& dr);
64 ComboAddress getCA(int port=0) const;
65 bool operator==(const DNSRecordContent& rhs) const override
67 if(typeid(*this) != typeid(rhs))
69 return d_ip == dynamic_cast<const ARecordContent&>(rhs).d_ip;
75 class AAAARecordContent : public DNSRecordContent
78 AAAARecordContent(std::string &val);
79 explicit AAAARecordContent(const ComboAddress& ca);
80 includeboilerplate(AAAA);
81 ComboAddress getCA(int port=0) const;
82 bool operator==(const DNSRecordContent& rhs) const override
84 if(typeid(*this) != typeid(rhs))
86 return d_ip6 == dynamic_cast<const decltype(this)>(&rhs)->d_ip6;
89 string d_ip6; // why??
92 class MXRecordContent : public DNSRecordContent
95 MXRecordContent(uint16_t preference, const DNSName& mxname);
97 includeboilerplate(MX)
99 uint16_t d_preference;
102 bool operator==(const DNSRecordContent& rhs) const override
104 if(typeid(*this) != typeid(rhs))
106 auto rrhs =dynamic_cast<const decltype(this)>(&rhs);
107 return std::tie(d_preference, d_mxname) == std::tie(rrhs->d_preference, rrhs->d_mxname);
112 class KXRecordContent : public DNSRecordContent
115 KXRecordContent(uint16_t preference, const DNSName& exchanger);
117 includeboilerplate(KX)
120 uint16_t d_preference;
124 class IPSECKEYRecordContent : public DNSRecordContent
127 IPSECKEYRecordContent(uint16_t preference, uint8_t gatewaytype, uint8_t algo, const DNSName& gateway, const string& publickey);
129 includeboilerplate(IPSECKEY)
136 uint8_t d_preference, d_gatewaytype, d_algorithm;
139 class DHCIDRecordContent : public DNSRecordContent
142 includeboilerplate(DHCID)
149 class SRVRecordContent : public DNSRecordContent
152 SRVRecordContent(uint16_t preference, uint16_t weight, uint16_t port, const DNSName& target);
154 includeboilerplate(SRV)
156 uint16_t d_weight, d_port;
158 uint16_t d_preference;
161 class TSIGRecordContent : public DNSRecordContent
164 includeboilerplate(TSIG)
165 TSIGRecordContent() {}
167 uint16_t d_origID{0};
174 // uint16_t d_macSize;
175 uint16_t d_eRcode{0};
176 // uint16_t d_otherLen
180 class TXTRecordContent : public DNSRecordContent
183 includeboilerplate(TXT)
188 class ENTRecordContent : public DNSRecordContent
191 includeboilerplate(ENT)
194 class SPFRecordContent : public DNSRecordContent
197 includeboilerplate(SPF)
204 class NSRecordContent : public DNSRecordContent
207 includeboilerplate(NS)
208 explicit NSRecordContent(const DNSName& content) : d_content(content){}
209 const DNSName& getNS() const { return d_content; }
210 bool operator==(const DNSRecordContent& rhs) const override
212 if(typeid(*this) != typeid(rhs))
214 auto rrhs =dynamic_cast<const decltype(this)>(&rhs);
215 return d_content == rrhs->d_content;
222 class PTRRecordContent : public DNSRecordContent
225 includeboilerplate(PTR)
226 explicit PTRRecordContent(const DNSName& content) : d_content(content){}
231 class CNAMERecordContent : public DNSRecordContent
234 includeboilerplate(CNAME)
235 CNAMERecordContent(const DNSName& content) : d_content(content){}
236 DNSName getTarget() const { return d_content; }
241 class ALIASRecordContent : public DNSRecordContent
244 includeboilerplate(ALIAS)
250 class DNAMERecordContent : public DNSRecordContent
253 includeboilerplate(DNAME)
258 class MRRecordContent : public DNSRecordContent
261 includeboilerplate(MR)
267 class MINFORecordContent : public DNSRecordContent
270 includeboilerplate(MINFO)
277 class OPTRecordContent : public DNSRecordContent
281 includeboilerplate(OPT)
282 void getData(vector<pair<uint16_t, string> > &opts);
288 class HINFORecordContent : public DNSRecordContent
291 includeboilerplate(HINFO)
294 string d_cpu, d_host;
297 class RPRecordContent : public DNSRecordContent
300 includeboilerplate(RP)
303 DNSName d_mbox, d_info;
307 class DNSKEYRecordContent : public DNSRecordContent
310 DNSKEYRecordContent();
311 includeboilerplate(DNSKEY)
312 uint16_t getTag() const;
316 uint8_t d_protocol{0};
317 uint8_t d_algorithm{0};
319 bool operator<(const DNSKEYRecordContent& rhs) const
321 return tie(d_flags, d_protocol, d_algorithm, d_key) <
322 tie(rhs.d_flags, rhs.d_protocol, rhs.d_algorithm, rhs.d_key);
326 class CDNSKEYRecordContent : public DNSRecordContent
329 CDNSKEYRecordContent();
330 includeboilerplate(CDNSKEY)
334 uint8_t d_protocol{0};
335 uint8_t d_algorithm{0};
339 class DSRecordContent : public DNSRecordContent
343 bool operator==(const DNSRecordContent& rhs) const override
345 if(typeid(*this) != typeid(rhs))
347 auto rrhs =dynamic_cast<const decltype(this)>(&rhs);
348 return tie(d_tag, d_algorithm, d_digesttype, d_digest) ==
349 tie(rrhs->d_tag, rrhs->d_algorithm, rrhs->d_digesttype, rrhs->d_digest);
351 bool operator<(const DSRecordContent& rhs) const
353 return tie(d_tag, d_algorithm, d_digesttype, d_digest) <
354 tie(rhs.d_tag, rhs.d_algorithm, rhs.d_digesttype, rhs.d_digest);
357 includeboilerplate(DS)
360 uint8_t d_algorithm{0}, d_digesttype{0};
364 class CDSRecordContent : public DNSRecordContent
368 includeboilerplate(CDS)
371 uint8_t d_algorithm{0}, d_digesttype{0};
375 class DLVRecordContent : public DNSRecordContent
379 includeboilerplate(DLV)
382 uint8_t d_algorithm{0}, d_digesttype{0};
387 class SSHFPRecordContent : public DNSRecordContent
390 includeboilerplate(SSHFP)
393 uint8_t d_algorithm, d_fptype;
394 string d_fingerprint;
397 class KEYRecordContent : public DNSRecordContent
400 includeboilerplate(KEY)
404 uint8_t d_protocol, d_algorithm;
405 string d_certificate;
408 class AFSDBRecordContent : public DNSRecordContent
411 includeboilerplate(AFSDB)
419 class CERTRecordContent : public DNSRecordContent
422 includeboilerplate(CERT)
425 uint16_t d_type, d_tag;
426 string d_certificate;
430 class TLSARecordContent : public DNSRecordContent
433 includeboilerplate(TLSA)
436 uint8_t d_certusage, d_selector, d_matchtype;
440 class SMIMEARecordContent : public DNSRecordContent
443 includeboilerplate(SMIMEA)
446 uint8_t d_certusage, d_selector, d_matchtype;
450 class OPENPGPKEYRecordContent : public DNSRecordContent
453 includeboilerplate(OPENPGPKEY)
460 class RRSIGRecordContent : public DNSRecordContent
463 RRSIGRecordContent();
464 includeboilerplate(RRSIG)
470 uint32_t d_originalttl{0}, d_sigexpire{0}, d_siginception{0};
471 uint8_t d_algorithm{0}, d_labels{0};
485 class RKEYRecordContent : public DNSRecordContent
489 includeboilerplate(RKEY)
491 uint8_t d_protocol{0}, d_algorithm{0};
495 class SOARecordContent : public DNSRecordContent
498 includeboilerplate(SOA)
499 SOARecordContent(const DNSName& mname, const DNSName& rname, const struct soatimes& st);
501 struct soatimes d_st;
506 class NSECRecordContent : public DNSRecordContent
509 static void report(void);
512 NSECRecordContent(const string& content, const string& zone=""); //FIXME400: DNSName& zone?
514 static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
515 static DNSRecordContent* make(const string& content);
516 string getZoneRepresentation(bool noDot=false) const override;
517 void toPacket(DNSPacketWriter& pw) override;
518 uint16_t getType() const override
523 std::set<uint16_t> d_set;
527 class NSEC3RecordContent : public DNSRecordContent
530 static void report(void);
533 NSEC3RecordContent(const string& content, const string& zone=""); //FIXME400: DNSName& zone?
535 static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
536 static DNSRecordContent* make(const string& content);
537 string getZoneRepresentation(bool noDot=false) const override;
538 void toPacket(DNSPacketWriter& pw) override;
540 uint8_t d_algorithm{0}, d_flags{0};
541 uint16_t d_iterations{0};
544 std::set<uint16_t> d_set;
546 uint16_t getType() const override
556 class NSEC3PARAMRecordContent : public DNSRecordContent
559 static void report(void);
560 NSEC3PARAMRecordContent()
562 NSEC3PARAMRecordContent(const string& content, const string& zone=""); // FIXME400: DNSName& zone?
564 static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
565 static DNSRecordContent* make(const string& content);
566 string getZoneRepresentation(bool noDot=false) const override;
567 void toPacket(DNSPacketWriter& pw) override;
569 uint16_t getType() const override
571 return QType::NSEC3PARAM;
575 uint8_t d_algorithm{0}, d_flags{0};
576 uint16_t d_iterations{0};
581 class LOCRecordContent : public DNSRecordContent
584 static void report(void);
587 LOCRecordContent(const string& content, const string& zone="");
589 static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
590 static DNSRecordContent* make(const string& content);
591 string getZoneRepresentation(bool noDot=false) const override;
592 void toPacket(DNSPacketWriter& pw) override;
594 uint8_t d_version{0}, d_size{0}, d_horizpre{0}, d_vertpre{0};
595 uint32_t d_latitude{0}, d_longitude{0}, d_altitude{0};
596 uint16_t getType() const override
605 class WKSRecordContent : public DNSRecordContent
608 static void report(void);
611 WKSRecordContent(const string& content, const string& zone=""); // FIXME400: DNSName& zone?
613 static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
614 static DNSRecordContent* make(const string& content);
615 string getZoneRepresentation(bool noDot=false) const override;
616 void toPacket(DNSPacketWriter& pw) override;
619 std::bitset<65535> d_services;
623 class EUI48RecordContent : public DNSRecordContent
626 EUI48RecordContent() {};
627 static void report(void);
628 static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
629 static DNSRecordContent* make(const string& zone); // FIXME400: DNSName& zone?
630 string getZoneRepresentation(bool noDot=false) const override;
631 void toPacket(DNSPacketWriter& pw) override;
632 uint16_t getType() const override { return QType::EUI48; }
634 // storage for the bytes
638 class EUI64RecordContent : public DNSRecordContent
641 EUI64RecordContent() {};
642 static void report(void);
643 static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
644 static DNSRecordContent* make(const string& zone); // FIXME400: DNSName& zone?
645 string getZoneRepresentation(bool noDot=false) const override;
646 void toPacket(DNSPacketWriter& pw) override;
647 uint16_t getType() const override { return QType::EUI64; }
649 // storage for the bytes
653 class TKEYRecordContent : public DNSRecordContent
657 includeboilerplate(TKEY)
659 // storage for the bytes
660 uint16_t d_othersize{0};
662 uint32_t d_inception{0};
663 uint32_t d_expiration{0};
670 uint16_t d_keysize{0};
674 class URIRecordContent : public DNSRecordContent {
676 includeboilerplate(URI)
678 uint16_t d_priority, d_weight;
682 class CAARecordContent : public DNSRecordContent {
684 includeboilerplate(CAA)
687 string d_tag, d_value;
690 #define boilerplate(RNAME, RTYPE) \
691 RNAME##RecordContent::DNSRecordContent* RNAME##RecordContent::make(const DNSRecord& dr, PacketReader& pr) \
693 return new RNAME##RecordContent(dr, pr); \
696 RNAME##RecordContent::RNAME##RecordContent(const DNSRecord& dr, PacketReader& pr) \
702 RNAME##RecordContent::DNSRecordContent* RNAME##RecordContent::make(const string& zonedata) \
704 return new RNAME##RecordContent(zonedata); \
707 void RNAME##RecordContent::toPacket(DNSPacketWriter& pw) \
709 this->xfrPacket(pw); \
712 void RNAME##RecordContent::report(void) \
714 regist(1, RTYPE, &RNAME##RecordContent::make, &RNAME##RecordContent::make, #RNAME); \
715 regist(254, RTYPE, &RNAME##RecordContent::make, &RNAME##RecordContent::make, #RNAME); \
717 void RNAME##RecordContent::unreport(void) \
719 unregist(1, RTYPE); \
720 unregist(254, RTYPE); \
723 RNAME##RecordContent::RNAME##RecordContent(const string& zoneData) \
726 RecordTextReader rtr(zoneData); \
729 catch(RecordTextException& rtr) { \
730 throw MOADNSException("Parsing record content (try 'pdnsutil check-zone'): "+string(rtr.what())); \
734 string RNAME##RecordContent::getZoneRepresentation(bool noDot) const \
737 RecordTextWriter rtw(ret, noDot); \
738 const_cast<RNAME##RecordContent*>(this)->xfrPacket(rtw); \
743 #define boilerplate_conv(RNAME, TYPE, CONV) \
744 boilerplate(RNAME, TYPE) \
745 template<class Convertor> \
746 void RNAME##RecordContent::xfrPacket(Convertor& conv, bool noDot) \
749 if (conv.eof() == false) throw MOADNSException("All data was not consumed"); \
754 enum zFlags { DNSSECOK=32768 };
755 vector<pair<uint16_t, string> > d_options;
756 uint16_t d_packetsize{0};
758 uint8_t d_extRCode, d_version;
760 //! Convenience function that fills out EDNS0 options, and returns true if there are any
763 bool getEDNSOpts(const MOADNSParser& mdp, EDNSOpts* eo);
764 DNSRecord makeOpt(int udpsize, int extRCode, int Z);
765 void reportBasicTypes();
766 void reportOtherTypes();
767 void reportAllTypes();
768 ComboAddress getAddr(const DNSRecord& dr, uint16_t defport=0);