From 2ff9a013f8789c94447268917bd017ebd92dfc2b Mon Sep 17 00:00:00 2001 From: Brian Lutz Date: Thu, 10 Jun 2021 10:23:51 -0400 Subject: [PATCH 1/2] add optional domain query callbacks --- include/dnsparser.h | 3 +++ src/dnsparse.cpp | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/include/dnsparser.h b/include/dnsparser.h index 4d81ea3..2db4bc1 100644 --- a/include/dnsparser.h +++ b/include/dnsparser.h @@ -25,6 +25,9 @@ class DnsParserListener */ virtual void onDnsRec(in_addr addr, std::string name, std::string path) = 0; virtual void onDnsRec(in6_addr addr, std::string name, std::string path) = 0; +#ifdef REPORT_QUERIES + virtual void onDnsReq(uint16_t type, std::string name) = 0; +#endif }; class DnsParser diff --git a/src/dnsparse.cpp b/src/dnsparse.cpp index 38b94e3..7e79f5a 100644 --- a/src/dnsparse.cpp +++ b/src/dnsparse.cpp @@ -23,6 +23,7 @@ class DnsParserImpl : public DnsParser private: int dnsReadAnswers(char *payload, int payloadLen, char *ptr, int remaining, int numAnswers); + int dnsReadQueries(char *payload, int payloadLen, char *ptr, int remaining, int numQueries); DnsParserListener* _listener; bool _ignoreCnames; @@ -75,12 +76,25 @@ int skip_name(char *ptr, int remaining) return -1; } +void reDotName(char* ptr, int remaining) { + char *p = ptr; + char *end = p + remaining; + while (p < end) { + int dotLen = *p; + if (dotLen < 0 || dotLen >= remaining) return; + if (dotLen == 0) return; + *p='.'; + p += dotLen + 1; + remaining -= dotLen + 1; + } +} + //------------------------------------------------------------------------- // Read query records // @returns -1 on error // @returns Number of bytes taken up by query records //------------------------------------------------------------------------- -int dnsReadQueries(char *payload, int payloadLen, char *ptr, int remaining, int numQueries) +int DnsParserImpl::dnsReadQueries(char *payload, int payloadLen, char *ptr, int remaining, int numQueries) { int rem = remaining; char *p = ptr; @@ -88,6 +102,21 @@ int dnsReadQueries(char *payload, int payloadLen, char *ptr, int remaining, int { int nameLen = skip_name(p, remaining); if (nameLen <= 0) return -1; + +#ifdef REPORT_QUERIES + // copy the queried host, change dotlen specifiers to dots, and feed it (minus the leading dot) to our listener + char* nameTmp=(char*)malloc(nameLen+1); + if (nameTmp) { + memcpy(nameTmp,p,nameLen); + nameTmp[nameLen]=0; + reDotName(nameTmp,nameLen); + uint16_t type; + memcpy(&type,(p+nameLen),sizeof(uint16_t)); + if (0L != _listener) _listener->onDnsReq(ntohs(type),nameTmp+1); + free(nameTmp); + } +#endif + remaining -= nameLen + 4; p += nameLen + 4; if (remaining < 0) return -1; @@ -306,12 +335,16 @@ int DnsParserImpl::parse(char *payload, int payloadLen) if (DNS_FLAG_OPCODE(hdr._flags) != 0) return -1; // not a standard query. +#ifndef REPORT_QUERIES if ((hdr._flags & DNS_FLAG_RESPONSE) == 0) return 0; +#endif { // response - + +#ifndef REPORT_QUERIES if (hdr._numAnswers <= 0) return 0; // only care about answers +#endif if (hdr._numQueries > 4 || hdr._numAnswers > 20) return -1; // unreasonable? From db5efeb19ff388ce5cf579e82226706c06542fd0 Mon Sep 17 00:00:00 2001 From: Brian Lutz Date: Thu, 10 Jun 2021 10:25:39 -0400 Subject: [PATCH 2/2] add ifdef around this method too, as its only used when report queries is enabled --- src/dnsparse.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dnsparse.cpp b/src/dnsparse.cpp index 7e79f5a..086ce64 100644 --- a/src/dnsparse.cpp +++ b/src/dnsparse.cpp @@ -76,6 +76,7 @@ int skip_name(char *ptr, int remaining) return -1; } +#ifdef REPORT_QUERIES void reDotName(char* ptr, int remaining) { char *p = ptr; char *end = p + remaining; @@ -88,6 +89,7 @@ void reDotName(char* ptr, int remaining) { remaining -= dotLen + 1; } } +#endif //------------------------------------------------------------------------- // Read query records