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