aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampus <campus@ntop.org>2015-12-29 18:17:52 +0100
committerCampus <campus@ntop.org>2015-12-29 18:17:52 +0100
commit60e7e19dab72a37d57bc7854e702264e7d25886d (patch)
treecbbc7b598035070f47d0a781c01fac28b03f20b3
parent6d37ee2970c5866260a3fd66920a6bf6e740b702 (diff)
wrote new dns dissector - deleted useless part of dns to slim data structures used in nDPI and ntopng
-rw-r--r--src/include/ndpi_typedefs.h48
-rw-r--r--src/lib/ndpi_main.c4
-rw-r--r--src/lib/protocols/dns.c341
3 files changed, 110 insertions, 283 deletions
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h
index d73768f52..c4f4fdf73 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -270,7 +270,12 @@ struct ndpi_udphdr
PACK_ON
struct ndpi_dns_packet_header {
- u_int16_t transaction_id, flags, num_queries, answer_rrs, authority_rrs, additional_rrs;
+ u_int16_t tr_id;
+ u_int16_t flags;
+ u_int16_t num_queries;
+ u_int16_t num_answers;
+ u_int16_t authority_rrs;
+ u_int16_t additional_rrs;
} PACK_OFF;
typedef union
@@ -340,7 +345,7 @@ typedef enum {
HTTP_METHOD_CONNECT
} ndpi_http_method;
-typedef struct ndpi_id_struct {
+struct ndpi_id_struct {
/**
detected_protocol_bitmask:
access this bitmask to find out whether an id has used skype or not
@@ -436,7 +441,7 @@ typedef struct ndpi_id_struct {
#ifdef NDPI_PROTOCOL_RTSP
u_int32_t rtsp_ts_set:1;
#endif
-} ndpi_id_struct;
+};
/* ************************************************** */
@@ -628,12 +633,12 @@ struct ndpi_flow_udp_struct {
/* ************************************************** */
-typedef struct ndpi_int_one_line_struct {
+struct ndpi_int_one_line_struct {
const u_int8_t *ptr;
u_int16_t len;
-} ndpi_int_one_line_struct_t;
+};
-typedef struct ndpi_packet_struct {
+struct ndpi_packet_struct {
const struct ndpi_iphdr *iph;
#ifdef NDPI_DETECTION_SUPPORT_IPV6
const struct ndpi_ipv6hdr *iphv6;
@@ -688,22 +693,22 @@ typedef struct ndpi_packet_struct {
u_int8_t packet_lines_parsed_complete:1,
packet_direction:1,
empty_line_position_set:1;
-} ndpi_packet_struct_t;
+};
struct ndpi_detection_module_struct;
struct ndpi_flow_struct;
-typedef struct ndpi_call_function_struct {
+struct ndpi_call_function_struct {
NDPI_PROTOCOL_BITMASK detection_bitmask;
NDPI_PROTOCOL_BITMASK excluded_protocol_bitmask;
NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_bitmask;
void (*func) (struct ndpi_detection_module_struct *, struct ndpi_flow_struct *flow);
u_int8_t detection_feature;
-} ndpi_call_function_struct_t;
+};
-typedef struct ndpi_subprotocol_conf_struct {
+struct ndpi_subprotocol_conf_struct {
void (*func) (struct ndpi_detection_module_struct *, char *attr, char *value, int protocol_id);
-} ndpi_subprotocol_conf_struct_t;
+};
typedef struct {
@@ -746,7 +751,8 @@ typedef struct ndpi_proto {
#define NDPI_PROTOCOL_NULL { NDPI_PROTOCOL_UNKNOWN , NDPI_PROTOCOL_UNKNOWN }
-typedef struct ndpi_detection_module_struct {
+struct ndpi_detection_module_struct {
+
NDPI_PROTOCOL_BITMASK detection_bitmask;
NDPI_PROTOCOL_BITMASK generic_http_packet_bitmask;
@@ -799,6 +805,7 @@ typedef struct ndpi_detection_module_struct {
content_automa, /* Used for HTTP subprotocol_detection */
subprotocol_automa, /* Used for HTTP subprotocol_detection */
bigrams_automa, impossible_bigrams_automa; /* TOR */
+
/* IP-based protocol detection */
void *protocols_ptree;
@@ -842,11 +849,11 @@ typedef struct ndpi_detection_module_struct {
ndpi_proto_defaults_t proto_defaults[NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS];
- u_int8_t match_dns_host_names:1, http_dont_dissect_response:1;
+ u_int8_t http_dont_dissect_response:1;
u_int8_t direction_detect_disable:1; /* disable internal detection of packet direction */
-} ndpi_detection_module_struct_t;
+};
-typedef struct ndpi_flow_struct {
+struct ndpi_flow_struct {
u_int16_t detected_protocol_stack[NDPI_PROTOCOL_HISTORY_SIZE];
#ifndef WIN32
__attribute__ ((__packed__))
@@ -899,12 +906,13 @@ typedef struct ndpi_flow_struct {
} http;
union {
+
+ /* the only fields useful for nDPI and ntopng */
struct {
- u_int8_t num_queries, num_answers, ret_code;
- u_int8_t bad_packet /* the received packet looks bad */;
- u_int16_t query_type, query_class, rsp_type;
+ u_int8_t num_answers, ret_code;
+ u_int16_t query_type;
} dns;
-
+
struct {
u_int8_t request_code;
u_int8_t version;
@@ -1003,6 +1011,6 @@ typedef struct ndpi_flow_struct {
struct ndpi_flow_struct *flow;
struct ndpi_id_struct *src;
struct ndpi_id_struct *dst;
-} ndpi_flow_struct_t;
+};
#endif/* __NDPI_TYPEDEFS_H__ */
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index dd5022b03..afff64e98 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -1664,10 +1664,6 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(u_int32_t ticks_
ndpi_str->user_data = NULL;
#endif
- ndpi_str->match_dns_host_names = 1; /*
- Set it to 0 to increase library speed avoid
- matching host names
- */
ndpi_str->ticks_per_second = ticks_per_second;
ndpi_str->tcp_max_retransmission_window_size = NDPI_DEFAULT_MAX_TCP_RETRANSMISSION_WINDOW_SIZE;
ndpi_str->directconnect_connection_ip_tick_timeout =
diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c
index 3b4322823..ea136f453 100644
--- a/src/lib/protocols/dns.c
+++ b/src/lib/protocols/dns.c
@@ -1,7 +1,9 @@
/*
* dns.c
*
- * Copyright (C) 2012-15 - ntop.org
+ * Copyright (C) 2012-16 - ntop.org
+ *
+ * Michele Campus - <campus@ntop.org>
*
* This file is part of nDPI, an open source deep packet inspection
* library based on the OpenDPI and PACE technology by ipoque GmbH
@@ -21,282 +23,103 @@
*
*/
-
#include "ndpi_protocols.h"
#ifdef NDPI_PROTOCOL_DNS
-static u_int getNameLength(u_int i, const u_int8_t *payload, u_int payloadLen) {
- if(payload[i] == 0x00)
- return(1);
- else if(payload[i] == 0xC0)
- return(2);
- else {
- u_int8_t len = payload[i];
- u_int8_t off = len + 1;
-
- if(off == 0) /* Bad packet */
- return(0);
- else
- return(off + getNameLength(i+off, payload, payloadLen));
- }
-}
-
-/* *********************************************** */
-
-static char* ndpi_intoa_v4(unsigned int addr, char* buf, u_short bufLen) {
- char *cp, *retStr;
- uint byte;
- int n;
-
- cp = &buf[bufLen];
- *--cp = '\0';
-
- n = 4;
- do {
- byte = addr & 0xff;
- *--cp = byte % 10 + '0';
- byte /= 10;
- if(byte > 0) {
- *--cp = byte % 10 + '0';
- byte /= 10;
- if(byte > 0)
- *--cp = byte + '0';
- }
- *--cp = '.';
- addr >>= 8;
- } while (--n > 0);
-
- /* Convert the string to lowercase */
- retStr = (char*)(cp+1);
-
- return(retStr);
-}
-
-/* *********************************************** */
-
-static u_int16_t get16(int *i, const u_int8_t *payload) {
- u_int16_t v = *(u_int16_t*)&payload[*i];
-
- (*i) += 2;
-
- return(ntohs(v));
-}
-
-/* *********************************************** */
+#define FLAGS_MASK 0x8000
void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
{
- struct ndpi_packet_struct *packet = &flow->packet;
- u_int16_t dport = 0, sport = 0;
-
-#define NDPI_MAX_DNS_REQUESTS 16
- NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "search DNS.\n");
+ int x;
+ u_int8_t is_query, ret_code;
+ u_int16_t s_port = 0;
+ u_int16_t d_port = 0;
- if (packet->udp != NULL) {
- sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest);
- NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "calculated dport over UDP.\n");
- } else if(packet->tcp != NULL) {
- sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest);
- NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "calculated dport over tcp.\n");
- }
-
- if(((dport == 53) || (sport == 53) || (dport == 5355))
- && (packet->payload_packet_len > sizeof(struct ndpi_dns_packet_header))) {
- int i = packet->tcp ? 2 : 0;
- struct ndpi_dns_packet_header header, *dns = (struct ndpi_dns_packet_header*)&packet->payload[i];
- u_int8_t is_query, ret_code, is_dns = 0;
- u_int32_t a_record[NDPI_MAX_DNS_REQUESTS] = { 0 }, query_offset, num_a_records = 0;
-
- header.flags = ntohs(dns->flags);
- header.transaction_id = ntohs(dns->transaction_id);
- header.num_queries = ntohs(dns->num_queries);
- header.answer_rrs = ntohs(dns->answer_rrs);
- header.authority_rrs = ntohs(dns->authority_rrs);
- header.additional_rrs = ntohs(dns->additional_rrs);
- is_query = (header.flags & 0x8000) ? 0 : 1;
- ret_code = is_query ? 0 : (header.flags & 0x0F);
- i += sizeof(struct ndpi_dns_packet_header);
- query_offset = i;
-
- if(is_query) {
- /* DNS Request */
- if((header.num_queries > 0) && (header.num_queries <= NDPI_MAX_DNS_REQUESTS)
- && (((header.flags & 0x2800) == 0x2800 /* Dynamic DNS Update */)
- || ((header.answer_rrs == 0) && (header.authority_rrs == 0)))) {
- /* This is a good query */
- is_dns = 1;
-
- if(header.num_queries > 0) {
- while(i < packet->payload_packet_len) {
- if(packet->payload[i] == '\0') {
- i++;
- flow->protos.dns.query_type = get16(&i, packet->payload);
- break;
- } else
- i++;
- }
- }
- }
- } else {
- /* DNS Reply */
-
- flow->server_id = flow->dst;
-
- if((header.num_queries <= NDPI_MAX_DNS_REQUESTS) /* Don't assume that num_queries must be zero */
- && (((header.answer_rrs > 0) && (header.answer_rrs <= NDPI_MAX_DNS_REQUESTS))
- || ((header.authority_rrs > 0) && (header.authority_rrs <= NDPI_MAX_DNS_REQUESTS))
- || ((header.additional_rrs > 0) && (header.additional_rrs <= NDPI_MAX_DNS_REQUESTS)))
- ) {
- /* This is a good reply */
- is_dns = 1;
-
- i++;
-
- if(packet->payload[i] != '\0') {
- while((i < packet->payload_packet_len)
- && (packet->payload[i] != '\0')) {
- i++;
- }
-
- i++;
- }
-
- i += 4;
-
- if(header.answer_rrs > 0) {
- u_int16_t rsp_type;
- u_int16_t num;
-
- for(num = 0; num < header.answer_rrs; num++) {
- u_int16_t data_len;
-
- if((i+6) >= packet->payload_packet_len) {
- break;
- }
-
- if((data_len = getNameLength(i, packet->payload, packet->payload_packet_len)) == 0) {
- break;
- } else
- i += data_len;
-
- rsp_type = get16(&i, packet->payload);
-
- // Skip past the CLASS (2 octets) and TTL (4 octets) fields.
- i += 6;
- data_len = get16(&i, packet->payload);
-
- if((data_len <= 1) || (data_len > (packet->payload_packet_len-i))) {
- break;
- }
-
- flow->protos.dns.rsp_type = rsp_type;
-
- if(rsp_type == 1 /* A */) {
- if(data_len == 4) {
- u_int32_t v = ntohl(*((u_int32_t*)&packet->payload[i]));
-
- if(num_a_records < (NDPI_MAX_DNS_REQUESTS-1))
- a_record[num_a_records++] = v;
- else
- break; /* One record is enough */
- }
- }
-
- if(data_len == 0) {
- break;
- }
+ NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "search DNS.\n");
- i += data_len;
- } /* for */
- }
- }
+ if(flow->packet.udp != NULL)
+ {
+ s_port = ntohs(flow->packet.udp->source);
+ d_port = ntohs(flow->packet.udp->dest);
+ x = 0;
+ }
+ else if(flow->packet.tcp != NULL) /* pkt size > 512 bytes */
+ {
+ s_port = ntohs(flow->packet.tcp->source);
+ d_port = ntohs(flow->packet.tcp->dest);
+ x = 2;
+ }
+ else
+ {
+ NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS);
+ }
- if((header.num_queries <= NDPI_MAX_DNS_REQUESTS)
- && ((header.answer_rrs == 0)
- || (header.authority_rrs == 0)
- || (header.additional_rrs == 0))
- && (ret_code != 0 /* 0 == OK */)
- ) {
- /* This is a good reply */
- is_dns = 1;
- }
+ if((s_port == 53 || d_port == 53 || d_port == 5355)
+ && (flow->packet.payload_packet_len > sizeof(struct ndpi_dns_packet_header)))
+ {
+ struct ndpi_dns_packet_header * dns_header = (struct ndpi_dns_packet_header*) &flow->packet.payload[x];
+ dns_header->tr_id = ntohs(dns_header->tr_id);
+ dns_header->flags = ntohs(dns_header->flags);
+ dns_header->num_queries = ntohs(dns_header->num_queries);
+ dns_header->num_answers = ntohs(dns_header->num_answers);
+ dns_header->authority_rrs = ntohs(dns_header->authority_rrs);
+ dns_header->additional_rrs = ntohs(dns_header->additional_rrs);
+
+ /* 0x0000 QUERY */
+ if(dns_header->flags & FLAGS_MASK == 0x0000)
+ is_query = 0;
+ /* 0x8000 RESPONSE */
+ else if(dns_header->flags & FLAGS_MASK != 0x8000)
+ is_query = 1;
+ else
+ {
+ NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS);
}
-
- if(is_dns) {
- int j = 0;
- int size_host_server_name = sizeof(flow->host_server_name);
-
- flow->protos.dns.num_queries = (u_int8_t)header.num_queries,
- flow->protos.dns.num_answers = (u_int8_t)(header.answer_rrs+header.authority_rrs+header.additional_rrs),
- flow->protos.dns.ret_code = ret_code;
-
- i = query_offset+1;
-
- while((i < packet->payload_packet_len)
- && (j < (size_host_server_name-1))
- && (packet->payload[i] != '\0')) {
- flow->host_server_name[j] = tolower(packet->payload[i]);
- if(flow->host_server_name[j] < ' ')
- flow->host_server_name[j] = '.';
- j++, i++;
- }
-
- if(a_record[0] != 0) {
- char a_buf[32];
- int i;
-
- for(i=0; i<num_a_records && j < size_host_server_name; i++) {
- j += snprintf((char*)&flow->host_server_name[j], size_host_server_name-1-j, "%s%s",
- (i == 0) ? "@" : ";",
- ndpi_intoa_v4(a_record[i], a_buf, sizeof(a_buf)));
- }
- }
-
- flow->host_server_name[j] = '\0';
-
- if(j > 0) {
-#ifdef DEBUG
- printf("==> %s\n", flow->host_server_name);
-#endif
-
- if(ndpi_struct->match_dns_host_names)
- ndpi_match_host_subprotocol(ndpi_struct, flow,
- (char *)flow->host_server_name,
- strlen((const char*)flow->host_server_name),
- NDPI_PROTOCOL_DNS);
- }
-
- i++;
-
- memcpy(&flow->protos.dns.query_type, &packet->payload[i], 2);
- flow->protos.dns.query_type = ntohs(flow->protos.dns.query_type), i += 2;
-
- memcpy(&flow->protos.dns.query_class, &packet->payload[i], 2);
- flow->protos.dns.query_class = ntohs(flow->protos.dns.query_class), i += 2;
-
-#ifdef DEBUG
- printf("%s [type=%04X][class=%04X]\n", flow->host_server_name, flow->protos.dns.query_type, flow->protos.dns.query_class);
-#endif
-
- if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
- /*
- Do not set the protocol with DNS if ndpi_match_host_subprotocol() has
- matched a subprotocol
- */
- NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "found DNS.\n");
- ndpi_set_detected_protocol(ndpi_struct, flow, (dport == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS, NDPI_PROTOCOL_UNKNOWN);
- }
- } else {
- flow->protos.dns.bad_packet = 1;
+
+ /* extract host name server */
+ ret_code = (is_query == 0) ? 0 : (dns_header->flags & 0x0F);
+ int j = 0;
+ int off = sizeof(struct ndpi_dns_packet_header) + 1;
+ while((flow->packet.payload[off] != '\0'))
+ {
+ flow->host_server_name[j] = flow->packet.payload[off];
+ if(flow->host_server_name[j] < ' ')
+ flow->host_server_name[j] = '.';
+ off++;
+ j++;
+ }
+ flow->host_server_name[j] = '\0';
+
+ flow->protos.dns.num_answers = (u_int8_t) (dns_header->num_answers + dns_header->authority_rrs + dns_header->additional_rrs);
+ flow->protos.dns.ret_code = ret_code;
+
+ if(j > 0)
+ ndpi_match_host_subprotocol(ndpi_struct, flow,
+ (char *)flow->host_server_name,
+ strlen((const char*)flow->host_server_name),
+ NDPI_PROTOCOL_DNS);
+
+ if(flow->packet.detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN)
+ {
+ /**
+ Do not set the protocol with DNS if ndpi_match_host_subprotocol() has
+ matched a subprotocol
+ **/
+ NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "found DNS.\n");
+ ndpi_set_detected_protocol(ndpi_struct, flow, (d_port == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS, NDPI_PROTOCOL_UNKNOWN);
+ }
+ else
+ {
NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n");
NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS);
}
}
}
-
void init_dns_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask)
{
ndpi_set_bitmask_protocol_detection("DNS", ndpi_struct, detection_bitmask, *id,