diff options
Diffstat (limited to 'src/lib/protocols')
-rw-r--r-- | src/lib/protocols/amazon_video.c | 43 | ||||
-rw-r--r-- | src/lib/protocols/dns.c | 4 | ||||
-rw-r--r-- | src/lib/protocols/ftp_control.c | 426 | ||||
-rw-r--r-- | src/lib/protocols/http.c | 163 | ||||
-rw-r--r-- | src/lib/protocols/iec60870-5-104.c | 18 | ||||
-rw-r--r-- | src/lib/protocols/irc.c | 3 | ||||
-rw-r--r-- | src/lib/protocols/kerberos.c | 283 | ||||
-rw-r--r-- | src/lib/protocols/mail_smtp.c | 84 | ||||
-rw-r--r-- | src/lib/protocols/ntp.c | 2 | ||||
-rw-r--r-- | src/lib/protocols/smpp.c | 2 | ||||
-rw-r--r-- | src/lib/protocols/ssh.c | 2 | ||||
-rw-r--r-- | src/lib/protocols/telnet.c | 33 | ||||
-rw-r--r-- | src/lib/protocols/tls.c | 21 |
13 files changed, 461 insertions, 623 deletions
diff --git a/src/lib/protocols/amazon_video.c b/src/lib/protocols/amazon_video.c index 41356d9ad..e92c87ad5 100644 --- a/src/lib/protocols/amazon_video.c +++ b/src/lib/protocols/amazon_video.c @@ -1,7 +1,7 @@ /* * amazon_video.c * - * Copyright (C) 2018 by ntop.org + * Copyright (C) 2018-19 by 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 @@ -28,37 +28,36 @@ #include "ndpi_api.h" static void ndpi_check_amazon_video(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow) { - + struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; NDPI_LOG_DBG(ndpi_struct, "search Amazon Prime\n"); - if((packet->tcp != NULL) && - (packet->payload[0] == 0xFE && - packet->payload[1] == 0xED && - packet->payload[2] == 0xFA && - packet->payload[3] == 0xCE)) - { + if(packet->payload_packet_len > 4) { + if((packet->tcp != NULL) && + (packet->payload[0] == 0xFE && + packet->payload[1] == 0xED && + packet->payload[2] == 0xFA && + packet->payload[3] == 0xCE)) { NDPI_LOG_INFO(ndpi_struct, "found Amazon Video on TCP\n"); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_AMAZON_VIDEO, NDPI_PROTOCOL_UNKNOWN); return; - } - else if((packet->udp != NULL) && - (packet->payload[0] == 0xDE && - packet->payload[1] == 0xAD && - packet->payload[2] == 0xBE && - packet->payload[3] == 0xEF)) - { + } else if((packet->udp != NULL) && + (packet->payload[0] == 0xDE && + packet->payload[1] == 0xAD && + packet->payload[2] == 0xBE && + packet->payload[3] == 0xEF)) { NDPI_LOG_INFO(ndpi_struct, "found Amazon Video on UDP\n"); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_AMAZON_VIDEO, NDPI_PROTOCOL_UNKNOWN); - } else { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + return; + } } + + NDPI_EXCLUDE_PROTO(ndpi_struct, flow); } -void ndpi_search_amazon_video(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ +void ndpi_search_amazon_video(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; NDPI_LOG_DBG(ndpi_struct, "search amazon_video\n"); @@ -69,8 +68,8 @@ void ndpi_search_amazon_video(struct ndpi_detection_module_struct *ndpi_struct, } -void init_amazon_video_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) -{ +void init_amazon_video_dissector(struct ndpi_detection_module_struct *ndpi_struct, + u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("AMAZON_VIDEO", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_AMAZON_VIDEO, ndpi_search_amazon_video, diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c index 7051b2227..3fbb39915 100644 --- a/src/lib/protocols/dns.c +++ b/src/lib/protocols/dns.c @@ -47,7 +47,9 @@ static u_int16_t get16(int *i, const u_int8_t *payload) { /* *********************************************** */ static u_int getNameLength(u_int i, const u_int8_t *payload, u_int payloadLen) { - if(payload[i] == 0x00) + if(i >= payloadLen) + return(0); + else if(payload[i] == 0x00) return(1); else if(payload[i] == 0xC0) return(2); diff --git a/src/lib/protocols/ftp_control.c b/src/lib/protocols/ftp_control.c index 135096743..2fbbece28 100644 --- a/src/lib/protocols/ftp_control.c +++ b/src/lib/protocols/ftp_control.c @@ -553,411 +553,21 @@ static int ndpi_ftp_control_check_response(struct ndpi_flow_struct *flow, printf("%s() [%s]\n", __FUNCTION__, payload); #endif - if(ndpi_match_strprefix(payload, payload_len, "110-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "120-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "125-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "150-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "202-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "211-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "212-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "213-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "214-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "215-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "220-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "221-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "225-")) { - return 1; - } + if(payload_len == 0) return(1); - if(ndpi_match_strprefix(payload, payload_len, "226-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "227-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "228-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "229-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "230-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "231-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "232-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "250-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "257-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "331-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "332-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "350-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "421-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "425-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "426-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "430-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "434-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "450-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "451-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "452-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "501-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "502-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "503-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "504-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "530-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "532-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "550-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "551-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "552-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "553-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "631-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "632-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "633-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "10054-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "10060-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "10061-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "10066-")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "10068-")) { - return 1; - } + switch(payload[0]) { + case '1': + case '2': + case '3': + case '6': + return(1); + break; - if(ndpi_match_strprefix(payload, payload_len, "110 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "120 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "125 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "150 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "202 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "211 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "212 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "213 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "214 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "215 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "220 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "221 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "225 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "226 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "227 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "228 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "229 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "230 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "231 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "232 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "250 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "257 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "331 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "332 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "350 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "421 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "425 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "426 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "430 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "434 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "450 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "451 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "452 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "501 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "502 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "503 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "504 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "530 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "532 ")) { - return 1; - } - if(ndpi_match_strprefix(payload, payload_len, "550 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "551 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "552 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "553 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "631 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "632 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "633 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "10054 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "10060 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "10061 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "10066 ")) { - return 1; - } - - if(ndpi_match_strprefix(payload, payload_len, "10068 ")) { - return 1; + case '4': + case '5': + flow->protos.ftp_imap_pop_smtp.auth_failed = 1; + return(1); + break; } return 0; @@ -972,8 +582,10 @@ static void ndpi_check_ftp_control(struct ndpi_detection_module_struct *ndpi_str /* Check connection over TCP */ if(packet->tcp) { + u_int16_t twentyfive = htons(25); + /* Exclude SMTP, which uses similar commands. */ - if(packet->tcp->dest == htons(25) || packet->tcp->source == htons(25)) { + if(packet->tcp->dest == twentyfive || packet->tcp->source == twentyfive) { NDPI_EXCLUDE_PROTO(ndpi_struct, flow); return; } @@ -988,8 +600,7 @@ static void ndpi_check_ftp_control(struct ndpi_detection_module_struct *ndpi_str if(flow->ftp_control_stage == 0) { NDPI_LOG_DBG2(ndpi_struct, "FTP_CONTROL stage 0: \n"); - if((payload_len > 0) - && ndpi_ftp_control_check_request(flow, packet->payload, payload_len)) { + if((payload_len > 0) && ndpi_ftp_control_check_request(flow, packet->payload, payload_len)) { NDPI_LOG_DBG2(ndpi_struct, "Possible FTP_CONTROL request detected, we will look further for the response..\n"); @@ -1011,8 +622,7 @@ static void ndpi_check_ftp_control(struct ndpi_detection_module_struct *ndpi_str } /* This is a packet in another direction. Check if we find the proper response. */ - if((payload_len > 0) - && ndpi_ftp_control_check_response(flow, packet->payload, payload_len)) { + if((payload_len > 0) && ndpi_ftp_control_check_response(flow, packet->payload, payload_len)) { NDPI_LOG_INFO(ndpi_struct, "found FTP_CONTROL\n"); #ifdef FTP_DEBUG diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c index 2525cfbd7..70ca0c389 100644 --- a/src/lib/protocols/http.c +++ b/src/lib/protocols/http.c @@ -33,7 +33,8 @@ static void ndpi_search_http_tcp(struct ndpi_detection_module_struct *ndpi_struc /* *********************************************** */ -static int ndpi_search_http_tcp_again(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { +static int ndpi_search_http_tcp_again(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { ndpi_search_http_tcp(ndpi_struct, flow); #ifdef HTTP_DEBUG @@ -52,9 +53,46 @@ static int ndpi_search_http_tcp_again(struct ndpi_detection_module_struct *ndpi_ /* *********************************************** */ +/* https://www.freeformatter.com/mime-types-list.html */ +static ndpi_protocol_category_t ndpi_http_check_content(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + + if(packet->content_line.len > 0) { + u_int app_len = sizeof("application"); + + if(packet->content_line.len > app_len) { + if(ndpi_strncasestr((const char *)&packet->content_line.ptr[app_len], "mpeg", + packet->content_line.len-app_len) != NULL) { + flow->guessed_category = flow->category = NDPI_PROTOCOL_CATEGORY_STREAMING; + return(flow->category); + } + } + + switch(packet->content_line.ptr[0]) { + case 'a': + if(strncasecmp((const char *)packet->content_line.ptr, "audio", + ndpi_min(packet->content_line.len, 5)) == 0) + flow->guessed_category = flow->category = NDPI_PROTOCOL_CATEGORY_MEDIA; + break; + + case 'v': + if(strncasecmp((const char *)packet->content_line.ptr, "video", + ndpi_min(packet->content_line.len, 5)) == 0) + flow->guessed_category = flow->category = NDPI_PROTOCOL_CATEGORY_MEDIA; + break; + } + } + + return(flow->category); +} + +/* *********************************************** */ + static void ndpi_int_http_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, - u_int16_t category) { + u_int16_t http_protocol, + ndpi_protocol_category_t category) { #ifdef HTTP_DEBUG printf("=> %s()\n", __FUNCTION__); #endif @@ -66,30 +104,36 @@ static void ndpi_int_http_add_connection(struct ndpi_detection_module_struct *nd ndpi_search_tcp_or_udp(ndpi_struct, flow); /* If no custom protocol has been detected */ - if(flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) { - ndpi_int_reset_protocol(flow); - ndpi_set_detected_protocol(ndpi_struct, flow, flow->guessed_host_protocol_id, NDPI_PROTOCOL_HTTP); - } else - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_HTTP, NDPI_PROTOCOL_UNKNOWN); + if((flow->guessed_host_protocol_id == NDPI_PROTOCOL_UNKNOWN) || (http_protocol != NDPI_PROTOCOL_HTTP)) + flow->guessed_host_protocol_id = http_protocol; + + category = ndpi_http_check_content(ndpi_struct, flow); + ndpi_int_reset_protocol(flow); + ndpi_set_detected_protocol(ndpi_struct, flow, flow->guessed_host_protocol_id, NDPI_PROTOCOL_HTTP); /* This is necessary to inform the core to call this dissector again */ flow->check_extra_packets = 1; flow->max_extra_packets_to_check = 5; flow->extra_packets_func = ndpi_search_http_tcp_again; - flow->http_detected = 1, flow->guessed_category = category; + flow->http_detected = 1, flow->guessed_category = flow->category = category; } +/* ************************************************************* */ + static void rtsp_parse_packet_acceptline(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; - if(packet->accept_line.len >= 28 && memcmp(packet->accept_line.ptr, "application/x-rtsp-tunnelled", 28) == 0) { + if((packet->accept_line.len >= 28) + && (memcmp(packet->accept_line.ptr, "application/x-rtsp-tunnelled", 28) == 0)) { NDPI_LOG_INFO(ndpi_struct, "found RTSP accept line\n"); - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RTSP); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RTSP, NDPI_PROTOCOL_CATEGORY_MEDIA); } } +/* ************************************************************* */ + static void setHttpUserAgent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, char *ua) { if ( !strcmp(ua, "Windows NT 5.0")) ua = "Windows 2000"; @@ -110,7 +154,10 @@ static void setHttpUserAgent(struct ndpi_detection_module_struct *ndpi_struct, } } -static void parseHttpSubprotocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { +/* ************************************************************* */ + +static void ndpi_http_parse_subprotocol(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { if((flow->l4.tcp.http_stage == 0) || (flow->http.url && flow->http_detected)) { char *double_col = strchr((char*)flow->host_server_name, ':'); ndpi_protocol_match_result ret_match; @@ -124,13 +171,14 @@ static void parseHttpSubprotocol(struct ndpi_detection_module_struct *ndpi_struc } } +/* ************************************************************* */ + /** NOTE ndpi_parse_packet_line_info is in ndpi_main.c */ static void check_content_type_and_change_protocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { - struct ndpi_packet_struct *packet = &flow->packet; ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_HTTP, NDPI_PROTOCOL_UNKNOWN); @@ -142,13 +190,12 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ /* PPStream */ if(flow->l4.tcp.ppstream_stage > 0 && flow->iqiyi_counter == 0) { NDPI_LOG_INFO(ndpi_struct, "found PPStream\n"); - /* ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_PPSTREAM); */ - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_PPSTREAM, NDPI_PROTOCOL_HTTP); - } - else if(flow->iqiyi_counter > 0) { + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_PPSTREAM, + NDPI_PROTOCOL_HTTP, NDPI_PROTOCOL_CATEGORY_STREAMING); + } else if(flow->iqiyi_counter > 0) { NDPI_LOG_INFO(ndpi_struct, "found iQiyi\n"); - /* ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_IQIYI); */ - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_IQIYI, NDPI_PROTOCOL_HTTP); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_IQIYI, + NDPI_PROTOCOL_HTTP, NDPI_PROTOCOL_CATEGORY_STREAMING); } #endif @@ -156,8 +203,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ /* 1KXUN */ if(flow->kxun_counter > 0) { NDPI_LOG_INFO(ndpi_struct, "found 1kxun\n"); - /* ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_1KXUN); */ - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_1KXUN, NDPI_PROTOCOL_HTTP); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_1KXUN, NDPI_PROTOCOL_CATEGORY_STREAMING); } #endif @@ -257,10 +303,9 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ setHttpUserAgent(ndpi_struct, flow, token); } } - } - else if(memcmp(ua, "netflix-ios-app", 15) == 0) { + } else if(memcmp(ua, "netflix-ios-app", 15) == 0) { NDPI_LOG_INFO(ndpi_struct, "found netflix\n"); - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_NETFLIX); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_NETFLIX, NDPI_PROTOCOL_CATEGORY_STREAMING); return; } } @@ -287,17 +332,6 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ NDPI_LOG_DBG2(ndpi_struct, "HOST line found %.*s\n", packet->host_line.len, packet->host_line.ptr); - /* call ndpi_match_host_subprotocol to see if there is a match with known-host HTTP subprotocol */ - if(flow->http_detected) { - ndpi_protocol_match_result ret_match; - - ndpi_match_host_subprotocol(ndpi_struct, flow, - (char*)packet->host_line.ptr, - packet->host_line.len, - &ret_match, - NDPI_PROTOCOL_HTTP); - } - /* Copy result for nDPI apps */ if(!ndpi_struct->disable_metadata_export) { len = ndpi_min(packet->host_line.len, sizeof(flow->host_server_name)-1); @@ -316,7 +350,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ } } - parseHttpSubprotocol(ndpi_struct, flow); + ndpi_http_parse_subprotocol(ndpi_struct, flow); /** check result of host subprotocol detection @@ -355,7 +389,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_HTTP) { NDPI_LOG_INFO(ndpi_struct, "found HTTP/%s\n", ndpi_get_proto_name(ndpi_struct, packet->detected_protocol_stack[0])); - ndpi_int_http_add_connection(ndpi_struct, flow, packet->detected_protocol_stack[0]); + ndpi_int_http_add_connection(ndpi_struct, flow, packet->detected_protocol_stack[0], NDPI_PROTOCOL_CATEGORY_WEB); return; /* We have identified a sub-protocol so we're done */ } } @@ -363,7 +397,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ #if 0 if(flow->http_detected) - parseHttpSubprotocol(ndpi_struct, flow); + ndpi_http_parse_subprotocol(ndpi_struct, flow); #endif if(flow->guessed_protocol_id == NDPI_PROTOCOL_UNKNOWN) @@ -385,7 +419,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ if((flow->http.content_type == NULL) && (packet->content_line.len > 0)) { int len = packet->content_line.len + 1; - + flow->http.content_type = ndpi_malloc(len); if(flow->http.content_type) { strncpy(flow->http.content_type, (char*)packet->content_line.ptr, @@ -393,7 +427,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ flow->http.content_type[packet->content_line.len] = '\0'; } } - + if(flow->http_detected) { ndpi_protocol_match_result ret_match; @@ -403,13 +437,17 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ } } - ndpi_int_http_add_connection(ndpi_struct, flow, packet->detected_protocol_stack[0]); + ndpi_int_http_add_connection(ndpi_struct, flow, packet->detected_protocol_stack[0], NDPI_PROTOCOL_CATEGORY_WEB); } +/* ************************************************************* */ + static void check_http_payload(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { /* Add here your paylod code check */ } +/* ************************************************************* */ + /** * Functions to check whether the packet begins with a valid http request * @param ndpi_struct @@ -446,7 +484,7 @@ static u_int16_t http_request_url_offset(struct ndpi_detection_module_struct *nd packet->payload_packet_len); /* Check first char */ - if(!strchr(http_fs,packet->payload[0])) return 0; + if(!packet->payload_packet_len || !strchr(http_fs,packet->payload[0])) return 0; /** FIRST PAYLOAD PACKET FROM CLIENT **/ @@ -540,7 +578,7 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct </cross-domain-policy> */ ookla_found: - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OOKLA, NDPI_PROTOCOL_UNKNOWN); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OOKLA, NDPI_PROTOCOL_CATEGORY_WEB); if(ndpi_struct->ookla_cache == NULL) ndpi_struct->ookla_cache = ndpi_lru_cache_init(1024); @@ -604,34 +642,12 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct goto ookla_found; } -#if OBSOLETE - /* Check for additional field introduced by Steam */ - int x = 1; - if(packet->line[x].len >= 11 && (memcmp(packet->line[x].ptr, "x-steam-sid", 11)) == 0) { - NDPI_LOG_INFO(ndpi_struct, "found STEAM\n"); - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_STEAM); - check_content_type_and_change_protocol(ndpi_struct, flow); - return; - } - - /* Check for additional field introduced by Facebook */ - x = 1; - while(packet->line[x].len != 0) { - if(packet->line[x].len >= 12 && (memcmp(packet->line[x].ptr, "X-FB-SIM-HNI", 12)) == 0) { - NDPI_LOG_INFO(ndpi_struct, "found FACEBOOK\n"); - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_FACEBOOK); - check_content_type_and_change_protocol(ndpi_struct, flow); - return; - } - x++; - } -#endif - #if defined(NDPI_PROTOCOL_1KXUN) || defined(NDPI_PROTOCOL_IQIYI) /* check PPStream protocol or iQiyi service (iqiyi is delivered by ppstream) */ // substring in url - if(ndpi_strnstr((const char*) &packet->payload[filename_start], "iqiyi.com", (packet->payload_packet_len - filename_start)) != NULL) { + if(ndpi_strnstr((const char*) &packet->payload[filename_start], "iqiyi.com", + (packet->payload_packet_len - filename_start)) != NULL) { if(flow->kxun_counter == 0) { flow->l4.tcp.ppstream_stage++; flow->iqiyi_counter++; @@ -673,14 +689,14 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct if((packet->http_url_name.len > 7) && (!strncmp((const char*) packet->http_url_name.ptr, "http://", 7))) { NDPI_LOG_INFO(ndpi_struct, "found HTTP_PROXY\n"); - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP_PROXY); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP_PROXY, NDPI_PROTOCOL_CATEGORY_WEB); check_content_type_and_change_protocol(ndpi_struct, flow); } if(filename_start == 8 && (memcmp(packet->payload, "CONNECT ", 8) == 0)) { /* nathan@getoffmalawn.com */ NDPI_LOG_INFO(ndpi_struct, "found HTTP_CONNECT\n"); - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP_CONNECT); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP_CONNECT, NDPI_PROTOCOL_CATEGORY_WEB); check_content_type_and_change_protocol(ndpi_struct, flow); } @@ -695,7 +711,7 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct in 99.99% of the cases is like that. */ - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP, NDPI_PROTOCOL_CATEGORY_WEB); flow->http_detected = 1; NDPI_LOG_DBG2(ndpi_struct, "HTTP START Found, we will look further for the response...\n"); @@ -723,7 +739,8 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OOKLA); /** - At first check, if this is for sure a response packet (in another direction. If not, if HTTP is detected do nothing now and return, + At first check, if this is for sure a response packet + (in another direction. If not, if HTTP is detected do nothing now and return, otherwise check the second packet for the HTTP request */ if((flow->l4.tcp.http_stage - packet->packet_direction) == 1) { /* Expected a response package */ @@ -757,7 +774,7 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct && memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) { NDPI_LOG_INFO(ndpi_struct, "found HTTP\n"); - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP, NDPI_PROTOCOL_CATEGORY_WEB); check_content_type_and_change_protocol(ndpi_struct, flow); NDPI_LOG_DBG2(ndpi_struct, @@ -779,7 +796,7 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct if((packet->parsed_lines == 1) && (packet->packet_direction == 1 /* server -> client */)) { /* In Apache if you do "GET /\n\n" the response comes without any header */ NDPI_LOG_INFO(ndpi_struct, "found HTTP. (apache)\n"); - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP, NDPI_PROTOCOL_CATEGORY_WEB); check_content_type_and_change_protocol(ndpi_struct, flow); return; } @@ -787,7 +804,7 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct /* If we already detected the HTTP request, we can add the connection and then check for the sub-protocol */ if(flow->http_detected) { NDPI_LOG_INFO(ndpi_struct, "found HTTP\n"); - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP, NDPI_PROTOCOL_CATEGORY_WEB); } /* Parse packet line and we look for the subprotocols */ diff --git a/src/lib/protocols/iec60870-5-104.c b/src/lib/protocols/iec60870-5-104.c index e34ca3d63..040a1842a 100644 --- a/src/lib/protocols/iec60870-5-104.c +++ b/src/lib/protocols/iec60870-5-104.c @@ -27,16 +27,16 @@ #include "ndpi_protocol_ids.h" #include "ndpi_api.h" -#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_104 +#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_IEC60870 -void ndpi_search_104_tcp(struct ndpi_detection_module_struct *ndpi_struct, +void ndpi_search_iec60870_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; - NDPI_LOG_DBG(ndpi_struct, "search 104\n"); - u_int16_t iec104_port = htons(2404); // port used by 104 + u_int16_t iec104_port = htons(2404); // port used by IEC60870 /* Check connection over TCP */ - + NDPI_LOG_DBG(ndpi_struct, "search IEC60870\n"); + if(packet->tcp) { /* The start byte of 104 is 0x68 * The usual port: 2404 @@ -44,7 +44,7 @@ void ndpi_search_104_tcp(struct ndpi_detection_module_struct *ndpi_struct, if((packet->payload[0] == 0x68) && ((packet->tcp->dest == iec104_port) || (packet->tcp->source == iec104_port)) ){ NDPI_LOG_INFO(ndpi_struct, "found 104\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_104, NDPI_PROTOCOL_UNKNOWN); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_IEC60870, NDPI_PROTOCOL_UNKNOWN); return; } } @@ -56,9 +56,9 @@ void ndpi_search_104_tcp(struct ndpi_detection_module_struct *ndpi_struct, void init_104_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { - ndpi_set_bitmask_protocol_detection("104", ndpi_struct, detection_bitmask, *id, - NDPI_PROTOCOL_104, - ndpi_search_104_tcp, + ndpi_set_bitmask_protocol_detection("IEC60870", ndpi_struct, detection_bitmask, *id, + NDPI_PROTOCOL_IEC60870, + ndpi_search_iec60870_tcp, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); diff --git a/src/lib/protocols/irc.c b/src/lib/protocols/irc.c index ec22ee38b..37cfbe1ed 100644 --- a/src/lib/protocols/irc.c +++ b/src/lib/protocols/irc.c @@ -492,9 +492,10 @@ void ndpi_search_irc_tcp(struct ndpi_detection_module_struct *ndpi_struct, struc ndpi_parse_packet_line_info(ndpi_struct, flow); } else { flow->l4.tcp.irc_3a_counter++; + packet->parsed_lines = 0; } for (i = 0; i < packet->parsed_lines; i++) { - if (packet->line[i].ptr[0] == ':') { + if ((packet->line[i].len > 0) && packet->line[i].ptr[0] == ':') { flow->l4.tcp.irc_3a_counter++; if (flow->l4.tcp.irc_3a_counter == 7) { /* ':' == 0x3a */ NDPI_LOG_INFO(ndpi_struct, "found irc. 0x3a. seven times."); diff --git a/src/lib/protocols/kerberos.c b/src/lib/protocols/kerberos.c index 533995604..1eb006108 100644 --- a/src/lib/protocols/kerberos.c +++ b/src/lib/protocols/kerberos.c @@ -28,7 +28,9 @@ #include "ndpi_api.h" -/* #define KERBEROS_DEBUG 1 */ +//#define KERBEROS_DEBUG 1 + +#define KERBEROS_PORT 88 static void ndpi_int_kerberos_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { @@ -41,62 +43,198 @@ static void ndpi_int_kerberos_add_connection(struct ndpi_detection_module_struct void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; + u_int16_t sport = packet->tcp ? ntohs(packet->tcp->source) : ntohs(packet->udp->source); + u_int16_t dport = packet->tcp ? ntohs(packet->tcp->dest) : ntohs(packet->udp->dest); + if((sport != KERBEROS_PORT) && (dport != KERBEROS_PORT)) { + NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + return; + } + NDPI_LOG_DBG(ndpi_struct, "search KERBEROS\n"); +#ifdef KERBEROS_DEBUG + printf("\n[Kerberos] Process packet [len: %u]\n", packet->payload_packet_len); +#endif + + if(flow->kerberos_buf.pktbuf != NULL) { + u_int missing = flow->kerberos_buf.pktbuf_maxlen - flow->kerberos_buf.pktbuf_currlen; + + if(packet->payload_packet_len <= missing) { + memcpy(&flow->kerberos_buf.pktbuf[flow->kerberos_buf.pktbuf_currlen], packet->payload, packet->payload_packet_len); + flow->kerberos_buf.pktbuf_currlen += packet->payload_packet_len; + + if(flow->kerberos_buf.pktbuf_currlen == flow->kerberos_buf.pktbuf_maxlen) { + packet->payload = (u_int8_t *)flow->kerberos_buf.pktbuf; + packet->payload_packet_len = flow->kerberos_buf.pktbuf_currlen; +#ifdef KERBEROS_DEBUG + printf("[Kerberos] Packet is now full: processing\n"); +#endif + } else { +#ifdef KERBEROS_DEBUG + printf("[Kerberos] Missing %u bytes: skipping\n", + flow->kerberos_buf.pktbuf_maxlen - flow->kerberos_buf.pktbuf_currlen); +#endif + + return; + } + } + } + /* I have observed 0a,0c,0d,0e at packet->payload[19/21], maybe there are other possibilities */ if(packet->payload_packet_len >= 4) { - u_int32_t kerberos_len = ntohl(get_u_int32_t(packet->payload, 0)); - u_int32_t expected_len = packet->payload_packet_len - 4; + u_int32_t kerberos_len, expected_len; + u_int16_t base_offset = 0; + + if(packet->tcp) { + kerberos_len = ntohl(get_u_int32_t(packet->payload, 0)), + expected_len = packet->payload_packet_len - 4; + base_offset = 4; + } else + base_offset = 0, kerberos_len = expected_len = packet->payload_packet_len; - if(kerberos_len < 1514) { +#ifdef KERBEROS_DEBUG + printf("[Kerberos] [Kerberos len: %u][expected_len: %u]\n", kerberos_len, expected_len); +#endif + + if(kerberos_len < 12000) { /* Kerberos packets might be too long for a TCP packet so it could be split across two packets. Instead of rebuilding the stream we use a heuristic approach */ - if(kerberos_len >= expected_len) { + if(kerberos_len > expected_len) { + if(packet->tcp) { + flow->kerberos_buf.pktbuf = (char*)ndpi_malloc(kerberos_len+4); + if(flow->kerberos_buf.pktbuf != NULL) { + flow->kerberos_buf.pktbuf_maxlen = kerberos_len+4; + memcpy(flow->kerberos_buf.pktbuf, packet->payload, packet->payload_packet_len); + flow->kerberos_buf.pktbuf_currlen = packet->payload_packet_len; + } + } + + return; + } else if(kerberos_len == expected_len) { if(packet->payload_packet_len > 128) { - u_int16_t koffset; + u_int16_t koffset, i; - if(packet->payload[14] == 0x05) /* PVNO */ - koffset = 19; - else - koffset = 21; + for(i=8; i<16; i++) + if((packet->payload[base_offset+i] == 0x03) + && (packet->payload[base_offset+i+1] == 0x02) + && (packet->payload[base_offset+i+2] == 0x01) + && (packet->payload[base_offset+i+3] != 0x05) + ) + break; + + koffset = base_offset + i + 3; - if((packet->payload[koffset] == 0x0a || packet->payload[koffset] == 0x0c || packet->payload[koffset] == 0x0d || packet->payload[koffset] == 0x0e)) { #ifdef KERBEROS_DEBUG - printf("[Kerberos] Packet found\n"); + printf("[Kerberos] [msg-type: 0x%02X/%u][koffset: %u]\n", + packet->payload[koffset], packet->payload[koffset], koffset); +#endif + + if(((packet->payload[koffset] == 0x0A) + || (packet->payload[koffset] == 0x0C) + || (packet->payload[koffset] == 0x0D) + || (packet->payload[koffset] == 0x0E))) { + u_int16_t koffsetp, body_offset, pad_len; + u_int8_t msg_type = packet->payload[koffset]; + +#ifdef KERBEROS_DEBUG + printf("[Kerberos] Packet found 0x%02X/%u\n", msg_type, msg_type); +#endif + if(msg_type != 0x0d) /* TGS-REP */ { + /* Process only on requests */ + if(packet->payload[koffset+1] == 0xA3) { + if(packet->payload[koffset+3] == 0x30) + pad_len = packet->payload[koffset+4]; + else { + /* Long pad */ + pad_len = packet->payload[koffset+2]; + for(i=3; i<10; i++) if(packet->payload[koffset+i] == pad_len) break; + + pad_len = (packet->payload[koffset+i+1] << 8) + packet->payload[koffset+i+2]; + koffset += i-2; + } + } else + pad_len = 0; + +#ifdef KERBEROS_DEBUG + printf("pad_len=0x%02X/%u\n", pad_len, pad_len); +#endif + + if(pad_len > 0) { + koffsetp = koffset + 2; + for(i=0; i<4; i++) if(packet->payload[koffsetp] != 0x30) koffsetp++; /* ASN.1 */ +#ifdef KERBEROS_DEBUG + printf("koffsetp=%u [%02X %02X] [byte 0 must be 0x30]\n", koffsetp, packet->payload[koffsetp], packet->payload[koffsetp+1]); +#endif + } else + koffsetp = koffset; + + body_offset = koffsetp + 1 + pad_len; + + for(i=0; i<10; i++) if(packet->payload[body_offset] != 0x05) body_offset++; /* ASN.1 */ +#ifdef KERBEROS_DEBUG + printf("body_offset=%u [%02X %02X] [byte 0 must be 0x05]\n", body_offset, packet->payload[body_offset], packet->payload[body_offset+1]); +#endif + } + + if(msg_type == 0x0A) /* AS-REQ */ { +#ifdef KERBEROS_DEBUG + printf("[Kerberos] Processing AS-REQ\n"); #endif - if(packet->payload[koffset] == 0x0a) /* AS-REQ */ { - u_int16_t koffsetp, pad_data_len, body_offset; - - koffsetp = koffset + 4; - pad_data_len = packet->payload[koffsetp]; - body_offset = pad_data_len + koffsetp; if(body_offset < packet->payload_packet_len) { - u_int name_offset = body_offset + 30; + u_int16_t name_offset; + + name_offset = body_offset + 13; + for(i=0; i<10; i++) if(packet->payload[name_offset] != 0x1b) name_offset++; /* ASN.1 */ + +#ifdef KERBEROS_DEBUG + printf("name_offset=%u [%02X %02X] [byte 0 must be 0x1b]\n", name_offset, packet->payload[name_offset], packet->payload[name_offset+1]); +#endif if(name_offset < packet->payload_packet_len) { - u_int cname_len = packet->payload[name_offset]; + u_int cname_len; + + name_offset += 1; + if(packet->payload[name_offset+1] < ' ') /* Isn't printable ? */ + name_offset++; + + if(packet->payload[name_offset+1] == 0x1b) + name_offset += 2; + + cname_len = packet->payload[name_offset]; if((cname_len+name_offset) < packet->payload_packet_len) { - u_int realm_len, realm_offset = cname_len + name_offset + 4, i; - char cname_str[24]; + u_int realm_len, realm_offset, i; + char cname_str[48]; + u_int8_t num_cname = 0; - if(cname_len > sizeof(cname_str)-1) - cname_len = sizeof(cname_str)-1; + while(++num_cname <= 2) { + if(cname_len > sizeof(cname_str)-1) + cname_len = sizeof(cname_str)-1; - strncpy(cname_str, (char*)&packet->payload[name_offset+1], cname_len); - cname_str[cname_len] = '\0'; - for(i=0; i<cname_len; i++) cname_str[i] = tolower(cname_str[i]); + strncpy(cname_str, (char*)&packet->payload[name_offset+1], cname_len); + cname_str[cname_len] = '\0'; + for(i=0; i<cname_len; i++) cname_str[i] = tolower(cname_str[i]); #ifdef KERBEROS_DEBUG - printf("[Kerberos Cname][len: %u][%s]\n", cname_len, cname_str); + printf("[AS-REQ][s/dport: %u/%u][Kerberos Cname][len: %u][%s]\n", + sport, dport, cname_len, cname_str); #endif + if(((strcmp(cname_str, "host") == 0) || (strcmp(cname_str, "ldap") == 0)) && (packet->payload[name_offset+1+cname_len] == 0x1b)) { + name_offset += cname_len + 2; + cname_len = packet->payload[name_offset]; + } else + break; + } + + realm_offset = cname_len + name_offset + 3; + /* if cname does not end with a $ then it's a username */ if(cname_len && cname_str[cname_len-1] == '$') { cname_str[cname_len-1] = '\0'; @@ -104,62 +242,97 @@ void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct, } else snprintf(flow->protos.kerberos.username, sizeof(flow->protos.kerberos.username), "%s", cname_str); + for(i=0; i<10; i++) if(packet->payload[realm_offset] != 0x1b) name_offset++; /* ASN.1 */ +#ifdef KERBEROS_DEBUG + printf("realm_offset=%u [%02X %02X] [byte 0 must be 0x1b]\n", realm_offset, packet->payload[realm_offset], packet->payload[realm_offset+1]); +#endif + realm_offset += 1; + //if(num_cname == 2) realm_offset++; realm_len = packet->payload[realm_offset]; if((realm_offset+realm_len) < packet->payload_packet_len) { - char realm_str[24]; + char realm_str[48]; if(realm_len > sizeof(realm_str)-1) realm_len = sizeof(realm_str); - strncpy(realm_str, (char*)&packet->payload[realm_offset+1], realm_len); + realm_offset += 1; + + strncpy(realm_str, (char*)&packet->payload[realm_offset], realm_len); realm_str[realm_len] = '\0'; for(i=0; i<realm_len; i++) realm_str[i] = tolower(realm_str[i]); #ifdef KERBEROS_DEBUG - printf("[Kerberos Realm][len: %u][%s]\n", realm_len, realm_str); + printf("[AS-REQ][Kerberos Realm][len: %u][%s]\n", realm_len, realm_str); #endif snprintf(flow->protos.kerberos.domain, sizeof(flow->protos.kerberos.domain), "%s", realm_str); } } } - } - } else if(packet->payload[koffset] == 0x0c) /* TGS-REQ */ { - u_int16_t koffsetp, pad_data_len, body_offset; - - koffsetp = koffset + 3; - pad_data_len = ntohs(*((u_int16_t*)&packet->payload[koffsetp])); - body_offset = pad_data_len + koffsetp + 4; + } + } else if(msg_type == 0x0c) /* TGS-REQ */ { +#ifdef KERBEROS_DEBUG + printf("[Kerberos] Processing TGS-REQ\n"); +#endif if(body_offset < packet->payload_packet_len) { - u_int name_offset = body_offset + 14; + u_int name_offset, padding_offset = body_offset + 4; + + name_offset = padding_offset; + for(i=0; i<10; i++) if(packet->payload[name_offset] != 0x1b) name_offset++; /* ASN.1 */ + +#ifdef KERBEROS_DEBUG + printf("name_offset=%u [%02X %02X] [byte 0 must be 0x1b]\n", name_offset, packet->payload[name_offset], packet->payload[name_offset+1]); +#endif if(name_offset < packet->payload_packet_len) { - u_int realm_len = packet->payload[name_offset]; + u_int realm_len; + + name_offset++; + realm_len = packet->payload[name_offset]; if((realm_len+name_offset) < packet->payload_packet_len) { u_int i; - char realm_str[24]; + char realm_str[48]; if(realm_len > sizeof(realm_str)-1) realm_len = sizeof(realm_str)-1; - strncpy(realm_str, (char*)&packet->payload[name_offset+1], realm_len); + name_offset += 1; + + strncpy(realm_str, (char*)&packet->payload[name_offset], realm_len); realm_str[realm_len] = '\0'; for(i=0; i<realm_len; i++) realm_str[i] = tolower(realm_str[i]); #ifdef KERBEROS_DEBUG - printf("[Kerberos Realm][len: %u][%s]\n", realm_len, realm_str); + printf("[TGS-REQ][s/dport: %u/%u][Kerberos Realm][len: %u][%s]\n", sport, dport, realm_len, realm_str); #endif snprintf(flow->protos.kerberos.domain, sizeof(flow->protos.kerberos.domain), "%s", realm_str); + + /* If necessary we can decode sname */ + + if(flow->kerberos_buf.pktbuf) ndpi_free(flow->kerberos_buf.pktbuf); + flow->kerberos_buf.pktbuf = NULL; } } } + if(packet->udp) + ndpi_int_kerberos_add_connection(ndpi_struct, flow); + /* We set the protocol in the response */ + if(flow->kerberos_buf.pktbuf != NULL) { + free(flow->kerberos_buf.pktbuf); + flow->kerberos_buf.pktbuf = NULL; + } + return; - } else if(packet->payload[koffset] == 0x0d) /* TGS-RES */ { + } else if(msg_type == 0x0d) /* TGS-REP */ { u_int16_t koffsetp, pad_data_len, cname_offset; + +#ifdef KERBEROS_DEBUG + printf("[Kerberos] Processing TGS-REP\n"); +#endif koffsetp = koffset + 4; pad_data_len = packet->payload[koffsetp]; @@ -170,20 +343,21 @@ void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct, u_int8_t cname_len = packet->payload[cname_offset]; if((cname_offset+cname_offset) < packet->payload_packet_len) { - char cname_str[24]; + char cname_str[48]; u_int i; - + if(cname_len > sizeof(cname_str)-1) cname_len = sizeof(cname_str)-1; - + strncpy(cname_str, (char*)&packet->payload[cname_offset+1], cname_len); cname_str[cname_len] = '\0'; for(i=0; i<cname_len; i++) cname_str[i] = tolower(cname_str[i]); - + #ifdef KERBEROS_DEBUG - printf("[Kerberos Cname][len: %u][%s]\n", cname_len, cname_str); + printf("[TGS-REP][s/dport: %u/%u][Kerberos Cname][len: %u][%s]\n", + sport, dport, cname_len, cname_str); #endif - + if(cname_len && cname_str[cname_len-1] == '$') { cname_str[cname_len-1] = '\0'; snprintf(flow->protos.kerberos.hostname, sizeof(flow->protos.kerberos.hostname), "%s", cname_str); @@ -194,7 +368,7 @@ void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct, } } } - + return; } @@ -208,6 +382,11 @@ void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct, } } } else { +#ifdef KERBEROS_DEBUG + printf("[Kerberos][s/dport: %u/%u] Skipping packet: too long [kerberos_len: %u]\n", + sport, dport, kerberos_len); +#endif + if(flow->protos.kerberos.domain[0] != '\0') return; } @@ -222,7 +401,7 @@ void init_kerberos_dissector(struct ndpi_detection_module_struct *ndpi_struct, ndpi_set_bitmask_protocol_detection("Kerberos", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_KERBEROS, ndpi_search_kerberos, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); diff --git a/src/lib/protocols/mail_smtp.c b/src/lib/protocols/mail_smtp.c index 2cd4657c9..86ff79486 100644 --- a/src/lib/protocols/mail_smtp.c +++ b/src/lib/protocols/mail_smtp.c @@ -70,9 +70,9 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG_DBG(ndpi_struct, "search mail_smtp\n"); if((packet->payload_packet_len > 2) - && (packet->parsed_lines < NDPI_MAX_PARSE_LINES_PER_PACKET) - && (ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a) - ) { + && (packet->parsed_lines < NDPI_MAX_PARSE_LINES_PER_PACKET) + && (ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a) + ) { u_int8_t a; u_int8_t bit_count = 0; @@ -97,33 +97,33 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct, // expected client requests if(packet->line[a].len >= 5) { if((((packet->line[a].ptr[0] == 'H' || packet->line[a].ptr[0] == 'h') - && (packet->line[a].ptr[1] == 'E' || packet->line[a].ptr[1] == 'e')) - || ((packet->line[a].ptr[0] == 'E' || packet->line[a].ptr[0] == 'e') - && (packet->line[a].ptr[1] == 'H' || packet->line[a].ptr[1] == 'h'))) - && (packet->line[a].ptr[2] == 'L' || packet->line[a].ptr[2] == 'l') - && (packet->line[a].ptr[3] == 'O' || packet->line[a].ptr[3] == 'o') - && packet->line[a].ptr[4] == ' ') { + && (packet->line[a].ptr[1] == 'E' || packet->line[a].ptr[1] == 'e')) + || ((packet->line[a].ptr[0] == 'E' || packet->line[a].ptr[0] == 'e') + && (packet->line[a].ptr[1] == 'H' || packet->line[a].ptr[1] == 'h'))) + && (packet->line[a].ptr[2] == 'L' || packet->line[a].ptr[2] == 'l') + && (packet->line[a].ptr[3] == 'O' || packet->line[a].ptr[3] == 'o') + && packet->line[a].ptr[4] == ' ') { flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_HELO_EHLO; flow->protos.ftp_imap_pop_smtp.auth_found = 0; } else if((packet->line[a].ptr[0] == 'M' || packet->line[a].ptr[0] == 'm') - && (packet->line[a].ptr[1] == 'A' || packet->line[a].ptr[1] == 'a') - && (packet->line[a].ptr[2] == 'I' || packet->line[a].ptr[2] == 'i') - && (packet->line[a].ptr[3] == 'L' || packet->line[a].ptr[3] == 'l') - && packet->line[a].ptr[4] == ' ') { + && (packet->line[a].ptr[1] == 'A' || packet->line[a].ptr[1] == 'a') + && (packet->line[a].ptr[2] == 'I' || packet->line[a].ptr[2] == 'i') + && (packet->line[a].ptr[3] == 'L' || packet->line[a].ptr[3] == 'l') + && packet->line[a].ptr[4] == ' ') { flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_MAIL; flow->protos.ftp_imap_pop_smtp.auth_found = 0; } else if((packet->line[a].ptr[0] == 'R' || packet->line[a].ptr[0] == 'r') - && (packet->line[a].ptr[1] == 'C' || packet->line[a].ptr[1] == 'c') - && (packet->line[a].ptr[2] == 'P' || packet->line[a].ptr[2] == 'p') - && (packet->line[a].ptr[3] == 'T' || packet->line[a].ptr[3] == 't') - && packet->line[a].ptr[4] == ' ') { + && (packet->line[a].ptr[1] == 'C' || packet->line[a].ptr[1] == 'c') + && (packet->line[a].ptr[2] == 'P' || packet->line[a].ptr[2] == 'p') + && (packet->line[a].ptr[3] == 'T' || packet->line[a].ptr[3] == 't') + && packet->line[a].ptr[4] == ' ') { flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_RCPT; flow->protos.ftp_imap_pop_smtp.auth_found = 0; } else if((packet->line[a].ptr[0] == 'A' || packet->line[a].ptr[0] == 'a') - && (packet->line[a].ptr[1] == 'U' || packet->line[a].ptr[1] == 'u') - && (packet->line[a].ptr[2] == 'T' || packet->line[a].ptr[2] == 't') - && (packet->line[a].ptr[3] == 'H' || packet->line[a].ptr[3] == 'h') - && packet->line[a].ptr[4] == ' ') { + && (packet->line[a].ptr[1] == 'U' || packet->line[a].ptr[1] == 'u') + && (packet->line[a].ptr[2] == 'T' || packet->line[a].ptr[2] == 't') + && (packet->line[a].ptr[3] == 'H' || packet->line[a].ptr[3] == 'h') + && packet->line[a].ptr[4] == ' ') { #ifdef SMTP_DEBUG printf("%s() AUTH [%s]\n", __FUNCTION__, packet->line[a].ptr); #endif @@ -143,7 +143,7 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct, u_char *out; size_t out_len; - ndpi_user_pwd_payload_copy(buf, sizeof(buf), 0, + ndpi_user_pwd_payload_copy(buf, sizeof(buf)-1, 0, packet->line[a].ptr, packet->line[a].len); #ifdef SMTP_DEBUG @@ -191,32 +191,32 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct, if(packet->line[a].len >= 8) { if((packet->line[a].ptr[0] == 'S' || packet->line[a].ptr[0] == 's') - && (packet->line[a].ptr[1] == 'T' || packet->line[a].ptr[1] == 't') - && (packet->line[a].ptr[2] == 'A' || packet->line[a].ptr[2] == 'a') - && (packet->line[a].ptr[3] == 'R' || packet->line[a].ptr[3] == 'r') - && (packet->line[a].ptr[4] == 'T' || packet->line[a].ptr[4] == 't') - && (packet->line[a].ptr[5] == 'T' || packet->line[a].ptr[5] == 't') - && (packet->line[a].ptr[6] == 'L' || packet->line[a].ptr[6] == 'l') - && (packet->line[a].ptr[7] == 'S' || packet->line[a].ptr[7] == 's')) { + && (packet->line[a].ptr[1] == 'T' || packet->line[a].ptr[1] == 't') + && (packet->line[a].ptr[2] == 'A' || packet->line[a].ptr[2] == 'a') + && (packet->line[a].ptr[3] == 'R' || packet->line[a].ptr[3] == 'r') + && (packet->line[a].ptr[4] == 'T' || packet->line[a].ptr[4] == 't') + && (packet->line[a].ptr[5] == 'T' || packet->line[a].ptr[5] == 't') + && (packet->line[a].ptr[6] == 'L' || packet->line[a].ptr[6] == 'l') + && (packet->line[a].ptr[7] == 'S' || packet->line[a].ptr[7] == 's')) { flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_STARTTLS; } } if(packet->line[a].len >= 4) { if((packet->line[a].ptr[0] == 'D' || packet->line[a].ptr[0] == 'd') - && (packet->line[a].ptr[1] == 'A' || packet->line[a].ptr[1] == 'a') - && (packet->line[a].ptr[2] == 'T' || packet->line[a].ptr[2] == 't') - && (packet->line[a].ptr[3] == 'A' || packet->line[a].ptr[3] == 'a')) { + && (packet->line[a].ptr[1] == 'A' || packet->line[a].ptr[1] == 'a') + && (packet->line[a].ptr[2] == 'T' || packet->line[a].ptr[2] == 't') + && (packet->line[a].ptr[3] == 'A' || packet->line[a].ptr[3] == 'a')) { flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_DATA; } else if((packet->line[a].ptr[0] == 'N' || packet->line[a].ptr[0] == 'n') - && (packet->line[a].ptr[1] == 'O' || packet->line[a].ptr[1] == 'o') - && (packet->line[a].ptr[2] == 'O' || packet->line[a].ptr[2] == 'o') - && (packet->line[a].ptr[3] == 'P' || packet->line[a].ptr[3] == 'p')) { + && (packet->line[a].ptr[1] == 'O' || packet->line[a].ptr[1] == 'o') + && (packet->line[a].ptr[2] == 'O' || packet->line[a].ptr[2] == 'o') + && (packet->line[a].ptr[3] == 'P' || packet->line[a].ptr[3] == 'p')) { flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_NOOP; } else if((packet->line[a].ptr[0] == 'R' || packet->line[a].ptr[0] == 'r') - && (packet->line[a].ptr[1] == 'S' || packet->line[a].ptr[1] == 's') - && (packet->line[a].ptr[2] == 'E' || packet->line[a].ptr[2] == 'e') - && (packet->line[a].ptr[3] == 'T' || packet->line[a].ptr[3] == 't')) { + && (packet->line[a].ptr[1] == 'S' || packet->line[a].ptr[1] == 's') + && (packet->line[a].ptr[2] == 'E' || packet->line[a].ptr[2] == 'e') + && (packet->line[a].ptr[3] == 'T' || packet->line[a].ptr[3] == 't')) { flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_RSET; } } @@ -229,7 +229,7 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct, } } NDPI_LOG_DBG2(ndpi_struct, "seen smtp commands and responses: %u\n", - bit_count); + bit_count); if(bit_count >= 3) { NDPI_LOG_INFO(ndpi_struct, "mail smtp identified\n"); @@ -251,9 +251,9 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct, /* when the first or second packets are split into two packets, those packets are ignored. */ if(flow->packet_counter <= 4 && - packet->payload_packet_len >= 4 && - (ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a - || memcmp(packet->payload, "220", 3) == 0 || memcmp(packet->payload, "EHLO", 4) == 0)) { + packet->payload_packet_len >= 4 && + (ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a + || memcmp(packet->payload, "220", 3) == 0 || memcmp(packet->payload, "EHLO", 4) == 0)) { NDPI_LOG_DBG2(ndpi_struct, "maybe SMTP, need next packet\n"); return; } diff --git a/src/lib/protocols/ntp.c b/src/lib/protocols/ntp.c index a03ed3b43..126dadc4c 100644 --- a/src/lib/protocols/ntp.c +++ b/src/lib/protocols/ntp.c @@ -58,8 +58,8 @@ void ndpi_search_ntp_udp(struct ndpi_detection_module_struct *ndpi_struct, struc return; } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + NDPI_EXCLUDE_PROTO(ndpi_struct, flow); } diff --git a/src/lib/protocols/smpp.c b/src/lib/protocols/smpp.c index c188bd91f..e0521ae12 100644 --- a/src/lib/protocols/smpp.c +++ b/src/lib/protocols/smpp.c @@ -68,7 +68,7 @@ void ndpi_search_smpp_tcp(struct ndpi_detection_module_struct* ndpi_struct, u_int32_t tmp_pdu_l = 0; u_int16_t pdu_c = 1; // loop PDUs (check if lengths are valid) - while(total_pdu_l < packet->payload_packet_len) { + while(total_pdu_l < (packet->payload_packet_len-4)) { // get next PDU length tmp_pdu_l = ntohl(get_u_int32_t(packet->payload, total_pdu_l)); // if zero or overflowing , return, will try the next TCP segment diff --git a/src/lib/protocols/ssh.c b/src/lib/protocols/ssh.c index 5bdf78959..068d2c345 100644 --- a/src/lib/protocols/ssh.c +++ b/src/lib/protocols/ssh.c @@ -296,7 +296,7 @@ static void ndpi_search_ssh_tcp(struct ndpi_detection_module_struct *ndpi_struct flow->l4.tcp.ssh_stage = 3; return; } - } else { + } else if(packet->payload_packet_len > 5) { u_int8_t msgcode = *(packet->payload + 5); ndpi_MD5_CTX ctx; diff --git a/src/lib/protocols/telnet.c b/src/lib/protocols/telnet.c index 0fd00e6d4..35693bf62 100644 --- a/src/lib/protocols/telnet.c +++ b/src/lib/protocols/telnet.c @@ -1,8 +1,8 @@ /* * telnet.c * - * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-19 - ntop.org + * Copyright (C) 2009-2011 by ipoque GmbH * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH @@ -47,6 +47,34 @@ static int search_telnet_again(struct ndpi_detection_module_struct *ndpi_struct, if(packet->payload_packet_len > 0) { int i; + if(flow->protos.telnet.username_detected) { + if((!flow->protos.telnet.password_found) + && (packet->payload_packet_len > 6)) { + + if(strncasecmp((char*)packet->payload, "password:", 9) == 0) { + flow->protos.telnet.password_found = 1; + } + + return(1); + } + + if(packet->payload[0] == '\r') { + if(!flow->protos.telnet.password_found) + return(1); + + flow->protos.telnet.password_detected = 1; + flow->protos.telnet.password[flow->protos.telnet.character_id] = '\0'; + return(0); + } + + for(i=0; i<packet->payload_packet_len; i++) { + if(flow->protos.telnet.character_id < (sizeof(flow->protos.telnet.password)-1)) + flow->protos.telnet.password[flow->protos.telnet.character_id++] = packet->payload[i]; + } + + return(1); + } + if((!flow->protos.telnet.username_found) && (packet->payload_packet_len > 6)) { @@ -60,7 +88,8 @@ static int search_telnet_again(struct ndpi_detection_module_struct *ndpi_struct, if(packet->payload[0] == '\r') { flow->protos.telnet.username_detected = 1; flow->protos.telnet.username[flow->protos.telnet.character_id] = '\0'; - return(0); + flow->protos.telnet.character_id = 0; + return(1); } for(i=0; i<packet->payload_packet_len; i++) { diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c index 9d22a66db..ed92814d9 100644 --- a/src/lib/protocols/tls.c +++ b/src/lib/protocols/tls.c @@ -308,7 +308,11 @@ int getTLScertificate(struct ndpi_detection_module_struct *ndpi_struct, #endif offset += 2 + 1; - extension_len = ntohs(*((u_int16_t*)&packet->payload[offset])); + + if((offset + 1) < packet->payload_packet_len) /* +1 because we are goint to read 2 bytes */ + extension_len = ntohs(*((u_int16_t*)&packet->payload[offset])); + else + extension_len = 0; #ifdef DEBUG_TLS printf("TLS [server][extension_len: %u]\n", extension_len); @@ -870,7 +874,7 @@ int getSSCertificateFingerprint(struct ndpi_detection_module_struct *ndpi_struct return(0); /* That's all */ } else if(flow->l4.tcp.tls_seen_certificate) return(0); /* That's all */ - else if(packet->payload_packet_len > flow->l4.tcp.tls_record_offset+7) { + else if(packet->payload_packet_len > flow->l4.tcp.tls_record_offset+7+1/* +1 because we are going to read 2 bytes */) { /* This is a handshake but not a certificate record */ u_int16_t len = ntohs(*(u_int16_t*)&packet->payload[flow->l4.tcp.tls_record_offset+7]); @@ -1400,19 +1404,16 @@ void ndpi_search_tls_tcp_udp(struct ndpi_detection_module_struct *ndpi_struct, u_int8_t ret, skip_cert_processing = 0; #ifdef DEBUG_TLS - printf("%s()\n", __FUNCTION__); + printf("==>> %u [len: %u][version: %u]\n", + flow->guessed_host_protocol_id, + packet->payload_packet_len, + flow->protos.stun_ssl.ssl.ssl_version); #endif if(packet->udp != NULL) { /* DTLS dissector */ int rc = sslTryAndRetrieveServerCertificate(ndpi_struct, flow); - -#ifdef DEBUG_TLS - printf("==>> %u [rc: %d][len: %u][%s][version: %u]\n", - flow->guessed_host_protocol_id, rc, packet->payload_packet_len, flow->protos.stun_ssl.ssl.ja3_server, - flow->protos.stun_ssl.ssl.ssl_version); -#endif - + if((rc == 0) && (flow->protos.stun_ssl.ssl.ssl_version != 0)) { flow->guessed_protocol_id = NDPI_PROTOCOL_TLS; |