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