aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/ndpi_api.h.in7
-rw-r--r--src/include/ndpi_define.h.in2
-rw-r--r--src/include/ndpi_typedefs.h6
-rw-r--r--src/lib/Makefile.in2
-rw-r--r--src/lib/ndpi_analyze.c96
-rw-r--r--src/lib/ndpi_content_match.c.inc2
-rw-r--r--src/lib/ndpi_main.c95
-rw-r--r--src/lib/ndpi_utils.c5
-rw-r--r--src/lib/protocols/dhcp.c10
-rw-r--r--src/lib/protocols/dns.c19
-rw-r--r--src/lib/protocols/h323.c2
-rw-r--r--src/lib/protocols/http.c16
-rw-r--r--src/lib/protocols/tls.c19
-rw-r--r--src/lib/third_party/include/ndpi_patricia.h2
14 files changed, 223 insertions, 60 deletions
diff --git a/src/include/ndpi_api.h.in b/src/include/ndpi_api.h.in
index 248d18cee..865ddc8dd 100644
--- a/src/include/ndpi_api.h.in
+++ b/src/include/ndpi_api.h.in
@@ -923,8 +923,8 @@ extern "C" {
/* ptree (trie) API */
ndpi_ptree_t* ndpi_ptree_create(void);
- int ndpi_ptree_insert(ndpi_ptree_t *tree, const ndpi_ip_addr_t *addr, u_int8_t bits, uint user_data);
- int ndpi_ptree_match_addr(ndpi_ptree_t *tree, const ndpi_ip_addr_t *addr, uint *user_data);
+ int ndpi_ptree_insert(ndpi_ptree_t *tree, const ndpi_ip_addr_t *addr, u_int8_t bits, u_int32_t user_data);
+ int ndpi_ptree_match_addr(ndpi_ptree_t *tree, const ndpi_ip_addr_t *addr, u_int32_t *user_data);
void ndpi_ptree_destroy(ndpi_ptree_t *tree);
/* DGA */
@@ -1072,7 +1072,10 @@ extern "C" {
void ndpi_free_bin(struct ndpi_bin *b);
void ndpi_inc_bin(struct ndpi_bin *b, u_int8_t slot_id);
void ndpi_normalize_bin(struct ndpi_bin *b);
+ char* ndpi_print_bin(struct ndpi_bin *b, u_int8_t normalize_first, char *out_buf, u_int out_buf_len);
+ float ndpi_bin_similarity(struct ndpi_bin *b1, struct ndpi_bin *b2, u_int8_t normalize_first);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/include/ndpi_define.h.in b/src/include/ndpi_define.h.in
index df28c15f3..5add2e1c8 100644
--- a/src/include/ndpi_define.h.in
+++ b/src/include/ndpi_define.h.in
@@ -279,7 +279,7 @@
#define NDPI_SET_BIT(num, n) num |= 1UL << n
#define NDPI_CLR_BIT(num, n) num &= ~(1UL << n)
#define NDPI_CLR_BIT(num, n) num &= ~(1UL << n)
-#define NDPI_ISSET_BIT(num, n) (num & (1 << n))
+#define NDPI_ISSET_BIT(num, n) (num & (1UL << n))
#define NDPI_ZERO_BIT(num) num = 0
/* this is a very very tricky macro *g*,
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h
index 3784f995a..99b91d4be 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -52,8 +52,9 @@ typedef enum {
/*
NOTE
- When the typedef below is modified don't forget
- to update ndpi_risk2str (in ndpi_utils.c)
+ When the typedef below is modified don't forget to update
+ - ndpi_risk2str (in ndpi_utils.c)
+ - https://github.com/ntop/ntopng/blob/dev/scripts/lua/modules/flow_risk_utils.lua
*/
typedef enum {
NDPI_NO_RISK = 0,
@@ -73,6 +74,7 @@ typedef enum {
NDPI_HTTP_SUSPICIOUS_HEADER,
NDPI_TLS_NOT_CARRYING_HTTPS,
NDPI_SUSPICIOUS_DGA_DOMAIN,
+ NDPI_MALFORMED_PACKET,
/* Leave this as last member */
NDPI_MAX_RISK
diff --git a/src/lib/Makefile.in b/src/lib/Makefile.in
index f69c81946..874cee20c 100644
--- a/src/lib/Makefile.in
+++ b/src/lib/Makefile.in
@@ -54,7 +54,7 @@ $(NDPI_LIB_SHARED): $(OBJECTS)
$(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS)
clean:
- /bin/rm -f $(NDPI_LIB_STATIC) $(OBJECTS) *.o *.so *.lo $(NDPI_LIB_SHARED)
+ /bin/rm -f $(NDPI_LIB_STATIC) $(OBJECTS) *.o *.so *.lo libndpi.so*
distclean: clean
/bin/rm -f Makefile
diff --git a/src/lib/ndpi_analyze.c b/src/lib/ndpi_analyze.c
index e1f37cc8d..4ca3ac25a 100644
--- a/src/lib/ndpi_analyze.c
+++ b/src/lib/ndpi_analyze.c
@@ -125,6 +125,12 @@ float ndpi_data_variance(struct ndpi_analyze_struct *s) {
/* ********************************************************************************* */
+/*
+ See the link below for "Population and sample standard deviation review"
+ https://www.khanacademy.org/math/statistics-probability/summarizing-quantitative-data/variance-standard-deviation-sample/a/population-and-sample-standard-deviation-review
+
+ In nDPI we use an approximate stddev calculation to avoid storing all data in memory
+*/
/* Compute the standard deviation on all values */
float ndpi_data_stddev(struct ndpi_analyze_struct *s) {
return(sqrt(ndpi_data_variance(s)));
@@ -260,6 +266,8 @@ int ndpi_init_bin(struct ndpi_bin *b, enum ndpi_bin_family f, u_int8_t num_bins)
return(0);
}
+/* ********************************************************************************* */
+
void ndpi_free_bin(struct ndpi_bin *b) {
switch(b->family) {
case ndpi_bin_family8:
@@ -274,6 +282,8 @@ void ndpi_free_bin(struct ndpi_bin *b) {
}
}
+/* ********************************************************************************* */
+
void ndpi_inc_bin(struct ndpi_bin *b, u_int8_t slot_id) {
if(slot_id >= b->num_bins) slot_id = 0;
@@ -292,6 +302,8 @@ void ndpi_inc_bin(struct ndpi_bin *b, u_int8_t slot_id) {
}
}
+/* ********************************************************************************* */
+
/*
Each bin slot is transformed in a % with respect to the value total
*/
@@ -316,3 +328,87 @@ void ndpi_normalize_bin(struct ndpi_bin *b) {
}
}
+/* ********************************************************************************* */
+
+char* ndpi_print_bin(struct ndpi_bin *b, u_int8_t normalize_first, char *out_buf, u_int out_buf_len) {
+ u_int8_t i;
+ u_int len = 0;
+
+ if(!out_buf) return(out_buf); else out_buf[0] = '\0';
+
+ if(normalize_first)
+ ndpi_normalize_bin(b);
+
+ switch(b->family) {
+ case ndpi_bin_family8:
+ for(i=0; i<b->num_bins; i++) {
+ int rc = snprintf(&out_buf[len], out_buf_len-len, "%s%u", (i > 0) ? "," : "", b->u.bins8[i]);
+
+ if(rc < 0) break;
+ len += rc;
+ }
+ break;
+
+ case ndpi_bin_family16:
+ for(i=0; i<b->num_bins; i++) {
+ int rc = snprintf(&out_buf[len], out_buf_len-len, "%s%u", (i > 0) ? "," : "", b->u.bins16[i]);
+
+ if(rc < 0) break;
+ len += rc;
+ }
+ break;
+
+ case ndpi_bin_family32:
+ for(i=0; i<b->num_bins; i++) {
+ int rc = snprintf(&out_buf[len], out_buf_len-len, "%s%u", (i > 0) ? "," : "", b->u.bins32[i]);
+
+ if(rc < 0) break;
+ len += rc;
+ }
+ break;
+ }
+
+ return(out_buf);
+}
+
+/* ********************************************************************************* */
+
+/*
+ Determines how similar are two bins
+
+ 0 = Very differet
+ ... (gray zone)
+ 1 = Alike
+
+ See https://en.wikipedia.org/wiki/Cosine_similarity for more details
+*/
+float ndpi_bin_similarity(struct ndpi_bin *b1, struct ndpi_bin *b2, u_int8_t normalize_first) {
+ u_int8_t i;
+ u_int32_t sumxx = 0, sumxy = 0, sumyy = 0;
+
+ if((b1->num_incs == 0) || (b2->num_incs == 0)
+ || (b1->family != b2->family) || (b1->num_bins != b2->num_bins))
+ return(0);
+
+ if(normalize_first)
+ ndpi_normalize_bin(b1), ndpi_normalize_bin(b2);
+
+ switch(b1->family) {
+ case ndpi_bin_family8:
+ for(i=0; i<b1->num_bins; i++)
+ sumxx += b1->u.bins8[i] * b1->u.bins8[i], sumyy += b2->u.bins8[i] * b2->u.bins8[i], sumxy += b1->u.bins8[i] * b2->u.bins8[i];
+ break;
+ case ndpi_bin_family16:
+ for(i=0; i<b1->num_bins; i++)
+ sumxx += b1->u.bins16[i] * b1->u.bins16[i], sumyy += b2->u.bins16[i] * b2->u.bins16[i], sumxy += b1->u.bins16[i] * b2->u.bins16[i];
+ break;
+ case ndpi_bin_family32:
+ for(i=0; i<b1->num_bins; i++)
+ sumxx += b1->u.bins32[i] * b1->u.bins32[i], sumyy += b2->u.bins32[i] * b2->u.bins32[i], sumxy += b1->u.bins32[i] * b2->u.bins32[i];
+ break;
+ }
+
+ return((float)sumxy / sqrt((float)(sumxx * sumyy)));
+}
+
+/* ********************************************************************************* */
diff --git a/src/lib/ndpi_content_match.c.inc b/src/lib/ndpi_content_match.c.inc
index 82a77183a..4ad5c5598 100644
--- a/src/lib/ndpi_content_match.c.inc
+++ b/src/lib/ndpi_content_match.c.inc
@@ -909,7 +909,7 @@ static ndpi_network host_protocol_list[] = {
/* Teamviewer 159.122.189.32-63 */
- { 0x9F7ABD30 /* 159.122.189.32 */, 21, NDPI_PROTOCOL_TEAMVIEWER },
+ { 0x9F7ABD20 /* 159.122.189.32 */, 27, NDPI_PROTOCOL_TEAMVIEWER },
#if 0
/*
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index ec0ade60b..199c34a5b 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -275,7 +275,7 @@ u_int8_t ndpi_is_subprotocol_informative(struct ndpi_detection_module_struct *nd
if(protoId >= NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS)
return(0);
- switch (protoId) {
+ switch(protoId) {
/* All dissectors that have calls to ndpi_match_host_subprotocol() */
case NDPI_PROTOCOL_DNS:
return(1);
@@ -578,7 +578,7 @@ static void init_string_based_protocols(struct ndpi_detection_module_struct *ndp
for (i = 0; ndpi_en_popular_bigrams[i] != NULL; i++)
ndpi_string_to_automa(ndpi_str, &ndpi_str->bigrams_automa, (char *) ndpi_en_popular_bigrams[i], 1, 1, 1, 0);
#endif
-
+
for (i = 0; ndpi_en_impossible_bigrams[i] != NULL; i++)
ndpi_string_to_automa(ndpi_str, &ndpi_str->impossible_bigrams_automa, (char *) ndpi_en_impossible_bigrams[i], 1,
1, 1, 0);
@@ -588,7 +588,7 @@ static void init_string_based_protocols(struct ndpi_detection_module_struct *ndp
int ndpi_set_detection_preferences(struct ndpi_detection_module_struct *ndpi_str, ndpi_detection_preference pref,
int value) {
- switch (pref) {
+ switch(pref) {
case ndpi_pref_direction_detect_disable:
ndpi_str->direction_detect_disable = (u_int8_t) value;
break;
@@ -2032,7 +2032,7 @@ void ndpi_finalize_initalization(struct ndpi_detection_module_struct *ndpi_str)
for (i = 0; i < 4; i++) {
ndpi_automa *automa;
- switch (i) {
+ switch(i) {
case 0:
automa = &ndpi_str->host_automa;
break;
@@ -2380,7 +2380,7 @@ static ndpi_default_ports_tree_node_t *ndpi_get_guessed_protocol_id(struct ndpi_
as they have been excluded
*/
u_int8_t is_udp_guessable_protocol(u_int16_t l7_guessed_proto) {
- switch (l7_guessed_proto) {
+ switch(l7_guessed_proto) {
case NDPI_PROTOCOL_QUIC:
case NDPI_PROTOCOL_SNMP:
case NDPI_PROTOCOL_NETFLOW:
@@ -2416,7 +2416,7 @@ u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_str,
} else {
/* No TCP/UDP */
- switch (proto) {
+ switch(proto) {
case NDPI_IPSEC_PROTOCOL_ESP:
case NDPI_IPSEC_PROTOCOL_AH:
return(NDPI_PROTOCOL_IP_IPSEC);
@@ -2425,6 +2425,21 @@ u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_str,
return(NDPI_PROTOCOL_IP_GRE);
break;
case NDPI_ICMP_PROTOCOL_TYPE:
+ if(flow) {
+ /* Run some basic consistency tests */
+
+ if(flow->packet.payload_packet_len < sizeof(struct ndpi_icmphdr))
+ NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET);
+ else {
+ u_int8_t icmp_type = (u_int8_t)flow->packet.payload[0];
+ u_int8_t icmp_code = (u_int8_t)flow->packet.payload[1];
+
+ /* https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml */
+ if(((icmp_type >= 44) && (icmp_type <= 252))
+ || (icmp_code > 15))
+ NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET);
+ }
+ }
return(NDPI_PROTOCOL_IP_ICMP);
break;
case NDPI_IGMP_PROTOCOL_TYPE:
@@ -2443,6 +2458,22 @@ u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_str,
return(NDPI_PROTOCOL_IP_IP_IN_IP);
break;
case NDPI_ICMPV6_PROTOCOL_TYPE:
+ if(flow) {
+ /* Run some basic consistency tests */
+
+ if(flow->packet.payload_packet_len < sizeof(struct ndpi_icmphdr))
+ NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET);
+ else {
+ u_int8_t icmp6_type = (u_int8_t)flow->packet.payload[0];
+ u_int8_t icmp6_code = (u_int8_t)flow->packet.payload[1];
+
+ /* https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol_for_IPv6 */
+ if(((icmp6_type >= 5) && (icmp6_type <= 127))
+ || (icmp6_type >= 156)
+ || ((icmp6_code > 7) && (icmp6_type != 255)))
+ NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET);
+ }
+ }
return(NDPI_PROTOCOL_IP_ICMPV6);
break;
case 112:
@@ -2491,7 +2522,7 @@ int ndpi_handle_rule(struct ndpi_detection_module_struct *ndpi_str, char *rule,
at[0] = 0, proto = &at[1];
for (i = 0; proto[i] != '\0'; i++) {
- switch (proto[i]) {
+ switch(proto[i]) {
case '/':
case '&':
case '^':
@@ -3261,6 +3292,9 @@ void ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *n
/* IEC 60870-5-104 */
init_104_dissector(ndpi_str, &a, detection_bitmask);
+ /* DNP3 */
+ init_dnp3_dissector(ndpi_str, &a, detection_bitmask);
+
/* WEBSOCKET */
init_websocket_dissector(ndpi_str, &a, detection_bitmask);
@@ -3625,6 +3659,10 @@ static int ndpi_init_packet_header(struct ndpi_detection_module_struct *ndpi_str
flow->packet.udp = (struct ndpi_udphdr *) l4ptr;
flow->packet.payload_packet_len = flow->packet.l4_packet_len - 8;
flow->packet.payload = ((u_int8_t *) flow->packet.udp) + 8;
+ } else if((l4protocol == IPPROTO_ICMP && flow->packet.l4_packet_len >= sizeof(struct ndpi_icmphdr))
+ || (l4protocol == IPPROTO_ICMPV6 && flow->packet.l4_packet_len >= sizeof(struct ndpi_icmp6hdr))) {
+ flow->packet.payload = ((u_int8_t *) l4ptr);
+ flow->packet.payload_packet_len = flow->packet.l4_packet_len;
} else {
flow->packet.generic_l4_ptr = l4ptr;
}
@@ -4345,7 +4383,8 @@ static void ndpi_reset_packet_line_info(struct ndpi_packet_struct *packet) {
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;
+ packet->http_response.ptr = NULL, packet->http_response.len = 0, packet->http_num_headers = 0,
+ packet->forwarded_line.ptr = NULL, packet->forwarded_line.len = 0;
}
/* ********************************************************************************* */
@@ -4382,13 +4421,13 @@ static void ndpi_reconcile_protocols(struct ndpi_detection_module_struct *ndpi_s
Skype for a host doing MS Teams means MS Teams
(MS Teams uses Skype as transport protocol for voice/video)
*/
-
+
if(flow) {
/* Do not go for DNS when there is an application protocol. Example DNS.Apple */
if((flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN)
&& (flow->detected_protocol_stack[0] /* app */ != flow->detected_protocol_stack[1] /* major */))
NDPI_CLR_BIT(flow->risk, NDPI_SUSPICIOUS_DGA_DOMAIN);
- }
+ }
switch(ret->app_protocol) {
case NDPI_PROTOCOL_MSTEAMS:
@@ -5676,7 +5715,7 @@ char *ndpi_protocol2name(struct ndpi_detection_module_struct *ndpi_str,
/* ****************************************************** */
int ndpi_is_custom_category(ndpi_protocol_category_t category) {
- switch (category) {
+ switch(category) {
case NDPI_PROTOCOL_CATEGORY_CUSTOM_1:
case NDPI_PROTOCOL_CATEGORY_CUSTOM_2:
case NDPI_PROTOCOL_CATEGORY_CUSTOM_3:
@@ -5699,7 +5738,7 @@ void ndpi_category_set_name(struct ndpi_detection_module_struct *ndpi_str,
if(!name)
return;
- switch (category) {
+ switch(category) {
case NDPI_PROTOCOL_CATEGORY_CUSTOM_1:
snprintf(ndpi_str->custom_category_labels[0], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
break;
@@ -5740,7 +5779,7 @@ const char *ndpi_category_get_name(struct ndpi_detection_module_struct *ndpi_str
}
if((category >= NDPI_PROTOCOL_CATEGORY_CUSTOM_1) && (category <= NDPI_PROTOCOL_CATEGORY_CUSTOM_5)) {
- switch (category) {
+ switch(category) {
case NDPI_PROTOCOL_CATEGORY_CUSTOM_1:
return(ndpi_str->custom_category_labels[0]);
case NDPI_PROTOCOL_CATEGORY_CUSTOM_2:
@@ -5806,7 +5845,7 @@ ndpi_protocol_breed_t ndpi_get_proto_breed(struct ndpi_detection_module_struct *
char *ndpi_get_proto_breed_name(struct ndpi_detection_module_struct *ndpi_str,
ndpi_protocol_breed_t breed_id) {
- switch (breed_id) {
+ switch(breed_id) {
case NDPI_PROTOCOL_SAFE:
return("Safe");
break;
@@ -5974,7 +6013,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) {
+ switch(previous_proto) {
case NDPI_PROTOCOL_WHATSAPP_CALL:
case NDPI_PROTOCOL_WHATSAPP_FILES:
if(new_proto == NDPI_PROTOCOL_WHATSAPP)
@@ -6324,7 +6363,7 @@ u_int8_t ndpi_extra_dissection_possible(struct ndpi_detection_module_struct *ndp
proto);
#endif
- switch (proto) {
+ switch(proto) {
case NDPI_PROTOCOL_TLS:
if(!flow->l4.tcp.tls.certificate_processed)
return(1); /* TODO: add check for TLS 1.3 */
@@ -6365,7 +6404,7 @@ u_int8_t ndpi_extra_dissection_possible(struct ndpi_detection_module_struct *ndp
/* ******************************************************************** */
const char *ndpi_get_l4_proto_name(ndpi_l4_proto_info proto) {
- switch (proto) {
+ switch(proto) {
case ndpi_l4_proto_unknown:
return("");
break;
@@ -6529,7 +6568,7 @@ int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str,
int len, rc = 0;
len = strlen(name);
-
+
if(len >= 5) {
int i, j, num_found = 0, num_impossible = 0, num_bigram_checks = 0, num_digits = 0, num_vowels = 0, num_words = 0;
char tmp[128], *word, *tok_tmp;
@@ -6548,29 +6587,29 @@ int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str,
if(!word) break;
num_words++;
-
+
if(strlen(word) < 3) continue;
#ifdef DGA_DEBUG
printf("-> %s [%s][len: %u]\n", word, name, (unsigned int)strlen(word));
#endif
-
+
for(i = 0; word[i+1] != '\0'; i++) {
if(isdigit(word[i])) {
num_digits++;
-
+
// if(!isdigit(word[i+1])) num_impossible++;
-
- continue;
+
+ continue;
}
-
+
switch(word[i]) {
case '_':
case '-':
case ':':
continue;
break;
-
+
case '.':
continue;
break;
@@ -6585,13 +6624,13 @@ int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str,
num_vowels++;
break;
}
-
+
if(isdigit(word[i+1])) {
num_digits++;
// num_impossible++;
continue;
}
-
+
num_bigram_checks++;
if(ndpi_match_bigram(ndpi_str, &ndpi_str->bigrams_automa, &word[i])) {
@@ -6613,7 +6652,7 @@ int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str,
printf("[num_found: %u][num_impossible: %u][num_digits: %u][num_bigram_checks: %u][num_vowels: %u/%u]\n",
num_found, num_impossible, num_digits, num_bigram_checks, num_vowels, j-num_vowels);
#endif
-
+
if(num_bigram_checks
&& ((num_found == 0) || ((num_digits > 5) && (num_words <= 3)) || enough(num_found, num_impossible)))
rc = 1;
diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c
index 335b9dd87..708ac38a0 100644
--- a/src/lib/ndpi_utils.c
+++ b/src/lib/ndpi_utils.c
@@ -1500,7 +1500,10 @@ const char* ndpi_risk2str(ndpi_risk_enum risk) {
case NDPI_SUSPICIOUS_DGA_DOMAIN:
return("Suspicious DGA domain name");
-
+
+ case NDPI_MALFORMED_PACKET:
+ return("Malformed packet");
+
default:
snprintf(buf, sizeof(buf), "%d", (int)risk);
return(buf);
diff --git a/src/lib/protocols/dhcp.c b/src/lib/protocols/dhcp.c
index f40a8138c..5bf2a122c 100644
--- a/src/lib/protocols/dhcp.c
+++ b/src/lib/protocols/dhcp.c
@@ -89,8 +89,10 @@ void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struct, stru
u_int8_t len = ndpi_min(dhcp->options[i+1] /* len as found in the packet */,
dhcp_options_size - (i+2) /* 1 for the type and 1 for the value */);
- if(len == 0) break;
-
+ if(len == 0)
+ break;
+
+
#ifdef DHCP_DEBUG
NDPI_LOG_DBG2(ndpi_struct, "[DHCP] Id=%d [len=%d]\n", id, len);
#endif
@@ -150,8 +152,8 @@ void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struct, stru
}
-void init_dhcp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask)
-{
+void init_dhcp_dissector(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) {
ndpi_set_bitmask_protocol_detection("DHCP", ndpi_struct, detection_bitmask, *id,
NDPI_PROTOCOL_DHCP,
ndpi_search_dhcp_udp,
diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c
index 897fb1e4b..5e6d01d69 100644
--- a/src/lib/protocols/dns.c
+++ b/src/lib/protocols/dns.c
@@ -104,9 +104,11 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct,
/* 0x8000 RESPONSE */
else if((dns_header->flags & FLAGS_MASK) == 0x8000)
*is_query = 0;
- else
+ else {
+ NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET);
return(1 /* invalid */);
-
+ }
+
if(*is_query) {
/* DNS Request */
if((dns_header->num_queries > 0) && (dns_header->num_queries <= NDPI_MAX_DNS_REQUESTS)
@@ -125,16 +127,18 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct,
} else
x++;
}
- } else
+ } else {
+ NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET);
return(1 /* invalid */);
+ }
} else {
/* DNS Reply */
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)))
+ && ((((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 */
@@ -213,8 +217,7 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct,
(s_port == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS,
NDPI_PROTOCOL_UNKNOWN);
}
- } else
- return(1 /* invalid */);
+ }
}
/* Valid */
diff --git a/src/lib/protocols/h323.c b/src/lib/protocols/h323.c
index 13ec9d364..1d70a8cec 100644
--- a/src/lib/protocols/h323.c
+++ b/src/lib/protocols/h323.c
@@ -33,7 +33,7 @@ void ndpi_search_h323(struct ndpi_detection_module_struct *ndpi_struct, struct n
NDPI_LOG_DBG2(ndpi_struct, "calculated dport over tcp\n");
/* H323 */
- if(packet->payload_packet_len >= 4
+ if(packet->payload_packet_len > 4
&& (packet->payload[0] == 0x03)
&& (packet->payload[1] == 0x00)) {
struct tpkt *t = (struct tpkt*)packet->payload;
diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c
index 1d5e88365..8f74d22ad 100644
--- a/src/lib/protocols/http.c
+++ b/src/lib/protocols/http.c
@@ -604,7 +604,9 @@ static u_int16_t http_request_url_offset(struct ndpi_detection_module_struct *nd
packet->payload_packet_len);
/* Check first char */
- if(!packet->payload_packet_len || !strchr(http_fs,packet->payload[0])) return 0;
+ if(!packet->payload_packet_len || !strchr(http_fs,packet->payload[0]))
+ return 0;
+
/**
FIRST PAYLOAD PACKET FROM CLIENT
**/
@@ -813,6 +815,13 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct
return;
}
+ /* try to get some additional request header info even if the packet may not be HTTP */
+ ndpi_parse_packet_line_info(ndpi_struct, flow);
+ if (packet->http_num_headers > 0) {
+ check_content_type_and_change_protocol(ndpi_struct, flow);
+ return;
+ }
+
NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
http_bitmask_exclude_other(flow);
return;
@@ -1021,9 +1030,10 @@ static void ndpi_search_http_tcp(struct ndpi_detection_module_struct *ndpi_struc
ndpi_http_method ndpi_get_http_method(struct ndpi_detection_module_struct *ndpi_mod,
struct ndpi_flow_struct *flow) {
- if(!flow)
+ if(!flow) {
+ NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET);
return(NDPI_HTTP_METHOD_UNKNOWN);
- else
+ } else
return(flow->http.method);
}
diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c
index b2cf1f23c..830232554 100644
--- a/src/lib/protocols/tls.c
+++ b/src/lib/protocols/tls.c
@@ -508,14 +508,18 @@ int processCertificate(struct ndpi_detection_module_struct *ndpi_struct,
packet->payload[3], packet->payload[4], packet->payload[5]);
#endif
- if((packet->payload_packet_len != (length + 4)) || (packet->payload[1] != 0x0))
+ if((packet->payload_packet_len != (length + 4)) || (packet->payload[1] != 0x0)) {
+ NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET);
return(-1); /* Invalid length */
-
+ }
+
certificates_length = (packet->payload[4] << 16) + (packet->payload[5] << 8) + packet->payload[6];
- if((packet->payload[4] != 0x0) || ((certificates_length+3) != length))
+ if((packet->payload[4] != 0x0) || ((certificates_length+3) != length)) {
+ NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET);
return(-2); /* Invalid length */
-
+ }
+
if(!flow->l4.tcp.tls.srv_cert_fingerprint_ctx) {
if((flow->l4.tcp.tls.srv_cert_fingerprint_ctx = (void*)ndpi_malloc(sizeof(SHA1_CTX))) == NULL)
return(-3); /* Not enough memory */
@@ -814,14 +818,14 @@ static void ndpi_int_tls_add_connection(struct ndpi_detection_module_struct *ndp
/* https://engineering.salesforce.com/tls-fingerprinting-with-ja3-and-ja3s-247362855967 */
#define JA3_STR_LEN 1024
-#define MAX_NUM_JA3 128
+#define MAX_NUM_JA3 512
struct ja3_info {
u_int16_t tls_handshake_version;
u_int16_t num_cipher, cipher[MAX_NUM_JA3];
u_int16_t num_tls_extension, tls_extension[MAX_NUM_JA3];
u_int16_t num_elliptic_curve, elliptic_curve[MAX_NUM_JA3];
- u_int8_t num_elliptic_curve_point_format, elliptic_curve_point_format[MAX_NUM_JA3];
+ u_int16_t num_elliptic_curve_point_format, elliptic_curve_point_format[MAX_NUM_JA3];
};
/* **************************************** */
@@ -1294,7 +1298,8 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
e_sni_len = ntohs(*((u_int16_t*)&packet->payload[e_offset]));
e_offset += 2;
- if((e_offset+e_sni_len-extension_len-initial_offset) >= 0) {
+ if((e_offset+e_sni_len-extension_len-initial_offset) >= 0 &&
+ e_offset+e_sni_len < packet->payload_packet_len) {
#ifdef DEBUG_ENCRYPTED_SNI
printf("Client SSL [Encrypted Server Name len: %u]\n", e_sni_len);
#endif
diff --git a/src/lib/third_party/include/ndpi_patricia.h b/src/lib/third_party/include/ndpi_patricia.h
index 6823c3112..b53253d95 100644
--- a/src/lib/third_party/include/ndpi_patricia.h
+++ b/src/lib/third_party/include/ndpi_patricia.h
@@ -107,7 +107,7 @@ union patricia_node_value_t {
/* User-defined values */
struct {
- u_int16_t user_value, additional_user_value;
+ u_int32_t user_value, additional_user_value;
} uv;
};