aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--example/ndpiReader.c45
-rw-r--r--fuzz/fuzz_config.cpp5
-rw-r--r--src/include/ndpi_api.h5
-rw-r--r--src/include/ndpi_typedefs.h17
-rw-r--r--src/lib/ndpi_main.c56
-rw-r--r--src/lib/protocols/http.c60
-rw-r--r--src/lib/protocols/ookla.c167
-rw-r--r--src/lib/protocols/tls.c25
-rw-r--r--tests/pcap/ookla.pcapbin7485 -> 42424 bytes
-rw-r--r--tests/result/alexa-app.pcapng.out2
-rw-r--r--tests/result/ookla.pcap.out46
-rw-r--r--tests/result/skype.pcap.out2
-rw-r--r--tests/result/skype_no_unknown.pcap.out2
-rw-r--r--tests/result/synscan.pcap.out2
14 files changed, 258 insertions, 176 deletions
diff --git a/example/ndpiReader.c b/example/ndpiReader.c
index 02cb7364b..452c0f5ae 100644
--- a/example/ndpiReader.c
+++ b/example/ndpiReader.c
@@ -96,6 +96,7 @@ u_int8_t verbose = 0, enable_flow_stats = 0;
int nDPI_LogLevel = 0;
char *_debug_protocols = NULL;
char *_disabled_protocols = NULL;
+int aggressiveness[NDPI_MAX_SUPPORTED_PROTOCOLS];
static u_int8_t stats_flag = 0;
ndpi_init_prefs init_prefs = ndpi_no_prefs;
u_int8_t human_readeable_string_len = 5;
@@ -515,6 +516,7 @@ static void help(u_int long_help) {
" -z | Enable JA3+\n"
" -A | Dump internal statistics (LRU caches / Patricia trees / Ahocarasick automas / ...\n"
" -M | Memory allocation stats on data-path (only by the library). It works only on single-thread configuration\n"
+ " -Z proto:value | Set this value of aggressiveness for this protocol (0 to disable it). This flag can be used multiple times\n"
,
human_readeable_string_len,
min_pattern_len, max_pattern_len, max_num_packets_per_flow, max_packet_payload_dissection,
@@ -797,7 +799,7 @@ void printCSVHeader() {
*/
static void parseOptions(int argc, char **argv) {
int option_idx = 0;
- int opt;
+ int opt, i;
#ifndef USE_DPDK
char *__pcap_file = NULL;
int thread_id, do_capture = 0;
@@ -818,7 +820,10 @@ static void parseOptions(int argc, char **argv) {
}
#endif
- while((opt = getopt_long(argc, argv, "a:Ab:B:e:Ec:C:dDf:g:i:Ij:k:K:S:hHp:pP:l:r:s:tu:v:V:n:rp:x:w:zq0123:456:7:89:m:MT:U:",
+ for(i = 0; i < NDPI_MAX_SUPPORTED_PROTOCOLS; i++)
+ aggressiveness[i] = -1; /* Use the default value */
+
+ while((opt = getopt_long(argc, argv, "a:Ab:B:e:Ec:C:dDf:g:i:Ij:k:K:S:hHp:pP:l:r:s:tu:v:V:n:rp:x:w:zZ:q0123:456:7:89:m:MT:U:",
longopts, &option_idx)) != EOF) {
#ifdef DEBUG_TRACE
if(trace) fprintf(trace, " #### Handling option -%c [%s] #### \n", opt, optarg ? optarg : "");
@@ -950,6 +955,35 @@ static void parseOptions(int argc, char **argv) {
_disabled_protocols = ndpi_strdup(optarg);
break;
+ case 'Z': /* proto_name:aggr_value */
+ {
+ struct ndpi_detection_module_struct *module_tmp;
+ NDPI_PROTOCOL_BITMASK all;
+ char *saveptr, *tmp_str, *proto_str, *aggr_str;
+
+ /* Use a temporary module with all protocols enabled */
+ module_tmp = ndpi_init_detection_module(0);
+ if(!module_tmp)
+ break;
+ NDPI_BITMASK_SET_ALL(all);
+ ndpi_set_protocol_detection_bitmask2(module_tmp, &all);
+ ndpi_finalize_initialization(module_tmp);
+
+ tmp_str = ndpi_strdup(optarg);
+ if(tmp_str) {
+ proto_str = strtok_r(tmp_str, ":", &saveptr);
+ if(proto_str) {
+ aggr_str = strtok_r(NULL, ":", &saveptr);
+ if(aggr_str) {
+ aggressiveness[ndpi_get_protocol_id(module_tmp, proto_str)] = atoi(aggr_str);
+ }
+ }
+ }
+ ndpi_free(tmp_str);
+ ndpi_exit_detection_module(module_tmp);
+ break;
+ }
+
case 'h':
help(0);
break;
@@ -2413,6 +2447,7 @@ static void debug_printf(u_int32_t protocol, void *id_struct,
static void setupDetection(u_int16_t thread_id, pcap_t * pcap_handle) {
NDPI_PROTOCOL_BITMASK enabled_bitmask;
struct ndpi_workflow_prefs prefs;
+ int i;
memset(&prefs, 0, sizeof(prefs));
prefs.decode_tunnels = decode_tunnels;
@@ -2472,6 +2507,12 @@ static void setupDetection(u_int16_t thread_id, pcap_t * pcap_handle) {
NDPI_LRUCACHE_BITTORRENT, 32768);
/* Enable/disable LRU caches TTL here */
+ /* Set aggressiviness here */
+ for(i = 0; i < NDPI_MAX_SUPPORTED_PROTOCOLS; i++) {
+ if(aggressiveness[i] != -1)
+ ndpi_set_protocol_aggressiveness(ndpi_thread_info[thread_id].workflow->ndpi_struct, i, aggressiveness[i]);
+ }
+
ndpi_finalize_initialization(ndpi_thread_info[thread_id].workflow->ndpi_struct);
if(enable_doh_dot_detection)
diff --git a/fuzz/fuzz_config.cpp b/fuzz/fuzz_config.cpp
index de1bdd3e8..2e0a27ff4 100644
--- a/fuzz/fuzz_config.cpp
+++ b/fuzz/fuzz_config.cpp
@@ -108,6 +108,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
ndpi_set_opportunistic_tls(ndpi_info_mod, random_proto, random_value);
ndpi_get_opportunistic_tls(ndpi_info_mod, random_proto);
+ for(i = 0; i < NDPI_MAX_SUPPORTED_PROTOCOLS; i++) {
+ ndpi_set_protocol_aggressiveness(ndpi_info_mod, i, random_value);
+ ndpi_get_protocol_aggressiveness(ndpi_info_mod, i);
+ }
+
ndpi_finalize_initialization(ndpi_info_mod);
/* Random protocol configuration */
diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h
index d1875b5d8..d3b02a4d5 100644
--- a/src/include/ndpi_api.h
+++ b/src/include/ndpi_api.h
@@ -1031,6 +1031,11 @@ extern "C" {
int ndpi_get_opportunistic_tls(struct ndpi_detection_module_struct *ndpi_struct,
u_int16_t proto);
+ int ndpi_set_protocol_aggressiveness(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int16_t proto, u_int32_t value);
+ u_int32_t ndpi_get_protocol_aggressiveness(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int16_t proto);
+
/**
* Find a protocol id associated with a string automata
*
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h
index 6d560ef36..a5b1175bc 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -659,6 +659,14 @@ struct ndpi_lru_cache {
struct ndpi_lru_cache_entry *entries;
};
+
+/* Aggressiveness values */
+
+#define NDPI_AGGRESSIVENESS_DISABLED 0x00 /* For all protocols */
+
+/* Ookla */
+#define NDPI_AGGRESSIVENESS_OOKLA_TLS 0x01 /* Enable detection over TLS (using ookla cache) */
+
/* ************************************************** */
struct ndpi_flow_tcp_struct {
@@ -920,7 +928,8 @@ typedef enum {
NDPI_CONFIDENCE_DPI_CACHE, /* Classification results based on some LRU cache (i.e. correlation among sessions) */
NDPI_CONFIDENCE_DPI, /* Deep packet inspection */
NDPI_CONFIDENCE_MATCH_BY_IP, /* Classification obtained looking only at the IP addresses */
-
+ NDPI_CONFIDENCE_DPI_AGGRESSIVE, /* Aggressive DPI: it might be a false positive */
+
/*
IMPORTANT
@@ -1229,6 +1238,8 @@ struct ndpi_detection_module_struct {
int opportunistic_tls_pop_enabled;
int opportunistic_tls_ftp_enabled;
+ u_int32_t aggressiveness_ookla;
+
u_int16_t ndpi_to_user_proto_id[NDPI_MAX_NUM_CUSTOM_PROTOCOLS]; /* custom protocolId mapping */
ndpi_proto_defaults_t proto_defaults[NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS];
@@ -1563,6 +1574,10 @@ struct ndpi_flow_struct {
/* NDPI_PROTOCOL_Z3950 */
u_int8_t z3950_stage : 2; // 0-3
+ /* NDPI_PROTOCOL_OOKLA */
+ u_int8_t ookla_stage : 1;
+
+
/* NDPI_PROTOCOL_OPENVPN */
u_int8_t ovpn_session_id[8];
u_int8_t ovpn_counter;
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index f4266d87d..dc5834549 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -198,6 +198,10 @@ extern void ndpi_unset_risk(struct ndpi_detection_module_struct *ndpi_str,
struct ndpi_flow_struct *flow, ndpi_risk_enum r);
extern u_int32_t make_mining_key(struct ndpi_flow_struct *flow);
extern int stun_search_into_zoom_cache(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
+extern void ookla_add_to_cache(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow);
+extern int ookla_search_into_cache(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow);
/* Forward */
static int addDefaultPort(struct ndpi_detection_module_struct *ndpi_str,
@@ -2932,7 +2936,7 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(ndpi_init_prefs
ndpi_str->msteams_cache_num_entries = 1024;
ndpi_str->stun_zoom_cache_num_entries = 1024;
- ndpi_str->ookla_cache_ttl = 0;
+ ndpi_str->ookla_cache_ttl = 120; /* sec */
ndpi_str->bittorrent_cache_ttl = 0;
ndpi_str->zoom_cache_ttl = 0;
ndpi_str->stun_cache_ttl = 0;
@@ -2946,6 +2950,8 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(ndpi_init_prefs
ndpi_str->opportunistic_tls_pop_enabled = 1;
ndpi_str->opportunistic_tls_ftp_enabled = 1;
+ ndpi_str->aggressiveness_ookla = NDPI_AGGRESSIVENESS_OOKLA_TLS;
+
for(i = 0; i < NUM_CUSTOM_CATEGORIES; i++)
ndpi_snprintf(ndpi_str->custom_category_labels[i], CUSTOM_CATEGORY_LABEL_LEN, "User custom category %u",
(unsigned int) (i + 1));
@@ -6254,6 +6260,13 @@ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_st
ret.app_protocol = flow->detected_protocol_stack[0];
}
+ /* Does it looks like Ookla? */
+ if(ret.app_protocol == NDPI_PROTOCOL_UNKNOWN &&
+ ntohs(flow->s_port) == 8080 && ookla_search_into_cache(ndpi_str, flow)) {
+ ndpi_set_detected_protocol(ndpi_str, flow, NDPI_PROTOCOL_OOKLA, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI_PARTIAL_CACHE);
+ ret.app_protocol = flow->detected_protocol_stack[0];
+ }
+
/* Classification by-port is the last resort */
if(enable_guess && ret.app_protocol == NDPI_PROTOCOL_UNKNOWN) {
@@ -8052,6 +8065,9 @@ const char *ndpi_confidence_get_name(ndpi_confidence_t confidence)
case NDPI_CONFIDENCE_MATCH_BY_IP:
return "Match by IP";
+ case NDPI_CONFIDENCE_DPI_AGGRESSIVE:
+ return "DPI (aggressive)";
+
default:
return NULL;
}
@@ -8572,6 +8588,11 @@ int ndpi_match_hostname_protocol(struct ndpi_detection_module_struct *ndpi_struc
ndpi_set_detected_protocol(ndpi_struct, flow, subproto, master_protocol, NDPI_CONFIDENCE_DPI);
if(!category_depends_on_master(master_protocol))
ndpi_int_change_category(ndpi_struct, flow, ret_match.protocol_category);
+
+ if(subproto == NDPI_PROTOCOL_OOKLA) {
+ ookla_add_to_cache(ndpi_struct, flow);
+ }
+
return(1);
} else
return(0);
@@ -9643,3 +9664,36 @@ int ndpi_get_opportunistic_tls(struct ndpi_detection_module_struct *ndpi_struct,
return -1;
}
}
+
+/* ******************************************************************** */
+
+int ndpi_set_protocol_aggressiveness(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int16_t proto, u_int32_t value)
+{
+ if(!ndpi_struct)
+ return -1;
+
+ switch(proto) {
+ case NDPI_PROTOCOL_OOKLA:
+ ndpi_struct->aggressiveness_ookla = value;
+ return 0;
+ default:
+ return -1;
+ }
+}
+
+/* ******************************************************************** */
+
+u_int32_t ndpi_get_protocol_aggressiveness(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int16_t proto)
+{
+ if(!ndpi_struct)
+ return -1;
+
+ switch(proto) {
+ case NDPI_PROTOCOL_OOKLA:
+ return ndpi_struct->aggressiveness_ookla;
+ default:
+ return -1;
+ }
+}
diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c
index e0f56c4e8..4f139b8d3 100644
--- a/src/lib/protocols/http.c
+++ b/src/lib/protocols/http.c
@@ -46,6 +46,9 @@ static const char* binary_file_ext[] = {
NULL
};
+extern void ookla_add_to_cache(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow);
+
static void ndpi_search_http_tcp(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow);
@@ -436,6 +439,7 @@ static void ndpi_http_parse_subprotocol(struct ndpi_detection_module_struct *ndp
|| (strstr(flow->http.url, ":8080/upload?n=0.") != NULL))) {
/* This looks like Ookla speedtest */
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OOKLA, master_protocol, NDPI_CONFIDENCE_DPI);
+ ookla_add_to_cache(ndpi_struct, flow);
}
}
@@ -1217,30 +1221,6 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct
return;
}
- if((packet->payload_packet_len == 3) && memcmp(packet->payload, "HI\n", 3) == 0) {
- /* This looks like Ookla: we don't give up with HTTP yet */
- flow->l4.tcp.http_stage = 1;
- return;
- }
-
- if((packet->payload_packet_len == 40) && (flow->l4.tcp.http_stage == 0)) {
- /*
- -> QR O06L0072-6L91-4O43-857J-K8OO172L6L51
- <- QNUUX 2.5 2017-08-15.1314.4jn12m5
- -> MXFWUXJM 31625365
- */
-
- if((packet->payload[2] == ' ')
- && (packet->payload[11] == '-')
- && (packet->payload[16] == '-')
- && (packet->payload[21] == '-')
- && (packet->payload[26] == '-')
- && (packet->payload[39] == 0x0A)
- )
- flow->l4.tcp.http_stage = 1;
- return;
- }
-
if((packet->payload_packet_len == 23) && (memcmp(packet->payload, "<policy-file-request/>", 23) == 0)) {
/*
<policy-file-request/>
@@ -1251,25 +1231,7 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct
*/
ookla_found:
ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OOKLA, NDPI_PROTOCOL_CATEGORY_WEB);
-
- if(ndpi_struct->ookla_cache != NULL) {
- if(packet->iph != NULL) {
- if(packet->tcp->source == htons(8080))
- ndpi_lru_add_to_cache(ndpi_struct->ookla_cache, packet->iph->saddr, 1 /* dummy */, ndpi_get_current_time(flow));
- else
- ndpi_lru_add_to_cache(ndpi_struct->ookla_cache, packet->iph->daddr, 1 /* dummy */, ndpi_get_current_time(flow));
- } else if(packet->iphv6 != NULL) {
- u_int32_t h;
-
- if(packet->tcp->source == htons(8080))
- h = ndpi_quick_hash((unsigned char *)&packet->iphv6->ip6_src, sizeof(packet->iphv6->ip6_src));
- else
- h = ndpi_quick_hash((unsigned char *)&packet->iphv6->ip6_dst, sizeof(packet->iphv6->ip6_dst));
-
- ndpi_lru_add_to_cache(ndpi_struct->ookla_cache, h, 1 /* dummy */, ndpi_get_current_time(flow));
- }
- }
-
+ ookla_add_to_cache(ndpi_struct, flow);
return;
}
@@ -1389,18 +1351,6 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct
} else if((flow->l4.tcp.http_stage == 1) || (flow->l4.tcp.http_stage == 2)) {
NDPI_LOG_DBG2(ndpi_struct, "HTTP stage %u: \n", flow->l4.tcp.http_stage);
- if((packet->payload_packet_len == 34) && (flow->l4.tcp.http_stage == 1)) {
- if((packet->payload[5] == ' ') && (packet->payload[9] == ' ')) {
- goto ookla_found;
- }
- }
-
- if((packet->payload_packet_len > 6) && memcmp(packet->payload, "HELLO ", 6) == 0) {
- /* This looks like Ookla */
- goto ookla_found;
- } else
- NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OOKLA);
-
/**
At first check, if this is for sure a response packet
(in another direction. If not, if HTTP is detected do nothing now and return,
diff --git a/src/lib/protocols/ookla.c b/src/lib/protocols/ookla.c
index 0da42212c..d7764e630 100644
--- a/src/lib/protocols/ookla.c
+++ b/src/lib/protocols/ookla.c
@@ -23,111 +23,92 @@
#include "ndpi_api.h"
+/* #define DEBUG_OOKLA_LRU */
+
const u_int16_t ookla_port = 8080;
/* ************************************************************* */
-static void ndpi_search_ookla(struct ndpi_detection_module_struct* ndpi_struct, struct ndpi_flow_struct* flow) {
- struct ndpi_packet_struct* packet = &ndpi_struct->packet;
- u_int32_t addr = 0;
- u_int16_t sport, dport;
-
- NDPI_LOG_DBG(ndpi_struct, "Ookla detection\n");
-
- if(packet->tcp)
- sport = ntohs(packet->tcp->source), dport = htons(packet->tcp->dest);
+static u_int32_t get_ookla_key(struct ndpi_flow_struct *flow)
+{
+ if(flow->is_ipv6)
+ return ndpi_quick_hash(flow->c_address.v6, 16);
else
- sport = ntohs(packet->udp->source), dport = htons(packet->udp->dest);
+ return ntohl(flow->c_address.v4);
+}
- if((sport != ookla_port) && (dport != ookla_port)) {
-#ifdef OOKLA_DEBUG
- printf("=>>>>>>>> [OOKLA IPv6] Skipping flow [%u -> %u]\n", sport, dport);
-#endif
- goto ookla_exclude;
- }
-
- if(packet->iphv6 != NULL) {
- if((dport == ookla_port) && (packet->payload_packet_len >= 3)) {
- u_int32_t h;
-
- if((packet->payload_packet_len == 3)
- && (packet->payload[0] == 0x48) /* HI\n */
- && (packet->payload[1] == 0x49)
- && (packet->payload[2] == 0x0A)) {
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OOKLA, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
-
- if(ndpi_struct->ookla_cache != NULL) {
- /* In order to avoid creating an IPv6 LRU we hash the IPv6 address */
- h = ndpi_quick_hash((unsigned char *)&packet->iphv6->ip6_dst, sizeof(packet->iphv6->ip6_dst));
-
-#ifdef OOKLA_DEBUG
- printf("=>>>>>>>> [OOKLA IPv6] Adding %u\n", h);
-#endif
- ndpi_lru_add_to_cache(ndpi_struct->ookla_cache, h, 1 /* dummy */, ndpi_get_current_time(flow));
- }
- return;
- } else {
- if(sport == ookla_port)
- h = ndpi_quick_hash((unsigned char *)&packet->iphv6->ip6_src, sizeof(packet->iphv6->ip6_src));
- else
- h = ndpi_quick_hash((unsigned char *)&packet->iphv6->ip6_dst, sizeof(packet->iphv6->ip6_dst));
-
- if(ndpi_struct->ookla_cache != NULL) {
- u_int16_t dummy;
-
-#ifdef OOKLA_DEBUG
- printf("=>>>>>>>> [OOKLA IPv6] Searching %u\n", h);
-#endif
-
- if(ndpi_lru_find_cache(ndpi_struct->ookla_cache, h, &dummy, 0 /* Don't remove it as it can be used for other connections */,
- ndpi_get_current_time(flow))) {
- NDPI_LOG_INFO(ndpi_struct, "found ookla tcp connection\n");
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OOKLA, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI_CACHE);
-#ifdef OOKLA_DEBUG
- printf("=>>>>> Found %u\n", h);
-#endif
- return;
- } else {
-#ifdef OOKLA_DEBUG
- printf("=>>>>> NOT Found %u\n", h);
-#endif
- }
- }
- }
- } else {
+/* ************************************************************* */
- goto ookla_exclude;
- }
- } else {
- if(sport == ookla_port)
- addr = packet->iph->saddr;
- else
- addr = packet->iph->daddr;
-
-#ifdef OOKLA_DEBUG
- printf("=>>>>>>>> [OOKLA IPv4] Searching %u\n", addr);
-#endif
-
- if(ndpi_struct->ookla_cache != NULL) {
- u_int16_t dummy;
-
- if(ndpi_lru_find_cache(ndpi_struct->ookla_cache, addr, &dummy, 0 /* Don't remove it as it can be used for other connections */,
- ndpi_get_current_time(flow))) {
- NDPI_LOG_INFO(ndpi_struct, "found ookla tcp connection\n");
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OOKLA, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI_CACHE);
-#ifdef OOKLA_DEBUG
- printf("=>>>>> Found %u\n", addr);
+int ookla_search_into_cache(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ u_int32_t key;
+ u_int16_t dummy;
+
+ if(ndpi_struct->ookla_cache) {
+ key = get_ookla_key(flow);
+#ifdef DEBUG_OOKLA_LRU
+ printf("[LRU OOKLA] Search %u\n", key);
#endif
- return;
- } else {
-#ifdef OOKLA_DEBUG
- printf("=>>>>> NOT Found %u\n", addr);
+
+ if(ndpi_lru_find_cache(ndpi_struct->ookla_cache, key,
+ &dummy, 0 /* Don't remove it as it can be used for other connections */,
+ ndpi_get_current_time(flow))) {
+#ifdef DEBUG_OOKLA_LRU
+ printf("[LRU OOKLA] Found\n");
#endif
- }
+ return 1;
}
}
+ return 0;
+}
+
+/* ************************************************************* */
+
+void ookla_add_to_cache(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ u_int32_t key;
+
+ if(ndpi_struct->ookla_cache) {
+ key = get_ookla_key(flow);
+#ifdef DEBUG_OOKLA_LRU
+ printf("[LRU OOKLA] ADDING %u\n", key);
+#endif
+ ndpi_lru_add_to_cache(ndpi_struct->ookla_cache, key, 1 /* dummy */,
+ ndpi_get_current_time(flow));
+ }
+
+}
+
+/* ************************************************************* */
+
+void ndpi_search_ookla(struct ndpi_detection_module_struct* ndpi_struct, struct ndpi_flow_struct* flow) {
+ struct ndpi_packet_struct *packet = &ndpi_struct->packet;
+
+ NDPI_LOG_DBG(ndpi_struct, "Ookla detection\n");
+
+ if(ntohs(flow->s_port) != ookla_port && ntohs(flow->c_port) != ookla_port) {
+ NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ return;
+ }
+
+ if(flow->packet_counter == 1 &&
+ packet->payload_packet_len >= NDPI_STATICSTRING_LEN("HI") &&
+ memcmp(packet->payload, "HI", NDPI_STATICSTRING_LEN("HI")) == 0) {
+ flow->ookla_stage = 1;
+ return;
+ }
+ if(flow->packet_counter == 2 &&
+ flow->ookla_stage == 1 &&
+ packet->payload_packet_len >= NDPI_STATICSTRING_LEN("HELLO") &&
+ memcmp(packet->payload, "HELLO", NDPI_STATICSTRING_LEN("HELLO")) == 0) {
+ NDPI_LOG_INFO(ndpi_struct, "found ookla (Hi + Hello)\n");
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OOKLA, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
+ ookla_add_to_cache(ndpi_struct, flow);
+ return;
+ }
- ookla_exclude:
NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
}
diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c
index 8e3fbedb8..58b19d0d5 100644
--- a/src/lib/protocols/tls.c
+++ b/src/lib/protocols/tls.c
@@ -33,6 +33,8 @@ extern int processClientServerHello(struct ndpi_detection_module_struct *ndpi_st
extern int http_process_user_agent(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
const u_int8_t *ua_ptr, u_int16_t ua_ptr_len);
+extern int ookla_search_into_cache(struct ndpi_detection_module_struct* ndpi_struct,
+ struct ndpi_flow_struct* flow);
/* QUIC/GQUIC stuff */
extern int quic_len(const uint8_t *buf, uint64_t *value);
extern int quic_len_buffer_still_required(uint8_t value);
@@ -1153,8 +1155,27 @@ static int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct,
#ifdef DEBUG_TLS_BLOCKS
printf("*** [TLS Block] No more blocks\n");
#endif
- flow->extra_packets_func = NULL;
- return(0); /* That's all */
+ /* An ookla flow? */
+ if((ndpi_struct->aggressiveness_ookla & NDPI_AGGRESSIVENESS_OOKLA_TLS) && /* Feature enabled */
+ (!something_went_wrong &&
+ flow->tls_quic.certificate_processed == 1 &&
+ flow->protos.tls_quic.hello_processed == 1) && /* TLS handshake found without errors */
+ flow->detected_protocol_stack[0] == NDPI_PROTOCOL_TLS && /* No IMAPS/FTPS/... */
+ flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN && /* No sub-classification */
+ ntohs(flow->s_port) == 8080 && /* Ookla port */
+ ookla_search_into_cache(ndpi_struct, flow)) {
+ NDPI_LOG_INFO(ndpi_struct, "found ookla (cache over TLS)\n");
+ /* Even if a LRU cache is involved, NDPI_CONFIDENCE_DPI_AGGRESSIVE seems more
+ suited than NDPI_CONFIDENCE_DPI_CACHE */
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OOKLA, NDPI_PROTOCOL_TLS, NDPI_CONFIDENCE_DPI_AGGRESSIVE);
+ /* TLS over port 8080 usually triggers that risk; clear it */
+ ndpi_unset_risk(ndpi_struct, flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT);
+ flow->extra_packets_func = NULL;
+ return(0); /* That's all */
+ } else {
+ flow->extra_packets_func = NULL;
+ return(0); /* That's all */
+ }
} else
return(1);
}
diff --git a/tests/pcap/ookla.pcap b/tests/pcap/ookla.pcap
index 80123e856..ac57c6d17 100644
--- a/tests/pcap/ookla.pcap
+++ b/tests/pcap/ookla.pcap
Binary files differ
diff --git a/tests/result/alexa-app.pcapng.out b/tests/result/alexa-app.pcapng.out
index bcfa72705..c7dc0f77a 100644
--- a/tests/result/alexa-app.pcapng.out
+++ b/tests/result/alexa-app.pcapng.out
@@ -7,7 +7,7 @@ Confidence Match by port : 5 (flows)
Confidence DPI (partial) : 9 (flows)
Confidence DPI : 146 (flows)
Num dissector calls: 473 (2.96 diss/flow)
-LRU cache ookla: 0/0/0 (insert/search/found)
+LRU cache ookla: 0/5/0 (insert/search/found)
LRU cache bittorrent: 0/42/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
LRU cache stun: 0/0/0 (insert/search/found)
diff --git a/tests/result/ookla.pcap.out b/tests/result/ookla.pcap.out
index 5923011c1..98af01625 100644
--- a/tests/result/ookla.pcap.out
+++ b/tests/result/ookla.pcap.out
@@ -1,27 +1,37 @@
-Guessed flow protos: 0
+Guessed flow protos: 1
-DPI Packets (TCP): 16 (8.00 pkts/flow)
-Confidence DPI (cache) : 1 (flows)
-Confidence DPI : 1 (flows)
-Num dissector calls: 97 (48.50 diss/flow)
-LRU cache ookla: 3/1/1 (insert/search/found)
-LRU cache bittorrent: 0/0/0 (insert/search/found)
+DPI Packets (TCP): 46 (7.67 pkts/flow)
+Confidence DPI (partial cache): 1 (flows)
+Confidence DPI : 4 (flows)
+Confidence DPI (aggressive) : 1 (flows)
+Num dissector calls: 488 (81.33 diss/flow)
+LRU cache ookla: 6/2/2 (insert/search/found)
+LRU cache bittorrent: 0/3/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
LRU cache stun: 0/0/0 (insert/search/found)
-LRU cache tls_cert: 0/0/0 (insert/search/found)
-LRU cache mining: 0/0/0 (insert/search/found)
+LRU cache tls_cert: 0/2/0 (insert/search/found)
+LRU cache mining: 0/1/0 (insert/search/found)
LRU cache msteams: 0/0/0 (insert/search/found)
LRU cache stun_zoom: 0/0/0 (insert/search/found)
-Automa host: 0/0 (search/found)
-Automa domain: 0/0 (search/found)
+Automa host: 2/1 (search/found)
+Automa domain: 2/0 (search/found)
Automa tls cert: 0/0 (search/found)
-Automa risk mask: 0/0 (search/found)
-Automa common alpns: 0/0 (search/found)
-Patricia risk mask: 4/0 (search/found)
+Automa risk mask: 1/0 (search/found)
+Automa common alpns: 4/4 (search/found)
+Patricia risk mask: 12/0 (search/found)
Patricia risk: 0/0 (search/found)
-Patricia protocols: 4/0 (search/found)
+Patricia protocols: 11/1 (search/found)
-Ookla 50 6661 2
+Ookla 113 38411 6
- 1 TCP 192.168.1.7:51207 <-> 46.44.253.187:80 [proto: 7.191/HTTP.Ookla][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 12][cat: Network/14][12 pkts/2238 bytes <-> 8 pkts/2082 bytes][Goodput ratio: 64/74][5.33 sec][bytes ratio: 0.036 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 0/4 528/47 5005/84 1493/28][Pkt Len c2s/s2c min/avg/max/stddev: 66/66 186/260 430/523 168/194][Risk: ** HTTP Susp User-Agent **** HTTP Obsolete Server **][Risk Score: 150][Risk Info: Obsolete Apache server 2.2.22 / Empty or missing User-Agent][PLAIN TEXT (GET /crossdomain.xml HTTP/1.1)][Plen Bins: 0,0,0,0,0,0,0,0,0,0,12,75,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
- 2 TCP 192.168.1.7:51215 <-> 46.44.253.187:8080 [proto: 191/Ookla][IP: 0/Unknown][ClearText][Confidence: DPI (cache)][DPI packets: 4][cat: Network/14][19 pkts/1421 bytes <-> 11 pkts/920 bytes][Goodput ratio: 11/20][0.80 sec][bytes ratio: 0.214 (Upload)][IAT c2s/s2c min/avg/max/stddev: 26/0 44/75 103/137 23/41][Pkt Len c2s/s2c min/avg/max/stddev: 66/66 75/84 85/100 9/8][PLAIN TEXT ( 6HELLO 2.4 2016)][Plen Bins: 94,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
+JA3 Host Stats:
+ IP Address # JA3C
+ 1 192.168.1.128 2
+
+
+ 1 TCP 192.168.1.128:35830 <-> 89.96.108.170:8080 [proto: 91.191/TLS.Ookla][IP: 0/Unknown][Encrypted][Confidence: DPI (aggressive)][DPI packets: 6][cat: Web/5][21 pkts/21216 bytes <-> 8 pkts/1950 bytes][Goodput ratio: 93/72][0.32 sec][Hostname/SNI: spd-pub-mi-01-01.fastwebnet.it][(Advertised) ALPNs: h2;http/1.1][TLS Supported Versions: TLSv1.3;TLSv1.2][bytes ratio: 0.832 (Upload)][IAT c2s/s2c min/avg/max/stddev: 0/0 17/61 274/280 62/109][Pkt Len c2s/s2c min/avg/max/stddev: 66/66 1010/244 1514/387 612/138][TLSv1.3][JA3C: c279b0189edb9269da7bc43dea5e0c36][JA3S: fcb2d4d0991292272fcb1e464eedfd43][Firefox][Cipher: TLS_AES_128_GCM_SHA256][Plen Bins: 0,0,4,0,0,0,0,4,9,0,9,0,0,0,0,0,4,0,0,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,55,0,0]
+ 2 TCP 192.168.1.128:48854 <-> 104.16.209.12:443 [proto: 91.191/TLS.Ookla][IP: 220/Cloudflare][Encrypted][Confidence: DPI][DPI packets: 6][cat: Network/14][8 pkts/1620 bytes <-> 6 pkts/3818 bytes][Goodput ratio: 67/89][0.06 sec][Hostname/SNI: www.speedtest.net][(Advertised) ALPNs: h2;http/1.1][TLS Supported Versions: TLSv1.3;TLSv1.2][bytes ratio: -0.404 (Download)][IAT c2s/s2c min/avg/max/stddev: 0/0 7/5 18/15 7/6][Pkt Len c2s/s2c min/avg/max/stddev: 66/66 202/636 583/1514 181/646][TLSv1.3][JA3C: 579ccef312d18482fc42e2b822ca2430][JA3S: eb1d94daa7e0344597e756a1fb6e7054][Firefox][Cipher: TLS_AES_128_GCM_SHA256][PLAIN TEXT (@oTAgOeedtest.net)][Plen Bins: 0,0,14,0,0,14,0,0,0,0,14,0,0,0,0,0,28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,0,0]
+ 3 TCP 192.168.1.7:51207 <-> 46.44.253.187:80 [proto: 7.191/HTTP.Ookla][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 12][cat: Network/14][12 pkts/2238 bytes <-> 8 pkts/2082 bytes][Goodput ratio: 64/74][5.33 sec][bytes ratio: 0.036 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 0/4 528/47 5005/84 1493/28][Pkt Len c2s/s2c min/avg/max/stddev: 66/66 186/260 430/523 168/194][Risk: ** HTTP Susp User-Agent **** HTTP Obsolete Server **][Risk Score: 150][Risk Info: Obsolete Apache server 2.2.22 / Empty or missing User-Agent][PLAIN TEXT (GET /crossdomain.xml HTTP/1.1)][Plen Bins: 0,0,0,0,0,0,0,0,0,0,12,75,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
+ 4 TCP 192.168.1.192:51156 <-> 89.96.108.170:8080 [proto: 191/Ookla][IP: 0/Unknown][ClearText][Confidence: DPI (partial cache)][DPI packets: 10][cat: Network/14][6 pkts/591 bytes <-> 4 pkts/1784 bytes][Goodput ratio: 32/85][0.05 sec][bytes ratio: -0.502 (Download)][IAT c2s/s2c min/avg/max/stddev: 0/0 9/10 15/20 6/8][Pkt Len c2s/s2c min/avg/max/stddev: 66/66 98/446 143/1514 31/617][PLAIN TEXT (gKRZvA)][Plen Bins: 0,40,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,0,0]
+ 5 TCP 192.168.1.7:51215 <-> 46.44.253.187:8080 [proto: 191/Ookla][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 6][cat: Network/14][19 pkts/1421 bytes <-> 11 pkts/920 bytes][Goodput ratio: 11/20][0.80 sec][bytes ratio: 0.214 (Upload)][IAT c2s/s2c min/avg/max/stddev: 26/0 44/75 103/137 23/41][Pkt Len c2s/s2c min/avg/max/stddev: 66/66 75/84 85/100 9/8][PLAIN TEXT ( 6HELLO 2.4 2016)][Plen Bins: 94,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
+ 6 TCP 192.168.1.192:37790 <-> 185.157.229.246:8080 [proto: 191/Ookla][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 6][cat: Network/14][6 pkts/454 bytes <-> 4 pkts/317 bytes][Goodput ratio: 11/14][0.06 sec][bytes ratio: 0.178 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 0/0 12/5 46/9 17/4][Pkt Len c2s/s2c min/avg/max/stddev: 66/66 76/79 106/108 14/17][PLAIN TEXT (HELLO 2.9 )][Plen Bins: 50,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
diff --git a/tests/result/skype.pcap.out b/tests/result/skype.pcap.out
index 5091e3a4e..d26ba706f 100644
--- a/tests/result/skype.pcap.out
+++ b/tests/result/skype.pcap.out
@@ -7,7 +7,7 @@ Confidence Unknown : 59 (flows)
Confidence Match by port : 27 (flows)
Confidence DPI (partial) : 1 (flows)
Confidence DPI : 206 (flows)
-Num dissector calls: 26899 (91.81 diss/flow)
+Num dissector calls: 26897 (91.80 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/261/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
diff --git a/tests/result/skype_no_unknown.pcap.out b/tests/result/skype_no_unknown.pcap.out
index be90096f6..328c50280 100644
--- a/tests/result/skype_no_unknown.pcap.out
+++ b/tests/result/skype_no_unknown.pcap.out
@@ -6,7 +6,7 @@ DPI Packets (other): 5 (1.00 pkts/flow)
Confidence Unknown : 44 (flows)
Confidence Match by port : 22 (flows)
Confidence DPI : 201 (flows)
-Num dissector calls: 22405 (83.91 diss/flow)
+Num dissector calls: 22404 (83.91 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/198/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
diff --git a/tests/result/synscan.pcap.out b/tests/result/synscan.pcap.out
index 9932b97b2..3bdf713b4 100644
--- a/tests/result/synscan.pcap.out
+++ b/tests/result/synscan.pcap.out
@@ -4,7 +4,7 @@ DPI Packets (TCP): 2011 (1.01 pkts/flow)
Confidence Unknown : 1862 (flows)
Confidence Match by port : 132 (flows)
Num dissector calls: 0 (0.00 diss/flow)
-LRU cache ookla: 0/0/0 (insert/search/found)
+LRU cache ookla: 0/2/0 (insert/search/found)
LRU cache bittorrent: 0/5976/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
LRU cache stun: 0/0/0 (insert/search/found)