remove safearray, dnsmessagereader can now parse "any" length

This commit is contained in:
bert hubert 2018-04-15 16:29:17 +02:00
parent ec773d45d4
commit a7c4670284
3 changed files with 37 additions and 53 deletions

View File

@ -8,19 +8,20 @@ DNSMessageReader::DNSMessageReader(const char* in, uint16_t size)
if(size < sizeof(dnsheader))
throw std::runtime_error("DNS message too small");
memcpy(&dh, in, sizeof(dh));
auto rest = size-sizeof(dh);
memcpy(&payload.payload.at(rest)-rest, in+sizeof(dh), rest);
payload.reserve(size-12);
payload.insert(payload.begin(), (const unsigned char*)in + 12, (const unsigned char*)in + size);
d_qname = getName();
d_qtype = (DNSType) payload.getUInt16();
d_qclass = (DNSClass) payload.getUInt16();
d_qtype = (DNSType) getUInt16();
d_qclass = (DNSClass) getUInt16();
if(dh.arcount) {
if(payload.getUInt8() == 0 && payload.getUInt16() == (uint16_t)DNSType::OPT) {
d_bufsize=payload.getUInt16();
payload.getUInt8(); // extended RCODE
d_ednsVersion = payload.getUInt8();
auto flags = payload.getUInt8();
if(getUInt8() == 0 && getUInt16() == (uint16_t)DNSType::OPT) {
d_bufsize=getUInt16();
getUInt8(); // extended RCODE
d_ednsVersion = getUInt8();
auto flags = getUInt8();
d_doBit = flags & 0x80;
payload.getUInt8(); payload.getUInt16(); // ignore rest
getUInt8(); getUInt16(); // ignore rest
cout<<" There was an EDNS section, size supported: "<< d_bufsize<<endl;
d_haveEDNS = true;
}
@ -31,12 +32,12 @@ DNSName DNSMessageReader::getName()
{
DNSName name;
for(;;) {
uint8_t labellen=payload.getUInt8();
uint8_t labellen=getUInt8();
if(labellen > 63)
throw std::runtime_error("Got a compressed label");
if(!labellen) // end of DNSName
break;
DNSLabel label = payload.getBlob(labellen);
DNSLabel label = getBlob(labellen);
name.push_back(label);
}
return name;

View File

@ -1,8 +1,8 @@
#pragma once
#include "dns.hh"
#include "safearray.hh"
#include "dns-storage.hh"
#include "record-types.hh"
#include <arpa/inet.h>
#include <vector>
class DNSMessageReader
@ -11,13 +11,34 @@ public:
DNSMessageReader(const char* input, uint16_t length);
DNSMessageReader(const std::string& str) : DNSMessageReader(str.c_str(), str.size()) {}
struct dnsheader dh=dnsheader{};
SafeArray<500> payload;
std::vector<uint8_t> payload;
uint16_t payloadpos{0};
void getQuestion(DNSName& name, DNSType& type) const;
bool getEDNS(uint16_t* newsize, bool* doBit) const;
uint8_t d_ednsVersion{0};
private:
DNSName getName();
uint8_t getUInt8()
{
return payload.at(payloadpos++);
}
uint16_t getUInt16()
{
uint16_t ret;
memcpy(&ret, &payload.at(payloadpos+1)-1, 2);
payloadpos+=2;
return htons(ret);
}
std::string getBlob(int size)
{
std::string ret(&payload.at(payloadpos), &payload.at(payloadpos+size));
payloadpos += size;
return ret;
}
DNSName d_qname;
DNSType d_qtype;
DNSClass d_qclass;

View File

@ -1,38 +0,0 @@
#pragma once
#include <string>
#include <cstdint>
#include <array>
#include <arpa/inet.h>
#include <string.h>
template<int N>
struct SafeArray
{
std::array<uint8_t, N> payload;
uint16_t payloadpos{0}, payloadsize{0};
void rewind()
{
payloadpos = 0;
}
uint8_t getUInt8()
{
return payload.at(payloadpos++);
}
uint16_t getUInt16()
{
uint16_t ret;
memcpy(&ret, &payload.at(payloadpos+2)-2, 2);
payloadpos+=2;
return htons(ret);
}
std::string getBlob(int size)
{
std::string ret(&payload.at(payloadpos), &payload.at(payloadpos+size));
payloadpos += size;
return ret;
}
};