]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/dnsrecords.hh
Implement RFC 6742 RR Types
[thirdparty/pdns.git] / pdns / dnsrecords.hh
CommitLineData
4192ca66 1/*
12471842
PL
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 */
e8c59f2d 22#pragma once
8900e2e3
CHB
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
a0a276c2
BH
27#include "dnsparser.hh"
28#include "dnswriter.hh"
cbf0e7f3 29#include "rcpgenerator.hh"
8c1c9170 30#include <set>
51083cab 31#include <bitset>
61b26744 32#include "namespaces.hh"
f4352636 33#include "iputils.hh"
373914dc 34#include "svc-records.hh"
a0a276c2 35
2770fad0
BH
36#define includeboilerplate(RNAME) RNAME##RecordContent(const DNSRecord& dr, PacketReader& pr); \
37 RNAME##RecordContent(const string& zoneData); \
38 static void report(void); \
ee1ada80 39 static void unreport(void); \
32122aab
RG
40 static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr); \
41 static std::shared_ptr<DNSRecordContent> make(const string& zonedata); \
f21fc0aa 42 string getZoneRepresentation(bool noDot=false) const override; \
2cca142e 43 void toPacket(DNSPacketWriter& pw) override; \
5a1f298f 44 uint16_t getType() const override { return QType::RNAME; } \
f21fc0aa 45 template<class Convertor> void xfrPacket(Convertor& conv, bool noDot=false);
a0a276c2
BH
46
47class NAPTRRecordContent : public DNSRecordContent
48{
49public:
4a51ff72 50 NAPTRRecordContent(uint16_t order, uint16_t preference, string flags, string services, string regexp, DNSName replacement);
a0a276c2 51
1d1d688a 52 includeboilerplate(NAPTR)
cbf0e7f3 53 template<class Convertor> void xfrRecordContent(Convertor& conv);
a0a276c2
BH
54private:
55 uint16_t d_order, d_preference;
4a51ff72
PD
56 string d_flags, d_services, d_regexp;
57 DNSName d_replacement;
a0a276c2
BH
58};
59
2770fad0 60
a0a276c2
BH
61class ARecordContent : public DNSRecordContent
62{
63public:
447e0cff 64 explicit ARecordContent(const ComboAddress& ca);
efb265e3 65 explicit ARecordContent(uint32_t ip);
1d1d688a 66 includeboilerplate(A)
2770fad0 67 void doRecordCheck(const DNSRecord& dr);
447e0cff 68 ComboAddress getCA(int port=0) const;
f18e430f 69 bool operator==(const DNSRecordContent& rhs) const override
70 {
71 if(typeid(*this) != typeid(rhs))
72 return false;
73 return d_ip == dynamic_cast<const ARecordContent&>(rhs).d_ip;
74 }
2770fad0
BH
75private:
76 uint32_t d_ip;
77};
a0a276c2 78
fc465b41
AT
79class AAAARecordContent : public DNSRecordContent
80{
81public:
82 AAAARecordContent(std::string &val);
447e0cff 83 explicit AAAARecordContent(const ComboAddress& ca);
1d1d688a 84 includeboilerplate(AAAA)
447e0cff 85 ComboAddress getCA(int port=0) const;
f18e430f 86 bool operator==(const DNSRecordContent& rhs) const override
87 {
88 if(typeid(*this) != typeid(rhs))
89 return false;
90 return d_ip6 == dynamic_cast<const decltype(this)>(&rhs)->d_ip6;
91 }
fc465b41 92private:
447e0cff 93 string d_ip6; // why??
fc465b41
AT
94};
95
2770fad0
BH
96class MXRecordContent : public DNSRecordContent
97{
98public:
1290c1d2 99 MXRecordContent(uint16_t preference, DNSName mxname);
a0a276c2 100
2770fad0 101 includeboilerplate(MX)
a0a276c2 102
2770fad0 103 uint16_t d_preference;
89735451 104 DNSName d_mxname;
f18e430f 105
106 bool operator==(const DNSRecordContent& rhs) const override
107 {
108 if(typeid(*this) != typeid(rhs))
109 return false;
110 auto rrhs =dynamic_cast<const decltype(this)>(&rhs);
111 return std::tie(d_preference, d_mxname) == std::tie(rrhs->d_preference, rrhs->d_mxname);
112 }
113
2770fad0
BH
114};
115
9fd71f2e
BH
116class KXRecordContent : public DNSRecordContent
117{
118public:
89735451 119 KXRecordContent(uint16_t preference, const DNSName& exchanger);
9fd71f2e
BH
120
121 includeboilerplate(KX)
122
123private:
124 uint16_t d_preference;
89735451 125 DNSName d_exchanger;
9fd71f2e
BH
126};
127
128class IPSECKEYRecordContent : public DNSRecordContent
129{
130public:
c2f3be9d 131 IPSECKEYRecordContent(uint16_t preference, uint8_t gatewaytype, uint8_t algo, const DNSName& gateway, const string& publickey);
9fd71f2e
BH
132
133 includeboilerplate(IPSECKEY)
134
135private:
d0793109 136 uint32_t d_ip4;
c2f3be9d
PD
137 DNSName d_gateway;
138 string d_publickey;
1cafb958 139 string d_ip6;
adc18742 140 uint8_t d_preference, d_gatewaytype, d_algorithm;
9fd71f2e
BH
141};
142
143class DHCIDRecordContent : public DNSRecordContent
144{
145public:
146 includeboilerplate(DHCID)
147
148private:
149 string d_content;
150};
151
152
2770fad0
BH
153class SRVRecordContent : public DNSRecordContent
154{
155public:
1290c1d2 156 SRVRecordContent(uint16_t preference, uint16_t weight, uint16_t port, DNSName target);
2770fad0
BH
157
158 includeboilerplate(SRV)
159
a2d7c36a 160 uint16_t d_weight, d_port;
89735451 161 DNSName d_target;
a2d7c36a 162 uint16_t d_preference;
2770fad0
BH
163};
164
06ffdc52
BH
165class TSIGRecordContent : public DNSRecordContent
166{
167public:
168 includeboilerplate(TSIG)
5a1f298f 169 TSIGRecordContent() {}
06ffdc52 170
34c513f9
RG
171 uint16_t d_origID{0};
172 uint16_t d_fudge{0};
c3a81a30 173
0b6fa0eb 174 DNSName d_algoName;
483d2f10
PL
175 string d_mac;
176 string d_otherData;
34c513f9 177 uint64_t d_time{0};
06ffdc52 178 // uint16_t d_macSize;
34c513f9 179 uint16_t d_eRcode{0};
06ffdc52 180 // uint16_t d_otherLen
06ffdc52
BH
181};
182
2770fad0
BH
183
184class TXTRecordContent : public DNSRecordContent
185{
186public:
187 includeboilerplate(TXT)
188
2770fad0 189 string d_text;
a0a276c2
BH
190};
191
8900e2e3 192#ifdef HAVE_LUA_RECORDS
6b547a53 193class LUARecordContent : public DNSRecordContent
194{
195public:
196 includeboilerplate(LUA)
98fa3598 197 string getCode() const;
5dbd408c 198 uint16_t d_type;
6b547a53 199 string d_code;
200};
8900e2e3 201#endif
6b547a53 202
acedb99e 203class ENTRecordContent : public DNSRecordContent
204{
205public:
206 includeboilerplate(ENT)
207};
208
8c1c9170
BH
209class SPFRecordContent : public DNSRecordContent
210{
211public:
212 includeboilerplate(SPF)
0bd2e252
RG
213 const std::string& getText() const
214 {
215 return d_text;
216 }
8c1c9170
BH
217
218private:
219 string d_text;
220};
221
222
cbf0e7f3
BH
223class NSRecordContent : public DNSRecordContent
224{
225public:
226 includeboilerplate(NS)
5a1f298f 227 explicit NSRecordContent(const DNSName& content) : d_content(content){}
f18e430f 228 const DNSName& getNS() const { return d_content; }
229 bool operator==(const DNSRecordContent& rhs) const override
230 {
231 if(typeid(*this) != typeid(rhs))
232 return false;
233 auto rrhs =dynamic_cast<const decltype(this)>(&rhs);
234 return d_content == rrhs->d_content;
235 }
236
cbf0e7f3 237private:
89735451 238 DNSName d_content;
cbf0e7f3
BH
239};
240
241class PTRRecordContent : public DNSRecordContent
242{
243public:
244 includeboilerplate(PTR)
98cda0a9 245 explicit PTRRecordContent(const DNSName& content) : d_content(content){}
0bd2e252 246 const DNSName& getContent() const { return d_content; }
cbf0e7f3 247private:
89735451 248 DNSName d_content;
cbf0e7f3
BH
249};
250
251class CNAMERecordContent : public DNSRecordContent
252{
253public:
254 includeboilerplate(CNAME)
90ba52e0 255 CNAMERecordContent(const DNSName& content) : d_content(content){}
447e0cff 256 DNSName getTarget() const { return d_content; }
cbf0e7f3 257private:
89735451 258 DNSName d_content;
cbf0e7f3
BH
259};
260
d59b894d 261class ALIASRecordContent : public DNSRecordContent
262{
263public:
264 includeboilerplate(ALIAS)
265
89735451 266 DNSName d_content;
d59b894d 267};
268
269
8dee0750 270class DNAMERecordContent : public DNSRecordContent
271{
272public:
273 includeboilerplate(DNAME)
c3491dd6 274 DNAMERecordContent(const DNSName& content) : d_content(content){}
dc0d34db 275 const DNSName& getTarget() const { return d_content; }
c3491dd6 276private:
89735451 277 DNSName d_content;
8dee0750 278};
279
280
fa552262
CHB
281class MBRecordContent : public DNSRecordContent
282{
283public:
284 includeboilerplate(MB)
285
286private:
287 DNSName d_madname;
288};
289
290class MGRecordContent : public DNSRecordContent
291{
292public:
293 includeboilerplate(MG)
294
295private:
296 DNSName d_mgmname;
297};
298
4e0805a6
BH
299class MRRecordContent : public DNSRecordContent
300{
301public:
302 includeboilerplate(MR)
303
304private:
89735451 305 DNSName d_alias;
4e0805a6
BH
306};
307
7c0b8593 308class MINFORecordContent : public DNSRecordContent
309{
310public:
311 includeboilerplate(MINFO)
312
313private:
89735451
PD
314 DNSName d_rmailbx;
315 DNSName d_emailbx;
7c0b8593 316};
cbf0e7f3 317
878435ce
BH
318class OPTRecordContent : public DNSRecordContent
319{
320public:
c541004c 321 OPTRecordContent(){}
878435ce 322 includeboilerplate(OPT)
7f7b8d55 323 void getData(vector<pair<uint16_t, string> > &opts);
878435ce
BH
324private:
325 string d_data;
326};
327
328
cbf0e7f3
BH
329class HINFORecordContent : public DNSRecordContent
330{
331public:
332 includeboilerplate(HINFO)
333
334private:
335 string d_cpu, d_host;
336};
337
338class RPRecordContent : public DNSRecordContent
339{
340public:
341 includeboilerplate(RP)
342
343private:
89735451 344 DNSName d_mbox, d_info;
cbf0e7f3
BH
345};
346
347
8c1c9170
BH
348class DNSKEYRecordContent : public DNSRecordContent
349{
350public:
1c4d88c5 351 DNSKEYRecordContent();
8c1c9170 352 includeboilerplate(DNSKEY)
523c312b 353 uint16_t getTag() const;
354ccf4e 354 uint16_t getTag();
8c1c9170 355
34c513f9
RG
356 uint16_t d_flags{0};
357 uint8_t d_protocol{0};
358 uint8_t d_algorithm{0};
8c1c9170 359 string d_key;
523c312b 360 bool operator<(const DNSKEYRecordContent& rhs) const
361 {
362 return tie(d_flags, d_protocol, d_algorithm, d_key) <
363 tie(rhs.d_flags, rhs.d_protocol, rhs.d_algorithm, rhs.d_key);
364 }
8c1c9170
BH
365};
366
882de365
PL
367class CDNSKEYRecordContent : public DNSRecordContent
368{
369public:
370 CDNSKEYRecordContent();
371 includeboilerplate(CDNSKEY)
372 uint16_t getTag();
373
34c513f9
RG
374 uint16_t d_flags{0};
375 uint8_t d_protocol{0};
376 uint8_t d_algorithm{0};
882de365
PL
377 string d_key;
378};
379
8c1c9170
BH
380class DSRecordContent : public DNSRecordContent
381{
382public:
1c4d88c5 383 DSRecordContent();
0b062478 384 bool operator==(const DNSRecordContent& rhs) const override
a820bc34 385 {
0b062478
RG
386 if(typeid(*this) != typeid(rhs))
387 return false;
388 auto rrhs =dynamic_cast<const decltype(this)>(&rhs);
a820bc34 389 return tie(d_tag, d_algorithm, d_digesttype, d_digest) ==
0b062478 390 tie(rrhs->d_tag, rrhs->d_algorithm, rrhs->d_digesttype, rrhs->d_digest);
a820bc34 391 }
392 bool operator<(const DSRecordContent& rhs) const
393 {
394 return tie(d_tag, d_algorithm, d_digesttype, d_digest) <
395 tie(rhs.d_tag, rhs.d_algorithm, rhs.d_digesttype, rhs.d_digest);
396 }
397
8c1c9170
BH
398 includeboilerplate(DS)
399
34c513f9
RG
400 uint16_t d_tag{0};
401 uint8_t d_algorithm{0}, d_digesttype{0};
8c1c9170
BH
402 string d_digest;
403};
404
882de365
PL
405class CDSRecordContent : public DNSRecordContent
406{
407public:
408 CDSRecordContent();
409 includeboilerplate(CDS)
410
34c513f9
RG
411 uint16_t d_tag{0};
412 uint8_t d_algorithm{0}, d_digesttype{0};
882de365
PL
413 string d_digest;
414};
415
0b55f2f5
BH
416class DLVRecordContent : public DNSRecordContent
417{
418public:
419 DLVRecordContent();
420 includeboilerplate(DLV)
421
34c513f9
RG
422 uint16_t d_tag{0};
423 uint8_t d_algorithm{0}, d_digesttype{0};
0b55f2f5
BH
424 string d_digest;
425};
426
427
a40a693b
BH
428class SSHFPRecordContent : public DNSRecordContent
429{
430public:
431 includeboilerplate(SSHFP)
432
433private:
434 uint8_t d_algorithm, d_fptype;
435 string d_fingerprint;
436};
8c1c9170 437
4b5762f1
BH
438class KEYRecordContent : public DNSRecordContent
439{
440public:
441 includeboilerplate(KEY)
442
443private:
444 uint16_t d_flags;
445 uint8_t d_protocol, d_algorithm;
446 string d_certificate;
447};
448
37f47031
BH
449class AFSDBRecordContent : public DNSRecordContent
450{
451public:
452 includeboilerplate(AFSDB)
453
454private:
455 uint16_t d_subtype;
89735451 456 DNSName d_hostname;
37f47031
BH
457};
458
459
2475a4fc
BH
460class CERTRecordContent : public DNSRecordContent
461{
462public:
463 includeboilerplate(CERT)
464
465private:
466 uint16_t d_type, d_tag;
2475a4fc 467 string d_certificate;
1e56bb82 468 uint8_t d_algorithm;
2475a4fc
BH
469};
470
07dbe87e
BH
471class TLSARecordContent : public DNSRecordContent
472{
473public:
474 includeboilerplate(TLSA)
475
476private:
f5a09796 477 uint8_t d_certusage, d_selector, d_matchtype;
07dbe87e
BH
478 string d_cert;
479};
480
291935bb
PL
481class SMIMEARecordContent : public DNSRecordContent
482{
483public:
484 includeboilerplate(SMIMEA)
485
486private:
487 uint8_t d_certusage, d_selector, d_matchtype;
488 string d_cert;
489};
490
68066337
JC
491class OPENPGPKEYRecordContent : public DNSRecordContent
492{
493public:
494 includeboilerplate(OPENPGPKEY)
495
496private:
3fd06ce5 497 string d_keyring;
68066337
JC
498};
499
373914dc
PL
500class SVCBRecordContent : public DNSRecordContent
501{
502public:
503 includeboilerplate(SVCB)
8d0d65ef
PL
504 const DNSName& getTarget() const {return d_target;}
505 uint16_t getPriority() const {return d_priority;}
373914dc
PL
506
507private:
508 uint16_t d_priority;
509 DNSName d_target;
510 set<SvcParam> d_params;
511};
512
513class HTTPSRecordContent : public DNSRecordContent
514{
515public:
516 includeboilerplate(HTTPS)
8d0d65ef
PL
517 const DNSName& getTarget() const {return d_target;}
518 uint16_t getPriority() const {return d_priority;}
373914dc
PL
519
520private:
521 uint16_t d_priority;
522 DNSName d_target;
523 set<SvcParam> d_params;
524};
07dbe87e 525
8c1c9170
BH
526class RRSIGRecordContent : public DNSRecordContent
527{
528public:
1c4d88c5 529 RRSIGRecordContent();
8c1c9170
BH
530 includeboilerplate(RRSIG)
531
34c513f9
RG
532 uint16_t d_type{0};
533 uint16_t d_tag{0};
89735451
PD
534 DNSName d_signer;
535 string d_signature;
34c513f9
RG
536 uint32_t d_originalttl{0}, d_sigexpire{0}, d_siginception{0};
537 uint8_t d_algorithm{0}, d_labels{0};
8c1c9170
BH
538};
539
5ac6a3a3 540//namespace {
2770fad0
BH
541 struct soatimes
542 {
543 uint32_t serial;
544 uint32_t refresh;
545 uint32_t retry;
546 uint32_t expire;
547 uint32_t minimum;
548 };
5ac6a3a3 549//}
2770fad0 550
3150a49c 551class RKEYRecordContent : public DNSRecordContent
552{
553public:
554 RKEYRecordContent();
555 includeboilerplate(RKEY)
34c513f9
RG
556 uint16_t d_flags{0};
557 uint8_t d_protocol{0}, d_algorithm{0};
3150a49c 558 string d_key;
559};
2770fad0
BH
560
561class SOARecordContent : public DNSRecordContent
562{
563public:
564 includeboilerplate(SOA)
1290c1d2 565 SOARecordContent(DNSName mname, DNSName rname, const struct soatimes& st);
2770fad0 566
89735451
PD
567 DNSName d_mname;
568 DNSName d_rname;
1c21ab45 569 struct soatimes d_st;
2770fad0 570};
a0a276c2 571
27d4a65b
RG
572class NSECBitmap
573{
574public:
22a0ef16
RG
575 NSECBitmap(): d_bitset(nullptr)
576 {
577 }
578 NSECBitmap(const NSECBitmap& rhs): d_set(rhs.d_set)
579 {
580 if (rhs.d_bitset) {
581 d_bitset = std::unique_ptr<std::bitset<nbTypes>>(new std::bitset<nbTypes>(*(rhs.d_bitset)));
582 }
583 }
584 NSECBitmap& operator=(const NSECBitmap& rhs)
585 {
586 d_set = rhs.d_set;
587
588 if (rhs.d_bitset) {
589 d_bitset = std::unique_ptr<std::bitset<nbTypes>>(new std::bitset<nbTypes>(*(rhs.d_bitset)));
590 }
591
592 return *this;
593 }
594 NSECBitmap(NSECBitmap&& rhs): d_bitset(std::move(rhs.d_bitset)), d_set(std::move(rhs.d_set))
595 {
596 }
27d4a65b
RG
597 bool isSet(uint16_t type) const
598 {
599 if (d_bitset) {
600 return d_bitset->test(type);
601 }
602 return d_set.count(type);
603 }
604 void set(uint16_t type)
605 {
606 if (!d_bitset) {
607 if (d_set.size() >= 200) {
608 migrateToBitSet();
609 }
610 }
611 if (d_bitset) {
612 d_bitset->set(type);
613 }
614 else {
615 d_set.insert(type);
616 }
617 }
618 size_t count() const
619 {
620 if (d_bitset) {
621 return d_bitset->count();
622 }
623 else {
624 return d_set.size();
625 }
626 }
627
628 void fromPacket(PacketReader& pr);
629 void toPacket(DNSPacketWriter& pw);
630 std::string getZoneRepresentation() const;
631
9f607f21
RG
632 static constexpr size_t const nbTypes = 65536;
633
27d4a65b 634private:
9f607f21 635
27d4a65b
RG
636 void migrateToBitSet()
637 {
9f607f21 638 d_bitset = std::unique_ptr<std::bitset<nbTypes>>(new std::bitset<nbTypes>());
27d4a65b
RG
639 for (const auto& type : d_set) {
640 d_bitset->set(type);
641 }
642 d_set.clear();
643 }
644 /* using a dynamic set is very efficient for a small number of
645 types covered (~200), but uses a lot of memory (up to 3MB)
646 when there are a lot of them.
647 So we start with the set, but allocate and switch to a bitset
648 if the number of covered types increases a lot */
9f607f21 649 std::unique_ptr<std::bitset<nbTypes>> d_bitset;
27d4a65b
RG
650 std::set<uint16_t> d_set;
651};
652
20133c59
BH
653class NSECRecordContent : public DNSRecordContent
654{
655public:
656 static void report(void);
5a1f298f 657 NSECRecordContent()
20133c59 658 {}
a2a77b28 659 NSECRecordContent(const string& content, const DNSName& zone=DNSName());
20133c59 660
32122aab
RG
661 static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);
662 static std::shared_ptr<DNSRecordContent> make(const string& content);
f21fc0aa 663 string getZoneRepresentation(bool noDot=false) const override;
2cca142e 664 void toPacket(DNSPacketWriter& pw) override;
5a1f298f 665 uint16_t getType() const override
666 {
667 return QType::NSEC;
668 }
27d4a65b
RG
669 bool isSet(uint16_t type) const
670 {
671 return d_bitmap.isSet(type);
672 }
673 void set(uint16_t type)
674 {
675 d_bitmap.set(type);
676 }
22a0ef16
RG
677 void set(const NSECBitmap& bitmap)
678 {
679 d_bitmap = bitmap;
680 }
27d4a65b
RG
681 size_t numberOfTypesSet() const
682 {
683 return d_bitmap.count();
684 }
685
89735451 686 DNSName d_next;
20133c59 687private:
27d4a65b 688 NSECBitmap d_bitmap;
20133c59
BH
689};
690
1c4d88c5
BH
691class NSEC3RecordContent : public DNSRecordContent
692{
693public:
694 static void report(void);
2cca142e 695 NSEC3RecordContent()
1c4d88c5 696 {}
a2a77b28 697 NSEC3RecordContent(const string& content, const DNSName& zone=DNSName());
1c4d88c5 698
32122aab
RG
699 static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);
700 static std::shared_ptr<DNSRecordContent> make(const string& content);
f21fc0aa 701 string getZoneRepresentation(bool noDot=false) const override;
2cca142e 702 void toPacket(DNSPacketWriter& pw) override;
1c4d88c5 703
34c513f9
RG
704 uint8_t d_algorithm{0}, d_flags{0};
705 uint16_t d_iterations{0};
1c4d88c5 706 string d_salt;
1c4d88c5 707 string d_nexthash;
1c4d88c5 708
5a1f298f 709 uint16_t getType() const override
710 {
711 return QType::NSEC3;
712 }
27d4a65b
RG
713 bool isSet(uint16_t type) const
714 {
715 return d_bitmap.isSet(type);
716 }
717 void set(uint16_t type)
718 {
719 d_bitmap.set(type);
720 }
22a0ef16
RG
721 void set(const NSECBitmap& bitmap)
722 {
723 d_bitmap = bitmap;
724 }
27d4a65b
RG
725 size_t numberOfTypesSet() const
726 {
727 return d_bitmap.count();
728 }
0cbcfeda
RG
729 bool isOptOut() const
730 {
731 return d_flags & 1;
732 }
5a1f298f 733
1c4d88c5 734private:
27d4a65b 735 NSECBitmap d_bitmap;
1c4d88c5
BH
736};
737
3a63bb5f
PD
738class CSYNCRecordContent : public DNSRecordContent
739{
740public:
741 static void report(void);
742 CSYNCRecordContent()
743 {}
744 CSYNCRecordContent(const string& content, const DNSName& zone=DNSName());
745
746 static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);
747 static std::shared_ptr<DNSRecordContent> make(const string& content);
748 string getZoneRepresentation(bool noDot=false) const override;
749 void toPacket(DNSPacketWriter& pw) override;
750
751 uint16_t getType() const override
752 {
753 return QType::CSYNC;
754 }
755
756 void set(uint16_t type)
757 {
758 d_bitmap.set(type);
759 }
760
761private:
98c7dd26
PD
762 uint32_t d_serial{0};
763 uint16_t d_flags{0};
3a63bb5f
PD
764 NSECBitmap d_bitmap;
765};
1c4d88c5
BH
766
767class NSEC3PARAMRecordContent : public DNSRecordContent
768{
769public:
827634f0 770 static void report(void);
5a1f298f 771 NSEC3PARAMRecordContent()
827634f0 772 {}
a2a77b28 773 NSEC3PARAMRecordContent(const string& content, const DNSName& zone=DNSName());
827634f0 774
32122aab
RG
775 static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);
776 static std::shared_ptr<DNSRecordContent> make(const string& content);
f21fc0aa 777 string getZoneRepresentation(bool noDot=false) const override;
2cca142e 778 void toPacket(DNSPacketWriter& pw) override;
827634f0 779
5a1f298f 780 uint16_t getType() const override
781 {
782 return QType::NSEC3PARAM;
783 }
784
1c4d88c5 785
34c513f9
RG
786 uint8_t d_algorithm{0}, d_flags{0};
787 uint16_t d_iterations{0};
1c4d88c5
BH
788 string d_salt;
789};
790
791
c6a60874
BH
792class LOCRecordContent : public DNSRecordContent
793{
794public:
795 static void report(void);
2cca142e 796 LOCRecordContent()
c6a60874
BH
797 {}
798 LOCRecordContent(const string& content, const string& zone="");
20133c59 799
32122aab
RG
800 static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);
801 static std::shared_ptr<DNSRecordContent> make(const string& content);
f21fc0aa 802 string getZoneRepresentation(bool noDot=false) const override;
2cca142e 803 void toPacket(DNSPacketWriter& pw) override;
c6a60874 804
34c513f9
RG
805 uint8_t d_version{0}, d_size{0}, d_horizpre{0}, d_vertpre{0};
806 uint32_t d_latitude{0}, d_longitude{0}, d_altitude{0};
5a1f298f 807 uint16_t getType() const override
808 {
809 return QType::LOC;
810 }
811
c6a60874
BH
812private:
813};
8c1c9170 814
786ed0ff
PL
815
816class NIDRecordContent : public DNSRecordContent
817{
818public:
819 includeboilerplate(NID);
820
821private:
822 uint16_t d_preference;
823 NodeOrLocatorID d_node_id;
824};
825
826class L32RecordContent : public DNSRecordContent
827{
828public:
829 includeboilerplate(L32);
830
831private:
832 uint16_t d_preference;
833 uint32_t d_locator;
834};
835
836class L64RecordContent : public DNSRecordContent
837{
838public:
839 includeboilerplate(L64);
840
841private:
842 uint16_t d_preference;
843 NodeOrLocatorID d_locator;
844};
845
846class LPRecordContent : public DNSRecordContent
847{
848public:
849 includeboilerplate(LP);
850
851private:
852 uint16_t d_preference;
853 DNSName d_fqdn;
854};
855
66a07c55
AT
856class EUI48RecordContent : public DNSRecordContent
857{
858public:
5a1f298f 859 EUI48RecordContent() {};
66a07c55 860 static void report(void);
32122aab
RG
861 static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);
862 static std::shared_ptr<DNSRecordContent> make(const string& zone); // FIXME400: DNSName& zone?
f21fc0aa 863 string getZoneRepresentation(bool noDot=false) const override;
2cca142e 864 void toPacket(DNSPacketWriter& pw) override;
5a1f298f 865 uint16_t getType() const override { return QType::EUI48; }
66a07c55
AT
866private:
867 // storage for the bytes
868 uint8_t d_eui48[6];
869};
870
871class EUI64RecordContent : public DNSRecordContent
872{
873public:
5a1f298f 874 EUI64RecordContent() {};
66a07c55 875 static void report(void);
32122aab
RG
876 static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);
877 static std::shared_ptr<DNSRecordContent> make(const string& zone); // FIXME400: DNSName& zone?
f21fc0aa 878 string getZoneRepresentation(bool noDot=false) const override;
2cca142e 879 void toPacket(DNSPacketWriter& pw) override;
5a1f298f 880 uint16_t getType() const override { return QType::EUI64; }
66a07c55
AT
881private:
882 // storage for the bytes
883 uint8_t d_eui64[8];
884};
d34d3e01 885
66eb5eb7
ND
886#define APL_FAMILY_IPV4 1
887#define APL_FAMILY_IPV6 2
343ef20b
ND
888typedef struct s_APLRDataElement {
889 uint16_t d_family;
890 uint8_t d_prefix;
891 bool d_n : 1;
892 unsigned int d_afdlength : 7;
a7bc63dd
ND
893 union u_d_ip {
894 uint8_t d_ip4[4];
895 uint8_t d_ip6[16];
896 } d_ip;
343ef20b 897} APLRDataElement;
66eb5eb7
ND
898class APLRecordContent : public DNSRecordContent
899{
900public:
901 APLRecordContent() {};
16d54fe8 902 includeboilerplate(APL)
66eb5eb7 903private:
343ef20b
ND
904 std::vector<APLRDataElement> aplrdata;
905 APLRDataElement parseAPLElement(const string &element);
66eb5eb7
ND
906};
907
908
b3ac6324
AT
909class TKEYRecordContent : public DNSRecordContent
910{
911public:
912 TKEYRecordContent();
913 includeboilerplate(TKEY)
914
915 // storage for the bytes
34c513f9
RG
916 uint16_t d_othersize{0};
917 uint16_t d_mode{0};
918 uint32_t d_inception{0};
919 uint32_t d_expiration{0};
adc18742 920
0b6fa0eb 921 DNSName d_algo;
b3ac6324 922 string d_key;
b3ac6324 923 string d_other;
adc18742 924
34c513f9
RG
925 uint16_t d_error{0};
926 uint16_t d_keysize{0};
b3ac6324
AT
927private:
928};
929
20966479
PL
930class URIRecordContent : public DNSRecordContent {
931 public:
932 includeboilerplate(URI)
933 private:
fa38400f 934 uint16_t d_priority, d_weight;
20966479
PL
935 string d_target;
936};
937
f75f6821
PL
938class CAARecordContent : public DNSRecordContent {
939 public:
940 includeboilerplate(CAA)
941 private:
942 uint8_t d_flags;
943 string d_tag, d_value;
944};
945
46fd1cbb 946#define boilerplate(RNAME) \
32122aab 947std::shared_ptr<RNAME##RecordContent::DNSRecordContent> RNAME##RecordContent::make(const DNSRecord& dr, PacketReader& pr) \
8c1c9170 948{ \
32122aab 949 return std::make_shared<RNAME##RecordContent>(dr, pr); \
8c1c9170
BH
950} \
951 \
5a1f298f 952RNAME##RecordContent::RNAME##RecordContent(const DNSRecord& dr, PacketReader& pr) \
8c1c9170
BH
953{ \
954 doRecordCheck(dr); \
955 xfrPacket(pr); \
956} \
957 \
32122aab 958std::shared_ptr<RNAME##RecordContent::DNSRecordContent> RNAME##RecordContent::make(const string& zonedata) \
8c1c9170 959{ \
32122aab 960 return std::make_shared<RNAME##RecordContent>(zonedata); \
8c1c9170
BH
961} \
962 \
963void RNAME##RecordContent::toPacket(DNSPacketWriter& pw) \
964{ \
965 this->xfrPacket(pw); \
966} \
967 \
968void RNAME##RecordContent::report(void) \
969{ \
46fd1cbb
OM
970 regist(1, QType::RNAME, &RNAME##RecordContent::make, &RNAME##RecordContent::make, #RNAME); \
971 regist(254, QType::RNAME, &RNAME##RecordContent::make, &RNAME##RecordContent::make, #RNAME); \
ee1ada80
BH
972} \
973void RNAME##RecordContent::unreport(void) \
974{ \
46fd1cbb
OM
975 unregist(1, QType::RNAME); \
976 unregist(254, QType::RNAME); \
8c1c9170
BH
977} \
978 \
5a1f298f 979RNAME##RecordContent::RNAME##RecordContent(const string& zoneData) \
8c1c9170 980{ \
aab4adb0
BH
981 try { \
982 RecordTextReader rtr(zoneData); \
983 xfrPacket(rtr); \
984 } \
81bb680e
JS
985 catch(RecordTextException& rte) { \
986 throw MOADNSException("Parsing record content (try 'pdnsutil check-zone'): "+string(rte.what())); \
1649b6ef 987 } \
8c1c9170
BH
988} \
989 \
f21fc0aa 990string RNAME##RecordContent::getZoneRepresentation(bool noDot) const \
8c1c9170
BH
991{ \
992 string ret; \
f21fc0aa 993 RecordTextWriter rtw(ret, noDot); \
8c1c9170
BH
994 const_cast<RNAME##RecordContent*>(this)->xfrPacket(rtw); \
995 return ret; \
996}
997
998
46fd1cbb
OM
999#define boilerplate_conv(RNAME, CONV) \
1000boilerplate(RNAME) \
8c1c9170 1001template<class Convertor> \
f21fc0aa 1002void RNAME##RecordContent::xfrPacket(Convertor& conv, bool noDot) \
8c1c9170
BH
1003{ \
1004 CONV; \
ddb79bca 1005 if (conv.eof() == false) throw MOADNSException("When parsing " #RNAME " trailing data was not parsed: '" + conv.getRemaining() + "'"); \
8c1c9170
BH
1006} \
1007
7f7b8d55
BH
1008struct EDNSOpts
1009{
5ca95d47
PL
1010 enum zFlags { DNSSECOK=32768 };
1011 vector<pair<uint16_t, string> > d_options;
447e0cff 1012 uint16_t d_packetsize{0};
d6c335ab 1013 uint16_t d_extFlags{0};
5ca95d47 1014 uint8_t d_extRCode, d_version;
7f7b8d55
BH
1015};
1016//! Convenience function that fills out EDNS0 options, and returns true if there are any
1017
1018class MOADNSParser;
1019bool getEDNSOpts(const MOADNSParser& mdp, EDNSOpts* eo);
d6c335ab 1020DNSRecord makeOpt(const uint16_t udpsize, const uint16_t extRCode, const uint16_t extFlags);
ea634573
BH
1021void reportBasicTypes();
1022void reportOtherTypes();
1023void reportAllTypes();
f1ae49f7 1024ComboAddress getAddr(const DNSRecord& dr, uint16_t defport=0);
97c8ea81 1025void checkHostnameCorrectness(const DNSResourceRecord& rr);