diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/ndpi_main.c | 89 | ||||
-rw-r--r-- | src/lib/protocols/dns.c | 157 | ||||
-rw-r--r-- | src/lib/protocols/steam.c | 76 |
3 files changed, 171 insertions, 151 deletions
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 79ca7b064..48404fcfd 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -4050,8 +4050,14 @@ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_st if(flow == NULL) return(ret); - else - ret.category = flow->category; + + /* Init defaults */ + ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0]; + ret.category = flow->category; + + /* Ensure that we don't change our mind if detection is already complete */ + if((ret.master_protocol != NDPI_PROTOCOL_UNKNOWN) && (ret.app_protocol != NDPI_PROTOCOL_UNKNOWN)) + return(ret); /* TODO: add the remaining stage_XXXX protocols */ if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) { @@ -4466,6 +4472,44 @@ void ndpi_fill_protocol_category(struct ndpi_detection_module_struct *ndpi_struc /* ********************************************************************************* */ +static void ndpi_reset_packet_line_info(struct ndpi_packet_struct *packet) { + packet->parsed_lines = 0, + packet->empty_line_position_set = 0, + packet->host_line.ptr = NULL, + packet->host_line.len = 0, + packet->referer_line.ptr = NULL, + packet->referer_line.len = 0, + packet->content_line.ptr = NULL, + packet->content_line.len = 0, + packet->accept_line.ptr = NULL, + packet->accept_line.len = 0, + packet->user_agent_line.ptr = NULL, + packet->user_agent_line.len = 0, + packet->http_url_name.ptr = NULL, + packet->http_url_name.len = 0, + packet->http_encoding.ptr = NULL, + packet->http_encoding.len = 0, + packet->http_transfer_encoding.ptr = NULL, + packet->http_transfer_encoding.len = 0, + packet->http_contentlen.ptr = NULL, + packet->http_contentlen.len = 0, + packet->http_cookie.ptr = NULL, + packet->http_cookie.len = 0, + packet->http_origin.len = 0, + packet->http_origin.ptr = NULL, + packet->http_x_session_type.ptr = NULL, + packet->http_x_session_type.len = 0, + packet->server_line.ptr = NULL, + packet->server_line.len = 0, + packet->http_method.ptr = NULL, + packet->http_method.len = 0, + packet->http_response.ptr = NULL, + packet->http_response.len = 0, + packet->http_num_headers = 0; +} + +/* ********************************************************************************* */ + ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, const unsigned char *packet, @@ -4707,8 +4751,9 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct Invalidate packet memory to avoid accessing the pointers below when the packet is no longer accessible */ - flow->packet.iph = NULL, flow->packet.tcp = NULL, flow->packet.udp = NULL; - + flow->packet.iph = NULL, flow->packet.tcp = NULL, flow->packet.udp = NULL, flow->packet.payload = NULL; + ndpi_reset_packet_line_info(&flow->packet); + return(ret); } @@ -4870,40 +4915,8 @@ void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_struc return; packet->packet_lines_parsed_complete = 1; - packet->parsed_lines = 0; - packet->empty_line_position_set = 0; - packet->host_line.ptr = NULL; - packet->host_line.len = 0; - packet->referer_line.ptr = NULL; - packet->referer_line.len = 0; - packet->content_line.ptr = NULL; - packet->content_line.len = 0; - packet->accept_line.ptr = NULL; - packet->accept_line.len = 0; - packet->user_agent_line.ptr = NULL; - packet->user_agent_line.len = 0; - packet->http_url_name.ptr = NULL; - packet->http_url_name.len = 0; - packet->http_encoding.ptr = NULL; - packet->http_encoding.len = 0; - packet->http_transfer_encoding.ptr = NULL; - packet->http_transfer_encoding.len = 0; - packet->http_contentlen.ptr = NULL; - packet->http_contentlen.len = 0; - packet->http_cookie.ptr = NULL; - packet->http_cookie.len = 0; - packet->http_origin.len = 0; - packet->http_origin.ptr = NULL; - packet->http_x_session_type.ptr = NULL; - packet->http_x_session_type.len = 0; - packet->server_line.ptr = NULL; - packet->server_line.len = 0; - packet->http_method.ptr = NULL; - packet->http_method.len = 0; - packet->http_response.ptr = NULL; - packet->http_response.len = 0; - packet->http_num_headers=0; - + ndpi_reset_packet_line_info(packet); + if((packet->payload_packet_len < 3) || (packet->payload == NULL)) return; diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c index b9cd1a9cb..4e3ffb5ed 100644 --- a/src/lib/protocols/dns.c +++ b/src/lib/protocols/dns.c @@ -72,84 +72,57 @@ static u_int getNameLength(u_int i, const u_int8_t *payload, u_int payloadLen) { static uint32_t dns_validchar[8] = { 0x00000000,0x03ff2000,0x87fffffe,0x07fffffe,0,0,0,0 }; -/* *********************************************** */ - -void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { - int x, payload_offset; - u_int8_t is_query; - 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); - payload_offset = 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); - payload_offset = 2; - } else { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - return; - } - - x = payload_offset; - - if((s_port == 53 || d_port == 53 || d_port == 5355) - && (flow->packet.payload_packet_len > sizeof(struct ndpi_dns_packet_header)+x)) { - struct ndpi_dns_packet_header dns_header; - int invalid = 0; - - memcpy(&dns_header, (struct ndpi_dns_packet_header*) &flow->packet.payload[x], sizeof(struct ndpi_dns_packet_header)); - 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); - x += sizeof(struct ndpi_dns_packet_header); - - /* 0x0000 QUERY */ - if((dns_header.flags & FLAGS_MASK) == 0x0000) - is_query = 1; - /* 0x8000 RESPONSE */ - else if((dns_header.flags & FLAGS_MASK) == 0x8000) - is_query = 0; - else - invalid = 1; +/* *********************************************** */ - if(!invalid) { - int j = 0, max_len, off; - if(is_query) { - /* DNS Request */ - if((dns_header.num_queries > 0) && (dns_header.num_queries <= NDPI_MAX_DNS_REQUESTS) - && (((dns_header.flags & 0x2800) == 0x2800 /* Dynamic DNS Update */) - || ((dns_header.num_answers == 0) && (dns_header.authority_rrs == 0)))) { - /* This is a good query */ - - while(x < flow->packet.payload_packet_len) { - if(flow->packet.payload[x] == '\0') { - x++; - flow->protos.dns.query_type = get16(&x, flow->packet.payload); +static int search_valid_dns(struct ndpi_flow_struct *flow, struct ndpi_dns_packet_header *dns_header, int payload_offset, u_int8_t*is_query) { + int x = payload_offset; + + memcpy(dns_header, (struct ndpi_dns_packet_header*) &flow->packet.payload[x], sizeof(struct ndpi_dns_packet_header)); + 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); + x += sizeof(struct ndpi_dns_packet_header); + + /* 0x0000 QUERY */ + if((dns_header->flags & FLAGS_MASK) == 0x0000) + *is_query = 1; + /* 0x8000 RESPONSE */ + else if((dns_header->flags & FLAGS_MASK) == 0x8000) + *is_query = 0; + else + return(1 /* invalid */); + + if(*is_query) { + /* DNS Request */ + if((dns_header->num_queries > 0) && (dns_header->num_queries <= NDPI_MAX_DNS_REQUESTS) + && (((dns_header->flags & 0x2800) == 0x2800 /* Dynamic DNS Update */) + || ((dns_header->num_answers == 0) && (dns_header->authority_rrs == 0)))) { + /* This is a good query */ + while(x < flow->packet.payload_packet_len) { + if(flow->packet.payload[x] == '\0') { + x++; + flow->protos.dns.query_type = get16(&x, flow->packet.payload); #ifdef DNS_DEBUG - NDPI_LOG_DBG2(ndpi_struct, "query_type=%2d\n", flow->protos.dns.query_type); + NDPI_LOG_DBG2(ndpi_struct, "query_type=%2d\n", flow->protos.dns.query_type); #endif - break; - } else - x++; - } - } else - invalid = 1; - } else { + break; + } else + x++; + } + } else + return(1 /* invalid */); + } else { /* DNS Reply */ + flow->protos.dns.reply_code = dns_header->flags & 0x0F; - flow->protos.dns.reply_code = dns_header.flags & 0x0F; - - if((dns_header.num_queries > 0) && (dns_header.num_queries <= NDPI_MAX_DNS_REQUESTS) /* Don't assume that num_queries must be zero */ - && (((dns_header.num_answers > 0) && (dns_header.num_answers <= NDPI_MAX_DNS_REQUESTS)) - || ((dns_header.authority_rrs > 0) && (dns_header.authority_rrs <= NDPI_MAX_DNS_REQUESTS)) - || ((dns_header.additional_rrs > 0) && (dns_header.additional_rrs <= NDPI_MAX_DNS_REQUESTS))) + if((dns_header->num_queries > 0) && (dns_header->num_queries <= NDPI_MAX_DNS_REQUESTS) /* Don't assume that num_queries must be zero */ + && (((dns_header->num_answers > 0) && (dns_header->num_answers <= NDPI_MAX_DNS_REQUESTS)) + || ((dns_header->authority_rrs > 0) && (dns_header->authority_rrs <= NDPI_MAX_DNS_REQUESTS)) + || ((dns_header->additional_rrs > 0) && (dns_header->additional_rrs <= NDPI_MAX_DNS_REQUESTS))) ) { /* This is a good reply: we dissect it both for request and response */ @@ -168,11 +141,11 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd x += 4; - if(dns_header.num_answers > 0) { + if(dns_header->num_answers > 0) { u_int16_t rsp_type; u_int16_t num; - for(num = 0; num < dns_header.num_answers; num++) { + for(num = 0; num < dns_header->num_answers; num++) { u_int16_t data_len; if((x+6) >= flow->packet.payload_packet_len) { @@ -207,8 +180,39 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd } } } else - invalid = 1; - } + return(1 /* invalid */); + } + + /* Valid */ + return(0); +} + +/* *********************************************** */ + +void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { + int payload_offset; + u_int8_t is_query; + 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); + payload_offset = 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); + payload_offset = 2; + } else { + NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + return; + } + + if((s_port == 53 || d_port == 53 || d_port == 5355) + && (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(flow, &dns_header, payload_offset, &is_query); if(invalid) { NDPI_EXCLUDE_PROTO(ndpi_struct, flow); @@ -273,7 +277,6 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd } else { NDPI_EXCLUDE_PROTO(ndpi_struct, flow); } - } } } diff --git a/src/lib/protocols/steam.c b/src/lib/protocols/steam.c index 0a737baf9..6e1034aee 100644 --- a/src/lib/protocols/steam.c +++ b/src/lib/protocols/steam.c @@ -1,6 +1,7 @@ /* * steam.c * + * Copyright (C) 2011-19 - ntop.org * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk> * * The signature is mostly based on the Libprotoident library @@ -242,52 +243,55 @@ static void ndpi_check_steam_udp3(struct ndpi_detection_module_struct *ndpi_stru void ndpi_search_steam(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; - /* Break after 20 packets. */ - if (flow->packet_counter > 20) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - return; - } - - /* skip marked or retransmitted packets */ - if (packet->tcp_retransmission != 0) { - return; - } - - if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM) { - return; - } - - NDPI_LOG_DBG(ndpi_struct, "search STEAM\n"); - ndpi_check_steam_http(ndpi_struct, flow); + if(flow->packet.udp != NULL) { + if(flow->packet_counter > 5) { + NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + return; + } + + ndpi_check_steam_udp1(ndpi_struct, flow); - if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM) { - return; - } - - ndpi_check_steam_tcp(ndpi_struct, flow); + if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM) + return; - if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM) { - return; - } + ndpi_check_steam_udp2(ndpi_struct, flow); - ndpi_check_steam_udp1(ndpi_struct, flow); + if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM) + return; - if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM) { - return; - } + ndpi_check_steam_udp3(ndpi_struct, flow); + } else { + /* Break after 10 packets. */ + if(flow->packet_counter > 10) { + NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + return; + } + + + /* skip marked or retransmitted packets */ + if(packet->tcp_retransmission != 0) { + return; + } + + if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM) + return; + + NDPI_LOG_DBG(ndpi_struct, "search STEAM\n"); + ndpi_check_steam_http(ndpi_struct, flow); - ndpi_check_steam_udp2(ndpi_struct, flow); + if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM) + return; + + ndpi_check_steam_tcp(ndpi_struct, flow); - if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM) { - return; + if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM) + return; } - - ndpi_check_steam_udp3(ndpi_struct, flow); } -void init_steam_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) -{ +void init_steam_dissector(struct ndpi_detection_module_struct *ndpi_struct, + u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Steam", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_STEAM, ndpi_search_steam, |