remove safearray, dnsmessagereader can now parse "any" length
This commit is contained in:
parent
ec773d45d4
commit
a7c4670284
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue
Block a user