diff --git a/example/ndpiReader.c b/example/ndpiReader.c index 9f6643b578d2..ff98d8ee321a 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -94,6 +94,16 @@ u_int8_t enable_protocol_guess = 1, enable_payload_analyzer = 0, num_bin_cluster u_int8_t verbose = 0, enable_flow_stats = 0; int stun_monitoring_pkts_to_process = -1; /* Default */ int stun_monitoring_flags = -1; /* Default */ + +struct cfg { + char *proto; + char *param; + char *value; +}; +#define MAX_NUM_CFGS 16 +static struct cfg cfgs[MAX_NUM_CFGS]; +static int num_cfgs = 0; + int nDPI_LogLevel = 0; char *_debug_protocols = NULL; char *_disabled_protocols = NULL; @@ -574,6 +584,7 @@ static void help(u_int long_help) { " --lru-cache-ttl=NAME:size | Specify the TTL [in seconds] for this LRU cache (0 to disable it). This flag can be used multiple times\n" " --stun-monitoring=: | Configure STUN monitoring: keep monitoring STUN session for more pkts looking for RTP\n" " | (0:0 to disable the feature); set the specified features in \n" + " --cfg=proto,param,value | Configure the specific attribute of this protocol\n" , human_readeable_string_len, min_pattern_len, max_pattern_len, max_num_packets_per_flow, max_packet_payload_dissection, @@ -629,6 +640,8 @@ static void help(u_int long_help) { #define OPTLONG_VALUE_STUN_MONITORING 2000 +#define OPTLONG_VALUE_CFG 3000 + static struct option longopts[] = { /* mandatory extcap options */ { "extcap-interfaces", no_argument, NULL, '0'}, @@ -674,6 +687,8 @@ static struct option longopts[] = { { "lru-cache-ttl", required_argument, NULL, OPTLONG_VALUE_LRU_CACHE_TTL}, { "stun-monitoring", required_argument, NULL, OPTLONG_VALUE_STUN_MONITORING}, + { "cfg", required_argument, NULL, OPTLONG_VALUE_CFG}, + {0, 0, 0, 0} }; @@ -930,6 +945,37 @@ static int parse_two_unsigned_integer(char *param, u_int32_t *num1, u_int32_t *n return -1; } +static int parse_three_strings(char *param, char **s1, char **s2, char **s3) +{ + char *saveptr, *tmp_str, *s1_str, *s2_str, *s3_str; + + tmp_str = ndpi_strdup(param); + if(tmp_str) { + s1_str = strtok_r(tmp_str, ",", &saveptr); + if(s1_str) { + s2_str = strtok_r(NULL, ",", &saveptr); + if(s2_str) { + s3_str = strtok_r(NULL, ",", &saveptr); + if(s3_str) { + *s1 = ndpi_strdup(s1_str); + *s2 = ndpi_strdup(s2_str); + *s3 = ndpi_strdup(s3_str); + ndpi_free(tmp_str); + if(!s1 || !s2 || !s3) { + ndpi_free(s1); + ndpi_free(s2); + ndpi_free(s3); + return -1; + } + return 0; + } + } + } + } + ndpi_free(tmp_str); + return -1; +} + /* ********************************** */ /** @@ -948,6 +994,7 @@ static void parseOptions(int argc, char **argv) { #endif int cache_idx, cache_size, cache_ttl; u_int32_t num_pkts, flags; + char *s1, *s2, *s3; #ifdef USE_DPDK { @@ -1268,7 +1315,20 @@ static void parseOptions(int argc, char **argv) { break; case 'z': - init_prefs |= ndpi_enable_ja3_plus; + if(num_cfgs < MAX_NUM_CFGS) { + cfgs[num_cfgs].proto = ndpi_strdup("tls"); + cfgs[num_cfgs].param = ndpi_strdup("ja3_plus.enable"); + cfgs[num_cfgs].value = ndpi_strdup("1"); + if(cfgs[num_cfgs].proto && + cfgs[num_cfgs].param && + cfgs[num_cfgs].value) { + num_cfgs++; + } else { + ndpi_free(cfgs[num_cfgs].proto); + ndpi_free(cfgs[num_cfgs].param); + ndpi_free(cfgs[num_cfgs].value); + } + } break; case OPTLONG_VALUE_LRU_CACHE_SIZE: @@ -1296,6 +1356,18 @@ static void parseOptions(int argc, char **argv) { stun_monitoring_flags = flags; break; + case OPTLONG_VALUE_CFG: + if(num_cfgs >= MAX_NUM_CFGS || + parse_three_strings(optarg, &s1, &s2, &s3) == -1) { + printf("Invalid parameter [%s] [num:%d/%d]\n", optarg, num_cfgs, MAX_NUM_CFGS); + exit(1); + } + cfgs[num_cfgs].proto = s1; + cfgs[num_cfgs].param = s2; + cfgs[num_cfgs].value = s3; + num_cfgs++; + break; + default: #ifdef DEBUG_TRACE if(trace) fprintf(trace, " #### Unknown option -%c: skipping it #### \n", opt); @@ -2635,7 +2707,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; + int i, rc; memset(&prefs, 0, sizeof(prefs)); prefs.decode_tunnels = decode_tunnels; @@ -2714,6 +2786,14 @@ static void setupDetection(u_int16_t thread_id, pcap_t * pcap_handle) { ndpi_set_protocol_aggressiveness(ndpi_thread_info[thread_id].workflow->ndpi_struct, i, aggressiveness[i]); } + for(i = 0; i < num_cfgs; i++) { + rc = ndpi_set_config(ndpi_thread_info[thread_id].workflow->ndpi_struct, + cfgs[i].proto, cfgs[i].param, cfgs[i].value); + if (rc != 0) + fprintf(stderr, "Error setting config [%s][%s][%s]: %d\n", + cfgs[i].proto, cfgs[i].param, cfgs[i].value, rc); + } + if(stun_monitoring_pkts_to_process != -1 && stun_monitoring_flags != -1) ndpi_set_monitoring_state(ndpi_thread_info[thread_id].workflow->ndpi_struct, NDPI_PROTOCOL_STUN, @@ -5633,6 +5713,12 @@ int main(int argc, char **argv) { ndpi_free(_debug_protocols); ndpi_free(_disabled_protocols); + for(i = 0; i < num_cfgs; i++) { + ndpi_free(cfgs[i].proto); + ndpi_free(cfgs[i].param); + ndpi_free(cfgs[i].value); + } + #ifdef DEBUG_TRACE if(trace) fclose(trace); #endif diff --git a/fuzz/fuzz_common_code.c b/fuzz/fuzz_common_code.c index bc4d32155405..b99390fae02d 100644 --- a/fuzz/fuzz_common_code.c +++ b/fuzz/fuzz_common_code.c @@ -36,7 +36,7 @@ void fuzz_set_alloc_callbacks_and_seed(int seed) void fuzz_init_detection_module(struct ndpi_detection_module_struct **ndpi_info_mod) { - ndpi_init_prefs prefs = ndpi_enable_ja3_plus; + ndpi_init_prefs prefs = 0; NDPI_PROTOCOL_BITMASK all; NDPI_PROTOCOL_BITMASK debug_bitmask; diff --git a/fuzz/fuzz_config.cpp b/fuzz/fuzz_config.cpp index c5ee020428f1..70ddf89b0157 100644 --- a/fuzz/fuzz_config.cpp +++ b/fuzz/fuzz_config.cpp @@ -37,6 +37,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { 2 + 1 + 4 + /* ndpi_set_detection_preferences() */ 1 + 3 + 1 + 3 + /* Monitoring */ 7 + /* Opportunistic tls */ + 2 * 21 + /* Cfgs */ 2 + /* Pid */ 2 + /* Category */ 1 + /* Tunnel */ @@ -138,6 +139,51 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ndpi_get_protocol_aggressiveness(ndpi_info_mod, i); } + /* Cfgs */ + if(fuzzed_data.ConsumeBool()) + ndpi_set_config(ndpi_info_mod, "amazonaws", "ip_list.load", std::to_string(fuzzed_data.ConsumeIntegralInRange(0,2)).c_str()); + if(fuzzed_data.ConsumeBool()) + ndpi_set_config(ndpi_info_mod, "azure", "ip_list.load", std::to_string(fuzzed_data.ConsumeIntegralInRange(0,2)).c_str()); + if(fuzzed_data.ConsumeBool()) + ndpi_set_config(ndpi_info_mod, "cachefly", "ip_list.load", std::to_string(fuzzed_data.ConsumeIntegralInRange(0,2)).c_str()); + if(fuzzed_data.ConsumeBool()) + ndpi_set_config(ndpi_info_mod, "cloudflare", "ip_list.load", std::to_string(fuzzed_data.ConsumeIntegralInRange(0,2)).c_str()); + if(fuzzed_data.ConsumeBool()) + ndpi_set_config(ndpi_info_mod, "gambling", "domain_list.load", std::to_string(fuzzed_data.ConsumeIntegralInRange(0,2)).c_str()); + if(fuzzed_data.ConsumeBool()) + ndpi_set_config(ndpi_info_mod, "google", "ip_list.load", std::to_string(fuzzed_data.ConsumeIntegralInRange(0,2)).c_str()); + if(fuzzed_data.ConsumeBool()) + ndpi_set_config(ndpi_info_mod, "googlecloud", "ip_list.load", std::to_string(fuzzed_data.ConsumeIntegralInRange(0,2)).c_str()); + if(fuzzed_data.ConsumeBool()) + ndpi_set_config(ndpi_info_mod, "microsoft", "ip_list.load", std::to_string(fuzzed_data.ConsumeIntegralInRange(0,2)).c_str()); + if(fuzzed_data.ConsumeBool()) + ndpi_set_config(ndpi_info_mod, "mining", "ip_list.load", std::to_string(fuzzed_data.ConsumeIntegralInRange(0,2)).c_str()); + if(fuzzed_data.ConsumeBool()) + ndpi_set_config(ndpi_info_mod, "mullvad", "ip_list.load", std::to_string(fuzzed_data.ConsumeIntegralInRange(0,2)).c_str()); + if(fuzzed_data.ConsumeBool()) + ndpi_set_config(ndpi_info_mod, "protonvpn", "ip_list.load", std::to_string(fuzzed_data.ConsumeIntegralInRange(0,2)).c_str()); + if(fuzzed_data.ConsumeBool()) + ndpi_set_config(ndpi_info_mod, "tor", "ip_list.load", std::to_string(fuzzed_data.ConsumeIntegralInRange(0,2)).c_str()); + if(fuzzed_data.ConsumeBool()) + ndpi_set_config(ndpi_info_mod, "tls", "ja3_plus.enable", std::to_string(fuzzed_data.ConsumeIntegralInRange(0,2)).c_str()); + if(fuzzed_data.ConsumeBool()) + ndpi_set_config(ndpi_info_mod, "tls", "metadata.sha1_fingerprint.enable", std::to_string(fuzzed_data.ConsumeIntegralInRange(0,2)).c_str()); + if(fuzzed_data.ConsumeBool()) + ndpi_set_config(ndpi_info_mod, "whatsapp", "ip_list.load", std::to_string(fuzzed_data.ConsumeIntegralInRange(0,2)).c_str()); + if(fuzzed_data.ConsumeBool()) + ndpi_set_config(ndpi_info_mod, "zoom", "ip_list.load", std::to_string(fuzzed_data.ConsumeIntegralInRange(0,2)).c_str()); + if(fuzzed_data.ConsumeBool()) + ndpi_set_config(ndpi_info_mod, NULL, "asn_lists.load", std::to_string(fuzzed_data.ConsumeIntegralInRange(0,2)).c_str()); + if(fuzzed_data.ConsumeBool()) + ndpi_set_config(ndpi_info_mod, NULL, "flow_risk.anonymous_subscriber.list.icloudprivaterelay.load", std::to_string(fuzzed_data.ConsumeIntegralInRange(0,2)).c_str()); + if(fuzzed_data.ConsumeBool()) + ndpi_set_config(ndpi_info_mod, NULL, "flow_risk.anonymous_subscriber.list.protonvpn.load", std::to_string(fuzzed_data.ConsumeIntegralInRange(0,2)).c_str()); + if(fuzzed_data.ConsumeBool()) + ndpi_set_config(ndpi_info_mod, NULL, "flow_risk.crawler_bot.list.load", std::to_string(fuzzed_data.ConsumeIntegralInRange(0,2)).c_str()); + /* Wrong */ + if(fuzzed_data.ConsumeBool()) + ndpi_set_config(ndpi_info_mod, "xxx", "xxx", std::to_string(fuzzed_data.ConsumeIntegralInRange(0,2)).c_str()); + ndpi_finalize_initialization(ndpi_info_mod); /* Random protocol configuration */ diff --git a/fuzz/fuzz_filecfg_protocols.c b/fuzz/fuzz_filecfg_protocols.c index 6731b7af91b3..35a6bb1f34af 100644 --- a/fuzz/fuzz_filecfg_protocols.c +++ b/fuzz/fuzz_filecfg_protocols.c @@ -4,29 +4,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { struct ndpi_detection_module_struct *ndpi_struct; FILE *fd; - /* Try to be fast */ - ndpi_init_prefs prefs = ndpi_dont_load_tor_list | - ndpi_dont_load_azure_list | - ndpi_dont_load_whatsapp_list | - ndpi_dont_load_amazon_aws_list | - ndpi_dont_load_ethereum_list | - ndpi_dont_load_zoom_list | - ndpi_dont_load_cloudflare_list | - ndpi_dont_load_microsoft_list | - ndpi_dont_load_google_list | - ndpi_dont_load_google_cloud_list | - ndpi_dont_load_asn_lists | - ndpi_dont_init_risk_ptree | - ndpi_dont_load_cachefly_list | - ndpi_dont_load_protonvpn_list | - ndpi_dont_load_mullvad_list; NDPI_PROTOCOL_BITMASK all; NDPI_PROTOCOL_BITMASK debug_bitmask; /* To allow memory allocation failures */ fuzz_set_alloc_callbacks_and_seed(size); - ndpi_struct = ndpi_init_detection_module(prefs); + ndpi_struct = ndpi_init_detection_module(0); NDPI_BITMASK_SET_ALL(all); ndpi_set_protocol_detection_bitmask2(ndpi_struct, &all); diff --git a/fuzz/fuzz_ndpi_reader.c b/fuzz/fuzz_ndpi_reader.c index 8b1674c9b2f6..dd17cfb0ba45 100644 --- a/fuzz/fuzz_ndpi_reader.c +++ b/fuzz/fuzz_ndpi_reader.c @@ -18,7 +18,7 @@ u_int8_t enable_protocol_guess = 1, enable_payload_analyzer = 0; u_int8_t enable_flow_stats = 1; u_int8_t human_readeable_string_len = 5; u_int8_t max_num_udp_dissected_pkts = 16 /* 8 is enough for most protocols, Signal requires more */, max_num_tcp_dissected_pkts = 80 /* due to telnet */; -ndpi_init_prefs init_prefs = ndpi_track_flow_payload | ndpi_enable_ja3_plus | ndpi_enable_tcp_ack_payload_heuristic; +ndpi_init_prefs init_prefs = ndpi_track_flow_payload | ndpi_enable_tcp_ack_payload_heuristic; int enable_malloc_bins = 1; int malloc_size_stats = 0; int max_malloc_bins = 14; @@ -71,6 +71,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { ndpi_set_monitoring_state(workflow->ndpi_struct, NDPI_PROTOCOL_STUN, 10, NDPI_MONITORING_STUN_SUBCLASSIFIED); + ndpi_set_config(workflow->ndpi_struct, "tls", "ja3_plus.enable", "1"); + memset(workflow->stats.protocol_counter, 0, sizeof(workflow->stats.protocol_counter)); memset(workflow->stats.protocol_counter_bytes, 0, diff --git a/fuzz/fuzz_readerutils_parseprotolist.cpp b/fuzz/fuzz_readerutils_parseprotolist.cpp index 771719a8ff3f..b41a83d09d1e 100644 --- a/fuzz/fuzz_readerutils_parseprotolist.cpp +++ b/fuzz/fuzz_readerutils_parseprotolist.cpp @@ -13,7 +13,7 @@ u_int8_t enable_protocol_guess = 1, enable_payload_analyzer = 0; u_int8_t enable_flow_stats = 0; u_int8_t human_readeable_string_len = 5; u_int8_t max_num_udp_dissected_pkts = 16 /* 8 is enough for most protocols, Signal requires more */, max_num_tcp_dissected_pkts = 80 /* due to telnet */; -ndpi_init_prefs init_prefs = ndpi_track_flow_payload | ndpi_enable_ja3_plus | ndpi_enable_tcp_ack_payload_heuristic; +ndpi_init_prefs init_prefs = ndpi_track_flow_payload | ndpi_enable_tcp_ack_payload_heuristic; int enable_malloc_bins = 0; int malloc_size_stats = 0; int max_malloc_bins = 14; diff --git a/fuzz/fuzz_readerutils_workflow.cpp b/fuzz/fuzz_readerutils_workflow.cpp index 90d0ac0944f1..0f7d3cbea91e 100644 --- a/fuzz/fuzz_readerutils_workflow.cpp +++ b/fuzz/fuzz_readerutils_workflow.cpp @@ -15,7 +15,7 @@ u_int8_t enable_protocol_guess = 1, enable_payload_analyzer = 0; u_int8_t enable_flow_stats = 0; u_int8_t human_readeable_string_len = 5; u_int8_t max_num_udp_dissected_pkts = 16 /* 8 is enough for most protocols, Signal requires more */, max_num_tcp_dissected_pkts = 80 /* due to telnet */; -ndpi_init_prefs init_prefs = ndpi_track_flow_payload | ndpi_enable_ja3_plus | ndpi_enable_tcp_ack_payload_heuristic; +ndpi_init_prefs init_prefs = ndpi_track_flow_payload | ndpi_enable_tcp_ack_payload_heuristic; int enable_malloc_bins = 0; int malloc_size_stats = 0; int max_malloc_bins = 14; diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h index 8de8581887d7..6d367e37d209 100644 --- a/src/include/ndpi_api.h +++ b/src/include/ndpi_api.h @@ -2151,6 +2151,12 @@ extern "C" { */ void *ndpi_get_user_data(struct ndpi_detection_module_struct *ndpi_str); + + int ndpi_set_config(struct ndpi_detection_module_struct *ndpi_str, + const char *proto, const char *param, const char *value); + char *ndpi_get_config(struct ndpi_detection_module_struct *ndpi_str, + const char *proto, const char *param); + #ifdef __cplusplus } #endif diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index 4d4d22161cd8..b4c260295b9e 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -1237,6 +1237,33 @@ typedef struct { } nbpf_filter; #endif +struct ndpi_detection_module_config_struct { + /* IP lists */ + char ip_list_amazonaws_enabled; + char ip_list_azure_enabled; + char ip_list_cachefly_enabled; + char ip_list_cloudflare_enabled; + char ip_list_google_enabled; + char ip_list_googlecloud_enabled; + char ip_list_microsoft_enabled; + char ip_list_mining_enabled; + char ip_list_mullvad_enabled; + char ip_list_protonvpn_enabled; + char ip_list_tor_enabled; + char ip_list_whatsapp_enabled; + char ip_list_zoom_enabled; + + char asn_lists_enabled; + + char risk_anonymous_subscriber_list_icloudprivaterelay_enabled; + char risk_anonymous_subscriber_list_protonvpn_enabled; + char risk_crawler_bot_list_enabled; + + /* TLS */ + char sha1_fingerprint_enabled; + char ja3_plus_enabled; +}; + struct ndpi_detection_module_struct { NDPI_PROTOCOL_BITMASK detection_bitmask; @@ -1316,6 +1343,8 @@ struct ndpi_detection_module_struct { u_int8_t ip_version_limit; + struct ndpi_detection_module_config_struct cfg; + /* NDPI_PROTOCOL_TINC */ struct cache *tinc_cache; @@ -1778,22 +1807,8 @@ typedef u_int32_t ndpi_init_prefs; typedef enum { ndpi_no_prefs = 0, - ndpi_dont_load_tor_list = (1 << 0), ndpi_dont_init_libgcrypt = (1 << 1), - ndpi_enable_ja3_plus = (1 << 2), - ndpi_dont_load_azure_list = (1 << 3), - ndpi_dont_load_whatsapp_list = (1 << 4), - ndpi_dont_load_amazon_aws_list = (1 << 5), - ndpi_dont_load_ethereum_list = (1 << 6), - ndpi_dont_load_zoom_list = (1 << 7), - ndpi_dont_load_cloudflare_list = (1 << 8), - ndpi_dont_load_microsoft_list = (1 << 9), - ndpi_dont_load_google_list = (1 << 10), - ndpi_dont_load_google_cloud_list = (1 << 11), - ndpi_dont_load_asn_lists = (1 << 12), - ndpi_dont_load_icloud_private_relay_list = (1 << 13), ndpi_dont_init_risk_ptree = (1 << 14), - ndpi_dont_load_cachefly_list = (1 << 15), ndpi_track_flow_payload = (1 << 16), /* In some networks, there are some anomalous TCP flows where the smallest ACK packets have some kind of zero padding. @@ -1806,15 +1821,11 @@ typedef enum { correct detection/classification. See #1946 for other details */ ndpi_enable_tcp_ack_payload_heuristic = (1 << 17), - ndpi_dont_load_crawlers_list = (1 << 18), - ndpi_dont_load_protonvpn_list = (1 << 19), /* Heuristic to detect fully encrypted sessions, i.e. flows where every bytes of the payload is encrypted in an attempt to “look like nothing”. This heuristic only analyzes the first packet of the flow. See: https://www.usenix.org/system/files/sec23fall-prepub-234-wu-mingshi.pdf */ - ndpi_disable_fully_encrypted_heuristic = (1 << 20), - ndpi_dont_load_protonvpn_exit_nodes_list = (1 << 21), - ndpi_dont_load_mullvad_list = (1 << 22), + ndpi_disable_fully_encrypted_heuristic = (1 << 21), } ndpi_prefs; typedef struct { diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 17d1cd36c9a8..fdc615d7acbd 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -2814,9 +2814,6 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(ndpi_init_prefs NDPI_BITMASK_RESET(ndpi_str->debug_bitmask); #endif /* NDPI_ENABLE_DEBUG_MESSAGES */ - if(prefs & ndpi_enable_ja3_plus) - ndpi_str->enable_ja3_plus = 1; - if(!(prefs & ndpi_dont_init_libgcrypt)) { if(!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P)) { const char *gcrypt_ver = gcry_check_version(NULL); @@ -2835,103 +2832,40 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(ndpi_init_prefs if((ndpi_str->protocols_ptree = ndpi_patricia_new(32 /* IPv4 */)) != NULL) { ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, host_protocol_list); + } - if(!(prefs & ndpi_dont_load_cachefly_list)) - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_cachefly_protocol_list); - - if(!(prefs & ndpi_dont_load_tor_list)) - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_tor_protocol_list); - - if(!(prefs & ndpi_dont_load_azure_list)) - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_microsoft_azure_protocol_list); - - if(!(prefs & ndpi_dont_load_whatsapp_list)) - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_whatsapp_protocol_list); - - if(!(prefs & ndpi_dont_load_amazon_aws_list)) - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_amazon_aws_protocol_list); - - if(!(prefs & ndpi_dont_load_ethereum_list)) - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_mining_protocol_list); + if(prefs & ndpi_track_flow_payload) + ndpi_str->max_payload_track_len = 1024; /* track up to X payload bytes */ - if(!(prefs & ndpi_dont_load_zoom_list)) - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_zoom_protocol_list); + ndpi_str->ip_risk_mask_ptree = ndpi_patricia_new(32 /* IPv4 */); - if(!(prefs & ndpi_dont_load_cloudflare_list)) - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_cloudflare_protocol_list); + if(!(prefs & ndpi_dont_init_risk_ptree)) { + ndpi_str->ip_risk_ptree = ndpi_patricia_new(32 /* IPv4 */); + } - if(!(prefs & ndpi_dont_load_microsoft_list)) { - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_microsoft_365_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_ms_one_drive_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_ms_outlook_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_skype_teams_protocol_list); - } + ndpi_str->cfg.ip_list_amazonaws_enabled = 1; + ndpi_str->cfg.ip_list_azure_enabled = 1; + ndpi_str->cfg.ip_list_cachefly_enabled = 1; + ndpi_str->cfg.ip_list_cloudflare_enabled = 1; + ndpi_str->cfg.ip_list_google_enabled = 1; + ndpi_str->cfg.ip_list_googlecloud_enabled = 1; + ndpi_str->cfg.ip_list_microsoft_enabled = 1; + ndpi_str->cfg.ip_list_mining_enabled = 1; + ndpi_str->cfg.ip_list_mullvad_enabled = 1; + ndpi_str->cfg.ip_list_protonvpn_enabled = 1; + ndpi_str->cfg.ip_list_tor_enabled = 1; + ndpi_str->cfg.ip_list_whatsapp_enabled = 1; + ndpi_str->cfg.ip_list_zoom_enabled = 1; - if(!(prefs & ndpi_dont_load_google_list)) - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_google_protocol_list); + ndpi_str->cfg.asn_lists_enabled = 1; - if(!(prefs & ndpi_dont_load_google_cloud_list)) - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_google_cloud_protocol_list); + ndpi_str->cfg.risk_anonymous_subscriber_list_icloudprivaterelay_enabled = 1; + ndpi_str->cfg.risk_anonymous_subscriber_list_protonvpn_enabled = 1; + ndpi_str->cfg.risk_crawler_bot_list_enabled = 1; - if(!(prefs & ndpi_dont_load_protonvpn_list)) - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_protonvpn_protocol_list); + ndpi_str->cfg.sha1_fingerprint_enabled = 1; + ndpi_str->cfg.ja3_plus_enabled = 0; - if(!(prefs & ndpi_dont_load_mullvad_list)) - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_mullvad_protocol_list); - - if(!(prefs & ndpi_dont_load_asn_lists)) { - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_telegram_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_apple_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_twitter_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_netflix_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_webex_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_teamviewer_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_facebook_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_tencent_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_opendns_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_dropbox_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_starcraft_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_ubuntuone_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_twitch_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_hotspot_shield_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_github_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_steam_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_bloomberg_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_citrix_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_edgecast_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_goto_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_riotgames_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_threema_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_alibaba_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_avast_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_discord_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_line_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_vk_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_yandex_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_yandex_cloud_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_disneyplus_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_hulu_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_epicgames_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_nvidia_protocol_list); - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_roblox_protocol_list); - } - - if(prefs & ndpi_track_flow_payload) - ndpi_str->max_payload_track_len = 1024; /* track up to X payload bytes */ - } - - ndpi_str->ip_risk_mask_ptree = ndpi_patricia_new(32 /* IPv4 */); - - if(!(prefs & ndpi_dont_init_risk_ptree)) { - if((ndpi_str->ip_risk_ptree = ndpi_patricia_new(32 /* IPv4 */)) != NULL) { - if(!(prefs & ndpi_dont_load_icloud_private_relay_list)) - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->ip_risk_ptree, ndpi_anonymous_subscriber_icloud_private_relay_protocol_list); - if(!(prefs & ndpi_dont_load_protonvpn_exit_nodes_list)) - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->ip_risk_ptree, ndpi_anonymous_subscriber_protonvpn_protocol_list); - if(!(prefs & ndpi_dont_load_crawlers_list)) - ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->ip_risk_ptree, ndpi_http_crawler_bot_protocol_list); - } - } ndpi_str->max_packets_to_process = NDPI_DEFAULT_MAX_NUM_PKTS_PER_FLOW_TO_DISSECT; @@ -3144,6 +3078,102 @@ void ndpi_finalize_initialization(struct ndpi_detection_module_struct *ndpi_str) if(!ndpi_str) return; + /* IP lists */ + + if(ndpi_str->protocols_ptree) { + if(ndpi_str->cfg.ip_list_amazonaws_enabled) { + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_amazon_aws_protocol_list); + } + if(ndpi_str->cfg.ip_list_azure_enabled) { + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_microsoft_azure_protocol_list); + } + if(ndpi_str->cfg.ip_list_cachefly_enabled) { + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_cachefly_protocol_list); + } + if(ndpi_str->cfg.ip_list_cloudflare_enabled) { + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_cloudflare_protocol_list); + } + if(ndpi_str->cfg.ip_list_google_enabled) { + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_google_protocol_list); + } + if(ndpi_str->cfg.ip_list_googlecloud_enabled) { + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_google_cloud_protocol_list); + } + if(ndpi_str->cfg.ip_list_microsoft_enabled) { + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_microsoft_365_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_ms_one_drive_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_ms_outlook_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_skype_teams_protocol_list); + } + if(ndpi_str->cfg.ip_list_mining_enabled) { + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_mining_protocol_list); + } + if(ndpi_str->cfg.ip_list_protonvpn_enabled) { + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_protonvpn_protocol_list); + } + if(ndpi_str->cfg.ip_list_tor_enabled) { + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_tor_protocol_list); + } + if(ndpi_str->cfg.ip_list_whatsapp_enabled) { + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_whatsapp_protocol_list); + } + if(ndpi_str->cfg.ip_list_zoom_enabled) { + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_zoom_protocol_list); + } + if(ndpi_str->cfg.ip_list_mullvad_enabled) { + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_mullvad_protocol_list); + } + + if(ndpi_str->cfg.asn_lists_enabled) { + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_telegram_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_apple_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_twitter_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_netflix_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_webex_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_teamviewer_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_facebook_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_tencent_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_opendns_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_dropbox_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_starcraft_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_ubuntuone_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_twitch_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_hotspot_shield_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_github_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_steam_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_bloomberg_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_citrix_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_edgecast_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_goto_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_riotgames_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_threema_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_alibaba_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_avast_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_discord_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_line_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_vk_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_yandex_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_yandex_cloud_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_disneyplus_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_hulu_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_epicgames_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_nvidia_protocol_list); + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_roblox_protocol_list); + } + } + + if(ndpi_str->ip_risk_ptree) { + if(ndpi_str->cfg.risk_anonymous_subscriber_list_icloudprivaterelay_enabled) { + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->ip_risk_ptree, ndpi_anonymous_subscriber_icloud_private_relay_protocol_list); + } + if(ndpi_str->cfg.risk_anonymous_subscriber_list_protonvpn_enabled) { + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->ip_risk_ptree, ndpi_anonymous_subscriber_protonvpn_protocol_list); + } + if(ndpi_str->cfg.risk_crawler_bot_list_enabled) { + ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->ip_risk_ptree, ndpi_http_crawler_bot_protocol_list); + } + } + ndpi_add_domain_risk_exceptions(ndpi_str); if(ndpi_str->ookla_cache_num_entries > 0) { @@ -10228,3 +10258,75 @@ void *ndpi_get_user_data(struct ndpi_detection_module_struct *ndpi_str) return ndpi_str->user_data; return NULL; } + +/* ******************************************************************** */ + +static int _set_cfg_enable_disable(void *_variable, const char *value) +{ + char *variable = (char *)_variable; + + if(strcmp(value, "1") == 0) { + *variable = 1; + return 0; + } + if(strcmp(value, "0") == 0) { + *variable = 0; + return 0; + } + return -1; +} + +typedef int (*cfg_fn)(void *variable, const char *value); + +int ndpi_set_config(struct ndpi_detection_module_struct *ndpi_str, + const char *proto, const char *param, const char *value) +{ + if(!ndpi_str || !param || !value) + return -2; + + struct cfgs { + char *proto; + char *param; + cfg_fn fn; + void *variable; + } cfgs[] = { + /* Per-protocol */ + + { "amazonaws", "ip_list.load", _set_cfg_enable_disable, &ndpi_str->cfg.ip_list_amazonaws_enabled }, + { "azure", "ip_list.load", _set_cfg_enable_disable, &ndpi_str->cfg.ip_list_azure_enabled }, + { "cachefly", "ip_list.load", _set_cfg_enable_disable, &ndpi_str->cfg.ip_list_cachefly_enabled }, + { "cloudflare", "ip_list.load", _set_cfg_enable_disable, &ndpi_str->cfg.ip_list_cloudflare_enabled }, + { "google", "ip_list.load", _set_cfg_enable_disable, &ndpi_str->cfg.ip_list_google_enabled }, + { "googlecloud", "ip_list.load", _set_cfg_enable_disable, &ndpi_str->cfg.ip_list_googlecloud_enabled }, + { "microsoft", "ip_list.load", _set_cfg_enable_disable, &ndpi_str->cfg.ip_list_microsoft_enabled }, + { "mining", "ip_list.load", _set_cfg_enable_disable, &ndpi_str->cfg.ip_list_mining_enabled }, + { "mullvad", "ip_list.load", _set_cfg_enable_disable, &ndpi_str->cfg.ip_list_mullvad_enabled }, + { "protonvpn", "ip_list.load", _set_cfg_enable_disable, &ndpi_str->cfg.ip_list_protonvpn_enabled }, + { "tor", "ip_list.load", _set_cfg_enable_disable, &ndpi_str->cfg.ip_list_tor_enabled }, + { "tls", "ja3_plus.enable", _set_cfg_enable_disable, &ndpi_str->cfg.ja3_plus_enabled }, + { "tls", "metadata.sha1_fingerprint.enable", _set_cfg_enable_disable, &ndpi_str->cfg.sha1_fingerprint_enabled }, + { "whatsapp", "ip_list.load", _set_cfg_enable_disable, &ndpi_str->cfg.ip_list_whatsapp_enabled }, + { "zoom", "ip_list.load", _set_cfg_enable_disable, &ndpi_str->cfg.ip_list_zoom_enabled }, + + /* Global */ + + { NULL, "asn_lists.load", _set_cfg_enable_disable, &ndpi_str->cfg.asn_lists_enabled }, + { NULL, "flow_risk.anonymous_subscriber.list.icloudprivaterelay.load", _set_cfg_enable_disable, &ndpi_str->cfg.risk_anonymous_subscriber_list_icloudprivaterelay_enabled }, + { NULL, "flow_risk.anonymous_subscriber.list.protonvpn.load", _set_cfg_enable_disable, &ndpi_str->cfg.risk_anonymous_subscriber_list_protonvpn_enabled }, + { NULL, "flow_risk.crawler_bot.list.load", _set_cfg_enable_disable, &ndpi_str->cfg.risk_crawler_bot_list_enabled }, + + { NULL, NULL, NULL, NULL }, + }; + const struct cfgs *c; + + NDPI_LOG_ERR(ndpi_str, "[%s][%s][%s]\n", proto, param, value); + + for(c = &cfgs[0]; c && c->param; c++) { + if(((proto == NULL && c->proto == NULL) || + (proto && c->proto && strcmp(proto, c->proto) == 0)) && + strcmp(param, c->param) == 0) { + return c->fn(c->variable, value); + } + } + return -3; +}