aboutsummaryrefslogtreecommitdiff
path: root/src/lib/ndpi_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/ndpi_main.c')
-rw-r--r--src/lib/ndpi_main.c131
1 files changed, 97 insertions, 34 deletions
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);
}