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.c173
1 files changed, 91 insertions, 82 deletions
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index 572c2a736..85e3c0fbd 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -1757,16 +1757,16 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
no_master, "DNP3", NDPI_PROTOCOL_CATEGORY_NETWORK,
ndpi_build_default_ports(ports_a, 20000, 0, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
- ndpi_set_proto_defaults(ndpi_str, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_104,
+ ndpi_set_proto_defaults(ndpi_str, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IEC60870,
1 /* no subprotocol */, no_master,
- no_master, "104", NDPI_PROTOCOL_CATEGORY_NETWORK, /* Perhaps IoT in the future */
+ no_master, "IEC60870", NDPI_PROTOCOL_CATEGORY_NETWORK, /* Perhaps IoT in the future */
ndpi_build_default_ports(ports_a, 2404, 0, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
ndpi_set_proto_defaults(ndpi_str, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_BLOOMBERG,
1 /* no subprotocol */, no_master,
no_master, "Bloomberg", NDPI_PROTOCOL_CATEGORY_NETWORK,
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
- ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
ndpi_set_proto_defaults(ndpi_str, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_CAPWAP,
1 /* no subprotocol */, no_master,
no_master, "CAPWAP", NDPI_PROTOCOL_CATEGORY_NETWORK,
@@ -1950,7 +1950,7 @@ static patricia_node_t* add_to_ptree(patricia_tree_t *tree, int family,
/* ******************************************* */
/*
- Load a file containing IPv4 addresses in CIDR format as 'protocol_id'
+ Load a file containing IPv4 addresses in CIDR format as 'protocol_id'
Return: the number of entries loaded or -1 in case of error
*/
@@ -1960,7 +1960,7 @@ int ndpi_load_ipv4_ptree(struct ndpi_detection_module_struct *ndpi_str,
FILE *fd;
int len;
u_int num_loaded = 0;
-
+
fd = fopen(path, "r");
if(fd == NULL) {
@@ -1985,9 +1985,9 @@ int ndpi_load_ipv4_ptree(struct ndpi_detection_module_struct *ndpi_str,
if(addr) {
struct in_addr pin;
patricia_node_t *node;
-
+
cidr = strtok_r(NULL, "\n", &saveptr);
-
+
pin.s_addr = inet_addr(addr);
if((node = add_to_ptree(ndpi_str->protocols_ptree, AF_INET,
&pin, cidr ? atoi(cidr) : 32 /* bits */)) != NULL)
@@ -2013,7 +2013,7 @@ static void ndpi_init_ptree_ipv4(struct ndpi_detection_module_struct *ndpi_str,
if(skip_tor_hosts && (host_list[i].value == NDPI_PROTOCOL_TOR))
continue;
-
+
pin.s_addr = htonl(host_list[i].network);
if((node = add_to_ptree(ptree, AF_INET,
&pin, host_list[i].cidr /* bits */)) != NULL)
@@ -2307,7 +2307,7 @@ void ndpi_finalize_initalization(struct ndpi_detection_module_struct *ndpi_str)
automa = &ndpi_str->impossible_bigrams_automa;
break;
}
-
+
ac_automata_finalize((AC_AUTOMATA_t*)automa->ac_automa);
automa->ac_automa_finalized = 1;
}
@@ -3509,7 +3509,7 @@ void ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *n
#ifdef CUSTOM_NDPI_PROTOCOLS
#include "../../../nDPI-custom/custom_ndpi_main_init.c"
#endif
-
+
/* ----------------------------------------------------------------- */
ndpi_str->callback_buffer_size = a;
@@ -4055,22 +4055,24 @@ void check_ndpi_udp_flow_func(struct ndpi_detection_module_struct *ndpi_str,
func = ndpi_str->proto_defaults[flow->guessed_protocol_id].func;
}
- for(a = 0; a < ndpi_str->callback_buffer_size_udp; a++) {
- if((func != ndpi_str->callback_buffer_udp[a].func)
- && (ndpi_str->callback_buffer_udp[a].ndpi_selection_bitmask & *ndpi_selection_packet) ==
- ndpi_str->callback_buffer_udp[a].ndpi_selection_bitmask
- && NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
- ndpi_str->callback_buffer_udp[a].excluded_protocol_bitmask) == 0
- && NDPI_BITMASK_COMPARE(ndpi_str->callback_buffer_udp[a].detection_bitmask,
- detection_bitmask) != 0) {
- ndpi_str->callback_buffer_udp[a].func(ndpi_str, flow);
-
- // NDPI_LOG_DBG(ndpi_str, "[UDP,CALL] dissector of protocol as callback_buffer idx = %d\n",a);
- if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
- break; /* Stop after detecting the first protocol */
- } else
- if(_ndpi_debug_callbacks) NDPI_LOG_DBG2(ndpi_str,
- "[UDP,SKIP] dissector of protocol as callback_buffer idx = %d\n",a);
+ if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
+ for(a = 0; a < ndpi_str->callback_buffer_size_udp; a++) {
+ if((func != ndpi_str->callback_buffer_udp[a].func)
+ && (ndpi_str->callback_buffer_udp[a].ndpi_selection_bitmask & *ndpi_selection_packet) ==
+ ndpi_str->callback_buffer_udp[a].ndpi_selection_bitmask
+ && NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
+ ndpi_str->callback_buffer_udp[a].excluded_protocol_bitmask) == 0
+ && NDPI_BITMASK_COMPARE(ndpi_str->callback_buffer_udp[a].detection_bitmask,
+ detection_bitmask) != 0) {
+ ndpi_str->callback_buffer_udp[a].func(ndpi_str, flow);
+
+ // NDPI_LOG_DBG(ndpi_str, "[UDP,CALL] dissector of protocol as callback_buffer idx = %d\n",a);
+ if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
+ break; /* Stop after detecting the first protocol */
+ } else
+ if(_ndpi_debug_callbacks) NDPI_LOG_DBG2(ndpi_str,
+ "[UDP,SKIP] dissector of protocol as callback_buffer idx = %d\n",a);
+ }
}
}
@@ -4191,7 +4193,7 @@ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_st
ndpi_protocol ret = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED };
*protocol_was_guessed = 0;
-
+
if(flow == NULL)
return(ret);
@@ -4205,7 +4207,8 @@ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_st
/* TODO: add the remaining stage_XXXX protocols */
if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
- u_int16_t guessed_protocol_id, guessed_host_protocol_id;
+ u_int16_t guessed_protocol_id = NDPI_PROTOCOL_UNKNOWN,
+ guessed_host_protocol_id = NDPI_PROTOCOL_UNKNOWN;
if(flow->guessed_protocol_id == NDPI_PROTOCOL_STUN)
goto check_stun_export;
@@ -4249,6 +4252,8 @@ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_st
if(flow->host_server_name[0] != '\0') {
ndpi_protocol_match_result ret_match;
+ memset(&ret_match, 0, sizeof(ret_match));
+
ndpi_match_host_subprotocol(ndpi_str, flow,
(char *)flow->host_server_name,
strlen((const char*)flow->host_server_name),
@@ -4297,10 +4302,10 @@ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_st
ret.app_protocol = NDPI_PROTOCOL_HANGOUT_DUO;
}
}
-
+
if(ret.app_protocol != NDPI_PROTOCOL_UNKNOWN)
- ndpi_fill_protocol_category(ndpi_str, flow, &ret);
-
+ ndpi_fill_protocol_category(ndpi_str, flow, &ret);
+
return(ret);
}
@@ -4696,8 +4701,8 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
if(flow->check_extra_packets) {
ndpi_process_extra_packet(ndpi_str, flow, packet, packetlen, current_tick_l, src, dst);
/* Update in case of new match */
- ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0];
- return(ret);
+ ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0], ret.category = flow->category;;
+ goto invalidate_ptr;
} else
goto ret_protocols;
}
@@ -4795,7 +4800,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) {
u_int8_t protocol_was_guessed;
-
+
/* ret.master_protocol = flow->guessed_protocol_id , ret.app_protocol = flow->guessed_host_protocol_id; /\* ****** *\/ */
ret = ndpi_detection_giveup(ndpi_str, flow, 0, &protocol_was_guessed);
}
@@ -4815,34 +4820,33 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
addr.s_addr = flow->packet.iph->daddr;
flow->guessed_host_protocol_id = ndpi_network_ptree_match(ndpi_str, &addr);
}
+
+ /*
+ We could implement a shortcut here skipping dissectors for
+ protocols we have identified by other means such as with the IP
+
+ However we do NOT stop here and skip invoking the dissectors
+ because we want to dissect the flow (e.g. dissect the TLS)
+ and extract metadata.
+ */
+#if SKIP_INVOKING_THE_DISSECTORS
+ if(flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
+ /*
+ We have identified a protocol using the IP address so
+ it is not worth to dissect the traffic as we already have
+ the solution
+ */
+ ret.master_protocol = flow->guessed_protocol_id,
+ ret.app_protocol = flow->guessed_host_protocol_id;
+ }
+#endif
}
}
}
if(flow->guessed_host_protocol_id > NDPI_MAX_SUPPORTED_PROTOCOLS) {
/* This is a custom protocol and it has priority over everything else */
- ret.master_protocol = NDPI_PROTOCOL_UNKNOWN, ret.app_protocol = flow->guessed_host_protocol_id;
-
- if(flow->packet.tcp && (ret.master_protocol == NDPI_PROTOCOL_UNKNOWN)) {
- /* Minimal guess for HTTP/SSL-based protocols */
- int i;
-
- for(i=0; i<2; i++) {
- u_int16_t port = (i == 0) ? ntohs(flow->packet.tcp->dest) : ntohs(flow->packet.tcp->source);
-
- switch(port) {
- case 80:
- ret.master_protocol = NDPI_PROTOCOL_HTTP;
- break;
- case 443:
- ret.master_protocol = NDPI_PROTOCOL_TLS; /* QUIC could also match */
- break;
- }
-
- if(ret.master_protocol != NDPI_PROTOCOL_UNKNOWN)
- break;
- }
- }
+ ret.master_protocol = flow->guessed_protocol_id, ret.app_protocol = flow->guessed_host_protocol_id;
ndpi_check_flow_func(ndpi_str, flow, &ndpi_selection_packet);
ndpi_fill_protocol_category(ndpi_str, flow, &ret);
@@ -4878,7 +4882,8 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
ret.app_protocol = flow->detected_protocol_stack[0];
/* Don't overwrite the category if already set */
- if(flow->category == NDPI_PROTOCOL_CATEGORY_UNSPECIFIED)
+ if((flow->category == NDPI_PROTOCOL_CATEGORY_UNSPECIFIED)
+ && (ret.app_protocol != NDPI_PROTOCOL_UNKNOWN))
ndpi_fill_protocol_category(ndpi_str, flow, &ret);
else
ret.category = flow->category;
@@ -4891,7 +4896,7 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
&& (flow->guessed_protocol_id == 0)
) {
u_int8_t protocol_was_guessed;
-
+
/*
This is a TCP flow
- whose first packet is NOT a SYN
@@ -4903,6 +4908,13 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
ret = ndpi_detection_giveup(ndpi_str, flow, 0, &protocol_was_guessed);
}
+ if((ret.master_protocol == NDPI_PROTOCOL_UNKNOWN)
+ && (ret.app_protocol != NDPI_PROTOCOL_UNKNOWN)
+ && (flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN)) {
+ ret.master_protocol = ret.app_protocol;
+ ret.app_protocol = flow->guessed_host_protocol_id;
+ }
+
invalidate_ptr:
/*
Invalidate packet memory to avoid accessing the pointers below
@@ -5086,7 +5098,7 @@ void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_str,
for(a = 0; (a < packet->payload_packet_len)
&& (packet->parsed_lines < NDPI_MAX_PARSE_LINES_PER_PACKET); a++) {
- if((a + 1) == packet->payload_packet_len)
+ if((a + 1) >= packet->payload_packet_len)
return; /* Return if only one byte remains (prevent invalid reads past end-of-buffer) */
if(get_u_int16_t(packet->payload, a) == ntohs(0x0d0a)) { /* If end of line char sequence CR+NL "\r\n", process line */
@@ -5167,7 +5179,7 @@ void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_str,
while((packet->content_line.len > 0) && (packet->content_line.ptr[0] == ' '))
packet->content_line.len--, packet->content_line.ptr++;
-
+
packet->http_num_headers++;
}
/* "Content-Type:" header line in HTTP AGAIN. Probably a bogus response without space after ":" */
@@ -5184,14 +5196,14 @@ void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_str,
char separator[] = { ';', '\r', '\0' };
int i;
- for(i=0; separator[i] != '\0'; i++) {
+ for(i=0; separator[i] != '\0'; i++) {
char *c = memchr((char*)packet->content_line.ptr, separator[i], packet->content_line.len);
-
+
if(c != NULL)
packet->content_line.len = c - (char*)packet->content_line.ptr;
}
}
-
+
/* "Accept:" header line in HTTP request. */
if(packet->line[packet->parsed_lines].len > 8
&& strncasecmp((const char *)packet->line[packet->parsed_lines].ptr, "Accept: ", 8) == 0) {
@@ -6200,7 +6212,7 @@ static u_int8_t ndpi_is_more_generic_protocol(u_int16_t previous_proto, u_int16_
if((previous_proto == NDPI_PROTOCOL_UNKNOWN)
|| (previous_proto == new_proto))
return(0);
-
+
switch(previous_proto) {
case NDPI_PROTOCOL_WHATSAPP_CALL:
case NDPI_PROTOCOL_WHATSAPP_FILES:
@@ -6304,16 +6316,12 @@ u_int16_t ndpi_match_host_subprotocol(struct ndpi_detection_module_struct *ndpi_
u_int16_t rc = ndpi_automa_match_string_subprotocol(ndpi_str,
flow, string_to_match, string_to_match_len,
master_protocol_id, ret_match, 1);
+ unsigned long id = ret_match->protocol_category;
- if((flow->category == NDPI_PROTOCOL_CATEGORY_UNSPECIFIED)
- && (ret_match->protocol_category == NDPI_PROTOCOL_CATEGORY_UNSPECIFIED)) {
- unsigned long id = ret_match->protocol_category;
-
- if(ndpi_get_custom_category_match(ndpi_str, string_to_match, string_to_match_len, &id) != -1) {
- if(id != -1) {
- flow->category = ret_match->protocol_category = id;
- rc = master_protocol_id;
- }
+ if(ndpi_get_custom_category_match(ndpi_str, string_to_match, string_to_match_len, &id) != -1) {
+ if(id != -1) {
+ flow->category = ret_match->protocol_category = id;
+ rc = master_protocol_id;
}
}
@@ -6365,10 +6373,11 @@ int ndpi_match_bigram(struct ndpi_detection_module_struct *ndpi_str,
void ndpi_free_flow(struct ndpi_flow_struct *flow) {
if(flow) {
- if(flow->http.url) ndpi_free(flow->http.url);
- if(flow->http.content_type) ndpi_free(flow->http.content_type);
- if(flow->http.user_agent) ndpi_free(flow->http.user_agent);
-
+ if(flow->http.url) ndpi_free(flow->http.url);
+ if(flow->http.content_type) ndpi_free(flow->http.content_type);
+ if(flow->http.user_agent) ndpi_free(flow->http.user_agent);
+ if(flow->kerberos_buf.pktbuf) ndpi_free(flow->kerberos_buf.pktbuf);
+
if(flow->l4_proto == IPPROTO_TCP) {
if(flow->l4.tcp.tls_srv_cert_fingerprint_ctx)
ndpi_free(flow->l4.tcp.tls_srv_cert_fingerprint_ctx);
@@ -6580,7 +6589,7 @@ u_int8_t ndpi_extra_dissection_possible(struct ndpi_detection_module_struct *ndp
break;
case NDPI_PROTOCOL_TELNET:
- if(!flow->protos.telnet.username_detected)
+ if(!flow->protos.telnet.password_detected)
return(1);
break;
}
@@ -6595,15 +6604,15 @@ const char* ndpi_get_l4_proto_name(ndpi_l4_proto_info proto) {
case ndpi_l4_proto_unknown:
return("");
break;
-
+
case ndpi_l4_proto_tcp_only:
return("TCP");
break;
-
+
case ndpi_l4_proto_udp_only:
return("UDP");
break;
-
+
case ndpi_l4_proto_tcp_and_udp:
return("TCP/UDP");
break;
@@ -6615,7 +6624,7 @@ const char* ndpi_get_l4_proto_name(ndpi_l4_proto_info proto) {
/* ******************************************************************** */
ndpi_l4_proto_info ndpi_get_l4_proto_info(struct ndpi_detection_module_struct *ndpi_struct,
- u_int16_t ndpi_proto_id) {
+ u_int16_t ndpi_proto_id) {
if(ndpi_proto_id < ndpi_struct->ndpi_num_supported_protocols) {
u_int16_t idx = ndpi_struct->proto_defaults[ndpi_proto_id].protoIdx;
NDPI_SELECTION_BITMASK_PROTOCOL_SIZE bm = ndpi_struct->callback_buffer[idx].ndpi_selection_bitmask;