diff options
Diffstat (limited to 'src/lib/ndpi_main.c')
-rw-r--r-- | src/lib/ndpi_main.c | 140 |
1 files changed, 132 insertions, 8 deletions
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 27eddfd1a..9840d8715 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -24,11 +24,12 @@ #include <stdlib.h> #include <errno.h> #include "ahocorasick.h" +#include "libcache.h" #define NDPI_CURRENT_PROTO NDPI_PROTOCOL_UNKNOWN #include "ndpi_api.h" -#include "../../config.h" +#include "ndpi_config.h" #include <time.h> #ifndef WIN32 @@ -39,6 +40,17 @@ #include "third_party/include/ndpi_patricia.h" #include "third_party/src/ndpi_patricia.c" +#ifdef HAVE_HYPERSCAN +#include <hs.h> +#endif + +#ifdef HAVE_HYPERSCAN +struct hs { + hs_database_t *database; + hs_scratch_t *scratch; +}; +#endif + static int _ndpi_debug_callbacks = 0; /* implementation of the punycode check function */ @@ -731,10 +743,84 @@ void ndpi_init_protocol_match(struct ndpi_detection_module_struct *ndpi_mod, /* ******************************************************************** */ +#ifdef HAVE_HYPERSCAN + +static int init_hyperscan(struct ndpi_detection_module_struct *ndpi_mod) { + u_int num_patterns = 0, i; + const char **expressions; + unsigned int *ids; + hs_compile_error_t *compile_err; + struct hs *hs; + + ndpi_mod->hyperscan = (void*)malloc(sizeof(struct hs)); + if(!ndpi_mod->hyperscan) return(-1); + hs = (struct hs*)ndpi_mod->hyperscan; + + for(i=0; host_match[i].string_to_match != NULL; i++) { + if(host_match[i].pattern_to_match) { + /* printf("[DEBUG] %s\n", host_match[i].pattern_to_match); */ + num_patterns++; + } + } + + expressions = (const char**)calloc(sizeof(char*), num_patterns+1); + if(!expressions) return(-1); + + ids = (unsigned int*)calloc(sizeof(unsigned int), num_patterns+1); + if(!ids) { + free(expressions); + return(-1); + } + + for(i=0, num_patterns=0; host_match[i].string_to_match != NULL; i++) { + if(host_match[i].pattern_to_match) { + expressions[num_patterns] = host_match[i].pattern_to_match; + ids[num_patterns] = host_match[i].protocol_id; + num_patterns++; + } + } + + if(hs_compile_multi(expressions, NULL, ids, + num_patterns, HS_MODE_BLOCK, NULL, + &hs->database, &compile_err) != HS_SUCCESS) { + NDPI_LOG_ERR(ndpi_mod, "Unable to initialize hyperscan database\n"); + hs_free_compile_error(compile_err); + return -1; + } + + if(hs_alloc_scratch(hs->database, &hs->scratch) != HS_SUCCESS) { + NDPI_LOG_ERR(ndpi_mod, "Unable to allocate hyperscan scratch space\n"); + hs_free_database(hs->database); + return -1; + } + + return 0; +} + +/* ******************************************************************** */ + +static void destroy_hyperscan(struct ndpi_detection_module_struct *ndpi_mod) { + if(ndpi_mod->hyperscan) { + struct hs *hs = (struct hs*)ndpi_mod->hyperscan; + + hs_free_scratch(hs->scratch); + hs_free_database(hs->database); + } +} + +#endif + +/* ******************************************************************** */ + static void init_string_based_protocols(struct ndpi_detection_module_struct *ndpi_mod) { int i; +#ifdef HAVE_HYPERSCAN + // TODO check return value + init_hyperscan(ndpi_mod); +#endif + for(i=0; host_match[i].string_to_match != NULL; i++) ndpi_init_protocol_match(ndpi_mod, &host_match[i]); @@ -868,7 +954,7 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_BGP, no_master, no_master, "BGP", NDPI_PROTOCOL_CATEGORY_NETWORK, - ndpi_build_default_ports(ports_a, 2605, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_a, 179, 2605, 0, 0, 0) /* TCP */, ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SNMP, no_master, @@ -1871,13 +1957,13 @@ void ndpi_debug_printf(unsigned int proto, struct ndpi_detection_module_struct * { #ifdef NDPI_ENABLE_DEBUG_MESSAGES va_list args; -#define MAX_STR_LEN 120 +#define MAX_STR_LEN 250 char str[MAX_STR_LEN]; if(ndpi_str != NULL && log_level > NDPI_LOG_ERROR && proto > 0 && proto < NDPI_MAX_SUPPORTED_PROTOCOLS && !NDPI_ISSET(&ndpi_str->debug_bitmask,proto)) return; va_start(args, format); - vsprintf(str, format, args); + vsnprintf(str,sizeof(str)-1, format, args); va_end(args); if (ndpi_str != NULL) { @@ -2040,7 +2126,7 @@ void ndpi_exit_detection_module(struct ndpi_detection_module_struct *ndpi_struct #ifdef NDPI_PROTOCOL_TINC if(ndpi_struct->tinc_cache) - cache_free(ndpi_struct->tinc_cache); + cache_free((cache_t)(ndpi_struct->tinc_cache)); #endif if(ndpi_struct->protocols_ptree) @@ -2063,6 +2149,10 @@ void ndpi_exit_detection_module(struct ndpi_detection_module_struct *ndpi_struct if(ndpi_struct->impossible_bigrams_automa.ac_automa != NULL) ac_automata_release((AC_AUTOMATA_t*)ndpi_struct->impossible_bigrams_automa.ac_automa); +#ifdef HAVE_HYPERSCAN + destroy_hyperscan(ndpi_struct); +#endif + ndpi_free(ndpi_struct); } } @@ -4628,9 +4718,13 @@ char* ndpi_protocol2name(struct ndpi_detection_module_struct *ndpi_mod, ndpi_protocol proto, char *buf, u_int buf_len) { if((proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) && (proto.master_protocol != proto.app_protocol)) { - snprintf(buf, buf_len, "%s.%s", - ndpi_get_proto_name(ndpi_mod, proto.master_protocol), - ndpi_get_proto_name(ndpi_mod, proto.app_protocol)); + if(proto.app_protocol != NDPI_PROTOCOL_UNKNOWN) + snprintf(buf, buf_len, "%s.%s", + ndpi_get_proto_name(ndpi_mod, proto.master_protocol), + ndpi_get_proto_name(ndpi_mod, proto.app_protocol)); + else + snprintf(buf, buf_len, "%s", + ndpi_get_proto_name(ndpi_mod, proto.master_protocol)); } else snprintf(buf, buf_len, "%s", ndpi_get_proto_name(ndpi_mod, proto.app_protocol)); @@ -4929,6 +5023,8 @@ int ndpi_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_stru /* ****************************************************** */ +#ifndef HAVE_HYPERSCAN + static int ndpi_automa_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, char *string_to_match, u_int string_to_match_len, @@ -4969,6 +5065,34 @@ static int ndpi_automa_match_string_subprotocol(struct ndpi_detection_module_str return(NDPI_PROTOCOL_UNKNOWN); } +#else + +/* ******************************************************************** */ + +static int hyperscanEventHandler(unsigned int id, unsigned long long from, + unsigned long long to, unsigned int flags, void *ctx) { + *((int *)ctx) = (int)id; + return HS_SCAN_TERMINATED; +} + +static int ndpi_automa_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + char *string_to_match, u_int string_to_match_len, + u_int16_t master_protocol_id, + u_int8_t is_host_match) { + int rv = NDPI_PROTOCOL_UNKNOWN; + struct hs *hs = (struct hs*)ndpi_struct->hyperscan; + + if(hs_scan(hs->database, string_to_match, + string_to_match_len, 0, hs->scratch, + hyperscanEventHandler, &rv) != HS_SUCCESS) + NDPI_LOG_ERR(ndpi_struct, "[NDPI] Hyperscan match returned error\n"); + + return rv; +} + +#endif + /* ****************************************************** */ int ndpi_match_host_subprotocol(struct ndpi_detection_module_struct *ndpi_struct, |