2
2
PowerDNS Versatile Database Driven Nameserver
3
Copyright (C) 2005 PowerDNS.COM BV
3
Copyright (C) 2005 - 2007 PowerDNS.COM BV
5
5
This program is free software; you can redistribute it and/or modify
6
6
it under the terms of the GNU General Public License version 2 as
14
14
You should have received a copy of the GNU General Public License
15
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
19
#include "rcpgenerator.hh"
67
67
if(!isdigit(d_string.at(d_pos)))
68
throw RecordTextException("expected digits at position "+lexical_cast<string>(d_pos)+" in '"+d_string+"'");
68
throw RecordTextException("while parsing IP address, expected digits at position "+lexical_cast<string>(d_pos)+" in '"+d_string+"'");
72
if(!IpToU32(ip, &val))
73
throw RecordTextException("unable to parse IP address '"+ip+"'");
75
if(d_string.at(d_pos)=='.') {
83
else if(isdigit(d_string.at(d_pos))) {
85
octet+=d_string.at(d_pos) - '0';
87
throw RecordTextException("unable to parse IP address");
89
else if(dns_isspace(d_string.at(d_pos)))
92
throw RecordTextException("unable to parse IP address, strange character: "+d_string.at(d_pos));
95
if(d_pos == d_string.length())
97
126
throw RecordTextException("Overflow reading 8 bit integer from record content"); // fixme improve
101
void RecordTextReader::xfrLabel(string& val, bool)
129
void RecordTextReader::xfrLabel(string& val, bool)
106
133
val.reserve(d_end - d_pos);
135
const char* strptr=d_string.c_str();
108
136
while(d_pos < d_end) {
109
if(dns_isspace(d_string[d_pos]))
137
if(dns_isspace(strptr[d_pos]))
112
if(d_string[d_pos]=='\\' && d_pos < d_end - 1)
140
if(strptr[d_pos]=='\\' && d_pos < d_end - 1 && strptr[d_pos+1]!='.') // leave the \. escape around
115
val.append(1, d_string[d_pos]);
143
val.append(1, strptr[d_pos]);
141
170
B64Decode(tmp, val);
144
void RecordTextReader::xfrText(string& val)
174
static inline uint8_t hextodec(uint8_t val)
176
if(val >= '0' && val<='9')
178
else if(val >= 'A' && val<='F')
180
else if(val >= 'a' && val<='f')
183
throw RecordTextException("Unknown hexadecimal character '"+lexical_cast<string>(val)+"'");
187
void HEXDecode(const char* begin, const char* end, string& val)
190
throw RecordTextException("Hexadecimal blob with odd number of characters");
192
int limit=(int)(end-begin)/2;
194
for(int n=0; n < limit; ++n) {
195
val[n] = hextodec(begin[2*n])*16 + hextodec(begin[2*n+1]);
199
void RecordTextReader::xfrHexBlob(string& val)
147
if(d_string[d_pos]!='"')
148
throw RecordTextException("Data field in DNS should start with quote (\") at position "+lexical_cast<string>(d_pos)+" of '"+d_string+"'");
203
while(d_pos < d_end && !dns_isspace(d_string[d_pos]))
206
HEXDecode(d_string.c_str()+pos, d_string.c_str() + d_pos, val);
209
void RecordTextReader::xfrText(string& val, bool multi)
151
212
val.reserve(d_end - d_pos);
153
while(++d_pos < d_end && d_string[d_pos]!='"') {
154
if(d_string[d_pos]=='\\' && d_pos+1!=d_end) {
214
while(d_pos != d_end) {
219
if(d_string[d_pos]!='"')
220
throw RecordTextException("Data field in DNS should start with quote (\") at position "+lexical_cast<string>(d_pos)+" of '"+d_string+"'");
223
while(++d_pos < d_end && d_string[d_pos]!='"') {
224
if(d_string[d_pos]=='\\' && d_pos+1!=d_end) {
225
val.append(1, d_string[d_pos++]);
227
val.append(1, d_string[d_pos]);
157
val.append(1, d_string[d_pos]);
231
throw RecordTextException("Data field in DNS should end on a quote (\") in '"+d_string+"'");
160
throw RecordTextException("Data field in DNS should end on a quote (\") in '"+d_string+"'");
164
238
void RecordTextReader::xfrType(uint16_t& val)
168
242
while(d_pos < d_end && !dns_isspace(d_string[d_pos]))
178
252
void RecordTextReader::skipSpaces()
180
while(d_pos < d_end && dns_isspace(d_string[d_pos]))
254
const char* strptr = d_string.c_str();
255
while(d_pos < d_end && dns_isspace(strptr[d_pos]))
183
257
if(d_pos == d_end)
184
258
throw RecordTextException("missing field at the end of record content '"+d_string+"'");
213
287
d_string.append(1,' ');
216
snprintf(tmp, sizeof(tmp)-1, "%u.%u.%u.%u",
290
uint32_t ip=htonl(val);
293
memcpy(&vals[0], &ip, sizeof(ip));
297
for(int n=0; n < 4; ++n) {
299
*(pos++)=vals[n]+'0';
300
} else if(vals[n] < 100) {
301
*(pos++)=(vals[n]/10) +'0';
302
*(pos++)=(vals[n]%10) +'0';
304
*(pos++)=(vals[n]/100) +'0';
306
*(pos++)=(vals[n]/10) +'0';
307
*(pos++)=(vals[n]%10) +'0';
313
d_string.append(tmp, pos);
232
323
time_t time=val; // Y2038 bug!
233
325
gmtime_r(&time, &tm);
330
throw RecordTextException("Unable to convert timestamp into pretty printable time");
236
335
snprintf(tmp,sizeof(tmp)-1, "%04d%02d%02d" "%02d%02d%02d",
279
378
d_string+=Base64Encode(val);
282
void RecordTextWriter::xfrText(const string& val)
381
void RecordTextWriter::xfrHexBlob(const string& val)
284
383
if(!d_string.empty())
285
384
d_string.append(1,' ');
286
d_string.append(1,'"');
288
if(val.find_first_of("\\\"") == string::npos)
291
string::size_type end=val.size();
293
for(string::size_type pos=0; pos < end; ++pos) {
294
if(val[pos]=='\'' || val[pos]=='"')
295
d_string.append(1,'\\');
296
d_string.append(1, val[pos]);
386
string::size_type limit=val.size();
388
for(string::size_type n = 0; n < limit; ++n) {
389
snprintf(tmp, sizeof(tmp)-1, "%02x", (unsigned char)val[n]);
300
d_string.append(1,'"');
394
void RecordTextWriter::xfrText(const string& val, bool multi)
396
if(!d_string.empty())
397
d_string.append(1,' ');
399
d_string.append(val);