#include "dnswriter.hh"
#include "dnsname.hh"
#include "pdnsexception.hh"
+#include "iputils.hh"
/** DNS records have three representations:
1) in the packet
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");
xfrBlob(val, 16);
}
+ void xfrCAWithoutPort(uint8_t version, ComboAddress &val) {
+ string blob;
+ if (version == 4) xfrBlob(blob, 4);
+ else if (version == 6) xfrBlob(blob, 16);
+ else throw runtime_error("invalid IP protocol");
+ val = makeComboAddressFromRaw(version, blob);
+ }
+
+ void xfrCAPort(ComboAddress &val) {
+ uint16_t port;
+ xfr16BitInt(port);
+ val.sin4.sin_port = port;
+ }
+
void xfrTime(uint32_t& val)
{
xfr32BitInt(val);
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)
{
struct DNSRecord
{
- DNSRecord() {
- d_type = 0;
- d_class = QClass::IN;
- d_ttl = 0;
- d_clen = 0;
- d_place = DNSResourceRecord::ANSWER;
- }
+ DNSRecord() : d_type(0), d_class(QClass::IN), d_ttl(0), d_clen(0), d_place(DNSResourceRecord::ANSWER)
+ {}
explicit DNSRecord(const DNSResourceRecord& rr);
DNSName d_name;
std::shared_ptr<DNSRecordContent> d_content;
{
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)