aboutsummaryrefslogtreecommitdiff
path: root/src/lib/protocols/dns.c
diff options
context:
space:
mode:
authorLuca Deri <deri@ntop.org>2020-09-17 23:24:02 +0200
committerLuca Deri <deri@ntop.org>2020-09-17 23:24:02 +0200
commitd81bc1add631009eec2b6cb87e42720db4f17af3 (patch)
treec401ee25e5ee4f484e281b6d3e43ff41d77170bb /src/lib/protocols/dns.c
parent753b5dde16bae60299ca8e31afb4f519b13629c1 (diff)
Reworked MDNS dissector that is not based on the DNS dissector
Diffstat (limited to 'src/lib/protocols/dns.c')
-rw-r--r--src/lib/protocols/dns.c99
1 files changed, 80 insertions, 19 deletions
diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c
index 03ac7b9d2..12c6d0338 100644
--- a/src/lib/protocols/dns.c
+++ b/src/lib/protocols/dns.c
@@ -27,15 +27,47 @@
#include "ndpi_api.h"
-
#define FLAGS_MASK 0x8000
-// #define DNS_DEBUG 1
+/* #define DNS_DEBUG 1 */
+
+#define DNS_PORT 53
+#define LLMNR_PORT 5355
+#define MDNS_PORT 5353
static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
/* *********************************************** */
+static u_int16_t checkPort(u_int16_t port) {
+ switch(port) {
+ case DNS_PORT:
+ return(NDPI_PROTOCOL_DNS);
+ break;
+ case LLMNR_PORT:
+ return(NDPI_PROTOCOL_LLMNR);
+ break;
+ case MDNS_PORT:
+ return(NDPI_PROTOCOL_MDNS);
+ break;
+ }
+
+ return(0);
+}
+
+/* *********************************************** */
+
+static u_int16_t checkDNSSubprotocol(u_int16_t sport, u_int16_t dport) {
+ u_int16_t rc = checkPort(sport);
+
+ if(rc == 0)
+ return(checkPort(dport));
+ else
+ return(rc);
+}
+
+/* *********************************************** */
+
static u_int16_t get16(int *i, const u_int8_t *payload) {
u_int16_t v = *(u_int16_t*)&payload[*i];
@@ -108,7 +140,7 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct,
NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET);
return(1 /* invalid */);
}
-
+
if(*is_query) {
/* DNS Request */
if((dns_header->num_queries > 0) && (dns_header->num_queries <= NDPI_MAX_DNS_REQUESTS)
@@ -182,7 +214,7 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct,
if((x+12) <= flow->packet.payload_packet_len) {
x += 6;
data_len = get16(&x, flow->packet.payload);
-
+
if((x + data_len) <= flow->packet.payload_packet_len) {
// printf("[rsp_type: %u][data_len: %u]\n", rsp_type, data_len);
@@ -190,7 +222,7 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct,
x += data_len;
continue; /* Skip CNAME */
}
-
+
if((((rsp_type == 0x1) && (data_len == 4)) /* A */
#ifdef NDPI_DETECTION_SUPPORT_IPV6
|| ((rsp_type == 0x1c) && (data_len == 16)) /* AAAA */
@@ -200,11 +232,11 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct,
}
}
}
-
+
break;
}
}
-
+
if((flow->packet.detected_protocol_stack[0] == NDPI_PROTOCOL_DNS)
|| (flow->packet.detected_protocol_stack[1] == NDPI_PROTOCOL_DNS)) {
/* Request already set the protocol */
@@ -212,10 +244,8 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct,
} else {
/* We missed the request */
u_int16_t s_port = flow->packet.udp ? ntohs(flow->packet.udp->source) : ntohs(flow->packet.tcp->source);
-
- ndpi_set_detected_protocol(ndpi_struct, flow,
- (s_port == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS,
- NDPI_PROTOCOL_UNKNOWN);
+
+ ndpi_set_detected_protocol(ndpi_struct, flow, checkPort(s_port), NDPI_PROTOCOL_UNKNOWN);
}
}
}
@@ -256,15 +286,18 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st
return;
}
- if((s_port == 53 || d_port == 53 || d_port == 5355)
+ if(((s_port == DNS_PORT) || (d_port == DNS_PORT)
+ || (s_port == MDNS_PORT) || (d_port == MDNS_PORT)
+ || (d_port == LLMNR_PORT))
&& (flow->packet.payload_packet_len > sizeof(struct ndpi_dns_packet_header)+payload_offset)) {
struct ndpi_dns_packet_header dns_header;
int j = 0, max_len, off;
int invalid = search_valid_dns(ndpi_struct, flow, &dns_header, payload_offset, &is_query);
ndpi_protocol ret;
+ u_int num_queries, idx;
- ret.master_protocol = NDPI_PROTOCOL_UNKNOWN;
- ret.app_protocol = (d_port == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS;
+ ret.master_protocol = NDPI_PROTOCOL_UNKNOWN;
+ ret.app_protocol = (d_port == LLMNR_PORT) ? NDPI_PROTOCOL_LLMNR : ((d_port == MDNS_PORT) ? NDPI_PROTOCOL_MDNS : NDPI_PROTOCOL_DNS);
if(invalid) {
NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
@@ -274,7 +307,35 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st
/* extract host name server */
max_len = sizeof(flow->host_server_name)-1;
off = sizeof(struct ndpi_dns_packet_header) + payload_offset;
-
+
+ /* Before continuing let's dissect the following queries to see if they are valid */
+ for(idx=off, num_queries=0; (num_queries < dns_header.num_queries) && (idx < flow->packet.payload_packet_len);) {
+ u_int8_t name_len = flow->packet.payload[idx];
+
+#ifdef DNS_DEBUG
+ printf("[DNS] [name_len: %u]\n", name_len);
+#endif
+
+ if(name_len == 0) {
+ /* End of query */
+ num_queries++;
+ idx += 5;
+ continue;
+ }
+
+ if((name_len+idx) >= flow->packet.payload_packet_len) {
+ /* Invalid */
+#ifdef DNS_DEBUG
+ printf("[DNS] Invalid query len [%u >= %u]\n",
+ (name_len+idx),
+ flow->packet.payload_packet_len);
+#endif
+ NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET);
+ break;
+ } else
+ idx += name_len+1;
+ }
+
while(j < max_len && off < flow->packet.payload_packet_len && flow->packet.payload[off] != '\0') {
uint8_t c, cl = flow->packet.payload[off++];
@@ -288,7 +349,7 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st
while(j < max_len && cl != 0) {
u_int32_t shift;
-
+
c = flow->packet.payload[off++];
shift = ((u_int32_t) 1) << (c & 0x1f);
flow->host_server_name[j++] = tolower((dns_validchar[c >> 5] & shift) ? c : '_');
@@ -297,12 +358,12 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st
}
flow->host_server_name[j] = '\0';
-
+
if(j > 0) {
ndpi_protocol_match_result ret_match;
ndpi_check_dga_name(ndpi_struct, flow, (char*)flow->host_server_name, 1);
-
+
ret.app_protocol = ndpi_match_host_subprotocol(ndpi_struct, flow,
(char *)flow->host_server_name,
strlen((const char*)flow->host_server_name),
@@ -313,7 +374,7 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st
flow->category = ret_match.protocol_category;
if(ret.app_protocol == NDPI_PROTOCOL_UNKNOWN)
- ret.master_protocol = (d_port == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS;
+ ret.master_protocol = checkDNSSubprotocol(s_port, d_port);
else
ret.master_protocol = NDPI_PROTOCOL_DNS;
}