class PacketReader
{
public:
- PacketReader(const vector<uint8_t>& content)
- : d_pos(0), d_startrecordpos(0), d_content(content)
+ PacketReader(const std::string& content, uint16_t initialPos=sizeof(dnsheader))
+ : d_pos(initialPos), d_startrecordpos(initialPos), d_content(content)
{
if(content.size() > std::numeric_limits<uint16_t>::max())
throw std::out_of_range("packet too large");
void xfrBlob(string& blob, int length);
void xfrHexBlob(string& blob, bool keepReading=false);
- static uint16_t get16BitInt(const vector<unsigned char>&content, uint16_t& pos);
-
void getDnsrecordheader(struct dnsrecordheader &ah);
void copyRecord(vector<unsigned char>& dest, uint16_t len);
void copyRecord(unsigned char* dest, uint16_t len);
string getText(bool multi, bool lenField);
string getUnquotedText(bool lenField);
- uint16_t d_pos;
bool eof() { return true; };
const string getRemaining() const {
return "";
};
+ uint16_t getPosition() const
+ {
+ return d_pos;
+ }
+
+ void skip(uint16_t n)
+ {
+ d_pos += n;
+ }
+
private:
+ uint16_t d_pos;
uint16_t d_startrecordpos; // needed for getBlob later on
uint16_t d_recordlen; // ditto
uint16_t not_used; // Aligns the whole class on 8-byte boundries
- const vector<uint8_t>& d_content;
+ const std::string& d_content;
};
struct DNSRecord;
static std::shared_ptr<DNSRecordContent> mastermake(const DNSRecord &dr, PacketReader& pr);
static std::shared_ptr<DNSRecordContent> mastermake(const DNSRecord &dr, PacketReader& pr, uint16_t opcode);
static std::shared_ptr<DNSRecordContent> mastermake(uint16_t qtype, uint16_t qclass, const string& zone);
- static std::unique_ptr<DNSRecordContent> makeunique(uint16_t qtype, uint16_t qclass, const string& content);
virtual std::string getZoneRepresentation(bool noDot=false) const = 0;
virtual ~DNSRecordContent() {}
void doRecordCheck(const struct DNSRecord&){}
- typedef DNSRecordContent* makerfunc_t(const struct DNSRecord& dr, PacketReader& pr);
- typedef DNSRecordContent* zmakerfunc_t(const string& str);
+ typedef std::shared_ptr<DNSRecordContent> makerfunc_t(const struct DNSRecord& dr, PacketReader& pr);
+ typedef std::shared_ptr<DNSRecordContent> zmakerfunc_t(const string& str);
static void regist(uint16_t cl, uint16_t ty, makerfunc_t* f, zmakerfunc_t* z, const char* name)
{
{
public:
//! Parse from a string
- MOADNSParser(bool query, const string& buffer) : d_tsigPos(0)
+ MOADNSParser(bool query, const string& buffer): d_tsigPos(0)
{
- init(query, buffer.c_str(), (unsigned int)buffer.size());
+ init(query, buffer);
}
//! Parse from a pointer and length
MOADNSParser(bool query, const char *packet, unsigned int len) : d_tsigPos(0)
{
- init(query, packet, len);
+ init(query, std::string(packet, len));
}
DNSName d_qname;
//! All answers contained in this packet (everything *but* the question section)
answers_t d_answers;
- shared_ptr<PacketReader> getPacketReader(uint16_t offset)
- {
- shared_ptr<PacketReader> pr(new PacketReader(d_content));
- pr->d_pos=offset;
- return pr;
- }
-
uint16_t getTSIGPos() const
{
return d_tsigPos;
}
private:
- void getDnsrecordheader(struct dnsrecordheader &ah);
- void init(bool query, const char *packet, unsigned int len);
- vector<uint8_t> d_content;
+ void init(bool query, const std::string& packet);
uint16_t d_tsigPos;
};
void ageDNSPacket(char* packet, size_t length, uint32_t seconds);
void ageDNSPacket(std::string& packet, uint32_t seconds);
void editDNSPacketTTL(char* packet, size_t length, std::function<uint32_t(uint8_t, uint16_t, uint16_t, uint32_t)> visitor);
-uint32_t getDNSPacketMinTTL(const char* packet, size_t length);
+uint32_t getDNSPacketMinTTL(const char* packet, size_t length, bool* seenAuthSOA=nullptr);
uint32_t getDNSPacketLength(const char* packet, size_t length);
uint16_t getRecordsOfTypeCount(const char* packet, size_t length, uint8_t section, uint16_t type);
+bool getEDNSUDPPayloadSizeAndZ(const char* packet, size_t length, uint16_t* payloadSize, uint16_t* z);
template<typename T>
std::shared_ptr<T> getRR(const DNSRecord& dr)