From c839dcb74c5ab55191e91c2087fada9a079e70a7 Mon Sep 17 00:00:00 2001 From: Luca Deri Date: Fri, 27 Sep 2019 17:34:22 +0200 Subject: Improved category handlign in subprotocols Further DNS dissection fixes Fixed WeChat invalid category --- src/lib/ndpi_content_match.c.inc | 2 -- src/lib/ndpi_main.c | 10 +++++-- src/lib/protocols/dns.c | 59 ++++++++++++++++++++++------------------ 3 files changed, 40 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/lib/ndpi_content_match.c.inc b/src/lib/ndpi_content_match.c.inc index 46d032ac2..c6e753de6 100644 --- a/src/lib/ndpi_content_match.c.inc +++ b/src/lib/ndpi_content_match.c.inc @@ -8727,8 +8727,6 @@ ndpi_protocol_match host_match[] = { /* Detected "slack-assets2.s3-us-west-2.amazonaws.com.". Omitted "*amazonaws.com" CDN, but no generic pattern to use on first part */ { "slack-assets2.s3-", NULL, "slack-assets2\\.s3-", "Slack", NDPI_PROTOCOL_SLACK, NDPI_PROTOCOL_CATEGORY_COLLABORATIVE, NDPI_PROTOCOL_ACCEPTABLE }, - { "wechat.com", NULL, "wechat\\.com" TLD, "WeChat", NDPI_PROTOCOL_WECHAT, NDPI_PROTOCOL_CATEGORY_SOCIAL_NETWORK, NDPI_PROTOCOL_FUN }, - { "github.com", NULL, "github" TLD, "Github", NDPI_PROTOCOL_GITHUB, NDPI_PROTOCOL_CATEGORY_COLLABORATIVE, NDPI_PROTOCOL_ACCEPTABLE }, { ".github.com", NULL, "\\.github" TLD, "Github", NDPI_PROTOCOL_GITHUB, NDPI_PROTOCOL_CATEGORY_COLLABORATIVE, NDPI_PROTOCOL_ACCEPTABLE }, { "github.io", NULL, NULL, "Github", NDPI_PROTOCOL_GITHUB, NDPI_PROTOCOL_CATEGORY_COLLABORATIVE, NDPI_PROTOCOL_ACCEPTABLE }, diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 738a65388..dbcea0f42 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -978,7 +978,7 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp ndpi_build_default_ports(ports_b, 3544, 0, 0, 0, 0) /* UDP */); ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_WECHAT, 0 /* can_have_a_subprotocol */, no_master, /* wechat.com */ - no_master, "WeChat", NDPI_PROTOCOL_CATEGORY_SOCIAL_NETWORK, + no_master, "WeChat", NDPI_PROTOCOL_CATEGORY_CHAT, ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MEMCACHED, @@ -4738,8 +4738,12 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct } else ret.app_protocol = flow->detected_protocol_stack[0]; - ndpi_fill_protocol_category(ndpi_struct, flow, &ret); - + /* Don;t overwrite the category if already set */ + if(flow->category == NDPI_PROTOCOL_CATEGORY_UNSPECIFIED) + ndpi_fill_protocol_category(ndpi_struct, flow, &ret); + else + ret.category = flow->category; + if((flow->num_processed_pkts == 1) && (ret.master_protocol == NDPI_PROTOCOL_UNKNOWN) && (ret.app_protocol == NDPI_PROTOCOL_UNKNOWN) diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c index 4a11edb84..86575f23e 100644 --- a/src/lib/protocols/dns.c +++ b/src/lib/protocols/dns.c @@ -59,8 +59,8 @@ static u_int getNameLength(u_int i, const u_int8_t *payload, u_int payloadLen) { return(off + getNameLength(i+off, payload, payloadLen)); } } -/* - allowed chars for dns names A-Z 0-9 _ - +/* + allowed chars for dns names A-Z 0-9 _ - Perl script for generation map: my @M; for(my $ch=0; $ch < 256; $ch++) { @@ -89,7 +89,7 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct, 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); - + x += sizeof(struct ndpi_dns_packet_header); /* 0x0000 QUERY */ @@ -115,14 +115,10 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG_DBG2(ndpi_struct, "query_type=%2d\n", flow->protos.dns.query_type); printf("[DNS] query_type=%d\n", flow->protos.dns.query_type); #endif - - if(ndpi_struct->dns_dont_dissect_response) - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DNS, NDPI_PROTOCOL_UNKNOWN); - break; } else x++; - } + } } else return(1 /* invalid */); } else { @@ -205,7 +201,7 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd u_int16_t s_port = 0, d_port = 0; NDPI_LOG_DBG(ndpi_struct, "search DNS\n"); - + if(flow->packet.udp != NULL) { s_port = ntohs(flow->packet.udp->source); d_port = ntohs(flow->packet.udp->dest); @@ -224,7 +220,11 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd 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; + ret.master_protocol = NDPI_PROTOCOL_UNKNOWN; + ret.app_protocol = (d_port == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS; + if(invalid) { NDPI_EXCLUDE_PROTO(ndpi_struct, flow); return; @@ -236,15 +236,15 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd while(j < max_len && off < flow->packet.payload_packet_len && flow->packet.payload[off] != '\0') { uint8_t c, cl = flow->packet.payload[off++]; - + if( (cl & 0xc0) != 0 || // we not support compressed names in query off + cl >= flow->packet.payload_packet_len) { j = 0; break; } - + if(j && j < max_len) flow->host_server_name[j++] = '.'; - + while(j < max_len && cl != 0) { c = flow->packet.payload[off++]; flow->host_server_name[j++] = (dns_validchar[c >> 5] & (1 << (c & 0x1f))) ? c : '_'; @@ -253,26 +253,33 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd } flow->host_server_name[j] = '\0'; + if(j > 0) { + ndpi_protocol_match_result ret_match; + + ret.app_protocol = ndpi_match_host_subprotocol(ndpi_struct, flow, + (char *)flow->host_server_name, + strlen((const char*)flow->host_server_name), + &ret_match, + NDPI_PROTOCOL_DNS); + + if(ret_match.protocol_category != NDPI_PROTOCOL_CATEGORY_UNSPECIFIED) + 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; + else + ret.master_protocol = NDPI_PROTOCOL_DNS; + } + if(is_query && (ndpi_struct->dns_dont_dissect_response == 0)) { - // dpi_set_detected_protocol(ndpi_struct, flow, (d_port == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS, NDPI_PROTOCOL_UNKNOWN); + /* In this case we say that the protocol has been detected just to let apps carry on with their activities */ + ndpi_set_detected_protocol(ndpi_struct, flow, ret.app_protocol, ret.master_protocol); return; /* The response will set the verdict */ } flow->protos.dns.num_queries = (u_int8_t)dns_header.num_queries, flow->protos.dns.num_answers = (u_int8_t) (dns_header.num_answers + dns_header.authority_rrs + dns_header.additional_rrs); - if(j > 0) { - ndpi_protocol_match_result ret_match; - u_int32_t subproto = ndpi_match_host_subprotocol(ndpi_struct, flow, - (char *)flow->host_server_name, - strlen((const char*)flow->host_server_name), - &ret_match, - NDPI_PROTOCOL_DNS); - - if(ret_match.protocol_category != NDPI_PROTOCOL_CATEGORY_UNSPECIFIED) - flow->category = ret_match.protocol_category; - } - #ifdef DNS_DEBUG NDPI_LOG_DBG2(ndpi_struct, "[num_queries=%d][num_answers=%d][reply_code=%u][rsp_type=%u][host_server_name=%s]\n", flow->protos.dns.num_queries, flow->protos.dns.num_answers, @@ -286,7 +293,7 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd matched a subprotocol **/ NDPI_LOG_INFO(ndpi_struct, "found DNS\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, (d_port == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS, NDPI_PROTOCOL_UNKNOWN); + ndpi_set_detected_protocol(ndpi_struct, flow, ret.app_protocol, ret.master_protocol); } else { if((flow->packet.detected_protocol_stack[0] == NDPI_PROTOCOL_DNS) || (flow->packet.detected_protocol_stack[1] == NDPI_PROTOCOL_DNS)) -- cgit v1.2.3