]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/nsecrecords.cc
Merge pull request #7145 from cmouse/m4-lua.hpp
[thirdparty/pdns.git] / pdns / nsecrecords.cc
1 /*
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 */
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 #include "dnsrecords.hh"
26
27 void NSECRecordContent::report(void)
28 {
29 regist(1, 47, &make, &make, "NSEC");
30 }
31
32 std::shared_ptr<DNSRecordContent> NSECRecordContent::make(const string& content)
33 {
34 return std::make_shared<NSECRecordContent>(content);
35 }
36
37 NSECRecordContent::NSECRecordContent(const string& content, const string& zone)
38 {
39 RecordTextReader rtr(content, DNSName(zone));
40 rtr.xfrName(d_next);
41
42 while(!rtr.eof()) {
43 uint16_t type;
44 rtr.xfrType(type);
45 d_set.insert(type);
46 }
47 }
48
49 void NSECRecordContent::toPacket(DNSPacketWriter& pw)
50 {
51 pw.xfrName(d_next);
52
53 uint8_t res[34];
54 set<uint16_t>::const_iterator i;
55 int oldWindow = -1;
56 int window = 0;
57 int len = 0;
58 string tmp;
59
60 for(i=d_set.begin(); i != d_set.end(); ++i){
61 uint16_t bit = (*i)%256;
62 window = static_cast<int>((*i) / 256);
63
64 if (window != oldWindow) {
65 if (oldWindow > -1) {
66 res[0] = static_cast<unsigned char>(oldWindow);
67 res[1] = static_cast<unsigned char>(len);
68 tmp.assign(res, res+len+2);
69 pw.xfrBlob(tmp);
70 }
71 memset(res, 0, 34);
72 oldWindow = window;
73 }
74 res[2+bit/8] |= 1 << (7-(bit%8));
75 len=1+bit/8;
76 }
77
78 res[0] = static_cast<unsigned char>(window);
79 res[1] = static_cast<unsigned char>(len);
80 tmp.assign(res, res+len+2);
81 pw.xfrBlob(tmp);
82 }
83
84 std::shared_ptr<NSECRecordContent::DNSRecordContent> NSECRecordContent::make(const DNSRecord &dr, PacketReader& pr)
85 {
86 auto ret=std::make_shared<NSECRecordContent>();
87 pr.xfrName(ret->d_next);
88 string bitmap;
89 pr.xfrBlob(bitmap);
90
91 // 00 06 20 00 00 00 00 03 -> NS RRSIG NSEC ( 2, 46, 47 ) counts from left
92 if(bitmap.empty())
93 return ret;
94
95 if(bitmap.size() < 2)
96 throw MOADNSException("NSEC record with impossibly small bitmap");
97
98 for(unsigned int n = 0; n+1 < bitmap.size();) {
99 unsigned int window=static_cast<unsigned char>(bitmap[n++]);
100 unsigned int blen=static_cast<unsigned char>(bitmap[n++]);
101
102 // end if zero padding and ensure packet length
103 if(window == 0 && blen == 0) break;
104 if(n + blen > bitmap.size())
105 throw MOADNSException("NSEC record with bitmap length > packet length");
106
107 for(unsigned int k=0; k < blen; k++) {
108 uint8_t val=bitmap[n++];
109 for(int bit = 0; bit < 8 ; ++bit , val>>=1)
110 if(val & 1) {
111 ret->d_set.insert((7-bit) + 8*(k) + 256*window);
112 }
113 }
114 }
115 return ret;
116 }
117
118 string NSECRecordContent::getZoneRepresentation(bool noDot) const
119 {
120 string ret;
121 RecordTextWriter rtw(ret);
122 rtw.xfrName(d_next);
123
124 for(set<uint16_t>::const_iterator i=d_set.begin(); i!=d_set.end(); ++i) {
125 ret+=" ";
126 ret+=NumberToType(*i);
127 }
128
129 return ret;
130 }
131
132 ////// begin of NSEC3
133
134 void NSEC3RecordContent::report(void)
135 {
136 regist(1, 50, &make, &make, "NSEC3");
137 }
138
139 std::shared_ptr<DNSRecordContent> NSEC3RecordContent::make(const string& content)
140 {
141 return std::make_shared<NSEC3RecordContent>(content);
142 }
143
144 NSEC3RecordContent::NSEC3RecordContent(const string& content, const string& zone)
145 {
146 RecordTextReader rtr(content, DNSName(zone));
147 rtr.xfr8BitInt(d_algorithm);
148 rtr.xfr8BitInt(d_flags);
149 rtr.xfr16BitInt(d_iterations);
150
151 rtr.xfrHexBlob(d_salt);
152 rtr.xfrBase32HexBlob(d_nexthash);
153
154 while(!rtr.eof()) {
155 uint16_t type;
156 rtr.xfrType(type);
157 d_set.insert(type);
158 }
159 }
160
161 void NSEC3RecordContent::toPacket(DNSPacketWriter& pw)
162 {
163 pw.xfr8BitInt(d_algorithm);
164 pw.xfr8BitInt(d_flags);
165 pw.xfr16BitInt(d_iterations);
166 pw.xfr8BitInt(d_salt.length());
167 pw.xfrBlob(d_salt);
168
169 pw.xfr8BitInt(d_nexthash.length());
170 pw.xfrBlob(d_nexthash);
171
172 uint8_t res[34];
173 set<uint16_t>::const_iterator i;
174 int oldWindow = -1;
175 int window = 0;
176 int len = 0;
177 string tmp;
178
179 for(i=d_set.begin(); i != d_set.end(); ++i){
180 uint16_t bit = (*i)%256;
181 window = static_cast<int>((*i) / 256);
182
183 if (window != oldWindow) {
184 if (oldWindow > -1) {
185 res[0] = static_cast<unsigned char>(oldWindow);
186 res[1] = static_cast<unsigned char>(len);
187 tmp.assign(res, res+len+2);
188 pw.xfrBlob(tmp);
189 }
190 memset(res, 0, 34);
191 oldWindow = window;
192 }
193 res[2+bit/8] |= 1 << (7-(bit%8));
194 len=1+bit/8;
195 }
196
197 res[0] = static_cast<unsigned char>(window);
198 res[1] = static_cast<unsigned char>(len);
199
200 if (len) {
201 tmp.assign(res, res+len+2);
202 pw.xfrBlob(tmp);
203 }
204 }
205
206 std::shared_ptr<NSEC3RecordContent::DNSRecordContent> NSEC3RecordContent::make(const DNSRecord &dr, PacketReader& pr)
207 {
208 auto ret=std::make_shared<NSEC3RecordContent>();
209 pr.xfr8BitInt(ret->d_algorithm);
210 pr.xfr8BitInt(ret->d_flags);
211 pr.xfr16BitInt(ret->d_iterations);
212 uint8_t len;
213 pr.xfr8BitInt(len);
214 pr.xfrBlob(ret->d_salt, len);
215
216 pr.xfr8BitInt(len);
217 pr.xfrBlob(ret->d_nexthash, len);
218
219 string bitmap;
220 pr.xfrBlob(bitmap);
221
222 // 00 06 20 00 00 00 00 03 -> NS RRSIG NSEC ( 2, 46, 47 ) counts from left
223
224 if(bitmap.empty())
225 return ret;
226
227 if(bitmap.size() < 2)
228 throw MOADNSException("NSEC3 record with impossibly small bitmap");
229
230 for(unsigned int n = 0; n+1 < bitmap.size();) {
231 unsigned int window=static_cast<unsigned char>(bitmap[n++]);
232 unsigned int innerlen=static_cast<unsigned char>(bitmap[n++]);
233
234 // end if zero padding and ensure packet length
235 if(window == 0&&innerlen == 0) break;
236 if(n+innerlen>bitmap.size())
237 throw MOADNSException("NSEC record with bitmap length > packet length");
238
239 for(unsigned int k=0; k < innerlen; k++) {
240 uint8_t val=bitmap[n++];
241 for(int bit = 0; bit < 8 ; ++bit , val>>=1)
242 if(val & 1) {
243 ret->d_set.insert((7-bit) + 8*(k) + 256*window);
244 }
245 }
246 }
247 return ret;
248 }
249
250 string NSEC3RecordContent::getZoneRepresentation(bool noDot) const
251 {
252 string ret;
253 RecordTextWriter rtw(ret);
254 rtw.xfr8BitInt(d_algorithm);
255 rtw.xfr8BitInt(d_flags);
256 rtw.xfr16BitInt(d_iterations);
257
258 rtw.xfrHexBlob(d_salt);
259 rtw.xfrBase32HexBlob(d_nexthash);
260 for(set<uint16_t>::const_iterator i=d_set.begin(); i!=d_set.end(); ++i) {
261 ret+=" ";
262 ret+=NumberToType(*i);
263 }
264
265 return ret;
266 }
267
268
269 void NSEC3PARAMRecordContent::report(void)
270 {
271 regist(1, 51, &make, &make, "NSEC3PARAM");
272 regist(254, 51, &make, &make, "NSEC3PARAM");
273 }
274
275 std::shared_ptr<DNSRecordContent> NSEC3PARAMRecordContent::make(const string& content)
276 {
277 return std::make_shared<NSEC3PARAMRecordContent>(content);
278 }
279
280 NSEC3PARAMRecordContent::NSEC3PARAMRecordContent(const string& content, const string& zone)
281 {
282 RecordTextReader rtr(content, DNSName(zone));
283 rtr.xfr8BitInt(d_algorithm);
284 rtr.xfr8BitInt(d_flags);
285 rtr.xfr16BitInt(d_iterations);
286 rtr.xfrHexBlob(d_salt);
287 }
288
289 void NSEC3PARAMRecordContent::toPacket(DNSPacketWriter& pw)
290 {
291 pw.xfr8BitInt(d_algorithm);
292 pw.xfr8BitInt(d_flags);
293 pw.xfr16BitInt(d_iterations);
294 pw.xfr8BitInt(d_salt.length());
295 // cerr<<"salt: '"<<makeHexDump(d_salt)<<"', "<<d_salt.length()<<endl;
296 pw.xfrBlob(d_salt);
297 }
298
299 std::shared_ptr<NSEC3PARAMRecordContent::DNSRecordContent> NSEC3PARAMRecordContent::make(const DNSRecord &dr, PacketReader& pr)
300 {
301 auto ret=std::make_shared<NSEC3PARAMRecordContent>();
302 pr.xfr8BitInt(ret->d_algorithm);
303 pr.xfr8BitInt(ret->d_flags);
304 pr.xfr16BitInt(ret->d_iterations);
305 uint8_t len;
306 pr.xfr8BitInt(len);
307 pr.xfrHexBlob(ret->d_salt, len);
308 return ret;
309 }
310
311 string NSEC3PARAMRecordContent::getZoneRepresentation(bool noDot) const
312 {
313 string ret;
314 RecordTextWriter rtw(ret);
315 rtw.xfr8BitInt(d_algorithm);
316 rtw.xfr8BitInt(d_flags);
317 rtw.xfr16BitInt(d_iterations);
318 rtw.xfrHexBlob(d_salt);
319 return ret;
320 }
321