summaryrefslogtreecommitdiffstats
path: root/dnsparser.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dnsparser.cc')
-rw-r--r--dnsparser.cc67
1 files changed, 36 insertions, 31 deletions
diff --git a/dnsparser.cc b/dnsparser.cc
index b7c6a9b..5a17fc3 100644
--- a/dnsparser.cc
+++ b/dnsparser.cc
@@ -119,12 +119,12 @@ shared_ptr<DNSRecordContent> DNSRecordContent::deserialize(const DNSName& qname,
PacketReader pr(std::string_view(reinterpret_cast<const char*>(packet.data()), packet.size()), packet.size() - serialized.size() - sizeof(dnsrecordheader));
/* needed to get the record boundaries right */
pr.getDnsrecordheader(drh);
- auto content = DNSRecordContent::mastermake(dr, pr, Opcode::Query);
+ auto content = DNSRecordContent::make(dr, pr, Opcode::Query);
return content;
}
-std::shared_ptr<DNSRecordContent> DNSRecordContent::mastermake(const DNSRecord &dr,
- PacketReader& pr)
+std::shared_ptr<DNSRecordContent> DNSRecordContent::make(const DNSRecord& dr,
+ PacketReader& pr)
{
uint16_t searchclass = (dr.d_type == QType::OPT) ? 1 : dr.d_class; // class is invalid for OPT
@@ -136,8 +136,8 @@ std::shared_ptr<DNSRecordContent> DNSRecordContent::mastermake(const DNSRecord &
return i->second(dr, pr);
}
-std::shared_ptr<DNSRecordContent> DNSRecordContent::mastermake(uint16_t qtype, uint16_t qclass,
- const string& content)
+std::shared_ptr<DNSRecordContent> DNSRecordContent::make(uint16_t qtype, uint16_t qclass,
+ const string& content)
{
auto i = getZmakermap().find(pair(qclass, qtype));
if(i==getZmakermap().end()) {
@@ -147,7 +147,8 @@ std::shared_ptr<DNSRecordContent> DNSRecordContent::mastermake(uint16_t qtype, u
return i->second(content);
}
-std::shared_ptr<DNSRecordContent> DNSRecordContent::mastermake(const DNSRecord &dr, PacketReader& pr, uint16_t oc) {
+std::shared_ptr<DNSRecordContent> DNSRecordContent::make(const DNSRecord& dr, PacketReader& pr, uint16_t oc)
+{
// For opcode UPDATE and where the DNSRecord is an answer record, we don't care about content, because this is
// not used within the prerequisite section of RFC2136, so - we can simply use unknownrecordcontent.
// For section 3.2.3, we do need content so we need to get it properly. But only for the correct QClasses.
@@ -207,19 +208,20 @@ DNSRecord::DNSRecord(const DNSResourceRecord& rr): d_name(rr.qname)
d_class = rr.qclass;
d_place = DNSResourceRecord::ANSWER;
d_clen = 0;
- d_content = DNSRecordContent::mastermake(d_type, rr.qclass, rr.content);
+ d_content = DNSRecordContent::make(d_type, rr.qclass, rr.content);
}
// If you call this and you are not parsing a packet coming from a socket, you are doing it wrong.
-DNSResourceRecord DNSResourceRecord::fromWire(const DNSRecord& d) {
- DNSResourceRecord rr;
- rr.qname = d.d_name;
- rr.qtype = QType(d.d_type);
- rr.ttl = d.d_ttl;
- rr.content = d.getContent()->getZoneRepresentation(true);
- rr.auth = false;
- rr.qclass = d.d_class;
- return rr;
+DNSResourceRecord DNSResourceRecord::fromWire(const DNSRecord& wire)
+{
+ DNSResourceRecord resourceRecord;
+ resourceRecord.qname = wire.d_name;
+ resourceRecord.qtype = QType(wire.d_type);
+ resourceRecord.ttl = wire.d_ttl;
+ resourceRecord.content = wire.getContent()->getZoneRepresentation(true);
+ resourceRecord.auth = false;
+ resourceRecord.qclass = wire.d_class;
+ return resourceRecord;
}
void MOADNSParser::init(bool query, const std::string_view& packet)
@@ -277,8 +279,8 @@ void MOADNSParser::init(bool query, const std::string_view& packet)
dr.d_type=ah.d_type;
dr.d_class=ah.d_class;
- dr.d_name=name;
- dr.d_clen=ah.d_clen;
+ dr.d_name = std::move(name);
+ dr.d_clen = ah.d_clen;
if (query &&
!(d_qtype == QType::IXFR && dr.d_place == DNSResourceRecord::AUTHORITY && dr.d_type == QType::SOA) && // IXFR queries have a SOA in their AUTHORITY section
@@ -288,7 +290,7 @@ void MOADNSParser::init(bool query, const std::string_view& packet)
}
else {
// cerr<<"parsing RR, query is "<<query<<", place is "<<dr.d_place<<", type is "<<dr.d_type<<", class is "<<dr.d_class<<endl;
- dr.setContent(DNSRecordContent::mastermake(dr, pr, d_header.opcode));
+ dr.setContent(DNSRecordContent::make(dr, pr, d_header.opcode));
}
/* XXX: XPF records should be allowed after TSIG as soon as the actual XPF option code has been assigned:
@@ -515,6 +517,10 @@ string PacketReader::getText(bool multi, bool lenField)
break;
}
+ if (ret.empty() && !lenField) {
+ // all lenField == false cases (CAA and URI at the time of this writing) want that emptiness to be explicit
+ return "\"\"";
+ }
return ret;
}
@@ -535,7 +541,7 @@ string PacketReader::getUnquotedText(bool lenField)
return "";
d_pos++;
- string ret(&d_content.at(d_pos), &d_content.at(stop_at));
+ string ret(d_content.substr(d_pos, stop_at-d_pos));
d_pos = stop_at;
return ret;
}
@@ -768,7 +774,7 @@ static bool checkIfPacketContainsRecords(const PacketBuffer& packet, const std::
}
try {
- auto dh = reinterpret_cast<const dnsheader*>(packet.data());
+ const dnsheader_aligned dh(packet.data());
DNSPacketMangler dpm(const_cast<char*>(reinterpret_cast<const char*>(packet.data())), length);
const uint16_t qdcount = ntohs(dh->qdcount);
@@ -804,7 +810,7 @@ static int rewritePacketWithoutRecordTypes(const PacketBuffer& initialPacket, Pa
return EINVAL;
}
try {
- const struct dnsheader* dh = reinterpret_cast<const struct dnsheader*>(initialPacket.data());
+ const dnsheader_aligned dh(initialPacket.data());
if (ntohs(dh->qdcount) == 0)
return ENOENT;
@@ -979,7 +985,7 @@ uint32_t getDNSPacketMinTTL(const char* packet, size_t length, bool* seenAuthSOA
}
try
{
- const dnsheader* dh = (const dnsheader*) packet;
+ const dnsheader_aligned dh(packet);
DNSPacketMangler dpm(const_cast<char*>(packet), length);
const uint16_t qdcount = ntohs(dh->qdcount);
@@ -1026,7 +1032,7 @@ uint32_t getDNSPacketLength(const char* packet, size_t length)
}
try
{
- const dnsheader* dh = reinterpret_cast<const dnsheader*>(packet);
+ const dnsheader_aligned dh(packet);
DNSPacketMangler dpm(const_cast<char*>(packet), length);
const uint16_t qdcount = ntohs(dh->qdcount);
@@ -1058,7 +1064,7 @@ uint16_t getRecordsOfTypeCount(const char* packet, size_t length, uint8_t sectio
}
try
{
- const dnsheader* dh = (const dnsheader*) packet;
+ const dnsheader_aligned dh(packet);
DNSPacketMangler dpm(const_cast<char*>(packet), length);
const uint16_t qdcount = ntohs(dh->qdcount);
@@ -1148,7 +1154,7 @@ bool getEDNSUDPPayloadSizeAndZ(const char* packet, size_t length, uint16_t* payl
try
{
- const dnsheader* dh = (const dnsheader*) packet;
+ const dnsheader_aligned dh(packet);
DNSPacketMangler dpm(const_cast<char*>(packet), length);
const uint16_t qdcount = ntohs(dh->qdcount);
@@ -1191,13 +1197,12 @@ bool visitDNSPacket(const std::string_view& packet, const std::function<bool(uin
try
{
- dnsheader dh;
- memcpy(&dh, reinterpret_cast<const dnsheader*>(packet.data()), sizeof(dh));
- uint64_t numrecords = ntohs(dh.ancount) + ntohs(dh.nscount) + ntohs(dh.arcount);
+ const dnsheader_aligned dh(packet.data());
+ uint64_t numrecords = ntohs(dh->ancount) + ntohs(dh->nscount) + ntohs(dh->arcount);
PacketReader reader(packet);
uint64_t n;
- for (n = 0; n < ntohs(dh.qdcount) ; ++n) {
+ for (n = 0; n < ntohs(dh->qdcount) ; ++n) {
(void) reader.getName();
/* type and class */
reader.skip(4);
@@ -1206,7 +1211,7 @@ bool visitDNSPacket(const std::string_view& packet, const std::function<bool(uin
for (n = 0; n < numrecords; ++n) {
(void) reader.getName();
- uint8_t section = n < ntohs(dh.ancount) ? 1 : (n < (ntohs(dh.ancount) + ntohs(dh.nscount)) ? 2 : 3);
+ uint8_t section = n < ntohs(dh->ancount) ? 1 : (n < (ntohs(dh->ancount) + ntohs(dh->nscount)) ? 2 : 3);
uint16_t dnstype = reader.get16BitInt();
uint16_t dnsclass = reader.get16BitInt();