]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dnsrecords.hh
Merge pull request #7326 from jonathaneen/add_type_filter_to_api_search
[thirdparty/pdns.git] / pdns / dnsrecords.hh
1 /*
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 *
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.
8 *
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.
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
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22 #ifndef PDNS_DNSRECORDS_HH
23 #define PDNS_DNSRECORDS_HH
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include "dnsparser.hh"
30 #include "dnswriter.hh"
31 #include "rcpgenerator.hh"
32 #include <set>
33 #include <bitset>
34 #include "namespaces.hh"
35 #include "iputils.hh"
36
37 #define includeboilerplate(RNAME) RNAME##RecordContent(const DNSRecord& dr, PacketReader& pr); \
38 RNAME##RecordContent(const string& zoneData); \
39 static void report(void); \
40 static void unreport(void); \
41 static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr); \
42 static std::shared_ptr<DNSRecordContent> make(const string& zonedata); \
43 string getZoneRepresentation(bool noDot=false) const override; \
44 void toPacket(DNSPacketWriter& pw) override; \
45 uint16_t getType() const override { return QType::RNAME; } \
46 template<class Convertor> void xfrPacket(Convertor& conv, bool noDot=false);
47
48 class NAPTRRecordContent : public DNSRecordContent
49 {
50 public:
51 NAPTRRecordContent(uint16_t order, uint16_t preference, string flags, string services, string regexp, DNSName replacement);
52
53 includeboilerplate(NAPTR)
54 template<class Convertor> void xfrRecordContent(Convertor& conv);
55 private:
56 uint16_t d_order, d_preference;
57 string d_flags, d_services, d_regexp;
58 DNSName d_replacement;
59 };
60
61
62 class ARecordContent : public DNSRecordContent
63 {
64 public:
65 explicit ARecordContent(const ComboAddress& ca);
66 explicit ARecordContent(uint32_t ip);
67 includeboilerplate(A)
68 void doRecordCheck(const DNSRecord& dr);
69 ComboAddress getCA(int port=0) const;
70 bool operator==(const DNSRecordContent& rhs) const override
71 {
72 if(typeid(*this) != typeid(rhs))
73 return false;
74 return d_ip == dynamic_cast<const ARecordContent&>(rhs).d_ip;
75 }
76 private:
77 uint32_t d_ip;
78 };
79
80 class AAAARecordContent : public DNSRecordContent
81 {
82 public:
83 AAAARecordContent(std::string &val);
84 explicit AAAARecordContent(const ComboAddress& ca);
85 includeboilerplate(AAAA)
86 ComboAddress getCA(int port=0) const;
87 bool operator==(const DNSRecordContent& rhs) const override
88 {
89 if(typeid(*this) != typeid(rhs))
90 return false;
91 return d_ip6 == dynamic_cast<const decltype(this)>(&rhs)->d_ip6;
92 }
93 private:
94 string d_ip6; // why??
95 };
96
97 class MXRecordContent : public DNSRecordContent
98 {
99 public:
100 MXRecordContent(uint16_t preference, const DNSName& mxname);
101
102 includeboilerplate(MX)
103
104 uint16_t d_preference;
105 DNSName d_mxname;
106
107 bool operator==(const DNSRecordContent& rhs) const override
108 {
109 if(typeid(*this) != typeid(rhs))
110 return false;
111 auto rrhs =dynamic_cast<const decltype(this)>(&rhs);
112 return std::tie(d_preference, d_mxname) == std::tie(rrhs->d_preference, rrhs->d_mxname);
113 }
114
115 };
116
117 class KXRecordContent : public DNSRecordContent
118 {
119 public:
120 KXRecordContent(uint16_t preference, const DNSName& exchanger);
121
122 includeboilerplate(KX)
123
124 private:
125 uint16_t d_preference;
126 DNSName d_exchanger;
127 };
128
129 class IPSECKEYRecordContent : public DNSRecordContent
130 {
131 public:
132 IPSECKEYRecordContent(uint16_t preference, uint8_t gatewaytype, uint8_t algo, const DNSName& gateway, const string& publickey);
133
134 includeboilerplate(IPSECKEY)
135
136 private:
137 uint32_t d_ip4;
138 DNSName d_gateway;
139 string d_publickey;
140 string d_ip6;
141 uint8_t d_preference, d_gatewaytype, d_algorithm;
142 };
143
144 class DHCIDRecordContent : public DNSRecordContent
145 {
146 public:
147 includeboilerplate(DHCID)
148
149 private:
150 string d_content;
151 };
152
153
154 class SRVRecordContent : public DNSRecordContent
155 {
156 public:
157 SRVRecordContent(uint16_t preference, uint16_t weight, uint16_t port, const DNSName& target);
158
159 includeboilerplate(SRV)
160
161 uint16_t d_weight, d_port;
162 DNSName d_target;
163 uint16_t d_preference;
164 };
165
166 class TSIGRecordContent : public DNSRecordContent
167 {
168 public:
169 includeboilerplate(TSIG)
170 TSIGRecordContent() {}
171
172 uint16_t d_origID{0};
173 uint16_t d_fudge{0};
174
175 DNSName d_algoName;
176 string d_mac;
177 string d_otherData;
178 uint64_t d_time{0};
179 // uint16_t d_macSize;
180 uint16_t d_eRcode{0};
181 // uint16_t d_otherLen
182 };
183
184
185 class TXTRecordContent : public DNSRecordContent
186 {
187 public:
188 includeboilerplate(TXT)
189
190 string d_text;
191 };
192
193 #ifdef HAVE_LUA_RECORDS
194 class LUARecordContent : public DNSRecordContent
195 {
196 public:
197 includeboilerplate(LUA)
198 string getCode() const;
199 uint16_t d_type;
200 string d_code;
201 };
202 #endif
203
204 class ENTRecordContent : public DNSRecordContent
205 {
206 public:
207 includeboilerplate(ENT)
208 };
209
210 class SPFRecordContent : public DNSRecordContent
211 {
212 public:
213 includeboilerplate(SPF)
214 const std::string& getText() const
215 {
216 return d_text;
217 }
218
219 private:
220 string d_text;
221 };
222
223
224 class NSRecordContent : public DNSRecordContent
225 {
226 public:
227 includeboilerplate(NS)
228 explicit NSRecordContent(const DNSName& content) : d_content(content){}
229 const DNSName& getNS() const { return d_content; }
230 bool operator==(const DNSRecordContent& rhs) const override
231 {
232 if(typeid(*this) != typeid(rhs))
233 return false;
234 auto rrhs =dynamic_cast<const decltype(this)>(&rhs);
235 return d_content == rrhs->d_content;
236 }
237
238 private:
239 DNSName d_content;
240 };
241
242 class PTRRecordContent : public DNSRecordContent
243 {
244 public:
245 includeboilerplate(PTR)
246 explicit PTRRecordContent(const DNSName& content) : d_content(content){}
247 const DNSName& getContent() const { return d_content; }
248 private:
249 DNSName d_content;
250 };
251
252 class CNAMERecordContent : public DNSRecordContent
253 {
254 public:
255 includeboilerplate(CNAME)
256 CNAMERecordContent(const DNSName& content) : d_content(content){}
257 DNSName getTarget() const { return d_content; }
258 private:
259 DNSName d_content;
260 };
261
262 class ALIASRecordContent : public DNSRecordContent
263 {
264 public:
265 includeboilerplate(ALIAS)
266
267 DNSName d_content;
268 };
269
270
271 class DNAMERecordContent : public DNSRecordContent
272 {
273 public:
274 includeboilerplate(DNAME)
275 DNSName d_content;
276 };
277
278
279 class MBRecordContent : public DNSRecordContent
280 {
281 public:
282 includeboilerplate(MB)
283
284 private:
285 DNSName d_madname;
286 };
287
288 class MGRecordContent : public DNSRecordContent
289 {
290 public:
291 includeboilerplate(MG)
292
293 private:
294 DNSName d_mgmname;
295 };
296
297 class MRRecordContent : public DNSRecordContent
298 {
299 public:
300 includeboilerplate(MR)
301
302 private:
303 DNSName d_alias;
304 };
305
306 class MINFORecordContent : public DNSRecordContent
307 {
308 public:
309 includeboilerplate(MINFO)
310
311 private:
312 DNSName d_rmailbx;
313 DNSName d_emailbx;
314 };
315
316 class OPTRecordContent : public DNSRecordContent
317 {
318 public:
319 OPTRecordContent(){}
320 includeboilerplate(OPT)
321 void getData(vector<pair<uint16_t, string> > &opts);
322 private:
323 string d_data;
324 };
325
326
327 class HINFORecordContent : public DNSRecordContent
328 {
329 public:
330 includeboilerplate(HINFO)
331
332 private:
333 string d_cpu, d_host;
334 };
335
336 class RPRecordContent : public DNSRecordContent
337 {
338 public:
339 includeboilerplate(RP)
340
341 private:
342 DNSName d_mbox, d_info;
343 };
344
345
346 class DNSKEYRecordContent : public DNSRecordContent
347 {
348 public:
349 DNSKEYRecordContent();
350 includeboilerplate(DNSKEY)
351 uint16_t getTag() const;
352 uint16_t getTag();
353
354 uint16_t d_flags{0};
355 uint8_t d_protocol{0};
356 uint8_t d_algorithm{0};
357 string d_key;
358 bool operator<(const DNSKEYRecordContent& rhs) const
359 {
360 return tie(d_flags, d_protocol, d_algorithm, d_key) <
361 tie(rhs.d_flags, rhs.d_protocol, rhs.d_algorithm, rhs.d_key);
362 }
363 };
364
365 class CDNSKEYRecordContent : public DNSRecordContent
366 {
367 public:
368 CDNSKEYRecordContent();
369 includeboilerplate(CDNSKEY)
370 uint16_t getTag();
371
372 uint16_t d_flags{0};
373 uint8_t d_protocol{0};
374 uint8_t d_algorithm{0};
375 string d_key;
376 };
377
378 class DSRecordContent : public DNSRecordContent
379 {
380 public:
381 DSRecordContent();
382 bool operator==(const DNSRecordContent& rhs) const override
383 {
384 if(typeid(*this) != typeid(rhs))
385 return false;
386 auto rrhs =dynamic_cast<const decltype(this)>(&rhs);
387 return tie(d_tag, d_algorithm, d_digesttype, d_digest) ==
388 tie(rrhs->d_tag, rrhs->d_algorithm, rrhs->d_digesttype, rrhs->d_digest);
389 }
390 bool operator<(const DSRecordContent& rhs) const
391 {
392 return tie(d_tag, d_algorithm, d_digesttype, d_digest) <
393 tie(rhs.d_tag, rhs.d_algorithm, rhs.d_digesttype, rhs.d_digest);
394 }
395
396 includeboilerplate(DS)
397
398 uint16_t d_tag{0};
399 uint8_t d_algorithm{0}, d_digesttype{0};
400 string d_digest;
401 };
402
403 class CDSRecordContent : public DNSRecordContent
404 {
405 public:
406 CDSRecordContent();
407 includeboilerplate(CDS)
408
409 uint16_t d_tag{0};
410 uint8_t d_algorithm{0}, d_digesttype{0};
411 string d_digest;
412 };
413
414 class DLVRecordContent : public DNSRecordContent
415 {
416 public:
417 DLVRecordContent();
418 includeboilerplate(DLV)
419
420 uint16_t d_tag{0};
421 uint8_t d_algorithm{0}, d_digesttype{0};
422 string d_digest;
423 };
424
425
426 class SSHFPRecordContent : public DNSRecordContent
427 {
428 public:
429 includeboilerplate(SSHFP)
430
431 private:
432 uint8_t d_algorithm, d_fptype;
433 string d_fingerprint;
434 };
435
436 class KEYRecordContent : public DNSRecordContent
437 {
438 public:
439 includeboilerplate(KEY)
440
441 private:
442 uint16_t d_flags;
443 uint8_t d_protocol, d_algorithm;
444 string d_certificate;
445 };
446
447 class AFSDBRecordContent : public DNSRecordContent
448 {
449 public:
450 includeboilerplate(AFSDB)
451
452 private:
453 uint16_t d_subtype;
454 DNSName d_hostname;
455 };
456
457
458 class CERTRecordContent : public DNSRecordContent
459 {
460 public:
461 includeboilerplate(CERT)
462
463 private:
464 uint16_t d_type, d_tag;
465 string d_certificate;
466 uint8_t d_algorithm;
467 };
468
469 class TLSARecordContent : public DNSRecordContent
470 {
471 public:
472 includeboilerplate(TLSA)
473
474 private:
475 uint8_t d_certusage, d_selector, d_matchtype;
476 string d_cert;
477 };
478
479 class SMIMEARecordContent : public DNSRecordContent
480 {
481 public:
482 includeboilerplate(SMIMEA)
483
484 private:
485 uint8_t d_certusage, d_selector, d_matchtype;
486 string d_cert;
487 };
488
489 class OPENPGPKEYRecordContent : public DNSRecordContent
490 {
491 public:
492 includeboilerplate(OPENPGPKEY)
493
494 private:
495 string d_keyring;
496 };
497
498
499 class RRSIGRecordContent : public DNSRecordContent
500 {
501 public:
502 RRSIGRecordContent();
503 includeboilerplate(RRSIG)
504
505 uint16_t d_type{0};
506 uint16_t d_tag{0};
507 DNSName d_signer;
508 string d_signature;
509 uint32_t d_originalttl{0}, d_sigexpire{0}, d_siginception{0};
510 uint8_t d_algorithm{0}, d_labels{0};
511 };
512
513 //namespace {
514 struct soatimes
515 {
516 uint32_t serial;
517 uint32_t refresh;
518 uint32_t retry;
519 uint32_t expire;
520 uint32_t minimum;
521 };
522 //}
523
524 class RKEYRecordContent : public DNSRecordContent
525 {
526 public:
527 RKEYRecordContent();
528 includeboilerplate(RKEY)
529 uint16_t d_flags{0};
530 uint8_t d_protocol{0}, d_algorithm{0};
531 string d_key;
532 };
533
534 class SOARecordContent : public DNSRecordContent
535 {
536 public:
537 includeboilerplate(SOA)
538 SOARecordContent(const DNSName& mname, const DNSName& rname, const struct soatimes& st);
539
540 DNSName d_mname;
541 DNSName d_rname;
542 struct soatimes d_st;
543 };
544
545 class NSECBitmap
546 {
547 public:
548 NSECBitmap(): d_bitset(nullptr)
549 {
550 }
551 NSECBitmap(const NSECBitmap& rhs): d_set(rhs.d_set)
552 {
553 if (rhs.d_bitset) {
554 d_bitset = std::unique_ptr<std::bitset<nbTypes>>(new std::bitset<nbTypes>(*(rhs.d_bitset)));
555 }
556 }
557 NSECBitmap& operator=(const NSECBitmap& rhs)
558 {
559 d_set = rhs.d_set;
560
561 if (rhs.d_bitset) {
562 d_bitset = std::unique_ptr<std::bitset<nbTypes>>(new std::bitset<nbTypes>(*(rhs.d_bitset)));
563 }
564
565 return *this;
566 }
567 NSECBitmap(NSECBitmap&& rhs): d_bitset(std::move(rhs.d_bitset)), d_set(std::move(rhs.d_set))
568 {
569 }
570 bool isSet(uint16_t type) const
571 {
572 if (d_bitset) {
573 return d_bitset->test(type);
574 }
575 return d_set.count(type);
576 }
577 void set(uint16_t type)
578 {
579 if (!d_bitset) {
580 if (d_set.size() >= 200) {
581 migrateToBitSet();
582 }
583 }
584 if (d_bitset) {
585 d_bitset->set(type);
586 }
587 else {
588 d_set.insert(type);
589 }
590 }
591 size_t count() const
592 {
593 if (d_bitset) {
594 return d_bitset->count();
595 }
596 else {
597 return d_set.size();
598 }
599 }
600
601 void fromPacket(PacketReader& pr);
602 void toPacket(DNSPacketWriter& pw);
603 std::string getZoneRepresentation() const;
604
605 static constexpr size_t const nbTypes = 65536;
606
607 private:
608
609 void migrateToBitSet()
610 {
611 d_bitset = std::unique_ptr<std::bitset<nbTypes>>(new std::bitset<nbTypes>());
612 for (const auto& type : d_set) {
613 d_bitset->set(type);
614 }
615 d_set.clear();
616 }
617 /* using a dynamic set is very efficient for a small number of
618 types covered (~200), but uses a lot of memory (up to 3MB)
619 when there are a lot of them.
620 So we start with the set, but allocate and switch to a bitset
621 if the number of covered types increases a lot */
622 std::unique_ptr<std::bitset<nbTypes>> d_bitset;
623 std::set<uint16_t> d_set;
624 };
625
626 class NSECRecordContent : public DNSRecordContent
627 {
628 public:
629 static void report(void);
630 NSECRecordContent()
631 {}
632 NSECRecordContent(const string& content, const string& zone=""); //FIXME400: DNSName& zone?
633
634 static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);
635 static std::shared_ptr<DNSRecordContent> make(const string& content);
636 string getZoneRepresentation(bool noDot=false) const override;
637 void toPacket(DNSPacketWriter& pw) override;
638 uint16_t getType() const override
639 {
640 return QType::NSEC;
641 }
642 bool isSet(uint16_t type) const
643 {
644 return d_bitmap.isSet(type);
645 }
646 void set(uint16_t type)
647 {
648 d_bitmap.set(type);
649 }
650 void set(const NSECBitmap& bitmap)
651 {
652 d_bitmap = bitmap;
653 }
654 size_t numberOfTypesSet() const
655 {
656 return d_bitmap.count();
657 }
658
659 DNSName d_next;
660 private:
661 NSECBitmap d_bitmap;
662 };
663
664 class NSEC3RecordContent : public DNSRecordContent
665 {
666 public:
667 static void report(void);
668 NSEC3RecordContent()
669 {}
670 NSEC3RecordContent(const string& content, const string& zone=""); //FIXME400: DNSName& zone?
671
672 static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);
673 static std::shared_ptr<DNSRecordContent> make(const string& content);
674 string getZoneRepresentation(bool noDot=false) const override;
675 void toPacket(DNSPacketWriter& pw) override;
676
677 uint8_t d_algorithm{0}, d_flags{0};
678 uint16_t d_iterations{0};
679 string d_salt;
680 string d_nexthash;
681
682 uint16_t getType() const override
683 {
684 return QType::NSEC3;
685 }
686 bool isSet(uint16_t type) const
687 {
688 return d_bitmap.isSet(type);
689 }
690 void set(uint16_t type)
691 {
692 d_bitmap.set(type);
693 }
694 void set(const NSECBitmap& bitmap)
695 {
696 d_bitmap = bitmap;
697 }
698 size_t numberOfTypesSet() const
699 {
700 return d_bitmap.count();
701 }
702
703 private:
704 NSECBitmap d_bitmap;
705 };
706
707
708 class NSEC3PARAMRecordContent : public DNSRecordContent
709 {
710 public:
711 static void report(void);
712 NSEC3PARAMRecordContent()
713 {}
714 NSEC3PARAMRecordContent(const string& content, const string& zone=""); // FIXME400: DNSName& zone?
715
716 static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);
717 static std::shared_ptr<DNSRecordContent> make(const string& content);
718 string getZoneRepresentation(bool noDot=false) const override;
719 void toPacket(DNSPacketWriter& pw) override;
720
721 uint16_t getType() const override
722 {
723 return QType::NSEC3PARAM;
724 }
725
726
727 uint8_t d_algorithm{0}, d_flags{0};
728 uint16_t d_iterations{0};
729 string d_salt;
730 };
731
732
733 class LOCRecordContent : public DNSRecordContent
734 {
735 public:
736 static void report(void);
737 LOCRecordContent()
738 {}
739 LOCRecordContent(const string& content, const string& zone="");
740
741 static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);
742 static std::shared_ptr<DNSRecordContent> make(const string& content);
743 string getZoneRepresentation(bool noDot=false) const override;
744 void toPacket(DNSPacketWriter& pw) override;
745
746 uint8_t d_version{0}, d_size{0}, d_horizpre{0}, d_vertpre{0};
747 uint32_t d_latitude{0}, d_longitude{0}, d_altitude{0};
748 uint16_t getType() const override
749 {
750 return QType::LOC;
751 }
752
753 private:
754 };
755
756 class EUI48RecordContent : public DNSRecordContent
757 {
758 public:
759 EUI48RecordContent() {};
760 static void report(void);
761 static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);
762 static std::shared_ptr<DNSRecordContent> make(const string& zone); // FIXME400: DNSName& zone?
763 string getZoneRepresentation(bool noDot=false) const override;
764 void toPacket(DNSPacketWriter& pw) override;
765 uint16_t getType() const override { return QType::EUI48; }
766 private:
767 // storage for the bytes
768 uint8_t d_eui48[6];
769 };
770
771 class EUI64RecordContent : public DNSRecordContent
772 {
773 public:
774 EUI64RecordContent() {};
775 static void report(void);
776 static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);
777 static std::shared_ptr<DNSRecordContent> make(const string& zone); // FIXME400: DNSName& zone?
778 string getZoneRepresentation(bool noDot=false) const override;
779 void toPacket(DNSPacketWriter& pw) override;
780 uint16_t getType() const override { return QType::EUI64; }
781 private:
782 // storage for the bytes
783 uint8_t d_eui64[8];
784 };
785
786 class TKEYRecordContent : public DNSRecordContent
787 {
788 public:
789 TKEYRecordContent();
790 includeboilerplate(TKEY)
791
792 // storage for the bytes
793 uint16_t d_othersize{0};
794 uint16_t d_mode{0};
795 uint32_t d_inception{0};
796 uint32_t d_expiration{0};
797
798 DNSName d_algo;
799 string d_key;
800 string d_other;
801
802 uint16_t d_error{0};
803 uint16_t d_keysize{0};
804 private:
805 };
806
807 class URIRecordContent : public DNSRecordContent {
808 public:
809 includeboilerplate(URI)
810 private:
811 uint16_t d_priority, d_weight;
812 string d_target;
813 };
814
815 class CAARecordContent : public DNSRecordContent {
816 public:
817 includeboilerplate(CAA)
818 private:
819 uint8_t d_flags;
820 string d_tag, d_value;
821 };
822
823 #define boilerplate(RNAME, RTYPE) \
824 std::shared_ptr<RNAME##RecordContent::DNSRecordContent> RNAME##RecordContent::make(const DNSRecord& dr, PacketReader& pr) \
825 { \
826 return std::make_shared<RNAME##RecordContent>(dr, pr); \
827 } \
828 \
829 RNAME##RecordContent::RNAME##RecordContent(const DNSRecord& dr, PacketReader& pr) \
830 { \
831 doRecordCheck(dr); \
832 xfrPacket(pr); \
833 } \
834 \
835 std::shared_ptr<RNAME##RecordContent::DNSRecordContent> RNAME##RecordContent::make(const string& zonedata) \
836 { \
837 return std::make_shared<RNAME##RecordContent>(zonedata); \
838 } \
839 \
840 void RNAME##RecordContent::toPacket(DNSPacketWriter& pw) \
841 { \
842 this->xfrPacket(pw); \
843 } \
844 \
845 void RNAME##RecordContent::report(void) \
846 { \
847 regist(1, RTYPE, &RNAME##RecordContent::make, &RNAME##RecordContent::make, #RNAME); \
848 regist(254, RTYPE, &RNAME##RecordContent::make, &RNAME##RecordContent::make, #RNAME); \
849 } \
850 void RNAME##RecordContent::unreport(void) \
851 { \
852 unregist(1, RTYPE); \
853 unregist(254, RTYPE); \
854 } \
855 \
856 RNAME##RecordContent::RNAME##RecordContent(const string& zoneData) \
857 { \
858 try { \
859 RecordTextReader rtr(zoneData); \
860 xfrPacket(rtr); \
861 } \
862 catch(RecordTextException& rte) { \
863 throw MOADNSException("Parsing record content (try 'pdnsutil check-zone'): "+string(rte.what())); \
864 } \
865 } \
866 \
867 string RNAME##RecordContent::getZoneRepresentation(bool noDot) const \
868 { \
869 string ret; \
870 RecordTextWriter rtw(ret, noDot); \
871 const_cast<RNAME##RecordContent*>(this)->xfrPacket(rtw); \
872 return ret; \
873 }
874
875
876 #define boilerplate_conv(RNAME, TYPE, CONV) \
877 boilerplate(RNAME, TYPE) \
878 template<class Convertor> \
879 void RNAME##RecordContent::xfrPacket(Convertor& conv, bool noDot) \
880 { \
881 CONV; \
882 if (conv.eof() == false) throw MOADNSException("When parsing " #RNAME " trailing data was not parsed: '" + conv.getRemaining() + "'"); \
883 } \
884
885 struct EDNSOpts
886 {
887 enum zFlags { DNSSECOK=32768 };
888 vector<pair<uint16_t, string> > d_options;
889 uint16_t d_packetsize{0};
890 uint16_t d_extFlags{0};
891 uint8_t d_extRCode, d_version;
892 };
893 //! Convenience function that fills out EDNS0 options, and returns true if there are any
894
895 class MOADNSParser;
896 bool getEDNSOpts(const MOADNSParser& mdp, EDNSOpts* eo);
897 DNSRecord makeOpt(const uint16_t udpsize, const uint16_t extRCode, const uint16_t extFlags);
898 void reportBasicTypes();
899 void reportOtherTypes();
900 void reportAllTypes();
901 ComboAddress getAddr(const DNSRecord& dr, uint16_t defport=0);
902 void checkHostnameCorrectness(const DNSResourceRecord& rr);
903 #endif