]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/nsecrecords.cc
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
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.
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.
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.
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.
25 #include "dnsrecords.hh"
27 class NSECBitmapGenerator
30 NSECBitmapGenerator(DNSPacketWriter
& pw_
): pw(pw_
)
32 memset(res
, 0, sizeof(res
));
35 void set(uint16_t type
)
37 uint16_t bit
= type
% 256;
38 int window
= static_cast<int>(type
/ 256);
40 if (window
!= oldWindow
) {
42 res
[0] = static_cast<unsigned char>(oldWindow
);
43 res
[1] = static_cast<unsigned char>(len
);
44 tmp
.assign(res
, res
+len
+2);
47 memset(res
, 0, sizeof(res
));
50 res
[2+bit
/8] |= 1 << (7-(bit
%8));
56 res
[0] = static_cast<unsigned char>(oldWindow
);
57 res
[1] = static_cast<unsigned char>(len
);
59 tmp
.assign(res
, res
+len
+2);
66 /* one byte for the window,
68 then the maximum of 32 bytes */
75 void NSECBitmap::toPacket(DNSPacketWriter
& pw
) const
77 NSECBitmapGenerator
nbg(pw
);
80 size_t l_count
= d_bitset
->count();
81 for(size_t idx
= 0; idx
< nbTypes
&& found
< l_count
; ++idx
){
82 if (!d_bitset
->test(idx
)) {
90 for (const auto& type
: d_set
) {
98 void NSECBitmap::fromPacket(PacketReader
& pr
)
103 // 00 06 20 00 00 00 00 03 -> NS RRSIG NSEC ( 2, 46, 47 ) counts from left
108 if(bitmap
.size() < 2) {
109 throw MOADNSException("NSEC record with impossibly small bitmap");
112 for(unsigned int n
= 0; n
+1 < bitmap
.size();) {
113 uint8_t window
=static_cast<uint8_t>(bitmap
[n
++]);
114 uint8_t blen
=static_cast<uint8_t>(bitmap
[n
++]);
116 // end if zero padding and ensure packet length
117 if (window
== 0 && blen
== 0) {
122 throw MOADNSException("NSEC record with invalid bitmap length");
125 if (n
+ blen
> bitmap
.size()) {
126 throw MOADNSException("NSEC record with bitmap length > packet length");
129 for(unsigned int k
=0; k
< blen
; k
++) {
130 uint8_t val
=bitmap
[n
++];
131 for(int bit
= 0; bit
< 8 ; ++bit
, val
>>=1) {
133 set((7-bit
) + 8*(k
) + 256*window
);
140 string
NSECBitmap::getZoneRepresentation() const
146 size_t l_count
= d_bitset
->count();
147 for(size_t idx
= 0; idx
< nbTypes
&& found
< l_count
; ++idx
) {
148 if (!d_bitset
->test(idx
)) {
154 ret
+=DNSRecordContent::NumberToType(idx
);
158 for(const auto& type
: d_set
) {
160 ret
+=DNSRecordContent::NumberToType(type
);
167 void NSECRecordContent::report()
169 regist(1, 47, &make
, &make
, "NSEC");
172 std::shared_ptr
<DNSRecordContent
> NSECRecordContent::make(const string
& content
)
174 return std::make_shared
<NSECRecordContent
>(content
);
177 NSECRecordContent::NSECRecordContent(const string
& content
, const DNSName
& zone
)
179 RecordTextReader
rtr(content
, zone
);
189 void NSECRecordContent::toPacket(DNSPacketWriter
& pw
) const
192 d_bitmap
.toPacket(pw
);
195 std::shared_ptr
<NSECRecordContent::DNSRecordContent
> NSECRecordContent::make(const DNSRecord
& /* dr */, PacketReader
& pr
)
197 auto ret
=std::make_shared
<NSECRecordContent
>();
198 pr
.xfrName(ret
->d_next
);
200 ret
->d_bitmap
.fromPacket(pr
);
205 string
NSECRecordContent::getZoneRepresentation(bool /* noDot */) const
208 RecordTextWriter
rtw(ret
);
211 return ret
+ d_bitmap
.getZoneRepresentation();
214 ////// begin of NSEC3
216 void NSEC3RecordContent::report()
218 regist(1, 50, &make
, &make
, "NSEC3");
221 std::shared_ptr
<DNSRecordContent
> NSEC3RecordContent::make(const string
& content
)
223 return std::make_shared
<NSEC3RecordContent
>(content
);
226 NSEC3RecordContent::NSEC3RecordContent(const string
& content
, const DNSName
& zone
)
228 RecordTextReader
rtr(content
, zone
);
229 rtr
.xfr8BitInt(d_algorithm
);
230 rtr
.xfr8BitInt(d_flags
);
231 rtr
.xfr16BitInt(d_iterations
);
233 rtr
.xfrHexBlob(d_salt
);
234 rtr
.xfrBase32HexBlob(d_nexthash
);
243 void NSEC3RecordContent::toPacket(DNSPacketWriter
& pw
) const
245 pw
.xfr8BitInt(d_algorithm
);
246 pw
.xfr8BitInt(d_flags
);
247 pw
.xfr16BitInt(d_iterations
);
248 pw
.xfr8BitInt(d_salt
.length());
251 pw
.xfr8BitInt(d_nexthash
.length());
252 pw
.xfrBlob(d_nexthash
);
254 d_bitmap
.toPacket(pw
);
257 std::shared_ptr
<NSEC3RecordContent::DNSRecordContent
> NSEC3RecordContent::make(const DNSRecord
& /* dr */, PacketReader
& pr
)
259 auto ret
=std::make_shared
<NSEC3RecordContent
>();
260 pr
.xfr8BitInt(ret
->d_algorithm
);
261 pr
.xfr8BitInt(ret
->d_flags
);
262 pr
.xfr16BitInt(ret
->d_iterations
);
265 pr
.xfrBlob(ret
->d_salt
, len
);
268 pr
.xfrBlob(ret
->d_nexthash
, len
);
270 ret
->d_bitmap
.fromPacket(pr
);
274 string
NSEC3RecordContent::getZoneRepresentation(bool /* noDot */) const
277 RecordTextWriter
rtw(ret
);
278 rtw
.xfr8BitInt(d_algorithm
);
279 rtw
.xfr8BitInt(d_flags
);
280 rtw
.xfr16BitInt(d_iterations
);
282 rtw
.xfrHexBlob(d_salt
);
283 rtw
.xfrBase32HexBlob(d_nexthash
);
285 return ret
+ d_bitmap
.getZoneRepresentation();
289 void NSEC3PARAMRecordContent::report()
291 regist(1, 51, &make
, &make
, "NSEC3PARAM");
292 regist(254, 51, &make
, &make
, "NSEC3PARAM");
295 std::shared_ptr
<DNSRecordContent
> NSEC3PARAMRecordContent::make(const string
& content
)
297 return std::make_shared
<NSEC3PARAMRecordContent
>(content
);
300 NSEC3PARAMRecordContent::NSEC3PARAMRecordContent(const string
& content
, const DNSName
& zone
)
302 RecordTextReader
rtr(content
, zone
);
303 rtr
.xfr8BitInt(d_algorithm
);
304 rtr
.xfr8BitInt(d_flags
);
305 rtr
.xfr16BitInt(d_iterations
);
306 rtr
.xfrHexBlob(d_salt
);
309 void NSEC3PARAMRecordContent::toPacket(DNSPacketWriter
& pw
) const
311 pw
.xfr8BitInt(d_algorithm
);
312 pw
.xfr8BitInt(d_flags
);
313 pw
.xfr16BitInt(d_iterations
);
314 pw
.xfr8BitInt(d_salt
.length());
315 // cerr<<"salt: '"<<makeHexDump(d_salt)<<"', "<<d_salt.length()<<endl;
319 std::shared_ptr
<NSEC3PARAMRecordContent::DNSRecordContent
> NSEC3PARAMRecordContent::make(const DNSRecord
& /* dr */, PacketReader
& pr
)
321 auto ret
=std::make_shared
<NSEC3PARAMRecordContent
>();
322 pr
.xfr8BitInt(ret
->d_algorithm
);
323 pr
.xfr8BitInt(ret
->d_flags
);
324 pr
.xfr16BitInt(ret
->d_iterations
);
327 pr
.xfrHexBlob(ret
->d_salt
, len
);
331 string
NSEC3PARAMRecordContent::getZoneRepresentation(bool /* noDot */) const
334 RecordTextWriter
rtw(ret
);
335 rtw
.xfr8BitInt(d_algorithm
);
336 rtw
.xfr8BitInt(d_flags
);
337 rtw
.xfr16BitInt(d_iterations
);
338 rtw
.xfrHexBlob(d_salt
);
344 ////// begin of CSYNC
346 void CSYNCRecordContent::report()
348 regist(1, 62, &make
, &make
, "CSYNC");
351 std::shared_ptr
<DNSRecordContent
> CSYNCRecordContent::make(const string
& content
)
353 return std::make_shared
<CSYNCRecordContent
>(content
);
356 CSYNCRecordContent::CSYNCRecordContent(const string
& content
, const DNSName
& zone
)
358 RecordTextReader
rtr(content
, zone
);
359 rtr
.xfr32BitInt(d_serial
);
360 rtr
.xfr16BitInt(d_flags
);
369 void CSYNCRecordContent::toPacket(DNSPacketWriter
& pw
) const
371 pw
.xfr32BitInt(d_serial
);
372 pw
.xfr16BitInt(d_flags
);
374 d_bitmap
.toPacket(pw
);
377 std::shared_ptr
<CSYNCRecordContent::DNSRecordContent
> CSYNCRecordContent::make(const DNSRecord
& /* dr */, PacketReader
& pr
)
379 auto ret
=std::make_shared
<CSYNCRecordContent
>();
380 pr
.xfr32BitInt(ret
->d_serial
);
381 pr
.xfr16BitInt(ret
->d_flags
);
383 ret
->d_bitmap
.fromPacket(pr
);
387 string
CSYNCRecordContent::getZoneRepresentation(bool /* noDot */) const
390 RecordTextWriter
rtw(ret
);
391 rtw
.xfr32BitInt(d_serial
);
392 rtw
.xfr16BitInt(d_flags
);
394 return ret
+ d_bitmap
.getZoneRepresentation();