]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/dnsrecords.cc
Merge pull request #5523 from rubenk/fix-typos-in-logmessage
[thirdparty/pdns.git] / pdns / dnsrecords.cc
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 */
870a0fe4
AT
22#ifdef HAVE_CONFIG_H
23#include "config.h"
24#endif
705f31ae 25#include "utility.hh"
4192ca66 26#include "dnsrecords.hh"
447e0cff 27#include "iputils.hh"
fa8fd4d2 28
2770fad0 29
f7a69a4c
RA
30void DNSResourceRecord::setContent(const string &cont) {
31 content = cont;
b9bafae0
KM
32 switch(qtype.getCode()) {
33 case QType::SRV:
34 case QType::MX:
35 if (content.size() >= 2 && *(content.rbegin()+1) == ' ')
36 return;
37 case QType::CNAME:
165e5695 38 case QType::DNAME:
b9bafae0 39 case QType::NS:
b2e37c01 40 case QType::PTR:
b9bafae0
KM
41 if(!content.empty())
42 boost::erase_tail(content, 1);
f7a69a4c
RA
43 }
44}
45
f21fc0aa 46string DNSResourceRecord::getZoneRepresentation(bool noDot) const {
f7a69a4c
RA
47 ostringstream ret;
48 switch(qtype.getCode()) {
49 case QType::SRV:
50 case QType::MX:
f7a69a4c 51 case QType::CNAME:
165e5695 52 case QType::DNAME:
f7a69a4c 53 case QType::NS:
b2e37c01 54 case QType::PTR:
f21fc0aa
PD
55 if (*(content.rbegin()) != '.') {
56 ret<<content;
57 if(!noDot)
58 ret<<".";
59 }
b9bafae0 60 break;
f7a69a4c
RA
61 default:
62 ret<<content;
63 break;
64 }
65 return ret.str();
66}
67
68bool DNSResourceRecord::operator==(const DNSResourceRecord& rhs)
69{
70 string lcontent=toLower(content);
71 string rcontent=toLower(rhs.content);
914353ca 72
914353ca 73 return
675fa24c
PD
74 tie(qname, qtype, lcontent, ttl) ==
75 tie(rhs.qname, rhs.qtype, rcontent, rhs.ttl);
f7a69a4c
RA
76}
77
3bb50daa 78boilerplate_conv(A, QType::A, conv.xfrIP(d_ip));
8c1c9170 79
5a1f298f 80ARecordContent::ARecordContent(uint32_t ip)
efb265e3
BH
81{
82 d_ip = ip;
83}
84
5a1f298f 85ARecordContent::ARecordContent(const ComboAddress& ca)
447e0cff 86{
87 d_ip = ca.sin4.sin_addr.s_addr;
88}
89
5a1f298f 90AAAARecordContent::AAAARecordContent(const ComboAddress& ca)
748eff9f 91{
447e0cff 92 d_ip6.assign((const char*)ca.sin6.sin6_addr.s6_addr, 16);
748eff9f
BH
93}
94
447e0cff 95
96ComboAddress ARecordContent::getCA(int port) const
97{
98 ComboAddress ret;
99 ret.sin4.sin_family=AF_INET;
100 ret.sin4.sin_port=htons(port);
a683e8bd 101 memcpy(&ret.sin4.sin_addr.s_addr, &d_ip, sizeof(ret.sin4.sin_addr.s_addr));
447e0cff 102 return ret;
103}
104
105ComboAddress AAAARecordContent::getCA(int port) const
106{
107 ComboAddress ret;
108 memset(&ret, 0, sizeof(ret));
109
110 ret.sin4.sin_family=AF_INET6;
111 ret.sin6.sin6_port = htons(port);
a683e8bd 112 memcpy(&ret.sin6.sin6_addr.s6_addr, d_ip6.c_str(), sizeof(ret.sin6.sin6_addr.s6_addr));
447e0cff 113 return ret;
114}
115
116
2770fad0
BH
117void ARecordContent::doRecordCheck(const DNSRecord& dr)
118{
119 if(dr.d_clen!=4)
335da0ba 120 throw MOADNSException("Wrong size for A record ("+std::to_string(dr.d_clen)+")");
a0a276c2 121}
ff6a1e7b 122
3bb50daa 123boilerplate_conv(AAAA, QType::AAAA, conv.xfrIP6(d_ip6); );
9d9c52ef 124
ad8fa726
PD
125boilerplate_conv(NS, QType::NS, conv.xfrName(d_content, true));
126boilerplate_conv(PTR, QType::PTR, conv.xfrName(d_content, true));
127boilerplate_conv(CNAME, QType::CNAME, conv.xfrName(d_content, true));
128boilerplate_conv(ALIAS, QType::ALIAS, conv.xfrName(d_content, true));
129boilerplate_conv(DNAME, QType::DNAME, conv.xfrName(d_content));
130boilerplate_conv(MR, QType::MR, conv.xfrName(d_alias, true));
131boilerplate_conv(MINFO, QType::MINFO, conv.xfrName(d_rmailbx, true); conv.xfrName(d_emailbx, true));
3bb50daa 132boilerplate_conv(TXT, QType::TXT, conv.xfrText(d_text, true));
acedb99e 133boilerplate_conv(ENT, 0, );
ef6a78d5 134boilerplate_conv(SPF, 99, conv.xfrText(d_text, true));
3bb50daa 135boilerplate_conv(HINFO, QType::HINFO, conv.xfrText(d_cpu); conv.xfrText(d_host));
ff6a1e7b 136
3bb50daa 137boilerplate_conv(RP, QType::RP,
ad8fa726
PD
138 conv.xfrName(d_mbox);
139 conv.xfrName(d_info)
232f0877 140 );
ff6a1e7b 141
ff6a1e7b 142
3bb50daa 143boilerplate_conv(OPT, QType::OPT,
232f0877
CH
144 conv.xfrBlob(d_data)
145 );
878435ce 146
7f7b8d55
BH
147void OPTRecordContent::getData(vector<pair<uint16_t, string> >& options)
148{
149 string::size_type pos=0;
150 uint16_t code, len;
151 while(d_data.size() >= 4 + pos) {
17d6efc0
BH
152 code = 256 * (unsigned char)d_data[pos] + (unsigned char)d_data[pos+1];
153 len = 256 * (unsigned char)d_data[pos+2] + (unsigned char)d_data[pos+3];
7f7b8d55
BH
154 pos+=4;
155
156 if(pos + len > d_data.size())
157 break;
158
159 string field(d_data.c_str() + pos, len);
160 pos+=len;
7f7b8d55
BH
161 options.push_back(make_pair(code, field));
162 }
163}
06ffdc52 164
3bb50daa 165boilerplate_conv(TSIG, QType::TSIG,
ad8fa726 166 conv.xfrName(d_algoName);
232f0877
CH
167 conv.xfr48BitInt(d_time);
168 conv.xfr16BitInt(d_fudge);
169 uint16_t size=d_mac.size();
170 conv.xfr16BitInt(size);
11c029c0 171 if (size>0) conv.xfrBlobNoSpaces(d_mac, size);
232f0877
CH
172 conv.xfr16BitInt(d_origID);
173 conv.xfr16BitInt(d_eRcode);
11c029c0 174 size=d_otherData.size();
232f0877 175 conv.xfr16BitInt(size);
11c029c0 176 if (size>0) conv.xfrBlobNoSpaces(d_otherData, size);
232f0877 177 );
06ffdc52 178
5a1f298f 179MXRecordContent::MXRecordContent(uint16_t preference, const DNSName& mxname): d_preference(preference), d_mxname(mxname)
2770fad0
BH
180{
181}
ff6a1e7b 182
3bb50daa 183boilerplate_conv(MX, QType::MX,
232f0877 184 conv.xfr16BitInt(d_preference);
ad8fa726 185 conv.xfrName(d_mxname, true);
232f0877 186 )
ff6a1e7b 187
3bb50daa 188boilerplate_conv(KX, QType::KX,
232f0877 189 conv.xfr16BitInt(d_preference);
ad8fa726 190 conv.xfrName(d_exchanger, false);
232f0877 191 )
9fd71f2e 192
3bb50daa 193boilerplate_conv(IPSECKEY, QType::IPSECKEY,
1cafb958
AT
194 conv.xfr8BitInt(d_preference);
195 conv.xfr8BitInt(d_gatewaytype);
196 conv.xfr8BitInt(d_algorithm);
197
198 // now we need to determine values
199 switch(d_gatewaytype) {
200 case 0: // NO KEY
201 break;
202 case 1: // IPv4 GW
203 conv.xfrIP(d_ip4);
204 break;
205 case 2: // IPv6 GW
206 conv.xfrIP6(d_ip6);
207 break;
208 case 3: // DNS label
ad8fa726 209 conv.xfrName(d_gateway, false);
1cafb958
AT
210 break;
211 default:
212 throw MOADNSException("Parsing record content: invalid gateway type");
213 };
214
215 switch(d_algorithm) {
216 case 0:
217 break;
218 case 1:
219 case 2:
220 conv.xfrBlob(d_publickey);
221 break;
222 default:
223 throw MOADNSException("Parsing record content: invalid algorithm type");
74b3a069
AT
224 }
225)
9fd71f2e
BH
226
227boilerplate_conv(DHCID, 49,
232f0877
CH
228 conv.xfrBlob(d_content);
229 )
9fd71f2e
BH
230
231
3bb50daa 232boilerplate_conv(AFSDB, QType::AFSDB,
232f0877 233 conv.xfr16BitInt(d_subtype);
ad8fa726 234 conv.xfrName(d_hostname);
232f0877 235 )
37f47031 236
ff6a1e7b 237
3bb50daa 238boilerplate_conv(NAPTR, QType::NAPTR,
232f0877
CH
239 conv.xfr16BitInt(d_order); conv.xfr16BitInt(d_preference);
240 conv.xfrText(d_flags); conv.xfrText(d_services); conv.xfrText(d_regexp);
ad8fa726 241 conv.xfrName(d_replacement);
232f0877 242 )
8c1c9170 243
ff6a1e7b 244
4a51ff72 245SRVRecordContent::SRVRecordContent(uint16_t preference, uint16_t weight, uint16_t port, const DNSName& target)
5a1f298f 246: d_weight(weight), d_port(port), d_target(target), d_preference(preference)
2770fad0 247{}
ff6a1e7b 248
3bb50daa 249boilerplate_conv(SRV, QType::SRV,
232f0877 250 conv.xfr16BitInt(d_preference); conv.xfr16BitInt(d_weight); conv.xfr16BitInt(d_port);
ad8fa726 251 conv.xfrName(d_target);
232f0877 252 )
9d9c52ef 253
4a51ff72 254SOARecordContent::SOARecordContent(const DNSName& mname, const DNSName& rname, const struct soatimes& st)
5a1f298f 255: d_mname(mname), d_rname(rname)
a0a276c2 256{
2770fad0 257 d_st=st;
a0a276c2 258}
9d9c52ef 259
3bb50daa 260boilerplate_conv(SOA, QType::SOA,
ad8fa726
PD
261 conv.xfrName(d_mname, true);
262 conv.xfrName(d_rname, true);
232f0877
CH
263 conv.xfr32BitInt(d_st.serial);
264 conv.xfr32BitInt(d_st.refresh);
265 conv.xfr32BitInt(d_st.retry);
266 conv.xfr32BitInt(d_st.expire);
267 conv.xfr32BitInt(d_st.minimum);
268 );
4b5762f1 269#undef KEY
3bb50daa 270boilerplate_conv(KEY, QType::KEY,
232f0877
CH
271 conv.xfr16BitInt(d_flags);
272 conv.xfr8BitInt(d_protocol);
273 conv.xfr8BitInt(d_algorithm);
274 conv.xfrBlob(d_certificate);
275 );
8c1c9170 276
2475a4fc 277boilerplate_conv(CERT, 37,
232f0877 278 conv.xfr16BitInt(d_type);
689516b3
AT
279 if (d_type == 0) throw MOADNSException("CERT type 0 is reserved");
280
232f0877
CH
281 conv.xfr16BitInt(d_tag);
282 conv.xfr8BitInt(d_algorithm);
689516b3
AT
283 conv.xfrBlob(d_certificate);
284 )
285
2a4e06e9 286boilerplate_conv(TLSA, 52,
232f0877
CH
287 conv.xfr8BitInt(d_certusage);
288 conv.xfr8BitInt(d_selector);
289 conv.xfr8BitInt(d_matchtype);
290 conv.xfrHexBlob(d_cert, true);
291 )
292
68066337 293boilerplate_conv(OPENPGPKEY, 61,
e7917c06 294 conv.xfrBlob(d_keyring);
68066337
JC
295 )
296
291935bb
PL
297boilerplate_conv(SMIMEA, 53,
298 conv.xfr8BitInt(d_certusage);
299 conv.xfr8BitInt(d_selector);
300 conv.xfr8BitInt(d_matchtype);
301 conv.xfrHexBlob(d_cert, true);
302 )
303
5a1f298f 304DSRecordContent::DSRecordContent() {}
8c1c9170 305boilerplate_conv(DS, 43,
232f0877
CH
306 conv.xfr16BitInt(d_tag);
307 conv.xfr8BitInt(d_algorithm);
308 conv.xfr8BitInt(d_digesttype);
309 conv.xfrHexBlob(d_digest, true); // keep reading across spaces
310 )
8c1c9170 311
5a1f298f 312CDSRecordContent::CDSRecordContent() {}
882de365
PL
313boilerplate_conv(CDS, 59,
314 conv.xfr16BitInt(d_tag);
315 conv.xfr8BitInt(d_algorithm);
316 conv.xfr8BitInt(d_digesttype);
317 conv.xfrHexBlob(d_digest, true); // keep reading across spaces
318 )
319
5a1f298f 320DLVRecordContent::DLVRecordContent() {}
0b55f2f5 321boilerplate_conv(DLV,32769 ,
232f0877
CH
322 conv.xfr16BitInt(d_tag);
323 conv.xfr8BitInt(d_algorithm);
324 conv.xfr8BitInt(d_digesttype);
325 conv.xfrHexBlob(d_digest, true); // keep reading across spaces
326 )
0b55f2f5
BH
327
328
a40a693b 329boilerplate_conv(SSHFP, 44,
232f0877
CH
330 conv.xfr8BitInt(d_algorithm);
331 conv.xfr8BitInt(d_fptype);
02ca1c5b 332 conv.xfrHexBlob(d_fingerprint, true);
232f0877 333 )
a40a693b 334
8c1c9170 335boilerplate_conv(RRSIG, 46,
232f0877
CH
336 conv.xfrType(d_type);
337 conv.xfr8BitInt(d_algorithm);
338 conv.xfr8BitInt(d_labels);
339 conv.xfr32BitInt(d_originalttl);
340 conv.xfrTime(d_sigexpire);
341 conv.xfrTime(d_siginception);
342 conv.xfr16BitInt(d_tag);
ad8fa726 343 conv.xfrName(d_signer);
232f0877
CH
344 conv.xfrBlob(d_signature);
345 )
346
5a1f298f 347RRSIGRecordContent::RRSIGRecordContent() {}
1c4d88c5 348
8c1c9170 349boilerplate_conv(DNSKEY, 48,
232f0877
CH
350 conv.xfr16BitInt(d_flags);
351 conv.xfr8BitInt(d_protocol);
352 conv.xfr8BitInt(d_algorithm);
353 conv.xfrBlob(d_key);
354 )
5a1f298f 355DNSKEYRecordContent::DNSKEYRecordContent() {}
1c4d88c5 356
882de365
PL
357boilerplate_conv(CDNSKEY, 60,
358 conv.xfr16BitInt(d_flags);
359 conv.xfr8BitInt(d_protocol);
360 conv.xfr8BitInt(d_algorithm);
361 conv.xfrBlob(d_key);
362 )
5a1f298f 363CDNSKEYRecordContent::CDNSKEYRecordContent() {}
882de365 364
3150a49c 365boilerplate_conv(RKEY, 57,
232f0877
CH
366 conv.xfr16BitInt(d_flags);
367 conv.xfr8BitInt(d_protocol);
368 conv.xfrBlob(d_key);
369 )
5a1f298f 370RKEYRecordContent::RKEYRecordContent() {}
66a07c55 371
3150a49c 372/* EUI48 start */
66a07c55
AT
373void EUI48RecordContent::report(void)
374{
3bb50daa 375 regist(1, QType::EUI48, &make, &make, "EUI48");
66a07c55
AT
376}
377DNSRecordContent* EUI48RecordContent::make(const DNSRecord &dr, PacketReader& pr)
378{
379 if(dr.d_clen!=6)
380 throw MOADNSException("Wrong size for EUI48 record");
381
382 EUI48RecordContent* ret=new EUI48RecordContent();
383 pr.copyRecord((uint8_t*) &ret->d_eui48, 6);
384 return ret;
385}
386DNSRecordContent* EUI48RecordContent::make(const string& zone)
387{
388 // try to parse
389 EUI48RecordContent *ret=new EUI48RecordContent();
390 // format is 6 hex bytes and dashes
391 if (sscanf(zone.c_str(), "%2hhx-%2hhx-%2hhx-%2hhx-%2hhx-%2hhx",
392 ret->d_eui48, ret->d_eui48+1, ret->d_eui48+2,
393 ret->d_eui48+3, ret->d_eui48+4, ret->d_eui48+5) != 6) {
0fc965fd 394 throw MOADNSException("Asked to encode '"+zone+"' as an EUI48 address, but does not parse");
66a07c55
AT
395 }
396 return ret;
397}
398void EUI48RecordContent::toPacket(DNSPacketWriter& pw)
399{
400 string blob(d_eui48, d_eui48+6);
401 pw.xfrBlob(blob);
402}
f21fc0aa 403string EUI48RecordContent::getZoneRepresentation(bool noDot) const
66a07c55
AT
404{
405 char tmp[18];
a683e8bd 406 snprintf(tmp,sizeof(tmp),"%02x-%02x-%02x-%02x-%02x-%02x",
66a07c55
AT
407 d_eui48[0], d_eui48[1], d_eui48[2],
408 d_eui48[3], d_eui48[4], d_eui48[5]);
409 return tmp;
410}
411
412/* EUI48 end */
413
414/* EUI64 start */
415
416void EUI64RecordContent::report(void)
417{
3bb50daa 418 regist(1, QType::EUI64, &make, &make, "EUI64");
66a07c55
AT
419}
420DNSRecordContent* EUI64RecordContent::make(const DNSRecord &dr, PacketReader& pr)
421{
422 if(dr.d_clen!=8)
423 throw MOADNSException("Wrong size for EUI64 record");
424
425 EUI64RecordContent* ret=new EUI64RecordContent();
426 pr.copyRecord((uint8_t*) &ret->d_eui64, 8);
427 return ret;
428}
429DNSRecordContent* EUI64RecordContent::make(const string& zone)
430{
431 // try to parse
432 EUI64RecordContent *ret=new EUI64RecordContent();
433 // format is 8 hex bytes and dashes
434 if (sscanf(zone.c_str(), "%2hhx-%2hhx-%2hhx-%2hhx-%2hhx-%2hhx-%2hhx-%2hhx",
435 ret->d_eui64, ret->d_eui64+1, ret->d_eui64+2,
436 ret->d_eui64+3, ret->d_eui64+4, ret->d_eui64+5,
437 ret->d_eui64+6, ret->d_eui64+7) != 8) {
438 throw MOADNSException("Asked to encode '"+zone+"' as an EUI64 address, but does not parse");
439 }
440 return ret;
441}
442void EUI64RecordContent::toPacket(DNSPacketWriter& pw)
443{
444 string blob(d_eui64, d_eui64+8);
445 pw.xfrBlob(blob);
446}
f21fc0aa 447string EUI64RecordContent::getZoneRepresentation(bool noDot) const
66a07c55
AT
448{
449 char tmp[24];
a683e8bd 450 snprintf(tmp,sizeof(tmp),"%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
66a07c55
AT
451 d_eui64[0], d_eui64[1], d_eui64[2],
452 d_eui64[3], d_eui64[4], d_eui64[5],
453 d_eui64[6], d_eui64[7]);
454 return tmp;
455}
456
457/* EUI64 end */
458
b3ac6324 459boilerplate_conv(TKEY, QType::TKEY,
ad8fa726 460 conv.xfrName(d_algo);
b3ac6324
AT
461 conv.xfr32BitInt(d_inception);
462 conv.xfr32BitInt(d_expiration);
463 conv.xfr16BitInt(d_mode);
464 conv.xfr16BitInt(d_error);
465 conv.xfr16BitInt(d_keysize);
466 if (d_keysize>0) conv.xfrBlobNoSpaces(d_key, d_keysize);
467 conv.xfr16BitInt(d_othersize);
468 if (d_othersize>0) conv.xfrBlobNoSpaces(d_other, d_othersize);
469 )
5a1f298f 470TKEYRecordContent::TKEYRecordContent() { d_othersize = 0; } // fix CID#1288932
66a07c55 471
20966479 472boilerplate_conv(URI, QType::URI,
fa38400f
PD
473 conv.xfr16BitInt(d_priority);
474 conv.xfr16BitInt(d_weight);
20966479
PL
475 conv.xfrText(d_target, true, false);
476 )
477
f75f6821
PL
478boilerplate_conv(CAA, QType::CAA,
479 conv.xfr8BitInt(d_flags);
480 conv.xfrUnquotedText(d_tag, true);
481 conv.xfrText(d_value, true, false); /* no lenField */
482 )
483
354ccf4e 484static uint16_t makeTag(const std::string& data)
1c4d88c5 485{
1c4d88c5
BH
486 const unsigned char* key=(const unsigned char*)data.c_str();
487 unsigned int keysize=data.length();
488
489 unsigned long ac; /* assumed to be 32 bits or larger */
490 unsigned int i; /* loop index */
491
492 for ( ac = 0, i = 0; i < keysize; ++i )
493 ac += (i & 1) ? key[i] : key[i] << 8;
494 ac += (ac >> 16) & 0xFFFF;
495 return ac & 0xFFFF;
496}
497
354ccf4e 498uint16_t DNSKEYRecordContent::getTag() const
499{
500 DNSKEYRecordContent tmp(*this);
501 return makeTag(tmp.serialize(DNSName())); // this can't be const for some reason
502}
503
504uint16_t DNSKEYRecordContent::getTag()
505{
506 return makeTag(this->serialize(DNSName()));
507}
508
509
b88526ce
PL
510/*
511 * Fills `eo` by parsing the EDNS(0) OPT RR (RFC 6891)
512 */
7f7b8d55
BH
513bool getEDNSOpts(const MOADNSParser& mdp, EDNSOpts* eo)
514{
5b9853c9 515 eo->d_Z=0;
0e4ab7bc 516 if(mdp.d_header.arcount && !mdp.d_answers.empty()) {
ef7cd021 517 for(const MOADNSParser::answers_t::value_type& val : mdp.d_answers) {
e693ff5a 518 if(val.first.d_place == DNSResourceRecord::ADDITIONAL && val.first.d_type == QType::OPT) {
232f0877 519 eo->d_packetsize=val.first.d_class;
0e4ab7bc 520
232f0877
CH
521 EDNS0Record stuff;
522 uint32_t ttl=ntohl(val.first.d_ttl);
a683e8bd 523 static_assert(sizeof(EDNS0Record) == sizeof(uint32_t), "sizeof(EDNS0Record) must match sizeof(uint32_t)");
232f0877
CH
524 memcpy(&stuff, &ttl, sizeof(stuff));
525
526 eo->d_extRCode=stuff.extRCode;
527 eo->d_version=stuff.version;
528 eo->d_Z = ntohs(stuff.Z);
529 OPTRecordContent* orc =
530 dynamic_cast<OPTRecordContent*>(val.first.d_content.get());
531 if(!orc)
532 return false;
533 orc->getData(eo->d_options);
534 return true;
0e4ab7bc
BH
535 }
536 }
7f7b8d55 537 }
0e4ab7bc 538 return false;
7f7b8d55
BH
539}
540
c541004c 541DNSRecord makeOpt(int udpsize, int extRCode, int Z)
542{
543 EDNS0Record stuff;
544 stuff.extRCode=0;
545 stuff.version=0;
546 stuff.Z=htons(Z);
547 DNSRecord dr;
a683e8bd 548 static_assert(sizeof(EDNS0Record) == sizeof(dr.d_ttl), "sizeof(EDNS0Record) must match sizeof(DNSRecord.d_ttl)");
c541004c 549 memcpy(&dr.d_ttl, &stuff, sizeof(stuff));
550 dr.d_ttl=ntohl(dr.d_ttl);
12c06211 551 dr.d_name=g_rootdnsname;
c541004c 552 dr.d_type = QType::OPT;
553 dr.d_class=udpsize;
554 dr.d_place=DNSResourceRecord::ADDITIONAL;
555 dr.d_content = std::make_shared<OPTRecordContent>();
556 // if we ever do options, I think we stuff them into OPTRecordContent::data
557 return dr;
558}
559
7f7b8d55 560
ea634573 561void reportBasicTypes()
ff6a1e7b 562{
a9af3782
BH
563 ARecordContent::report();
564 AAAARecordContent::report();
565 NSRecordContent::report();
566 CNAMERecordContent::report();
567 MXRecordContent::report();
568 SOARecordContent::report();
569 SRVRecordContent::report();
570 PTRRecordContent::report();
3bb50daa 571 DNSRecordContent::regist(QClass::CHAOS, QType::TXT, &TXTRecordContent::make, &TXTRecordContent::make, "TXT");
a6a83beb 572 TXTRecordContent::report();
703761cc 573 DNSRecordContent::regist(QClass::IN, QType::ANY, 0, 0, "ANY");
c15e2752
AT
574 DNSRecordContent::regist(QClass::IN, QType::AXFR, 0, 0, "AXFR");
575 DNSRecordContent::regist(QClass::IN, QType::IXFR, 0, 0, "IXFR");
ea634573
BH
576}
577
578void reportOtherTypes()
579{
37f47031 580 AFSDBRecordContent::report();
8dee0750 581 DNAMERecordContent::report();
d59b894d 582 ALIASRecordContent::report();
ea634573
BH
583 SPFRecordContent::report();
584 NAPTRRecordContent::report();
c6a60874 585 LOCRecordContent::report();
acedb99e 586 ENTRecordContent::report();
9770663f 587 HINFORecordContent::report();
ea634573 588 RPRecordContent::report();
4b5762f1 589 KEYRecordContent::report();
ea634573 590 DNSKEYRecordContent::report();
ce834c99 591 DHCIDRecordContent::report();
882de365 592 CDNSKEYRecordContent::report();
3150a49c 593 RKEYRecordContent::report();
ea634573
BH
594 RRSIGRecordContent::report();
595 DSRecordContent::report();
882de365 596 CDSRecordContent::report();
59a0f653 597 SSHFPRecordContent::report();
2475a4fc 598 CERTRecordContent::report();
ea634573 599 NSECRecordContent::report();
1c4d88c5
BH
600 NSEC3RecordContent::report();
601 NSEC3PARAMRecordContent::report();
07dbe87e 602 TLSARecordContent::report();
291935bb 603 SMIMEARecordContent::report();
68066337 604 OPENPGPKEYRecordContent::report();
4fb75774 605 DLVRecordContent::report();
703761cc 606 DNSRecordContent::regist(QClass::ANY, QType::TSIG, &TSIGRecordContent::make, &TSIGRecordContent::make, "TSIG");
b3ac6324 607 DNSRecordContent::regist(QClass::ANY, QType::TKEY, &TKEYRecordContent::make, &TKEYRecordContent::make, "TKEY");
b7c7d872 608 //TSIGRecordContent::report();
ea634573 609 OPTRecordContent::report();
66a07c55
AT
610 EUI48RecordContent::report();
611 EUI64RecordContent::report();
5eea7309 612 MINFORecordContent::report();
20966479 613 URIRecordContent::report();
f75f6821 614 CAARecordContent::report();
ea634573
BH
615}
616
617void reportAllTypes()
618{
619 reportBasicTypes();
620 reportOtherTypes();
621}
622
f1ae49f7 623ComboAddress getAddr(const DNSRecord& dr, uint16_t defport)
624{
625 if(auto addr=getRR<ARecordContent>(dr)) {
626 return addr->getCA(defport);
627 }
628 else
629 return getRR<AAAARecordContent>(dr)->getCA(defport);
630}
631
632
ea634573
BH
633#if 0
634static struct Reporter
635{
636 Reporter()
637 {
638 reportAllTypes();
ff6a1e7b
BH
639 }
640} reporter __attribute__((init_priority(65535)));
250d1fd8 641#endif