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