diff options
-rw-r--r-- | doc/configuration_parameters.md | 4 | ||||
-rw-r--r-- | example/ndpiReader.c | 24 | ||||
-rw-r--r-- | example/ndpiSimpleIntegration.c | 3 | ||||
-rw-r--r-- | example/reader_util.c | 5 | ||||
-rw-r--r-- | fuzz/fuzz_common_code.c | 3 | ||||
-rw-r--r-- | fuzz/fuzz_config.cpp | 2 | ||||
-rw-r--r-- | fuzz/fuzz_filecfg_categories.c | 2 | ||||
-rw-r--r-- | fuzz/fuzz_filecfg_malicious_ja3.c | 2 | ||||
-rw-r--r-- | fuzz/fuzz_filecfg_malicious_sha1.c | 2 | ||||
-rw-r--r-- | fuzz/fuzz_filecfg_protocols.c | 2 | ||||
-rw-r--r-- | fuzz/fuzz_filecfg_risk_domains.c | 2 | ||||
-rw-r--r-- | fuzz/fuzz_ndpi_reader.c | 3 | ||||
-rw-r--r-- | fuzz/fuzz_readerutils_parseprotolist.cpp | 1 | ||||
-rw-r--r-- | fuzz/fuzz_readerutils_workflow.cpp | 1 | ||||
-rw-r--r-- | python/ndpi/ndpi.py | 2 | ||||
-rw-r--r-- | python/ndpi/ndpi_build.py | 2 | ||||
-rw-r--r-- | src/include/ndpi_api.h | 3 | ||||
-rw-r--r-- | src/include/ndpi_private.h | 18 | ||||
-rw-r--r-- | src/include/ndpi_typedefs.h | 24 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 55 | ||||
-rw-r--r-- | tests/dga/dga_evaluate.c | 5 | ||||
-rw-r--r-- | tests/unit/unit.c | 2 |
22 files changed, 77 insertions, 90 deletions
diff --git a/doc/configuration_parameters.md b/doc/configuration_parameters.md index 64080177b..e88c96057 100644 --- a/doc/configuration_parameters.md +++ b/doc/configuration_parameters.md @@ -7,6 +7,10 @@ TODO | ------ | ------ | ------ | ------ | ------ | ------ | ------ | | NULL | "packets_limit_per_flow" | 32 | 0 | 255 | The upper limit on the number of packets per flow that will be subject to DPI, after which classification will be considered complete (0 = no limit) | | NULL | "flow.direction_detection.enable" | 1 | NULL | NULL | Enable/disable internal detection of packet direction (client to server or server to client) | +| NULL | "flow.track_payload.enable" | 0 | NULL | NULL | Enable/disable tracking/export of flow payload (i.e. L5/7 data) | +| NULL | "tcp_ack_payload_heuristic.enable" | 0 | NULL | NULL | In some networks, there are some anomalous TCP flows where the smallest ACK packets have some kind of zero padding. It looks like the IP and TCP headers in those frames wrongly consider the 0x00 Ethernet padding bytes as part of the TCP payload. While this kind of packets is perfectly valid per-se, in some conditions they might be treated by the TCP reassembler logic as (partial) overlaps, deceiving the classification engine. This parameter enable/disable an heuristic to detect these packets and to ignore them, allowing correct detection/classification. See #1946 for other details | +| NULL | "fully_encrypted_heuristic.enable" | 1 | NULL | NULL | Enable/disable an 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 | +| NULL | "libgcrypt.init" | 1 | NULL | NULL | Enable/disable initialization of libgcrypt. When using the external libgcrypt (instead of the internal crypto code) the libgcrypt runtime must be initialized. If, for whatever reasons, the application alread does it, nDPI must be told to skip it. Note that, by default, nDPI uses the crypto code and not libgcrypt: in that case this parameter is ignored | | NULL | "flow_risk_lists.load" | 1 | NULL | NULL | Enable/disable loading of every IP addresses lists used to check any flow risks | | NULL | "flow_risk.anonymous_subscriber.list.icloudprivaterelay.load" | 1 | NULL | NULL | Enable/disable loading of internal iCouldPrivateRealy IP address list used to check `NDPI_ANONYMOUS_SUBSCRIBER` flow risk | | NULL | "flow_risk.anonymous_subscriber.list.protonvpn.load" | 1 | NULL | NULL | Enable/disable loading of internal IP address list of ProtonVPN exit nodes used to check `NDPI_ANONYMOUS_SUBSCRIBER` flow risk | diff --git a/example/ndpiReader.c b/example/ndpiReader.c index 742e442fc..e447bb520 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -108,7 +108,6 @@ int nDPI_LogLevel = 0; char *_debug_protocols = NULL; char *_disabled_protocols = NULL; static u_int8_t stats_flag = 0; -ndpi_init_prefs init_prefs = ndpi_no_prefs | ndpi_enable_tcp_ack_payload_heuristic; u_int8_t human_readeable_string_len = 5; u_int8_t max_num_udp_dissected_pkts = 24 /* 8 is enough for most protocols, Signal and SnapchatCall require more */, max_num_tcp_dissected_pkts = 80 /* due to telnet */; static u_int32_t pcap_analysis_duration = (u_int32_t)-1; @@ -331,7 +330,7 @@ void ndpiCheckHostStringMatch(char *testChar) { if(!testChar) return; - ndpi_str = ndpi_init_detection_module(init_prefs); + ndpi_str = ndpi_init_detection_module(); ndpi_finalize_initialization(ndpi_str); testRes = ndpi_match_string_subprotocol(ndpi_str, @@ -376,7 +375,7 @@ static void ndpiCheckIPMatch(char *testChar) { if(!testChar) return; - ndpi_str = ndpi_init_detection_module(init_prefs); + ndpi_str = ndpi_init_detection_module(); NDPI_BITMASK_SET_ALL(all); ndpi_set_protocol_detection_bitmask2(ndpi_str, &all); @@ -561,7 +560,6 @@ static void help(u_int long_help) { " | 2 - List known risks\n" " -d | Disable protocol guess and use only DPI\n" " -e <len> | Min human readeable string match len. Default %u\n" - " -E | Track flow payload\n" " -q | Quiet mode\n" " -F | Enable flow stats\n" " -t | Dissect GTP/TZSP tunnels\n" @@ -609,7 +607,7 @@ static void help(u_int long_help) { max_num_reported_top_payloads, max_num_tcp_dissected_pkts, max_num_udp_dissected_pkts); NDPI_PROTOCOL_BITMASK all; - struct ndpi_detection_module_struct *ndpi_info_mod = ndpi_init_detection_module(init_prefs); + struct ndpi_detection_module_struct *ndpi_info_mod = ndpi_init_detection_module(); NDPI_BITMASK_SET_ALL(all); ndpi_set_protocol_detection_bitmask2(ndpi_info_mod, &all); ndpi_finalize_initialization(ndpi_info_mod); @@ -769,7 +767,7 @@ void extcap_config() { ndpi_proto_defaults_t *proto_defaults; #endif - struct ndpi_detection_module_struct *ndpi_info_mod = ndpi_init_detection_module(init_prefs); + struct ndpi_detection_module_struct *ndpi_info_mod = ndpi_init_detection_module(); #if 0 ndpi_num_supported_protocols = ndpi_get_ndpi_num_supported_protocols(ndpi_info_mod); proto_defaults = ndpi_get_proto_defaults(ndpi_info_mod); @@ -1002,7 +1000,7 @@ static void parseOptions(int argc, char **argv) { #endif while((opt = getopt_long(argc, argv, - "a:Ab:B:e:Ec:C:dDFf:g:G:i:Ij:k:K:S:hHp:pP:l:r:Rs:tu:v:V:n:rp:x:X:w:q0123:456:7:89:m:MT:U:", + "a:Ab:B:e:c:C:dDFf:g:G:i:Ij:k:K:S:hHp:pP:l:r:Rs:tu:v:V:n:rp:x:X:w: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 : ""); @@ -1034,10 +1032,6 @@ static void parseOptions(int argc, char **argv) { human_readeable_string_len = atoi(optarg); break; - case 'E': - init_prefs |= ndpi_track_flow_payload; - break; - case 'i': case '3': _pcap_file[0] = optarg; @@ -1253,7 +1247,7 @@ static void parseOptions(int argc, char **argv) { case '9': { - struct ndpi_detection_module_struct *ndpi_info_mod = ndpi_init_detection_module(init_prefs); + struct ndpi_detection_module_struct *ndpi_info_mod = ndpi_init_detection_module(); extcap_packet_filter = ndpi_get_proto_by_name(ndpi_info_mod, optarg); if(extcap_packet_filter == NDPI_PROTOCOL_UNKNOWN) extcap_packet_filter = atoi(optarg); ndpi_exit_detection_module(ndpi_info_mod); @@ -2787,6 +2781,8 @@ static void setupDetection(u_int16_t thread_id, pcap_t * pcap_handle) { if(_protoFilePath != NULL) ndpi_load_protocols_file(ndpi_thread_info[thread_id].workflow->ndpi_struct, _protoFilePath); + ndpi_set_config(ndpi_thread_info[thread_id].workflow->ndpi_struct, NULL, "tcp_ack_payload_heuristic.enable", "1"); + 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); @@ -4770,7 +4766,7 @@ static void dgaUnitTest() { }; int debug = 0, i; NDPI_PROTOCOL_BITMASK all; - struct ndpi_detection_module_struct *ndpi_str = ndpi_init_detection_module(init_prefs); + struct ndpi_detection_module_struct *ndpi_str = ndpi_init_detection_module(); assert(ndpi_str != NULL); @@ -5613,7 +5609,7 @@ void outlierUnitTest() { void domainsUnitTest() { NDPI_PROTOCOL_BITMASK all; - struct ndpi_detection_module_struct *ndpi_info_mod = ndpi_init_detection_module(init_prefs); + struct ndpi_detection_module_struct *ndpi_info_mod = ndpi_init_detection_module(); const char *lists_path = "../lists/public_suffix_list.dat"; struct stat st; diff --git a/example/ndpiSimpleIntegration.c b/example/ndpiSimpleIntegration.c index d727d353e..2cc18057f 100644 --- a/example/ndpiSimpleIntegration.c +++ b/example/ndpiSimpleIntegration.c @@ -188,8 +188,7 @@ static struct nDPI_workflow * init_workflow(char const * const file_or_device) printf("pcap_setfilter error: '%s'\n", pcap_geterr(workflow->pcap_handle)); } - ndpi_init_prefs init_prefs = ndpi_no_prefs; - workflow->ndpi_struct = ndpi_init_detection_module(init_prefs); + workflow->ndpi_struct = ndpi_init_detection_module(); if (workflow->ndpi_struct == NULL) { free_workflow(&workflow); return NULL; diff --git a/example/reader_util.c b/example/reader_util.c index c16e1d93a..e5399ab16 100644 --- a/example/reader_util.c +++ b/example/reader_util.c @@ -79,7 +79,6 @@ extern u_int8_t max_num_udp_dissected_pkts /* 24 */, max_num_tcp_dissected_pkts static u_int32_t flow_id = 0; u_int8_t enable_doh_dot_detection = 0; -extern ndpi_init_prefs init_prefs; extern int malloc_size_stats; extern struct ndpi_bin malloc_bins; @@ -410,7 +409,7 @@ int parse_proto_name_list(char *str, NDPI_PROTOCOL_BITMASK *bitmask, int inverte else op = 0; /* Default action: remove from the bitmask */ /* Use a temporary module with all protocols enabled */ - module = ndpi_init_detection_module(0); + module = ndpi_init_detection_module(); if(!module) return 1; NDPI_BITMASK_SET_ALL(all); @@ -466,7 +465,7 @@ struct ndpi_workflow* ndpi_workflow_init(const struct ndpi_workflow_prefs * pref #endif /* TODO: just needed here to init ndpi ndpi_malloc wrapper */ - module = ndpi_init_detection_module(init_prefs); + module = ndpi_init_detection_module(); if(module == NULL) { LOG(NDPI_LOG_ERROR, "global structure initialization failed\n"); diff --git a/fuzz/fuzz_common_code.c b/fuzz/fuzz_common_code.c index 1344e8516..13318df37 100644 --- a/fuzz/fuzz_common_code.c +++ b/fuzz/fuzz_common_code.c @@ -36,12 +36,11 @@ 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_no_prefs; NDPI_PROTOCOL_BITMASK all; NDPI_PROTOCOL_BITMASK debug_bitmask; if(*ndpi_info_mod == NULL) { - *ndpi_info_mod = ndpi_init_detection_module(prefs); + *ndpi_info_mod = ndpi_init_detection_module(); NDPI_BITMASK_SET_ALL(debug_bitmask); ndpi_set_log_level(*ndpi_info_mod, 4); diff --git a/fuzz/fuzz_config.cpp b/fuzz/fuzz_config.cpp index b732a2507..e5236caaa 100644 --- a/fuzz/fuzz_config.cpp +++ b/fuzz/fuzz_config.cpp @@ -39,7 +39,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { /* To allow memory allocation failures */ fuzz_set_alloc_callbacks_and_seed(size); - ndpi_info_mod = ndpi_init_detection_module(fuzzed_data.ConsumeIntegral<u_int32_t>()); + ndpi_info_mod = ndpi_init_detection_module(); set_ndpi_debug_function(ndpi_info_mod, NULL); diff --git a/fuzz/fuzz_filecfg_categories.c b/fuzz/fuzz_filecfg_categories.c index 7c5bb27d8..17947b58c 100644 --- a/fuzz/fuzz_filecfg_categories.c +++ b/fuzz/fuzz_filecfg_categories.c @@ -11,7 +11,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { /* To allow memory allocation failures */ fuzz_set_alloc_callbacks_and_seed(size); - ndpi_struct = ndpi_init_detection_module(ndpi_no_prefs); + ndpi_struct = ndpi_init_detection_module(); NDPI_BITMASK_SET_ALL(all); ndpi_set_protocol_detection_bitmask2(ndpi_struct, &all); diff --git a/fuzz/fuzz_filecfg_malicious_ja3.c b/fuzz/fuzz_filecfg_malicious_ja3.c index bd5a1645b..2073ed5bd 100644 --- a/fuzz/fuzz_filecfg_malicious_ja3.c +++ b/fuzz/fuzz_filecfg_malicious_ja3.c @@ -11,7 +11,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { /* To allow memory allocation failures */ fuzz_set_alloc_callbacks_and_seed(size); - ndpi_struct = ndpi_init_detection_module(ndpi_no_prefs); + ndpi_struct = ndpi_init_detection_module(); NDPI_BITMASK_SET_ALL(all); ndpi_set_protocol_detection_bitmask2(ndpi_struct, &all); diff --git a/fuzz/fuzz_filecfg_malicious_sha1.c b/fuzz/fuzz_filecfg_malicious_sha1.c index fe74e59dc..665a8f942 100644 --- a/fuzz/fuzz_filecfg_malicious_sha1.c +++ b/fuzz/fuzz_filecfg_malicious_sha1.c @@ -11,7 +11,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { /* To allow memory allocation failures */ fuzz_set_alloc_callbacks_and_seed(size); - ndpi_struct = ndpi_init_detection_module(ndpi_no_prefs); + ndpi_struct = ndpi_init_detection_module(); NDPI_BITMASK_SET_ALL(all); ndpi_set_protocol_detection_bitmask2(ndpi_struct, &all); diff --git a/fuzz/fuzz_filecfg_protocols.c b/fuzz/fuzz_filecfg_protocols.c index 80fc23843..74a2c6e3d 100644 --- a/fuzz/fuzz_filecfg_protocols.c +++ b/fuzz/fuzz_filecfg_protocols.c @@ -11,7 +11,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { /* To allow memory allocation failures */ fuzz_set_alloc_callbacks_and_seed(size); - ndpi_struct = ndpi_init_detection_module(ndpi_no_prefs); + ndpi_struct = ndpi_init_detection_module(); NDPI_BITMASK_SET_ALL(all); ndpi_set_protocol_detection_bitmask2(ndpi_struct, &all); diff --git a/fuzz/fuzz_filecfg_risk_domains.c b/fuzz/fuzz_filecfg_risk_domains.c index 5a7bd0f5b..e7d0b4c7f 100644 --- a/fuzz/fuzz_filecfg_risk_domains.c +++ b/fuzz/fuzz_filecfg_risk_domains.c @@ -11,7 +11,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { /* To allow memory allocation failures */ fuzz_set_alloc_callbacks_and_seed(size); - ndpi_struct = ndpi_init_detection_module(ndpi_no_prefs); + ndpi_struct = ndpi_init_detection_module(); 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 6733a665f..d65e20b7c 100644 --- a/fuzz/fuzz_ndpi_reader.c +++ b/fuzz/fuzz_ndpi_reader.c @@ -18,7 +18,6 @@ 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_tcp_ack_payload_heuristic; int enable_malloc_bins = 1; int malloc_size_stats = 0; int max_malloc_bins = 14; @@ -72,6 +71,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { NDPI_BITMASK_SET_ALL(all); ndpi_set_protocol_detection_bitmask2(workflow->ndpi_struct, &all); + ndpi_set_config(workflow->ndpi_struct, NULL, "flow.track_payload.enable", "1"); + ndpi_set_config(workflow->ndpi_struct, NULL, "tcp_ack_payload_heuristic.enable", "1"); ndpi_set_config(workflow->ndpi_struct, "tls", "application_blocks_tracking.enable", "1"); memset(workflow->stats.protocol_counter, 0, diff --git a/fuzz/fuzz_readerutils_parseprotolist.cpp b/fuzz/fuzz_readerutils_parseprotolist.cpp index b41a83d09..c80ae8340 100644 --- a/fuzz/fuzz_readerutils_parseprotolist.cpp +++ b/fuzz/fuzz_readerutils_parseprotolist.cpp @@ -13,7 +13,6 @@ 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_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 a271fc2c7..e836cfdbf 100644 --- a/fuzz/fuzz_readerutils_workflow.cpp +++ b/fuzz/fuzz_readerutils_workflow.cpp @@ -15,7 +15,6 @@ 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_tcp_ack_payload_heuristic; int enable_malloc_bins = 0; int malloc_size_stats = 0; int max_malloc_bins = 14; diff --git a/python/ndpi/ndpi.py b/python/ndpi/ndpi.py index 2d73470ad..743b7a805 100644 --- a/python/ndpi/ndpi.py +++ b/python/ndpi/ndpi.py @@ -32,7 +32,7 @@ class NDPI(object): "_detection_module") def __init__(self): - self._detection_module = lib.ndpi_init_detection_module(0) + self._detection_module = lib.ndpi_init_detection_module() if self._detection_module == ffi.NULL: raise MemoryError("Unable to instantiate NDPI object") lib.ndpi_py_setup_detection_module(self._detection_module) diff --git a/python/ndpi/ndpi_build.py b/python/ndpi/ndpi_build.py index 84c1e04e4..6c07731f4 100644 --- a/python/ndpi/ndpi_build.py +++ b/python/ndpi/ndpi_build.py @@ -49,7 +49,7 @@ struct ndpi_flow_struct * ndpi_py_initialize_flow(void) { NDPI_APIS = """ u_int16_t ndpi_get_api_version(void); char* ndpi_revision(void); -struct ndpi_detection_module_struct *ndpi_init_detection_module(ndpi_init_prefs prefs); +struct ndpi_detection_module_struct *ndpi_init_detection_module(); void ndpi_exit_detection_module(struct ndpi_detection_module_struct *ndpi_struct); void ndpi_flow_free(void *ptr); ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct *ndpi_struct, diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h index 775665dab..9a0c240f8 100644 --- a/src/include/ndpi_api.h +++ b/src/include/ndpi_api.h @@ -211,11 +211,10 @@ extern "C" { * indipendent detection contexts) but all these calls MUST NOT run * in parallel * - * @par prefs = load preferences * @return the initialized detection module * */ - struct ndpi_detection_module_struct *ndpi_init_detection_module(ndpi_init_prefs prefs); + struct ndpi_detection_module_struct *ndpi_init_detection_module(void); /** * Completes the initialization (2nd step) diff --git a/src/include/ndpi_private.h b/src/include/ndpi_private.h index 50a84ffc3..7fac6d981 100644 --- a/src/include/ndpi_private.h +++ b/src/include/ndpi_private.h @@ -149,6 +149,24 @@ typedef struct { struct ndpi_detection_module_config_struct { int max_packets_to_process; int direction_detect_enabled; + /* In some networks, there are some anomalous TCP flows where + the smallest ACK packets have some kind of zero padding. + It looks like the IP and TCP headers in those frames wrongly consider the + 0x00 Ethernet padding bytes as part of the TCP payload. + While this kind of packets is perfectly valid per-se, in some conditions + they might be treated by the TCP reassembler logic as (partial) overlaps, + deceiving the classification engine. + Add an heuristic to detect these packets and to ignore them, allowing + correct detection/classification. + See #1946 for other details */ + int tcp_ack_paylod_heuristic; + /* 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 */ + int fully_encrypted_heuristic; + int track_payload_enabled; + int libgcrypt_init; char filename_config[CFG_MAX_LEN]; diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index 02a104d81..7fc5ce0de 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -1505,30 +1505,6 @@ typedef struct { u_int16_t value; } ndpi_network6; -typedef u_int32_t ndpi_init_prefs; - -typedef enum { - ndpi_no_prefs = 0, - ndpi_dont_init_libgcrypt = (1 << 1), - 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. - It looks like the IP and TCP headers in those frames wrongly consider the - 0x00 Ethernet padding bytes as part of the TCP payload. - While this kind of packets is perfectly valid per-se, in some conditions - they might be treated by the TCP reassembler logic as (partial) overlaps, - deceiving the classification engine. - Add an heuristic to detect these packets and to ignore them, allowing - correct detection/classification. - See #1946 for other details */ - ndpi_enable_tcp_ack_payload_heuristic = (1 << 17), - /* 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_prefs; - typedef struct { u_int32_t protocol_id; ndpi_protocol_category_t protocol_category; diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index f4b648ee2..e191a2877 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -3077,7 +3077,7 @@ static void free_ptree_data(void *data) { /* ******************************************************************** */ -struct ndpi_detection_module_struct *ndpi_init_detection_module(ndpi_init_prefs prefs) { +struct ndpi_detection_module_struct *ndpi_init_detection_module(void) { struct ndpi_detection_module_struct *ndpi_str = ndpi_malloc(sizeof(struct ndpi_detection_module_struct)); int i; @@ -3102,22 +3102,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_dont_init_libgcrypt)) { - if(!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P)) { - const char *gcrypt_ver = gcry_check_version(NULL); - if(!gcrypt_ver) { - NDPI_LOG_ERR(ndpi_str, "Error initializing libgcrypt\n"); - ndpi_free(ndpi_str); - return NULL; - } - NDPI_LOG_DBG(ndpi_str, "Libgcrypt %s\n", gcrypt_ver); - /* Tell Libgcrypt that initialization has completed. */ - gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); - } - } else { - NDPI_LOG_DBG(ndpi_str, "Libgcrypt initialization skipped\n"); - } - if((ndpi_str->protocols_ptree = ndpi_patricia_new(32 /* IPv4 */)) == NULL || (ndpi_str->protocols_ptree6 = ndpi_patricia_new(128 /* IPv6 */)) == NULL) { NDPI_LOG_ERR(ndpi_str, "[NDPI] Error allocating tree\n"); @@ -3126,8 +3110,6 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(ndpi_init_prefs } ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, host_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 */); ndpi_str->ip_risk_mask_ptree6 = ndpi_patricia_new(128 /* IPv6 */); @@ -3249,12 +3231,6 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(ndpi_init_prefs return(NULL); } - if(prefs & ndpi_enable_tcp_ack_payload_heuristic) - ndpi_str->tcp_ack_paylod_heuristic = 1; - - if(!(prefs & ndpi_disable_fully_encrypted_heuristic)) - ndpi_str->fully_encrypted_based_on_first_pkt_heuristic = 1; - 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)); @@ -3326,6 +3302,20 @@ int ndpi_finalize_initialization(struct ndpi_detection_module_struct *ndpi_str) if(ndpi_str->finalized) /* Already finalized */ return 0; + if(ndpi_str->cfg.libgcrypt_init) { + if(!gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P)) { + const char *gcrypt_ver = gcry_check_version(NULL); + if(!gcrypt_ver) { + NDPI_LOG_ERR(ndpi_str, "Error initializing libgcrypt\n"); + } + NDPI_LOG_DBG(ndpi_str, "Libgcrypt %s\n", gcrypt_ver); + /* Tell Libgcrypt that initialization has completed. */ + gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); + } + } else { + NDPI_LOG_DBG(ndpi_str, "Libgcrypt initialization skipped\n"); + } + if(is_ip_list_enabled(ndpi_str, NDPI_PROTOCOL_AMAZON_AWS)) { ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_amazon_aws_protocol_list); ndpi_init_ptree_ipv6(ndpi_str, ndpi_str->protocols_ptree6, ndpi_protocol_amazon_aws_protocol_list_6); @@ -3632,6 +3622,9 @@ int ndpi_finalize_initialization(struct ndpi_detection_module_struct *ndpi_str) ndpi_str->skip_tls_blocks_until_change_cipher = 1; } + if(ndpi_str->cfg.track_payload_enabled) + ndpi_str->max_payload_track_len = 1024; /* track up to X payload bytes */ + ndpi_str->finalized = 1; return 0; @@ -6650,7 +6643,7 @@ void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_str, } } - if(ndpi_str->tcp_ack_paylod_heuristic && tcp_ack_padding(packet)) { + if(ndpi_str->cfg.tcp_ack_paylod_heuristic && tcp_ack_padding(packet)) { NDPI_LOG_DBG2(ndpi_str, "TCP ACK with zero padding. Ignoring\n"); packet->tcp_retransmission = 1; } else if(flow->next_tcp_seq_nr[0] == 0 || flow->next_tcp_seq_nr[1] == 0 || @@ -8259,7 +8252,7 @@ static ndpi_protocol ndpi_internal_detection_process_packet(struct ndpi_detectio && (flow->l4_proto == IPPROTO_TCP)) ndpi_add_connection_as_zoom(ndpi_str, flow); - if(ndpi_str->fully_encrypted_based_on_first_pkt_heuristic && + if(ndpi_str->cfg.fully_encrypted_heuristic && ret.app_protocol == NDPI_PROTOCOL_UNKNOWN && /* Only for unknown traffic */ flow->packet_counter == 1 && packet->payload_packet_len > 0) { flow->first_pkt_fully_encrypted = fully_enc_heuristic(ndpi_str, flow); @@ -9361,7 +9354,7 @@ void ndpi_generate_options(u_int opt, FILE *options_out) { u_int i; if (!options_out) return; - ndpi_str = ndpi_init_detection_module(ndpi_no_prefs); + ndpi_str = ndpi_init_detection_module(); if (!ndpi_str) return; NDPI_BITMASK_SET_ALL(all); @@ -10572,7 +10565,7 @@ static u_int16_t __get_proto_id(const char *proto_name_or_id) /* Try to decode the string as protocol name */ /* Use a temporary module with all protocols enabled */ - module = ndpi_init_detection_module(ndpi_no_prefs); + module = ndpi_init_detection_module(); if(!module) return -1; NDPI_BITMASK_SET_ALL(all); @@ -10805,6 +10798,10 @@ static const struct cfg_param { { NULL, "packets_limit_per_flow", "32", "0", "255", CFG_PARAM_INT, __OFF(max_packets_to_process) }, { NULL, "flow.direction_detection.enable", "1", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(direction_detect_enabled) }, + { NULL, "flow.track_payload.enable", "0", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(track_payload_enabled), }, + { NULL, "tcp_ack_payload_heuristic.enable", "0", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(tcp_ack_paylod_heuristic) }, + { NULL, "fully_encrypted_heuristic.enable", "1", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(fully_encrypted_heuristic) }, + { NULL, "libgcrypt.init", "1", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(libgcrypt_init), }, { NULL, "flow_risk_lists.load", "1", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(flow_risk_lists_enabled)}, diff --git a/tests/dga/dga_evaluate.c b/tests/dga/dga_evaluate.c index 6f4d187f8..97ea362d0 100644 --- a/tests/dga/dga_evaluate.c +++ b/tests/dga/dga_evaluate.c @@ -48,7 +48,8 @@ static void ndpi_dbg_fn(u_int32_t protocol, { assert(protocol == NDPI_PROTOCOL_UNKNOWN); assert(module_struct != NULL); - assert(log_level == NDPI_LOG_DEBUG_EXTRA); + /* While this program always logs at NDPI_LOG_DEBUG_EXTRA level, the + initialization of the library may log at any level */ (void)file; (void)func; @@ -91,7 +92,7 @@ int main(int argc, char **argv) { /* Initialize nDPI detection module*/ NDPI_PROTOCOL_BITMASK all; - struct ndpi_detection_module_struct *ndpi_str = ndpi_init_detection_module(ndpi_no_prefs); + struct ndpi_detection_module_struct *ndpi_str = ndpi_init_detection_module(); assert(ndpi_str != NULL); NDPI_BITMASK_SET_ALL(all); ndpi_set_protocol_detection_bitmask2(ndpi_str, &all); diff --git a/tests/unit/unit.c b/tests/unit/unit.c index 37ed1315d..948fd2a9e 100644 --- a/tests/unit/unit.c +++ b/tests/unit/unit.c @@ -373,7 +373,7 @@ int main(int argc, char **argv) { return -1; } - ndpi_info_mod = ndpi_init_detection_module(ndpi_no_prefs); + ndpi_info_mod = ndpi_init_detection_module(); if (ndpi_info_mod == NULL) return -1; |