string PacketReader::getLabel(unsigned int recurs)
{
string ret;
+ size_t wirelength = 0;
ret.reserve(40);
- getLabelFromContent(d_content, d_pos, ret, recurs++);
+ getLabelFromContent(d_content, d_pos, ret, recurs++, wirelength);
return ret;
}
}
-void PacketReader::getLabelFromContent(const vector<uint8_t>& content, uint16_t& frompos, string& ret, int recurs)
+void PacketReader::getLabelFromContent(const vector<uint8_t>& content, uint16_t& frompos, string& ret, int recurs, size_t& wirelength)
{
if(recurs > 100) // the forward reference-check below should make this test 100% obsolete
throw MOADNSException("Loop");
// it is tempting to call reserve on ret, but it turns out it creates a malloc/free storm in the loop
for(;;) {
unsigned char labellen=content.at(frompos++);
+ wirelength++;
+ if (wirelength > 255) {
+ throw MOADNSException("Overly long DNS name ("+lexical_cast<string>(wirelength)+")");
+ }
if(!labellen) {
if(ret.empty())
if(offset >= pos)
throw MOADNSException("forward reference during label decompression");
- return getLabelFromContent(content, offset, ret, ++recurs);
+ /* the compression pointer does not count into the wire length */
+ return getLabelFromContent(content, offset, ret, ++recurs, --wirelength);
}
else if(labellen > 63)
throw MOADNSException("Overly long label during label decompression ("+lexical_cast<string>((unsigned int)labellen)+")");
else {
+ if (wirelength + labellen > 255) {
+ throw MOADNSException("Overly long DNS name ("+lexical_cast<string>(wirelength)+")");
+ }
+ wirelength += labellen;
// XXX FIXME THIS MIGHT BE VERY SLOW!
-
for(string::size_type n = 0 ; n < labellen; ++n, frompos++) {
if(content.at(frompos)=='.' || content.at(frompos)=='\\') {
ret.append(1, '\\');
void xfrHexBlob(string& blob, bool keepReading=false);
static uint16_t get16BitInt(const vector<unsigned char>&content, uint16_t& pos);
- static void getLabelFromContent(const vector<uint8_t>& content, uint16_t& frompos, string& ret, int recurs);
+ static void getLabelFromContent(const vector<uint8_t>& content, uint16_t& frompos, string& ret, int recurs, size_t& wirelength);
void getDnsrecordheader(struct dnsrecordheader &ah);
void copyRecord(vector<unsigned char>& dest, uint16_t len);
if(domain.empty())
return false;
- string::size_type fdot=domain.find('.');
-
- if(fdot==string::npos)
- domain="";
- else {
- string::size_type remain = domain.length() - (fdot + 1);
- char tmp[remain];
- memcpy(tmp, domain.c_str()+fdot+1, remain);
- domain.assign(tmp, remain); // don't dare to do this w/o tmp holder :-)
+ bool escaped = false;
+ const string::size_type domainLen = domain.length();
+ for (size_t fdot = 0; fdot < domainLen; fdot++)
+ {
+ if (domain[fdot] == '.' && !escaped) {
+ string::size_type remain = domainLen - (fdot + 1);
+ char tmp[remain];
+ memcpy(tmp, domain.c_str()+fdot+1, remain);
+ domain.assign(tmp, remain); // don't dare to do this w/o tmp holder :-)
+
+ return true;
+ }
+ else if (domain[fdot] == '\\' && !escaped) {
+ escaped = true;
+ }
+ else {
+ escaped = false;
+ }
}
+
+ domain = "";
return true;
}
if(domain.empty() || (domain.size()==1 && domain[0]=='.'))
return false;
- string::size_type fdot=domain.find('.');
- if(fdot == string::npos)
- return false;
-
- if(fdot==domain.size()-1)
- domain=".";
- else {
- string::size_type remain = domain.length() - (fdot + 1);
- char tmp[remain];
- memcpy(tmp, domain.c_str()+fdot+1, remain);
- domain.assign(tmp, remain);
+ bool escaped = false;
+ const string::size_type domainLen = domain.length();
+ for (size_t fdot = 0; fdot < domainLen; fdot++)
+ {
+ if (domain[fdot] == '.' && !escaped) {
+ if (fdot==domain.size()-1) {
+ domain=".";
+ }
+ else {
+ string::size_type remain = domainLen - (fdot + 1);
+ char tmp[remain];
+ memcpy(tmp, domain.c_str()+fdot+1, remain);
+ domain.assign(tmp, remain); // don't dare to do this w/o tmp holder :-)
+ }
+ return true;
+ }
+ else if (domain[fdot] == '\\' && !escaped) {
+ escaped = true;
+ }
+ else {
+ escaped = false;
+ }
}
- return true;
+
+ return false;
}