]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dnsrecords.cc
2 PowerDNS Versatile Database Driven Nameserver
3 Copyright (C) 2005 - 2009 PowerDNS.COM BV
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2 as
7 published by the Free Software Foundation
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #include "dnsrecords.hh"
21 #include <boost/foreach.hpp>
23 boilerplate_conv(A
, ns_t_a
, conv
.xfrIP(d_ip
));
25 ARecordContent::ARecordContent(uint32_t ip
) : DNSRecordContent(ns_t_a
)
30 uint32_t ARecordContent::getIP() const
35 void ARecordContent::doRecordCheck(const DNSRecord
& dr
)
38 throw MOADNSException("Wrong size for A record ("+lexical_cast
<string
>(dr
.d_clen
)+")");
41 boilerplate_conv(AAAA
, ns_t_aaaa
, conv
.xfrIP6(d_ip6
); );
43 boilerplate_conv(NS
, ns_t_ns
, conv
.xfrLabel(d_content
, true));
44 boilerplate_conv(PTR
, ns_t_ptr
, conv
.xfrLabel(d_content
, true));
45 boilerplate_conv(CNAME
, ns_t_cname
, conv
.xfrLabel(d_content
, true));
46 boilerplate_conv(MR
, ns_t_mr
, conv
.xfrLabel(d_alias
, true));
47 boilerplate_conv(TXT
, ns_t_txt
, conv
.xfrText(d_text
, true));
48 boilerplate_conv(SPF
, 99, conv
.xfrText(d_text
, true));
49 boilerplate_conv(HINFO
, ns_t_hinfo
, conv
.xfrText(d_cpu
); conv
.xfrText(d_host
));
51 boilerplate_conv(RP
, ns_t_rp
,
52 conv
.xfrLabel(d_mbox
);
57 boilerplate_conv(OPT
, ns_t_opt
,
61 void OPTRecordContent::getData(vector
<pair
<uint16_t, string
> >& options
)
63 string::size_type pos
=0;
65 while(d_data
.size() >= 4 + pos
) {
66 code
= 256 * (unsigned char)d_data
[pos
] + (unsigned char)d_data
[pos
+1];
67 len
= 256 * (unsigned char)d_data
[pos
+2] + (unsigned char)d_data
[pos
+3];
70 if(pos
+ len
> d_data
.size())
73 string
field(d_data
.c_str() + pos
, len
);
75 options
.push_back(make_pair(code
, field
));
79 boilerplate_conv(TSIG
, ns_t_tsig
,
80 conv
.xfrLabel(d_algoName
);
81 conv
.xfr48BitInt(d_time
);
82 conv
.xfr16BitInt(d_fudge
);
83 uint16_t size
=d_mac
.size();
84 conv
.xfr16BitInt(size
);
85 conv
.xfrBlob(d_mac
, size
);
86 conv
.xfr16BitInt(d_origID
);
87 conv
.xfr16BitInt(d_eRcode
);
88 size
=d_otherData
.size();
89 conv
.xfr16BitInt(size
);
90 if (size
>0) conv
.xfrBlob(d_otherData
, size
);
93 MXRecordContent::MXRecordContent(uint16_t preference
, const string
& mxname
) : DNSRecordContent(ns_t_mx
), d_preference(preference
), d_mxname(mxname
)
97 boilerplate_conv(MX
, ns_t_mx
,
98 conv
.xfr16BitInt(d_preference
);
99 conv
.xfrLabel(d_mxname
, true);
102 boilerplate_conv(KX
, ns_t_kx
,
103 conv
.xfr16BitInt(d_preference
);
104 conv
.xfrLabel(d_exchanger
, false);
107 boilerplate_conv(IPSECKEY
, ns_t_ipseckey
,
108 conv
.xfr8BitInt(d_preference
);
109 conv
.xfr8BitInt(d_gatewaytype
);
110 conv
.xfr8BitInt(d_algorithm
);
112 // now we need to determine values
113 switch(d_gatewaytype
) {
123 conv
.xfrLabel(d_gateway
, false);
126 throw MOADNSException("Parsing record content: invalid gateway type");
129 switch(d_algorithm
) {
134 conv
.xfrBlob(d_publickey
);
137 throw MOADNSException("Parsing record content: invalid algorithm type");
141 boilerplate_conv(DHCID
, 49,
142 conv
.xfrBlob(d_content
);
146 boilerplate_conv(AFSDB
, ns_t_afsdb
,
147 conv
.xfr16BitInt(d_subtype
);
148 conv
.xfrLabel(d_hostname
);
152 boilerplate_conv(NAPTR
, ns_t_naptr
,
153 conv
.xfr16BitInt(d_order
); conv
.xfr16BitInt(d_preference
);
154 conv
.xfrText(d_flags
); conv
.xfrText(d_services
); conv
.xfrText(d_regexp
);
155 conv
.xfrLabel(d_replacement
);
159 SRVRecordContent::SRVRecordContent(uint16_t preference
, uint16_t weight
, uint16_t port
, const string
& target
)
160 : DNSRecordContent(ns_t_srv
), d_preference(preference
), d_weight(weight
), d_port(port
), d_target(target
)
163 boilerplate_conv(SRV
, ns_t_srv
,
164 conv
.xfr16BitInt(d_preference
); conv
.xfr16BitInt(d_weight
); conv
.xfr16BitInt(d_port
);
165 conv
.xfrLabel(d_target
);
170 SOARecordContent::SOARecordContent(const string
& mname
, const string
& rname
, const struct soatimes
& st
)
171 : DNSRecordContent(ns_t_soa
), d_mname(mname
), d_rname(rname
)
176 boilerplate_conv(SOA
, ns_t_soa
,
177 conv
.xfrLabel(d_mname
, true);
178 conv
.xfrLabel(d_rname
, true);
179 conv
.xfr32BitInt(d_st
.serial
);
180 conv
.xfr32BitInt(d_st
.refresh
);
181 conv
.xfr32BitInt(d_st
.retry
);
182 conv
.xfr32BitInt(d_st
.expire
);
183 conv
.xfr32BitInt(d_st
.minimum
);
186 boilerplate_conv(KEY
, ns_t_key
,
187 conv
.xfr16BitInt(d_flags
);
188 conv
.xfr8BitInt(d_protocol
);
189 conv
.xfr8BitInt(d_algorithm
);
190 conv
.xfrBlob(d_certificate
);
193 boilerplate_conv(CERT
, 37,
194 conv
.xfr16BitInt(d_type
);
195 conv
.xfr16BitInt(d_tag
);
196 conv
.xfr8BitInt(d_algorithm
);
197 conv
.xfrBlob(d_certificate
);
200 boilerplate_conv(TLSA
, 52,
201 conv
.xfr8BitInt(d_certusage
);
202 conv
.xfr8BitInt(d_selector
);
203 conv
.xfr8BitInt(d_matchtype
);
204 conv
.xfrHexBlob(d_cert
, true);
208 DSRecordContent::DSRecordContent() : DNSRecordContent(43) {}
209 boilerplate_conv(DS
, 43,
210 conv
.xfr16BitInt(d_tag
);
211 conv
.xfr8BitInt(d_algorithm
);
212 conv
.xfr8BitInt(d_digesttype
);
213 conv
.xfrHexBlob(d_digest
, true); // keep reading across spaces
216 DLVRecordContent::DLVRecordContent() : DNSRecordContent(32769) {}
217 boilerplate_conv(DLV
,32769 ,
218 conv
.xfr16BitInt(d_tag
);
219 conv
.xfr8BitInt(d_algorithm
);
220 conv
.xfr8BitInt(d_digesttype
);
221 conv
.xfrHexBlob(d_digest
, true); // keep reading across spaces
225 boilerplate_conv(SSHFP
, 44,
226 conv
.xfr8BitInt(d_algorithm
);
227 conv
.xfr8BitInt(d_fptype
);
228 conv
.xfrHexBlob(d_fingerprint
);
231 boilerplate_conv(RRSIG
, 46,
232 conv
.xfrType(d_type
);
233 conv
.xfr8BitInt(d_algorithm
);
234 conv
.xfr8BitInt(d_labels
);
235 conv
.xfr32BitInt(d_originalttl
);
236 conv
.xfrTime(d_sigexpire
);
237 conv
.xfrTime(d_siginception
);
238 conv
.xfr16BitInt(d_tag
);
239 conv
.xfrLabel(d_signer
);
240 conv
.xfrBlob(d_signature
);
243 RRSIGRecordContent::RRSIGRecordContent() : DNSRecordContent(46) {}
245 boilerplate_conv(DNSKEY
, 48,
246 conv
.xfr16BitInt(d_flags
);
247 conv
.xfr8BitInt(d_protocol
);
248 conv
.xfr8BitInt(d_algorithm
);
251 DNSKEYRecordContent::DNSKEYRecordContent() : DNSRecordContent(48) {}
255 void EUI48RecordContent::report(void)
257 regist(1, ns_t_eui48
, &make
, &make
, "EUI48");
259 DNSRecordContent
* EUI48RecordContent::make(const DNSRecord
&dr
, PacketReader
& pr
)
262 throw MOADNSException("Wrong size for EUI48 record");
264 EUI48RecordContent
* ret
=new EUI48RecordContent();
265 pr
.copyRecord((uint8_t*) &ret
->d_eui48
, 6);
268 DNSRecordContent
* EUI48RecordContent::make(const string
& zone
)
271 EUI48RecordContent
*ret
=new EUI48RecordContent();
272 // format is 6 hex bytes and dashes
273 if (sscanf(zone
.c_str(), "%2hhx-%2hhx-%2hhx-%2hhx-%2hhx-%2hhx",
274 ret
->d_eui48
, ret
->d_eui48
+1, ret
->d_eui48
+2,
275 ret
->d_eui48
+3, ret
->d_eui48
+4, ret
->d_eui48
+5) != 6) {
276 throw MOADNSException("Asked to encode '"+zone
+"' as an EUI48 address, but does not parse");
280 void EUI48RecordContent::toPacket(DNSPacketWriter
& pw
)
282 string
blob(d_eui48
, d_eui48
+6);
285 string
EUI48RecordContent::getZoneRepresentation() const
288 snprintf(tmp
,18,"%02x-%02x-%02x-%02x-%02x-%02x",
289 d_eui48
[0], d_eui48
[1], d_eui48
[2],
290 d_eui48
[3], d_eui48
[4], d_eui48
[5]);
298 void EUI64RecordContent::report(void)
300 regist(1, ns_t_eui64
, &make
, &make
, "EUI64");
302 DNSRecordContent
* EUI64RecordContent::make(const DNSRecord
&dr
, PacketReader
& pr
)
305 throw MOADNSException("Wrong size for EUI64 record");
307 EUI64RecordContent
* ret
=new EUI64RecordContent();
308 pr
.copyRecord((uint8_t*) &ret
->d_eui64
, 8);
311 DNSRecordContent
* EUI64RecordContent::make(const string
& zone
)
314 EUI64RecordContent
*ret
=new EUI64RecordContent();
315 // format is 8 hex bytes and dashes
316 if (sscanf(zone
.c_str(), "%2hhx-%2hhx-%2hhx-%2hhx-%2hhx-%2hhx-%2hhx-%2hhx",
317 ret
->d_eui64
, ret
->d_eui64
+1, ret
->d_eui64
+2,
318 ret
->d_eui64
+3, ret
->d_eui64
+4, ret
->d_eui64
+5,
319 ret
->d_eui64
+6, ret
->d_eui64
+7) != 8) {
320 throw MOADNSException("Asked to encode '"+zone
+"' as an EUI64 address, but does not parse");
324 void EUI64RecordContent::toPacket(DNSPacketWriter
& pw
)
326 string
blob(d_eui64
, d_eui64
+8);
329 string
EUI64RecordContent::getZoneRepresentation() const
332 snprintf(tmp
,24,"%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
333 d_eui64
[0], d_eui64
[1], d_eui64
[2],
334 d_eui64
[3], d_eui64
[4], d_eui64
[5],
335 d_eui64
[6], d_eui64
[7]);
342 uint16_t DNSKEYRecordContent::getTag()
344 string data
=this->serialize("");
345 const unsigned char* key
=(const unsigned char*)data
.c_str();
346 unsigned int keysize
=data
.length();
348 unsigned long ac
; /* assumed to be 32 bits or larger */
349 unsigned int i
; /* loop index */
351 for ( ac
= 0, i
= 0; i
< keysize
; ++i
)
352 ac
+= (i
& 1) ? key
[i
] : key
[i
] << 8;
353 ac
+= (ac
>> 16) & 0xFFFF;
358 boilerplate_conv(URL
, QType::URL
,
359 conv
.xfrLabel(d_url
);
362 boilerplate_conv(MBOXFW
, QType::MBOXFW
,
363 conv
.xfrLabel(d_mboxfw
);
368 bool getEDNSOpts(const MOADNSParser
& mdp
, EDNSOpts
* eo
)
370 if(mdp
.d_header
.arcount
&& !mdp
.d_answers
.empty()) {
371 BOOST_FOREACH(const MOADNSParser::answers_t::value_type
& val
, mdp
.d_answers
) {
372 if(val
.first
.d_place
== DNSRecord::Additional
&& val
.first
.d_type
== QType::OPT
) {
373 eo
->d_packetsize
=val
.first
.d_class
;
376 uint32_t ttl
=ntohl(val
.first
.d_ttl
);
377 memcpy(&stuff
, &ttl
, sizeof(stuff
));
379 eo
->d_extRCode
=stuff
.extRCode
;
380 eo
->d_version
=stuff
.version
;
381 eo
->d_Z
= ntohs(stuff
.Z
);
382 OPTRecordContent
* orc
=
383 dynamic_cast<OPTRecordContent
*>(val
.first
.d_content
.get());
386 orc
->getData(eo
->d_options
);
395 void reportBasicTypes()
397 ARecordContent::report();
398 AAAARecordContent::report();
399 NSRecordContent::report();
400 CNAMERecordContent::report();
401 MXRecordContent::report();
402 SOARecordContent::report();
403 SRVRecordContent::report();
404 PTRRecordContent::report();
405 //DNSRecordContent::regist(3, ns_t_txt, &TXTRecordContent::make, &TXTRecordContent::make, "TXT");
406 TXTRecordContent::report();
407 TXTRecordContent::report();
408 DNSRecordContent::regist(1, QType::ANY
, 0, 0, "ANY");
411 void reportOtherTypes()
413 AFSDBRecordContent::report();
414 SPFRecordContent::report();
415 NAPTRRecordContent::report();
416 LOCRecordContent::report();
417 HINFORecordContent::report();
418 RPRecordContent::report();
419 KEYRecordContent::report();
420 DNSKEYRecordContent::report();
421 RRSIGRecordContent::report();
422 DSRecordContent::report();
423 SSHFPRecordContent::report();
424 CERTRecordContent::report();
425 NSECRecordContent::report();
426 NSEC3RecordContent::report();
427 NSEC3PARAMRecordContent::report();
428 TLSARecordContent::report();
429 DLVRecordContent::report();
430 //DNSRecordContent::regist(0xff, QType::TSIG, &TSIGRecordContent::make, &TSIGRecordContent::make, "TSIG");
431 TSIGRecordContent::report();
432 OPTRecordContent::report();
433 EUI48RecordContent::report();
434 EUI64RecordContent::report();
437 void reportFancyTypes()
439 URLRecordContent::report();
440 MBOXFWRecordContent::report();
443 void reportAllTypes()
450 static struct Reporter
456 } reporter
__attribute__((init_priority(65535)));