diff --git a/include/Flow.h b/include/Flow.h index af7bcbf704..9cddf1cf08 100644 --- a/include/Flow.h +++ b/include/Flow.h @@ -484,6 +484,9 @@ class Flow : public GenericHashEntry { inline void setDNSQuery(char *v) { if(isDNS()) { if(protos.dns.last_query) free(protos.dns.last_query); protos.dns.last_query = v; } } inline void setDNSQueryType(u_int16_t t) { if(isDNS()) { protos.dns.last_query_type = t; } } inline void setDNSRetCode(u_int16_t c) { if(isDNS()) { protos.dns.last_return_code = c; } } + inline u_int16_t getLastQueryType() { return(isDNS() ? protos.dns.last_query_type : 0); } + inline u_int16_t getDNSRetCode() { return(isDNS() ? protos.dns.last_return_code : 0); } + inline bool isDNSQuery() { return(isDNS() && ndpiFlow && ndpiFlow->protos.dns.is_query); } inline char* getHTTPURL() { return(isHTTP() ? protos.http.last_url : (char*)""); } inline void setHTTPURL(char *v) { if(isHTTP()) { if(protos.http.last_url) free(protos.http.last_url); protos.http.last_url = v; } } inline void setHTTPRetCode(u_int16_t c) { if(isHTTP()) { protos.http.last_return_code = c; } } diff --git a/src/Flow.cpp b/src/Flow.cpp index 75540109a9..46908b1ccd 100644 --- a/src/Flow.cpp +++ b/src/Flow.cpp @@ -468,6 +468,7 @@ void Flow::processDetectedProtocol() { protos.dns.invalid_query = false; } protos.dns.last_query = strdup((const char*)ndpiFlow->host_server_name); + protos.dns.last_query_type = ndpiFlow->protos.dns.query_type; for(int i = 0; protos.dns.last_query[i] != '\0'; i++) { if(!isprint(protos.dns.last_query[i])) { @@ -479,35 +480,7 @@ void Flow::processDetectedProtocol() { if(!protos.dns.invalid_query) protos.dns.invalid_query = (strlen(protos.dns.last_query) > MAX_VALID_DNS_QUERY_LEN) ? true : false; } - - if(ntop->getPrefs()->decode_dns_responses()) { - if(ndpiFlow->host_server_name[0] != '\0') { - char delimiter = '@', *name = NULL; - char *at = (char*)strchr((const char*)ndpiFlow->host_server_name, delimiter); - - /* Consider only positive DNS replies */ - if(at != NULL) - name = &at[1], at[0] = '\0'; - else if((!strstr((const char*)ndpiFlow->host_server_name, ".in-addr.arpa")) - && (!strstr((const char*)ndpiFlow->host_server_name, ".ip6.arpa"))) - name = (char*)ndpiFlow->host_server_name; - - if(name) { - // ntop->getTrace()->traceEvent(TRACE_NORMAL, "[DNS] %s", (char*)ndpiFlow->host_server_name); - - if(ndpiFlow->protos.dns.reply_code == 0) { - if(ndpiFlow->protos.dns.num_answers > 0) { - protocol_processed = true; - - if(at != NULL) { - // ntop->getTrace()->traceEvent(TRACE_NORMAL, "[DNS] %s <-> %s", name, (char*)ndpiFlow->host_server_name); - ntop->getRedis()->setResolvedAddress(name, (char*)ndpiFlow->host_server_name); - } - } - } - } - } - } + /* See Flow::processFullyDissectedProtocol for reply dissection */ break; case NDPI_PROTOCOL_TOR: @@ -625,6 +598,39 @@ void Flow::processFullyDissectedProtocol() { updateSrvJA3(); } break; + + case NDPI_PROTOCOL_DNS: + if(ntop->getPrefs()->decode_dns_responses()) { + + if(ndpiFlow->host_server_name[0] != '\0') { + char delimiter = '@', *name = NULL; + char *at = (char*)strchr((const char*)ndpiFlow->host_server_name, delimiter); + + /* Consider only positive DNS replies */ + if(at != NULL) + name = &at[1], at[0] = '\0'; + else if((!strstr((const char*)ndpiFlow->host_server_name, ".in-addr.arpa")) + && (!strstr((const char*)ndpiFlow->host_server_name, ".ip6.arpa"))) + name = (char*)ndpiFlow->host_server_name; + + if(name) { + // ntop->getTrace()->traceEvent(TRACE_NORMAL, "[DNS] %s", (char*)ndpiFlow->host_server_name); + protos.dns.last_return_code = ndpiFlow->protos.dns.reply_code; + + if(ndpiFlow->protos.dns.reply_code == 0) { + if(ndpiFlow->protos.dns.num_answers > 0) { + protocol_processed = true; + + if(at != NULL) { + // ntop->getTrace()->traceEvent(TRACE_NORMAL, "[DNS] %s <-> %s", name, (char*)ndpiFlow->host_server_name); + ntop->getRedis()->setResolvedAddress(name, (char*)ndpiFlow->host_server_name); + } + } + } + } + } + } + break; }; fully_processed = true; diff --git a/src/NetworkInterface.cpp b/src/NetworkInterface.cpp index 616407900a..446198d2cb 100644 --- a/src/NetworkInterface.cpp +++ b/src/NetworkInterface.cpp @@ -1829,8 +1829,6 @@ bool NetworkInterface::processPacket(u_int32_t bridge_iface_idx, if(flow->isDetectionCompleted() && (!isSampledTraffic()) && flow->get_cli_host() && flow->get_srv_host()) { - struct ndpi_flow_struct *ndpi_flow; - switch(ndpi_get_lower_proto(flow->get_detected_protocol())) { case NDPI_PROTOCOL_DHCP: { @@ -1969,8 +1967,6 @@ bool NetworkInterface::processPacket(u_int32_t bridge_iface_idx, break; case NDPI_PROTOCOL_DNS: - ndpi_flow = flow->get_ndpi_flow(); - /* DNS-over-TCP flows may carry zero-payload TCP segments e.g., during three-way-handshake, or when acknowledging. @@ -1981,11 +1977,6 @@ bool NetworkInterface::processPacket(u_int32_t bridge_iface_idx, DNS-over-TCP has a 2-bytes field with DNS payload length at the beginning. See RFC1035 section 4.2.2. TCP usage. */ - u_int8_t dns_offset = ((l4_proto == IPPROTO_TCP) && (trusted_payload_len > 1)) ? 2 : 0; - struct ndpi_dns_packet_header *header = (struct ndpi_dns_packet_header*)(payload + dns_offset); - u_int16_t dns_flags = ntohs(header->flags); - bool is_query = (dns_flags & 0x8000) ? 0 : 1; - if(flow->get_cli_host() && flow->get_srv_host()) { Host *client = src2dst_direction ? flow->get_cli_host() : flow->get_srv_host(); Host *server = src2dst_direction ? flow->get_srv_host() : flow->get_cli_host(); @@ -1996,13 +1987,11 @@ bool NetworkInterface::processPacket(u_int32_t bridge_iface_idx, by applications. */ - if(is_query) { - u_int16_t query_type = ndpi_flow ? ndpi_flow->protos.dns.query_type : 0; - + if(flow->isDNSQuery()) { + u_int16_t query_type = flow->getLastQueryType(); client->incNumDNSQueriesSent(query_type), server->incNumDNSQueriesRcvd(query_type); } else { - u_int8_t ret_code = (dns_flags & 0x000F); - + u_int8_t ret_code = flow->getDNSRetCode(); client->incNumDNSResponsesSent(ret_code), server->incNumDNSResponsesRcvd(ret_code); } }