aboutsummaryrefslogtreecommitdiff
path: root/src/lib/ndpi_main.c
diff options
context:
space:
mode:
authorLuca Deri <deri@ntop.org>2018-11-21 00:32:32 +0100
committerLuca Deri <deri@ntop.org>2018-11-21 00:32:32 +0100
commit669fdf6b5f3657c638ffa8df6ff1baebf5b311b1 (patch)
treeaf6540946a53550ea3d198c7e232ea5ac8ae072e /src/lib/ndpi_main.c
parent21504c849233d69b896fdff364b3933e8ec997d3 (diff)
Improved skype, teredo, netbios heuristics
Changed ndpi_detection_giveup() API: guess is now part of the call
Diffstat (limited to 'src/lib/ndpi_main.c')
-rw-r--r--src/lib/ndpi_main.c77
1 files changed, 62 insertions, 15 deletions
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index fcfaec713..c7d9e237e 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -2526,6 +2526,25 @@ static ndpi_default_ports_tree_node_t* ndpi_get_guessed_protocol_id(struct ndpi_
/* ****************************************************** */
+/*
+ These are UDP protocols that must fit a single packet
+ and thus that if have NOT been detected they cannot be guessed
+ as they have been excluded
+ */
+u_int8_t is_udp_guessable_protocol(u_int16_t l7_guessed_proto) {
+ switch(l7_guessed_proto) {
+ case NDPI_PROTOCOL_QUIC:
+ case NDPI_PROTOCOL_SNMP:
+ case NDPI_PROTOCOL_NETFLOW:
+ /* TODO: add more protocols (if any missing) */
+ return(1);
+ }
+
+ return(0);
+}
+
+/* ****************************************************** */
+
u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
u_int8_t proto, u_int16_t sport, u_int16_t dport,
@@ -2541,7 +2560,9 @@ u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_struc
/* We need to check if the guessed protocol isn't excluded by nDPI */
if(flow
&& (proto == IPPROTO_UDP)
- && (NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, guessed_proto)))
+ && NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, guessed_proto)
+ && is_udp_guessable_protocol(guessed_proto)
+ )
return(NDPI_PROTOCOL_UNKNOWN);
else {
*user_defined_proto = found->customUserProto;
@@ -3397,7 +3418,7 @@ static int ndpi_handle_ipv6_extension_headers(struct ndpi_detection_module_struc
}
return 0;
}
-#endif /* NDPI_DETECTION_SUPPORT_IPV6 */
+#endif /* NDPI_DETECTION_SUPPORT_IPV6 */
static u_int8_t ndpi_iph_is_valid_and_not_fragmented(const struct ndpi_iphdr *iph, const u_int16_t ipsize)
@@ -3605,13 +3626,18 @@ static int ndpi_init_packet_header(struct ndpi_detection_module_struct *ndpi_str
&& flow->init_finished != 0
&& flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
u_int8_t backup;
+ u_int16_t backup1, backup2;
if(flow->http.url) ndpi_free(flow->http.url);
if(flow->http.content_type) ndpi_free(flow->http.content_type);
- backup = flow->num_processed_pkts;
+ backup = flow->num_processed_pkts;
+ backup1 = flow->guessed_protocol_id;
+ backup2 = flow->guessed_host_protocol_id;
memset(flow, 0, sizeof(*(flow)));
flow->num_processed_pkts = backup;
+ flow->guessed_protocol_id = backup1;
+ flow->guessed_host_protocol_id = backup2;
NDPI_LOG_DBG(ndpi_struct,
"tcp syn packet for unknown protocol, reset detection state\n");
@@ -3785,9 +3811,8 @@ void check_ndpi_other_flow_func(struct ndpi_detection_module_struct *ndpi_struct
ndpi_struct->callback_buffer_non_tcp_udp[a].ndpi_selection_bitmask
&& (flow == NULL
||
- NDPI_BITMASK_COMPARE
- (flow->excluded_protocol_bitmask,
- ndpi_struct->callback_buffer_non_tcp_udp[a].excluded_protocol_bitmask) == 0)
+ NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
+ ndpi_struct->callback_buffer_non_tcp_udp[a].excluded_protocol_bitmask) == 0)
&& NDPI_BITMASK_COMPARE(ndpi_struct->callback_buffer_non_tcp_udp[a].detection_bitmask,
detection_bitmask) != 0) {
@@ -3905,8 +3930,7 @@ void check_ndpi_tcp_flow_func(struct ndpi_detection_module_struct *ndpi_struct,
&& (ndpi_struct->callback_buffer_tcp_no_payload[a].ndpi_selection_bitmask & *ndpi_selection_packet) ==
ndpi_struct->callback_buffer_tcp_no_payload[a].ndpi_selection_bitmask
&& NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
- ndpi_struct->
- callback_buffer_tcp_no_payload[a].excluded_protocol_bitmask) == 0
+ ndpi_struct->callback_buffer_tcp_no_payload[a].excluded_protocol_bitmask) == 0
&& NDPI_BITMASK_COMPARE(ndpi_struct->callback_buffer_tcp_no_payload[a].detection_bitmask,
detection_bitmask) != 0) {
ndpi_struct->callback_buffer_tcp_no_payload[a].func(ndpi_struct, flow);
@@ -3951,7 +3975,7 @@ static u_int16_t ndpi_guess_host_protocol_id(struct ndpi_detection_module_struct
/* ********************************************************************************* */
ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_struct,
- struct ndpi_flow_struct *flow) {
+ struct ndpi_flow_struct *flow, u_int8_t enable_guess) {
ndpi_protocol ret = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED };
if(flow == NULL) return(ret);
@@ -3973,13 +3997,18 @@ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_st
guessed_protocol_id = flow->guessed_protocol_id, guessed_host_protocol_id = flow->guessed_host_protocol_id;
if((guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN)
- && ((flow->packet.l4_protocol == IPPROTO_UDP) && NDPI_ISSET(&flow->excluded_protocol_bitmask, guessed_host_protocol_id)))
+ && ((flow->packet.l4_protocol == IPPROTO_UDP)
+ && NDPI_ISSET(&flow->excluded_protocol_bitmask, guessed_host_protocol_id)
+ && is_udp_guessable_protocol(guessed_host_protocol_id)
+ ))
flow->guessed_host_protocol_id = guessed_host_protocol_id = NDPI_PROTOCOL_UNKNOWN;
/* Ignore guessed protocol if they have been discarded */
if((guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN)
// && (guessed_host_protocol_id == NDPI_PROTOCOL_UNKNOWN)
- && (flow->packet.l4_protocol == IPPROTO_UDP) && NDPI_ISSET(&flow->excluded_protocol_bitmask, guessed_protocol_id))
+ && (flow->packet.l4_protocol == IPPROTO_UDP)
+ && NDPI_ISSET(&flow->excluded_protocol_bitmask, guessed_protocol_id)
+ && is_udp_guessable_protocol(guessed_protocol_id))
flow->guessed_protocol_id = guessed_protocol_id = NDPI_PROTOCOL_UNKNOWN;
if((guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN)
@@ -4026,6 +4055,20 @@ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_st
ret.app_protocol = NDPI_PROTOCOL_HANGOUT;
}
+ if(enable_guess
+ && (ret.app_protocol == NDPI_PROTOCOL_UNKNOWN)
+ && flow->packet.iph /* Guess only IPv4 */
+ && (flow->packet.tcp || flow->packet.udp)
+ )
+ ret = ndpi_guess_undetected_protocol(ndpi_struct,
+ flow,
+ flow->packet.l4_protocol,
+ ntohl(flow->packet.iph->saddr),
+ ntohs(flow->packet.udp ? flow->packet.udp->source : flow->packet.tcp->source),
+ ntohl(flow->packet.iph->daddr),
+ ntohs(flow->packet.udp ? flow->packet.udp->dest : flow->packet.tcp->dest)
+ );
+
ndpi_fill_protocol_category(ndpi_struct, flow, &ret);
return(ret);
@@ -4421,7 +4464,7 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
if(flow->packet.iph) {
if(flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
/* ret.master_protocol = flow->guessed_protocol_id , ret.app_protocol = flow->guessed_host_protocol_id; /\* ****** *\/ */
- ret = ndpi_detection_giveup(ndpi_struct, flow);
+ ret = ndpi_detection_giveup(ndpi_struct, flow, 0);
}
ndpi_fill_protocol_category(ndpi_struct, flow, &ret);
@@ -4499,7 +4542,7 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
We don't see how future packets can match anything
hence we giveup here
*/
- ret = ndpi_detection_giveup(ndpi_struct, flow);
+ ret = ndpi_detection_giveup(ndpi_struct, flow, 0);
}
return(ret);
@@ -5382,7 +5425,9 @@ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct
rc = ndpi_search_tcp_or_udp_raw(ndpi_struct, NULL, proto, shost, dhost, sport, dport);
if(rc != NDPI_PROTOCOL_UNKNOWN) {
- if(flow && (proto == IPPROTO_UDP) && NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, rc))
+ if(flow && (proto == IPPROTO_UDP)
+ && NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, rc)
+ && is_udp_guessable_protocol(rc))
;
else {
ret.app_protocol = rc,
@@ -5399,7 +5444,9 @@ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct
rc = ndpi_guess_protocol_id(ndpi_struct, NULL, proto, sport, dport, &user_defined_proto);
if(rc != NDPI_PROTOCOL_UNKNOWN) {
- if(flow && (proto == IPPROTO_UDP) && NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, rc))
+ if(flow && (proto == IPPROTO_UDP)
+ && NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, rc)
+ && is_udp_guessable_protocol(rc))
;
else {
ret.app_protocol = rc;