root/trunk/pdns/pdns/nsecrecords.cc @ 1614

Revision 1614, 5.9 KB (checked in by ahu, 3 years ago)

fix up NSEC3 rendering/generation/parsing

Line 
1#include "dnsrecords.hh"
2
3void NSECRecordContent::report(void)
4{
5  regist(1, 47, &make, &make, "NSEC");
6}
7
8DNSRecordContent* NSECRecordContent::make(const string& content)
9{
10  return new NSECRecordContent(content);
11}
12
13NSECRecordContent::NSECRecordContent(const string& content, const string& zone) : DNSRecordContent(47)
14{
15  RecordTextReader rtr(content, zone);
16  rtr.xfrLabel(d_next);
17
18  while(!rtr.eof()) {
19    uint16_t type;
20    rtr.xfrType(type);
21    d_set.insert(type);
22  }
23}
24
25void NSECRecordContent::toPacket(DNSPacketWriter& pw) 
26{
27  pw.xfrLabel(d_next);
28
29  uint8_t res[34];
30  memset(res, 0, sizeof(res));
31
32  set<uint16_t>::const_iterator i;
33  for(i=d_set.begin(); i != d_set.end() && *i<255; ++i){
34    res[2+*i/8] |= 1 << (7-(*i%8));
35  }
36  int len=0;
37  if(!d_set.empty()) 
38    len=1+*--i/8;
39
40  res[1]=len;
41
42  string tmp;
43  tmp.assign(res, res+len+2);
44  pw.xfrBlob(tmp);
45}
46
47NSECRecordContent::DNSRecordContent* NSECRecordContent::make(const DNSRecord &dr, PacketReader& pr) 
48{
49  NSECRecordContent* ret=new NSECRecordContent();
50  pr.xfrLabel(ret->d_next);
51  string bitmap;
52  pr.xfrBlob(bitmap);
53 
54  // 00 06 20 00 00 00 00 03  -> NS RRSIG NSEC  ( 2, 46, 47 ) counts from left
55 
56  if(bitmap.size() < 2)
57    throw MOADNSException("NSEC record with impossibly small bitmap");
58 
59  if(bitmap[0])
60    throw MOADNSException("Can't deal with NSEC mappings > 255 yet");
61 
62  unsigned int len=bitmap[1];
63  if(bitmap.size()!=2+len)
64    throw MOADNSException("Can't deal with multi-part NSEC mappings yet");
65 
66  for(unsigned int n=0 ; n < len ; ++n) {
67    uint8_t val=bitmap[2+n];
68    for(int bit = 0; bit < 8 ; ++bit , val>>=1)
69      if(val & 1) {
70        ret->d_set.insert((7-bit) + 8*(n));
71      }
72  }
73 
74  return ret;
75}
76
77string NSECRecordContent::getZoneRepresentation() const
78{
79  string ret;
80  RecordTextWriter rtw(ret);
81  rtw.xfrLabel(d_next);
82 
83  for(set<uint16_t>::const_iterator i=d_set.begin(); i!=d_set.end(); ++i) {
84    ret+=" ";
85    ret+=NumberToType(*i);
86  }
87 
88  return ret;
89}
90
91////// begin of NSEC3
92
93void NSEC3RecordContent::report(void)
94{
95  regist(1, 50, &make, &make, "NSEC3");
96}
97
98DNSRecordContent* NSEC3RecordContent::make(const string& content)
99{
100  return new NSEC3RecordContent(content);
101}
102
103NSEC3RecordContent::NSEC3RecordContent(const string& content, const string& zone) : DNSRecordContent(50)
104{
105  RecordTextReader rtr(content, zone);
106  rtr.xfr8BitInt(d_algorithm);
107  rtr.xfr8BitInt(d_flags);
108  rtr.xfr16BitInt(d_iterations);
109
110  rtr.xfrHexBlob(d_salt);
111  rtr.xfrBase32HexBlob(d_nexthash);
112 
113  while(!rtr.eof()) {
114    uint16_t type;
115    rtr.xfrType(type);
116    d_set.insert(type);
117  }
118}
119
120void NSEC3RecordContent::toPacket(DNSPacketWriter& pw) 
121{
122  pw.xfr8BitInt(d_algorithm);
123  pw.xfr8BitInt(d_flags);
124  pw.xfr16BitInt(d_iterations);
125  pw.xfr8BitInt(d_salt.length());
126  pw.xfrBlob(d_salt);
127
128  pw.xfr8BitInt(d_nexthash.length());
129  pw.xfrBlob(d_nexthash);
130 
131  uint8_t res[34];
132  memset(res, 0, sizeof(res));
133
134  set<uint16_t>::const_iterator i;
135  for(i=d_set.begin(); i != d_set.end() && *i<255; ++i){
136    res[2+*i/8] |= 1 << (7-(*i%8));
137  }
138  int len=0;
139  if(!d_set.empty()) 
140    len=1+*--i/8;
141
142  res[1]=len;
143
144  string tmp;
145  tmp.assign(res, res+len+2);
146  pw.xfrBlob(tmp);
147}
148
149NSEC3RecordContent::DNSRecordContent* NSEC3RecordContent::make(const DNSRecord &dr, PacketReader& pr) 
150{
151  NSEC3RecordContent* ret=new NSEC3RecordContent();
152  pr.xfr8BitInt(ret->d_algorithm);
153  pr.xfr8BitInt(ret->d_flags);
154  pr.xfr16BitInt(ret->d_iterations);
155  uint8_t len;
156  pr.xfr8BitInt(len);
157  pr.xfrBlob(ret->d_salt, len);
158
159  pr.xfr8BitInt(len);
160 
161  pr.xfrBlob(ret->d_nexthash, len);
162 
163  string bitmap;
164  pr.xfrBlob(bitmap);
165 
166  // 00 06 20 00 00 00 00 03  -> NS RRSIG NSEC  ( 2, 46, 47 ) counts from left
167 
168  if(bitmap.empty())
169    return ret;
170
171  if(bitmap.size() < 2)
172    throw MOADNSException("NSEC3 record with impossibly small bitmap");
173 
174  if(bitmap[0])
175    throw MOADNSException("Can't deal with NSEC3 mappings > 255 yet");
176 
177  unsigned int bitmaplen=bitmap[1];
178  if(bitmap.size()!=2+bitmaplen)
179    throw MOADNSException("Can't deal with multi-part NSEC3 mappings yet");
180 
181  for(unsigned int n=0 ; n < bitmaplen ; ++n) {
182    uint8_t val=bitmap[2+n];
183    for(int bit = 0; bit < 8 ; ++bit , val>>=1)
184      if(val & 1) {
185        ret->d_set.insert((7-bit) + 8*(n));
186      }
187  }
188 
189  return ret;
190}
191
192string NSEC3RecordContent::getZoneRepresentation() const
193{
194  string ret;
195  RecordTextWriter rtw(ret);
196  rtw.xfr8BitInt(d_algorithm);
197  rtw.xfr8BitInt(d_flags);
198  rtw.xfr16BitInt(d_iterations);
199
200  rtw.xfrHexBlob(d_salt);
201  rtw.xfrBase32HexBlob(d_nexthash);
202  for(set<uint16_t>::const_iterator i=d_set.begin(); i!=d_set.end(); ++i) {
203    ret+=" ";
204    ret+=NumberToType(*i);
205  }
206 
207  return ret;
208}
209
210
211void NSEC3PARAMRecordContent::report(void)
212{
213  regist(1, 51, &make, &make, "NSEC3PARAM");
214}
215
216DNSRecordContent* NSEC3PARAMRecordContent::make(const string& content)
217{
218  return new NSEC3PARAMRecordContent(content);
219}
220
221NSEC3PARAMRecordContent::NSEC3PARAMRecordContent(const string& content, const string& zone) : DNSRecordContent(51)
222{
223  RecordTextReader rtr(content, zone);
224  rtr.xfr8BitInt(d_algorithm); 
225  rtr.xfr8BitInt(d_flags); 
226  rtr.xfr16BitInt(d_iterations); 
227  rtr.xfrHexBlob(d_salt);
228}
229
230void NSEC3PARAMRecordContent::toPacket(DNSPacketWriter& pw) 
231{
232  pw.xfr8BitInt(d_algorithm); 
233        pw.xfr8BitInt(d_flags); 
234        pw.xfr16BitInt(d_iterations); 
235  pw.xfr8BitInt(d_salt.length());
236  cerr<<"salt: '"<<makeHexDump(d_salt)<<"', "<<d_salt.length()<<endl;
237  pw.xfrBlob(d_salt);
238}
239
240NSEC3PARAMRecordContent::DNSRecordContent* NSEC3PARAMRecordContent::make(const DNSRecord &dr, PacketReader& pr) 
241{
242  NSEC3PARAMRecordContent* ret=new NSEC3PARAMRecordContent();
243  pr.xfr8BitInt(ret->d_algorithm); 
244        pr.xfr8BitInt(ret->d_flags); 
245        pr.xfr16BitInt(ret->d_iterations); 
246  pr.xfr8BitInt(ret->d_saltlength);
247  pr.xfrHexBlob(ret->d_salt);
248 
249  return ret;
250}
251
252string NSEC3PARAMRecordContent::getZoneRepresentation() const
253{
254  string ret;
255  RecordTextWriter rtw(ret);
256  rtw.xfr8BitInt(d_algorithm); 
257        rtw.xfr8BitInt(d_flags); 
258        rtw.xfr16BitInt(d_iterations); 
259  rtw.xfrHexBlob(d_salt);
260  return ret;
261}
262
Note: See TracBrowser for help on using the browser.