diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/ndpi_typedefs.h | 2 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 131 |
2 files changed, 98 insertions, 35 deletions
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index b3c4486be..8ce77bf54 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -1316,7 +1316,7 @@ struct ndpi_flow_struct { u_int16_t guessed_header_category; u_int8_t l4_proto, protocol_id_already_guessed:1, fail_with_unknown:1, init_finished:1, client_packet_direction:1, packet_direction:1, is_ipv6:1, first_pkt_fully_encrypted:1, skip_entropy_check: 1; - u_int8_t monitoring:1, _pad:7; + u_int8_t monitoring:1, already_gaveup:1, _pad:6; u_int16_t num_dissector_calls; ndpi_confidence_t confidence; /* ndpi_confidence_t */ diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 8b3f1a3f9..0aa7d5646 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -239,6 +239,10 @@ static void ndpi_enabled_callbacks_init(struct ndpi_detection_module_struct *ndp static void set_default_config(struct ndpi_detection_module_config_struct *cfg); +static void internal_giveup(struct ndpi_detection_module_struct *ndpi_str, + struct ndpi_flow_struct *flow, + ndpi_protocol *ret); + /* ****************************************** */ ndpi_custom_dga_predict_fctn ndpi_dga_function = NULL; @@ -7125,21 +7129,21 @@ static int ndpi_init_packet(struct ndpi_detection_module_struct *ndpi_str, /* ************************************************ */ -static u_int8_t ndpi_is_multi_or_broadcast(struct ndpi_packet_struct *packet) { +static u_int8_t ndpi_is_multi_or_broadcast(struct ndpi_flow_struct *flow) { - if(packet->iph) { + if(!flow->is_ipv6) { /* IPv4 */ - u_int32_t daddr = ntohl(packet->iph->daddr); + u_int32_t daddr = ntohl(flow->s_address.v4); if(((daddr & 0xF0000000) == 0xE0000000 /* multicast 224.0.0.0/4 */) || ((daddr & 0x000000FF) == 0x000000FF /* last byte is 0xFF, not super correct, but a good approximation */) || ((daddr & 0x000000FF) == 0x00000000 /* last byte is 0x00, not super correct, but a good approximation */) || (daddr == 0xFFFFFFFF)) return(1); - } else if(packet->iphv6) { + } else { /* IPv6 */ - if((ntohl(packet->iphv6->ip6_dst.u6_addr.u6_addr32[0]) & 0xFF000000) == 0xFF000000) + if((ntohl((*(u_int32_t *)&flow->s_address.v6)) & 0xFF000000) == 0xFF000000) return(1); } @@ -7464,18 +7468,6 @@ static void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_s flow->packet_direction_complete_counter[packet->packet_direction]++; } - if(!ndpi_is_multi_or_broadcast(packet)) { - /* ! (multicast or broadcast) */ - - if(flow->packet_direction_complete_counter[flow->client_packet_direction] == 0) - ndpi_set_risk(ndpi_str, flow, NDPI_UNIDIRECTIONAL_TRAFFIC, "No client to server traffic"); /* Should never happen */ - else if(flow->packet_direction_complete_counter[!flow->client_packet_direction] == 0) - ndpi_set_risk(ndpi_str, flow, NDPI_UNIDIRECTIONAL_TRAFFIC, "No server to client traffic"); - else { - ndpi_unset_risk(ndpi_str, flow, NDPI_UNIDIRECTIONAL_TRAFFIC); /* Clear bit */ - } - } - if(ndpi_str->input_info && ndpi_str->input_info->in_pkt_dir == NDPI_IN_PKT_DIR_UNKNOWN) { if(current_pkt_from_client_to_server(ndpi_str, flow)) @@ -7816,21 +7808,6 @@ static void ndpi_reconcile_protocols(struct ndpi_detection_module_struct *ndpi_s ndpi_reconcile_msteams_udp(ndpi_str, flow, NDPI_PROTOCOL_STUN); break; - case NDPI_PROTOCOL_NETFLOW: - case NDPI_PROTOCOL_SFLOW: - case NDPI_PROTOCOL_COLLECTD: - /* Remove NDPI_UNIDIRECTIONAL_TRAFFIC from unidirectional protocols */ - ndpi_unset_risk(ndpi_str, flow, NDPI_UNIDIRECTIONAL_TRAFFIC); - break; - - case NDPI_PROTOCOL_SYSLOG: - case NDPI_PROTOCOL_MDNS: - case NDPI_PROTOCOL_SONOS: - case NDPI_PROTOCOL_RTP: - if(flow->l4_proto == IPPROTO_UDP) - ndpi_unset_risk(ndpi_str, flow, NDPI_UNIDIRECTIONAL_TRAFFIC); - break; - case NDPI_PROTOCOL_TLS: /* When Teams is unable to communicate via UDP @@ -8052,6 +8029,66 @@ static void ndpi_check_probing_attempt(struct ndpi_detection_module_struct *ndpi /* ********************************************************************************* */ +static int is_unidir_traffic_exception(struct ndpi_flow_struct *flow) { + + switch(flow->detected_protocol_stack[0]) { + case NDPI_PROTOCOL_NETFLOW: + case NDPI_PROTOCOL_SFLOW: + case NDPI_PROTOCOL_COLLECTD: + return 1; + + case NDPI_PROTOCOL_SYSLOG: + case NDPI_PROTOCOL_MDNS: + case NDPI_PROTOCOL_SONOS: + case NDPI_PROTOCOL_RTP: + if(flow->l4_proto == IPPROTO_UDP) + return 1; + } + return 0; +} + +/* ********************************************************************************* */ + +static void internal_giveup(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + ndpi_protocol *ret) { + + if(flow->already_gaveup) { + NDPI_LOG_INFO(ndpi_struct, "Already called!\n"); /* We shoudn't be here ...*/ + return; + } + flow->already_gaveup = 1; + + NDPI_LOG_DBG2(ndpi_struct, ""); + + /* This (internal) function is expected to be called for **every** flows, + exactly once, as **last** code processing the flow itself */ + + /* TODO: this function is similar to ndpi_detection_giveup(). We should try to unify them + or to have two more distinct logics... + The/A critical point is that ndpi_detection_giveup() is public and it is always used by + any programs linking to libnDPI: we must be sure to not change the external behavior + */ + + /* *** + * *** We can't access ndpi_str->packet from this function!! + * ***/ + + if(!ndpi_is_multi_or_broadcast(flow) && + !is_unidir_traffic_exception(flow)) { + + if(flow->packet_direction_complete_counter[flow->client_packet_direction] == 0) + ndpi_set_risk(ndpi_struct, flow, NDPI_UNIDIRECTIONAL_TRAFFIC, "No client to server traffic"); + else if(flow->packet_direction_complete_counter[!flow->client_packet_direction] == 0) + ndpi_set_risk(ndpi_struct, flow, NDPI_UNIDIRECTIONAL_TRAFFIC, "No server to client traffic"); + } + + /* TODO */ + (void)ret; +} + +/* ********************************************************************************* */ + ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow, u_int8_t *protocol_was_guessed) { ndpi_protocol ret = NDPI_PROTOCOL_NULL; @@ -8076,8 +8113,11 @@ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_st ret.category = flow->category; /* Ensure that we don't change our mind if detection is already complete */ - if(ret.proto.app_protocol != NDPI_PROTOCOL_UNKNOWN) + if(ret.proto.app_protocol != NDPI_PROTOCOL_UNKNOWN) { + /* Reason: public "ndpi_detection_giveup", already classified */ + internal_giveup(ndpi_str, flow, &ret); return(ret); + } /* Partial classification */ if(flow->fast_callback_protocol_id != NDPI_PROTOCOL_UNKNOWN) { @@ -8155,6 +8195,9 @@ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_st ndpi_fill_protocol_category(ndpi_str, flow, &ret); } + /* Reason: public "ndpi_detection_giveup" */ + internal_giveup(ndpi_str, flow, &ret); + return(ret); } @@ -8813,6 +8856,10 @@ static ndpi_protocol ndpi_internal_detection_process_packet(struct ndpi_detectio * It is quite uncommon, so we are not going to spend a lot of resources here... */ if(ndpi_init_packet(ndpi_str, flow, current_time_ms, packet_data, packetlen, input_info) == 0) ndpi_connection_tracking(ndpi_str, flow); + + /* Reason: too many packets */ + internal_giveup(ndpi_str, flow, &ret); + return(ret); /* Avoid spending too much time with this flow */ } @@ -8827,6 +8874,11 @@ static ndpi_protocol ndpi_internal_detection_process_packet(struct ndpi_detectio ret.proto.app_protocol = flow->detected_protocol_stack[0], ret.category = flow->category; + if(flow->extra_packets_func == NULL) { + /* Reason: extra dissection ended */ + internal_giveup(ndpi_str, flow, &ret); + } + return(ret); } else if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) { if(ndpi_init_packet(ndpi_str, flow, current_time_ms, packet_data, packetlen, input_info) != 0) @@ -8909,8 +8961,13 @@ static ndpi_protocol ndpi_internal_detection_process_packet(struct ndpi_detectio if(!flow->protocol_id_already_guessed) { flow->protocol_id_already_guessed = 1; - if(ndpi_do_guess(ndpi_str, flow, &ret) == -1) + if(ndpi_do_guess(ndpi_str, flow, &ret) == -1) { + + /* Reason: custom rules */ + internal_giveup(ndpi_str, flow, &ret); + return(ret); + } } num_calls = ndpi_check_flow_func(ndpi_str, flow, &ndpi_selection_packet); @@ -9108,6 +9165,12 @@ static ndpi_protocol ndpi_internal_detection_process_packet(struct ndpi_detectio if(flow->all_packets_counter == 1) fpc_check_eval(ndpi_str, flow); + if(ret.proto.app_protocol != NDPI_PROTOCOL_UNKNOWN && + flow->extra_packets_func == NULL) { + /* Reason: "normal" classification, without extra dissection */ + internal_giveup(ndpi_str, flow, &ret); + } + return(ret); } |