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