From: Russ Combs Date: Mon, 26 Jan 2015 22:36:17 +0000 (-0500) Subject: sync Mpse to 297, add SearchTool X-Git-Tag: 3.0.0-233~1067 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0cb07100e5bb7d2f22fa80f4b39ea18a999b32bb;p=thirdparty%2Fsnort3.git sync Mpse to 297, add SearchTool --- diff --git a/ChangeLog b/ChangeLog index b2b79e3d8..d8bd63a3b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ -pending - build 134 +15/01/26 - build 134 +-- sync Mpse to 297, add SearchTool -- 297 sync for sfghash, sfxhash, tag, u2spewfoo, profiler and target based -- addition of mime decoding stats and updates to mime detection limits -- snort2lua changed to add bindings for default ports if not explicitly diff --git a/configure.ac b/configure.ac index 94596f312..8180d6284 100644 --- a/configure.ac +++ b/configure.ac @@ -198,7 +198,7 @@ AC_FUNC_MALLOC AC_FUNC_REALLOC AC_FUNC_STRERROR_R AC_FUNC_STRTOD -AC_CHECK_FUNCS([endgrent endpwent ftruncate getcwd gettimeofday inet_ntoa isascii localtime_r memchr memmove memset mkdir select socket strcasecmp strchr strdup strerror strncasecmp strrchr strstr strtol strtoul mallinfo]) +AC_CHECK_FUNCS([endgrent endpwent ftruncate getcwd gettimeofday inet_ntoa isascii localtime_r memchr memmove memset mkdir select socket strcasecmp strchr strdup strerror strncasecmp strrchr strstr strtol strtoul mallinfo malloc_trim]) #-------------------------------------------------------------------------- # vars diff --git a/extra/src/search_engines/lowmem.cc b/extra/src/search_engines/lowmem.cc index 5622f34ac..e45e9803d 100644 --- a/extra/src/search_engines/lowmem.cc +++ b/extra/src/search_engines/lowmem.cc @@ -62,12 +62,10 @@ public: { KTrieDelete(obj); }; int add_pattern( - SnortConfig*, void* P, int m, - unsigned noCase, unsigned, unsigned, - unsigned negative, void* ID, int) override + SnortConfig*, const uint8_t* P, unsigned m, + bool noCase, bool negative, void* ID, int) override { - return KTrieAddPattern( - obj, (unsigned char *)P, m, noCase, negative, ID ); + return KTrieAddPattern(obj, P, m, noCase, negative, ID); }; int prep_patterns( diff --git a/extra/src/search_engines/lowmem_q.cc b/extra/src/search_engines/lowmem_q.cc index b86f2f6a4..dedd54de3 100644 --- a/extra/src/search_engines/lowmem_q.cc +++ b/extra/src/search_engines/lowmem_q.cc @@ -116,13 +116,10 @@ public: }; int add_pattern( - SnortConfig*, void* P, int m, - unsigned noCase, unsigned, unsigned, - unsigned negative, void* ID, int) override + SnortConfig*, const uint8_t* P, unsigned m, + bool noCase, bool negative, void* ID, int) override { - return KTrieAddPattern( - obj, (unsigned char *)P, m, - noCase, negative, ID ); + return KTrieAddPattern(obj, P, m, noCase, negative, ID); }; int prep_patterns( diff --git a/extra/src/search_engines/sfksearch.cc b/extra/src/search_engines/sfksearch.cc index d98fea5a9..2c1d02f9a 100644 --- a/extra/src/search_engines/sfksearch.cc +++ b/extra/src/search_engines/sfksearch.cc @@ -117,7 +117,7 @@ void KTrie_init_xlatcase(void) /* * */ -static inline void ConvertCaseEx( unsigned char * d, unsigned char *s, int m ) +static inline void ConvertCaseEx( unsigned char * d, const uint8_t* s, int m ) { int i; for( i=0; i < m; i++ ) { @@ -218,7 +218,7 @@ static void KTrieFree(KTRIENODE *n) /* * */ -static KTRIEPATTERN * KTrieNewPattern(unsigned char * P, int n) +static KTRIEPATTERN * KTrieNewPattern(const uint8_t* P, unsigned n) { KTRIEPATTERN *p; int ret; @@ -265,8 +265,9 @@ static KTRIEPATTERN * KTrieNewPattern(unsigned char * P, int n) /* * Add Pattern info to the list of patterns */ -int KTrieAddPattern( KTRIE_STRUCT * ts, unsigned char * P, int n, - int nocase, int negative, void * id ) +int KTrieAddPattern( + KTRIE_STRUCT * ts, const uint8_t* P, unsigned n, + bool nocase, bool negative, void * id) { KTRIEPATTERN *pnew; @@ -989,7 +990,7 @@ int main( int argc, char ** argv ) if( argv[i][0]=='-' ) continue; - KTrieAddPattern( ts, (unsigned char *)argv[i], strlen(argv[i]), nocase, i ); + KTrieAddPattern(ts, (uint8_t*)argv[i], strlen(argv[i]), nocase, i); } printf("Patterns added \n"); diff --git a/extra/src/search_engines/sfksearch.h b/extra/src/search_engines/sfksearch.h index dcd0bef5b..d7a753732 100644 --- a/extra/src/search_engines/sfksearch.h +++ b/extra/src/search_engines/sfksearch.h @@ -31,6 +31,8 @@ #include "config.h" #endif +#include + #define ALPHABET_SIZE 256 #define KTRIEMETHOD_STD 0 @@ -115,8 +117,8 @@ KTRIE_STRUCT* KTrieNew( void (*neg_list_free)(void**p)); int KTrieAddPattern( - KTRIE_STRUCT*ts, unsigned char* P, int n, - int nocase, int negative, void* id ); + KTRIE_STRUCT* ts, const uint8_t* P, unsigned n, + bool nocase, bool negative, void* id ); int KTrieCompile( KTRIE_STRUCT* ts, diff --git a/src/detection/fpcreate.cc b/src/detection/fpcreate.cc index defb1402d..b26abcd6a 100644 --- a/src/detection/fpcreate.cc +++ b/src/detection/fpcreate.cc @@ -612,7 +612,7 @@ static void neg_list_free(void **list) *list = NULL; } -int pmx_create_tree(SnortConfig* sc, void *id, void **existing_tree){ +static int pmx_create_tree(SnortConfig* sc, void *id, void **existing_tree){ PMX *pmx = NULL; RULE_NODE *rnNode = NULL; OptTreeNode *otn = NULL; @@ -1066,16 +1066,8 @@ static int fpFinishPortGroupRule( PrintFastPatternInfo(otn, pmd, pattern, pattern_length); pg->pgPms[pmd->pm_type]->add_pattern( - sc, - pattern, - pattern_length, - pmd->no_case, - pmd->offset, - pmd->depth, - (unsigned)pmd->negated, - pmx, - rn->iRuleNodeID - ); + sc, (uint8_t*)pattern, pattern_length, pmd->no_case, pmd->negated, + pmx, rn->iRuleNodeID); } return 0; diff --git a/src/file_api/file_api.h b/src/file_api/file_api.h index 01d6e1b59..4d3512f94 100644 --- a/src/file_api/file_api.h +++ b/src/file_api/file_api.h @@ -83,7 +83,7 @@ struct MimeBoundary { char boundary[2 + MAX_MIME_BOUNDARY_LEN + 1]; /* '--' + MIME boundary string + '\0' */ int boundary_len; - void *boundary_search; + class SearchTool* boundary_search; }; diff --git a/src/file_api/file_mime_process.cc b/src/file_api/file_mime_process.cc index 9f2d65b93..c0a1272aa 100644 --- a/src/file_api/file_mime_process.cc +++ b/src/file_api/file_mime_process.cc @@ -33,7 +33,7 @@ #include "file_api.h" #include "snort_bounds.h" #include "util.h" -#include "search_engines/str_search.h" +#include "search_engines/search_tool.h" #include "protocols/packet.h" #include "detection_util.h" @@ -81,7 +81,7 @@ typedef struct _MIMESearchInfo MIMESearchInfo mime_search_info; -void *mime_hdr_search_mpse = NULL; +SearchTool* mime_hdr_search_mpse = nullptr; MIMESearch mime_hdr_search[HDR_LAST]; MIMESearch *mime_current_search = NULL; @@ -269,18 +269,17 @@ static void set_mime_buffers(MimeState *ssn) static int init_boundary_search(MimeBoundary *mime_boundary ) { if (mime_boundary->boundary_search != NULL) - search_api->search_instance_free(mime_boundary->boundary_search); + delete mime_boundary->boundary_search; - mime_boundary->boundary_search = search_api->search_instance_new(); + mime_boundary->boundary_search = new SearchTool; if (mime_boundary->boundary_search == NULL) return -1; - search_api->search_instance_add(mime_boundary->boundary_search, - mime_boundary->boundary, - mime_boundary->boundary_len, BOUNDARY); + mime_boundary->boundary_search->add( + mime_boundary->boundary, mime_boundary->boundary_len, BOUNDARY); - search_api->search_instance_prep(mime_boundary->boundary_search); + mime_boundary->boundary_search->prep(); return 0; } @@ -599,9 +598,8 @@ static const uint8_t * process_mime_header( if(tolower((int)*ptr) == 'c') { mime_current_search = &mime_hdr_search[0]; - header_found =search_api->search_instance_find - (mime_hdr_search_mpse, (const char *)ptr, - eolm - ptr, 1, search_str_found); + header_found = mime_hdr_search_mpse->find( + (const char *)ptr, eolm - ptr, search_str_found, true); /* Headers must start at beginning of line */ if ((header_found > 0) && (mime_search_info.index == 0)) @@ -760,9 +758,8 @@ static const uint8_t * process_mime_body( /* look for boundary */ if (mime_ssn->state_flags & MIME_FLAG_GOT_BOUNDARY) { - boundary_found = search_api->search_instance_find - (mime_ssn->mime_boundary.boundary_search, (const char *)ptr, - data_end_marker - ptr, 0, boundary_str_found); + boundary_found = mime_ssn->mime_boundary.boundary_search->find( + (const char *)ptr, data_end_marker - ptr, boundary_str_found); mime_search_info.length = mime_ssn->mime_boundary.boundary_len; @@ -803,7 +800,7 @@ static const uint8_t * process_mime_body( mime_ssn->state_flags |= MIME_FLAG_MIME_END; /* free boundary search */ - search_api->search_instance_free(mime_ssn->mime_boundary.boundary_search); + delete mime_ssn->mime_boundary.boundary_search; mime_ssn->mime_boundary.boundary_search = NULL; } else @@ -846,7 +843,7 @@ static void reset_mime_state(MimeState *mime_ssn) if (mime_ssn->mime_boundary.boundary_search != NULL) { - search_api->search_instance_free(mime_ssn->mime_boundary.boundary_search); + delete mime_ssn->mime_boundary.boundary_search; mime_ssn->mime_boundary.boundary_search = NULL; } @@ -929,9 +926,8 @@ const uint8_t * process_mime_data(void *packet, const uint8_t *start, const uint * TODO check last bytes of previous packet to see if we had a partial * end of data */ /* mime_current_search = &mime_data_end_search[0]; - data_end_found = search_api->search_instance_find - (mime_data_search_mpse, (const char *)start, end - start, - 0, search_str_found); + data_end_found = mime_data_search_mpse->find( + (const char *)start, end - start, search_str_found); if (data_end_found > 0) { @@ -1060,7 +1056,7 @@ void init_mime(void) const MimeToken *tmp; /* Header search */ - mime_hdr_search_mpse = search_api->search_instance_new(); + mime_hdr_search_mpse = new SearchTool(); if (mime_hdr_search_mpse == NULL) { // FIXIT-M make configurable or at least fall back to any @@ -1073,11 +1069,10 @@ void init_mime(void) mime_hdr_search[tmp->search_id].name = tmp->name; mime_hdr_search[tmp->search_id].name_len = tmp->name_len; - search_api->search_instance_add(mime_hdr_search_mpse, tmp->name, - tmp->name_len, tmp->search_id); + mime_hdr_search_mpse->add(tmp->name, tmp->name_len, tmp->search_id); } - search_api->search_instance_prep(mime_hdr_search_mpse); + mime_hdr_search_mpse->prep(); /* create regex for finding boundary string - since it can be cut across multiple * lines, a straight search won't do. Shouldn't be too slow since it will most @@ -1111,7 +1106,7 @@ void free_mime(void) { if (mime_hdr_search_mpse != NULL) - search_api->search_instance_free(mime_hdr_search_mpse); + delete mime_hdr_search_mpse; if (mime_boundary_pcre.re ) pcre_free(mime_boundary_pcre.re); @@ -1127,7 +1122,7 @@ void free_mime_session(MimeState *mime_ssn) if (mime_ssn->mime_boundary.boundary_search != NULL) { - search_api->search_instance_free(mime_ssn->mime_boundary.boundary_search); + delete mime_ssn->mime_boundary.boundary_search; mime_ssn->mime_boundary.boundary_search = NULL; } diff --git a/src/framework/mpse.cc b/src/framework/mpse.cc index 3ed48d7dc..95cecf2d7 100644 --- a/src/framework/mpse.cc +++ b/src/framework/mpse.cc @@ -28,9 +28,8 @@ using namespace std; #include "snort_types.h" #include "snort.h" -// this is accumulated only for fast pattern searches -// for the detection engine; str_search based stuff -// is not tallied here. +// this is accumulated only for fast pattern +// searches for the detection engine static THREAD_LOCAL uint64_t s_bcnt=0; #ifdef PERF_PROFILING @@ -64,6 +63,13 @@ int Mpse::search( return ret; } +int Mpse::search_all( + const unsigned char * T, int n, mpse_action_f action, + void * data, int* current_state ) +{ + return _search(T, n, action, data, current_state); +} + uint64_t Mpse::get_pattern_byte_count() { return s_bcnt; diff --git a/src/framework/mpse.h b/src/framework/mpse.h index 40fc85a01..0b50e7ac4 100644 --- a/src/framework/mpse.h +++ b/src/framework/mpse.h @@ -56,27 +56,15 @@ typedef int (*mpse_action_f)(void* id, void* tree, int index, void *data, void * class SO_PUBLIC Mpse { public: - static Mpse* instantiate( - SnortConfig* sc, - const char* method, bool use_global_counter_flag, - void (*userfree)(void *p), - void (*optiontreefree)(void **p), - void (*neg_list_free)(void **p)); - static uint64_t get_pattern_byte_count(); static void reset_pattern_byte_count(); - static int print_summary(SnortConfig*, const char* method); - static void init_summary(); - static void print_qinfo(); - public: virtual ~Mpse() { }; virtual int add_pattern( - SnortConfig* sc, void* P, int m, - unsigned noCase, unsigned offset, unsigned depth, - unsigned negative, void* ID, int IID ) = 0; + SnortConfig* sc, const uint8_t* pat, unsigned len, + bool noCase, bool negate, void* ID, int IID) = 0; virtual int prep_patterns( SnortConfig*, mpse_build_f, mpse_negate_f) = 0; @@ -85,6 +73,10 @@ public: const unsigned char* T, int n, mpse_action_f, void* data, int* current_state ); + virtual int search_all( + const unsigned char* T, int n, mpse_action_f, + void* data, int* current_state ); + virtual void set_opt(int) { }; virtual int print_info() { return 0; }; virtual int get_pattern_count() { return 0; }; diff --git a/src/helpers/process.cc b/src/helpers/process.cc index ef9834668..e76ce8ba0 100644 --- a/src/helpers/process.cc +++ b/src/helpers/process.cc @@ -18,6 +18,10 @@ #include "process.h" +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include @@ -27,13 +31,13 @@ #include #endif +#ifdef HAVE_MALLOC_TRIM +#include +#endif + #include using namespace std; -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include "main.h" #include "main/analyzer.h" #include "main/thread.h" @@ -427,6 +431,13 @@ void daemonize() // heap stats //------------------------------------------------------------------------- +void trim_heap() +{ +#ifdef HAVE_MALLOC_TRIM + malloc_trim(0); +#endif +} + void log_malloc_info() { #ifdef HAVE_MALLINFO diff --git a/src/helpers/process.h b/src/helpers/process.h index 8385c7b8b..0ccc3c410 100644 --- a/src/helpers/process.h +++ b/src/helpers/process.h @@ -48,6 +48,8 @@ void help_signals(); void daemonize(); void set_quick_exit(bool); void init_main_thread_sig(); + +void trim_heap(); void log_malloc_info(); #endif diff --git a/src/main/snort.cc b/src/main/snort.cc index 7b3e4cae2..02957596e 100644 --- a/src/main/snort.cc +++ b/src/main/snort.cc @@ -23,6 +23,10 @@ # include "config.h" #endif +#ifdef HAVE_MALLOC_TRIM +#include +#endif + #include #include using namespace std; @@ -535,6 +539,7 @@ SnortConfig* get_reload_config() { snort_reloading = true; ModuleManager::reset_errors(); + trim_heap(); SnortConfig *sc = ParseSnortConf(snort_cmd_line_conf); sc = MergeSnortConfs(snort_cmd_line_conf, sc); diff --git a/src/main/snort_config.cc b/src/main/snort_config.cc index 0175fc15b..689b7189e 100644 --- a/src/main/snort_config.cc +++ b/src/main/snort_config.cc @@ -23,6 +23,10 @@ #include "config.h" #endif +#ifdef HAVE_MALLOC_TRIM +#include +#endif + #include "snort_types.h" #include "detection/treenodes.h" #include "events/event_queue.h" @@ -34,6 +38,7 @@ #include "parser/parser.h" #include "parser/config_file.h" #include "parser/vars.h" +#include "helpers/process.h" #include "filters/rate_filter.h" #include "managers/ips_manager.h" #include "managers/module_manager.h" @@ -356,7 +361,12 @@ void SnortConfFree(SnortConfig *sc) if (sc->gtp_ports) delete sc->gtp_ports; +#ifdef INTEL_SOFT_CPM + IntelPmRelease(sc->ipm_handles); +#endif + free(sc); + trim_heap(); } SnortConfig* MergeSnortConfs(SnortConfig *cmd_line, SnortConfig *config_file) diff --git a/src/main/snort_config.h b/src/main/snort_config.h index 5e7a5c86b..0c6f036b1 100644 --- a/src/main/snort_config.h +++ b/src/main/snort_config.h @@ -203,6 +203,10 @@ struct SnortConfig ppm_cfg_t ppm_cfg; #endif +#ifdef INTEL_SOFT_CPM + struct _IntelPmHandles *ipm_handles; +#endif + //------------------------------------------------------ // FIXIT-L command line only stuff, add to conf / module diff --git a/src/search_engines/CMakeLists.txt b/src/search_engines/CMakeLists.txt index fed42ee00..97f9b009b 100644 --- a/src/search_engines/CMakeLists.txt +++ b/src/search_engines/CMakeLists.txt @@ -44,10 +44,11 @@ set (PLUGIN_LIST set (SEARCH_ENGINE_SOURCES + search_common.h search_engines.cc search_engines.h - str_search.cc - str_search.h + search_tool.cc + search_tool.h ${BNFA_SOURCES} ) diff --git a/src/search_engines/Makefile.am b/src/search_engines/Makefile.am index e94eeee58..25245de42 100644 --- a/src/search_engines/Makefile.am +++ b/src/search_engines/Makefile.am @@ -40,10 +40,11 @@ $(acsmx2_sources) \ $(intel_sources) libsearch_engines_a_SOURCES = \ +search_common.h \ search_engines.cc \ search_engines.h \ -str_search.cc \ -str_search.h \ +search_tool.cc \ +search_tool.h \ pat_stats.cc \ $(bnfa_sources) diff --git a/src/search_engines/ac_banded.cc b/src/search_engines/ac_banded.cc index 654b251ad..46db89de2 100644 --- a/src/search_engines/ac_banded.cc +++ b/src/search_engines/ac_banded.cc @@ -55,19 +55,16 @@ public: }; int add_pattern( - SnortConfig*, void* P, int m, - unsigned noCase, unsigned offset, unsigned depth, - unsigned negative, void* ID, int IID) override + SnortConfig*, const uint8_t* P, unsigned m, + bool noCase, bool negative, void* ID, int IID) override { - return acsmAddPattern2( - obj, (unsigned char *)P, m, - noCase, offset, depth, negative, ID, IID ); + return acsmAddPattern2(obj, P, m, noCase, negative, ID, IID); }; int prep_patterns( SnortConfig* sc, mpse_build_f build_tree, mpse_negate_f neg_list) override { - return acsmCompile2WithSnortConf(sc, obj, build_tree, neg_list); + return acsmCompile2(sc, obj, build_tree, neg_list); }; int _search( diff --git a/src/search_engines/ac_bnfa.cc b/src/search_engines/ac_bnfa.cc index 2a34fb720..e711a0287 100644 --- a/src/search_engines/ac_bnfa.cc +++ b/src/search_engines/ac_bnfa.cc @@ -70,28 +70,25 @@ public: }; int add_pattern( - SnortConfig*, void* P, int m, - unsigned noCase, unsigned, unsigned, - unsigned negative, void* ID, int) override + SnortConfig*, const uint8_t* P, unsigned m, + bool noCase, bool negative, void* ID, int) override { - return bnfaAddPattern( - obj, (unsigned char *)P, m, - noCase, negative, ID ); + return bnfaAddPattern(obj, P, m, noCase, negative, ID); }; int prep_patterns( SnortConfig* sc, mpse_build_f build_tree, mpse_negate_f neg_list) override { - return bnfaCompileWithSnortConf(sc, obj, build_tree, neg_list); + return bnfaCompile(sc, obj, build_tree, neg_list); }; int _search( - const unsigned char* T, int n, mpse_action_f action, + const uint8_t* T, int n, mpse_action_f action, void* data, int* current_state ) override { /* return is actually the state */ return _bnfa_search_csparse_nfa( - obj, (unsigned char *)T, n, (bnfa_match_f)action, + obj, T, n, (bnfa_match_f)action, data, 0 /* start-state */, current_state); }; diff --git a/src/search_engines/ac_bnfa_q.cc b/src/search_engines/ac_bnfa_q.cc index 0976784c1..6675099ca 100644 --- a/src/search_engines/ac_bnfa_q.cc +++ b/src/search_engines/ac_bnfa_q.cc @@ -71,19 +71,16 @@ public: bnfaSetOpt(obj, flag); }; int add_pattern( - SnortConfig*, void* P, int m, - unsigned noCase, unsigned, unsigned, - unsigned negative, void* ID, int) override + SnortConfig*, const uint8_t* P, unsigned m, + bool noCase, bool negative, void* ID, int) override { - return bnfaAddPattern( - obj, (unsigned char *)P, m, - noCase, negative, ID ); + return bnfaAddPattern(obj, P, m, noCase, negative, ID); }; int prep_patterns( SnortConfig* sc, mpse_build_f build_tree, mpse_negate_f neg_list) override { - return bnfaCompileWithSnortConf(sc, obj, build_tree, neg_list); + return bnfaCompile(sc, obj, build_tree, neg_list); }; int _search( diff --git a/src/search_engines/ac_full.cc b/src/search_engines/ac_full.cc index cbf876956..d04df70c2 100644 --- a/src/search_engines/ac_full.cc +++ b/src/search_engines/ac_full.cc @@ -60,19 +60,16 @@ public: acsmCompressStates(obj, flag); }; int add_pattern( - SnortConfig*, void* P, int m, - unsigned noCase, unsigned offset, unsigned depth, - unsigned negative, void* ID, int IID) override + SnortConfig*, const uint8_t* P, unsigned m, + bool noCase, bool negative, void* ID, int IID) override { - return acsmAddPattern2( - obj, (unsigned char *)P, m, - noCase, offset, depth, negative, ID, IID ); + return acsmAddPattern2(obj, P, m, noCase, negative, ID, IID); }; int prep_patterns( SnortConfig* sc, mpse_build_f build_tree, mpse_negate_f neg_list) override { - return acsmCompile2WithSnortConf(sc, obj, build_tree, neg_list); + return acsmCompile2(sc, obj, build_tree, neg_list); }; int _search( @@ -83,6 +80,14 @@ public: obj, (unsigned char *)T, n, action, data, current_state); }; + int search_all( + const unsigned char* T, int n, mpse_action_f action, + void* data, int* current_state ) override + { + return acsmSearchSparseDFA_Full_All( + obj, (unsigned char *)T, n, action, data, current_state); + }; + int print_info() override { return acsmPrintDetailInfo2(obj); @@ -130,7 +135,7 @@ static const MpseApi acf_api = { PT_SEARCH_ENGINE, "ac_full", - "Aho-Corasick Full (high memory, best performance)", + "Aho-Corasick Full (high memory, best performance), implements search_all()", SEAPI_PLUGIN_V0, 0, nullptr, diff --git a/src/search_engines/ac_full_q.cc b/src/search_engines/ac_full_q.cc index 92d293214..bfda5812b 100644 --- a/src/search_engines/ac_full_q.cc +++ b/src/search_engines/ac_full_q.cc @@ -60,19 +60,16 @@ public: acsmCompressStates(obj, flag); }; int add_pattern( - SnortConfig*, void* P, int m, - unsigned noCase, unsigned offset, unsigned depth, - unsigned negative, void* ID, int IID) override + SnortConfig*, const uint8_t* P, unsigned m, + bool noCase, bool negative, void* ID, int IID) override { - return acsmAddPattern2( - obj, (unsigned char *)P, m, - noCase, offset, depth, negative, ID, IID ); + return acsmAddPattern2(obj, P, m, noCase, negative, ID, IID); }; int prep_patterns( SnortConfig* sc, mpse_build_f build_tree, mpse_negate_f neg_list) override { - return acsmCompile2WithSnortConf(sc, obj, build_tree, neg_list); + return acsmCompile2(sc, obj, build_tree, neg_list); }; int _search( @@ -83,6 +80,14 @@ public: obj, (unsigned char *)T, n, action, data, current_state); }; + int search_all( + const unsigned char* T, int n, mpse_action_f action, + void* data, int* current_state ) override + { + return acsmSearchSparseDFA_Full_q_all( + obj, (unsigned char *)T, n, action, data, current_state); + }; + int print_info() override { return acsmPrintDetailInfo2(obj); @@ -130,7 +135,8 @@ static const MpseApi acfq_api = { PT_SEARCH_ENGINE, "ac_full_q", - "Aho-Corasick Full (high memory, best performance) with queued events", + "Aho-Corasick Full (high memory, best performance) with queued events," + " implements search_all()", SEAPI_PLUGIN_V0, 0, nullptr, diff --git a/src/search_engines/ac_sparse.cc b/src/search_engines/ac_sparse.cc index 36342920e..2dfa9625b 100644 --- a/src/search_engines/ac_sparse.cc +++ b/src/search_engines/ac_sparse.cc @@ -52,19 +52,16 @@ public: { if (obj) acsmFree2(obj); }; int add_pattern( - SnortConfig*, void* P, int m, - unsigned noCase, unsigned offset, unsigned depth, - unsigned negative, void* ID, int IID) override + SnortConfig*, const uint8_t* P, unsigned m, + bool noCase, bool negative, void* ID, int IID) override { - return acsmAddPattern2( - obj, (unsigned char *)P, m, - noCase, offset, depth, negative, ID, IID ); + return acsmAddPattern2(obj, P, m, noCase, negative, ID, IID); }; int prep_patterns( SnortConfig* sc, mpse_build_f build_tree, mpse_negate_f neg_list) override { - return acsmCompile2WithSnortConf(sc, obj, build_tree, neg_list); + return acsmCompile2(sc, obj, build_tree, neg_list); }; int _search( diff --git a/src/search_engines/ac_sparse_bands.cc b/src/search_engines/ac_sparse_bands.cc index cf728503e..808fcc697 100644 --- a/src/search_engines/ac_sparse_bands.cc +++ b/src/search_engines/ac_sparse_bands.cc @@ -55,19 +55,16 @@ public: }; int add_pattern( - SnortConfig*, void* P, int m, - unsigned noCase, unsigned offset, unsigned depth, - unsigned negative, void* ID, int IID) override + SnortConfig*, const uint8_t* P, unsigned m, + bool noCase, bool negative, void* ID, int IID) override { - return acsmAddPattern2( - obj, (unsigned char *)P, m, - noCase, offset, depth, negative, ID, IID ); + return acsmAddPattern2(obj, P, m, noCase, negative, ID, IID); }; int prep_patterns( SnortConfig* sc, mpse_build_f build_tree, mpse_negate_f neg_list) override { - return acsmCompile2WithSnortConf(sc, obj, build_tree, neg_list); + return acsmCompile2(sc, obj, build_tree, neg_list); }; int _search( diff --git a/src/search_engines/ac_std.cc b/src/search_engines/ac_std.cc index 1b36b6041..4376f3b23 100644 --- a/src/search_engines/ac_std.cc +++ b/src/search_engines/ac_std.cc @@ -57,20 +57,16 @@ public: }; int add_pattern( - SnortConfig*, void* P, int m, - unsigned noCase, unsigned offset, unsigned depth, - unsigned negative, void* ID, int IID) override + SnortConfig*, const uint8_t* P, unsigned m, + bool noCase, bool negative, void* ID, int IID) override { - return acsmAddPattern( - obj, (unsigned char *)P, m, - noCase, offset, depth, negative, ID, IID ); + return acsmAddPattern(obj, P, m, noCase, negative, ID, IID); }; int prep_patterns( SnortConfig* sc, mpse_build_f build_tree, mpse_negate_f neg_list) override { - return acsmCompileWithSnortConf( - sc, obj, build_tree, neg_list); + return acsmCompile(sc, obj, build_tree, neg_list); }; int _search( diff --git a/src/search_engines/acsmx.cc b/src/search_engines/acsmx.cc index 443a4cc09..8afcad9a6 100644 --- a/src/search_engines/acsmx.cc +++ b/src/search_engines/acsmx.cc @@ -219,7 +219,7 @@ void acsmx_init_xlatcase () /* * */ -static inline void ConvertCaseEx (unsigned char *d, unsigned char *s, int m) +static inline void ConvertCaseEx (unsigned char *d, const uint8_t* s, int m) { int i; for (i = 0; i < m; i++) @@ -449,8 +449,9 @@ ACSM_STRUCT * acsmNew (void (*userfree)(void *p), * Add a pattern to the list of patterns for this state machine */ int -acsmAddPattern (ACSM_STRUCT * p, unsigned char *pat, int n, int nocase, - int offset, int depth, int negative, void * id, int iid) +acsmAddPattern( + ACSM_STRUCT * p, const uint8_t *pat, unsigned n, bool nocase, + bool negative, void * id, int iid) { ACSM_PATTERN * plist; plist = (ACSM_PATTERN *) AC_MALLOC (sizeof (ACSM_PATTERN)); @@ -468,8 +469,6 @@ acsmAddPattern (ACSM_STRUCT * p, unsigned char *pat, int n, int nocase, plist->n = n; plist->nocase = nocase; plist->negative = negative; - plist->offset = offset; - plist->depth = depth; plist->iid = iid; plist->next = p->acsmPatterns; p->acsmPatterns = plist; @@ -477,46 +476,7 @@ acsmAddPattern (ACSM_STRUCT * p, unsigned char *pat, int n, int nocase, return 0; } -static int acsmBuildMatchStateTrees( ACSM_STRUCT * acsm, - int (*build_tree)(void * id, void **existing_tree), - int (*neg_list_func)(void *id, void **list) ) -{ - int i, cnt = 0; - ACSM_PATTERN * mlist; - - /* Find the states that have a MatchList */ - for (i = 0; i < acsm->acsmMaxStates; i++) - { - for ( mlist=acsm->acsmStateTable[i].MatchList; - mlist!=NULL; - mlist=mlist->next ) - { - if (mlist->udata->id) - { - if (mlist->negative) - { - neg_list_func(mlist->udata->id, &acsm->acsmStateTable[i].MatchList->neg_list); - } - else - { - build_tree(mlist->udata->id, &acsm->acsmStateTable[i].MatchList->rule_option_tree); - } - } - - cnt++; - } - - if (acsm->acsmStateTable[i].MatchList) - { - /* Last call to finalize the tree */ - build_tree(NULL, &acsm->acsmStateTable[i].MatchList->rule_option_tree); - } - } - - return cnt; -} - -static int acsmBuildMatchStateTreesWithSnortConf( +static int acsmBuildMatchStateTrees( SnortConfig* sc, ACSM_STRUCT * acsm, int (*build_tree)(SnortConfig*, void * id, void **existing_tree), @@ -575,7 +535,7 @@ static inline int _acsmCompile (ACSM_STRUCT * acsm) acsm->acsmStateTable = (ACSM_STATETABLE *) AC_MALLOC (sizeof (ACSM_STATETABLE) * acsm->acsmMaxStates); - MEMASSERT (acsm->acsmStateTable, "acsmCompile"); + MEMASSERT (acsm->acsmStateTable, "_acsmCompile"); memset (acsm->acsmStateTable, 0, sizeof (ACSM_STATETABLE) * acsm->acsmMaxStates); @@ -622,24 +582,7 @@ static inline int _acsmCompile (ACSM_STRUCT * acsm) return 0; } -int acsmCompile (ACSM_STRUCT * acsm, - int (*build_tree)(void * id, void **existing_tree), - int (*neg_list_func)(void *id, void **list)) -{ - int rval; - - if ((rval = _acsmCompile (acsm))) - return rval; - - if (build_tree && neg_list_func) - { - acsmBuildMatchStateTrees(acsm, build_tree, neg_list_func); - } - - return 0; -} - -int acsmCompileWithSnortConf ( +int acsmCompile( SnortConfig* sc, ACSM_STRUCT * acsm, int (*build_tree)(SnortConfig*, void * id, void **existing_tree), @@ -652,7 +595,7 @@ int acsmCompileWithSnortConf ( if (build_tree && neg_list_func) { - acsmBuildMatchStateTreesWithSnortConf(sc, acsm, build_tree, neg_list_func); + acsmBuildMatchStateTrees(sc, acsm, build_tree, neg_list_func); } return 0; @@ -663,9 +606,9 @@ static THREAD_LOCAL unsigned char Tc[64*1024]; /* * Search Text or Binary Data for Pattern matches */ -int acsmSearch (ACSM_STRUCT * acsm, unsigned char *Tx, int n, - int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), - void *data, int* current_state ) +int acsmSearch ( + ACSM_STRUCT * acsm, unsigned char *Tx, int n, MpseCallback Match, + void *data, int* current_state ) { int state = 0; ACSM_PATTERN * mlist; @@ -873,7 +816,7 @@ int main (int argc, char **argv) { if (argv[i][0] == '-') continue; - acsmAddPattern (acsm, argv[i], strlen (argv[i]), nocase, 0, 0, + acsmAddPattern (acsm, (uint8_t*)argv[i], strlen (argv[i]), nocase, 0, 0, argv[i], i - 2); } acsmCompile (acsm); diff --git a/src/search_engines/acsmx.h b/src/search_engines/acsmx.h index be11ce540..ee30d6579 100644 --- a/src/search_engines/acsmx.h +++ b/src/search_engines/acsmx.h @@ -33,6 +33,7 @@ #include #include #include +#include "search_common.h" #ifndef ACSMX_H #define ACSMX_H @@ -60,11 +61,9 @@ typedef struct _acsm_pattern { unsigned char *casepatrn; int n; int nocase; - int offset; - int depth; int negative; - ACSM_USERDATA *udata; int iid; + ACSM_USERDATA *udata; void * rule_option_tree; void * neg_list; @@ -115,8 +114,8 @@ ACSM_STRUCT * acsmNew (void (*userfree)(void *p), void (*optiontreefree)(void **p), void (*neg_list_free)(void **p)); -int acsmAddPattern( ACSM_STRUCT * p, unsigned char * pat, int n, - int nocase, int offset, int depth, int negative, void * id, int iid ); +int acsmAddPattern( ACSM_STRUCT * p, const uint8_t * pat, unsigned n, + bool nocase, bool negative, void * id, int iid ); int acsmCompile ( ACSM_STRUCT * acsm, int (*build_tree)(void * id, void **existing_tree), @@ -124,15 +123,14 @@ int acsmCompile ( ACSM_STRUCT * acsm, struct SnortConfig; -int acsmCompileWithSnortConf ( +int acsmCompile( SnortConfig*, ACSM_STRUCT * acsm, int (*build_tree)(SnortConfig*, void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list)); int acsmSearch ( - ACSM_STRUCT * acsm,unsigned char * T, int n, - int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), + ACSM_STRUCT * acsm,unsigned char * T, int n, MpseCallback, void * data, int* current_state ); void acsmFree ( ACSM_STRUCT * acsm ); diff --git a/src/search_engines/acsmx2.cc b/src/search_engines/acsmx2.cc index 400dd595f..071c805b5 100644 --- a/src/search_engines/acsmx2.cc +++ b/src/search_engines/acsmx2.cc @@ -214,7 +214,7 @@ void acsmx2_init_xlatcase() /* * Case Conversion */ -static inline void ConvertCaseEx (unsigned char *d, unsigned char *s, int m) +static inline void ConvertCaseEx (unsigned char *d, const uint8_t* s, int m) { int i; #ifdef XXXX @@ -1512,8 +1512,9 @@ ACSM_STRUCT2 * acsmNew2 (void (*userfree)(void *p), * Add a pattern to the list of patterns for this state machine * */ -int acsmAddPattern2 (ACSM_STRUCT2 * p, unsigned char *pat, int n, int nocase, - int offset, int depth, int negative, void * id, int iid) +int acsmAddPattern2 ( + ACSM_STRUCT2 * p, const uint8_t* pat, unsigned n, bool nocase, + bool negative, void * id, int iid) { ACSM_PATTERN2 * plist; @@ -1535,8 +1536,6 @@ int acsmAddPattern2 (ACSM_STRUCT2 * p, unsigned char *pat, int n, int nocase, plist->n = n; plist->nocase = nocase; - plist->offset = offset; - plist->depth = depth; plist->negative = negative; plist->iid = iid; plist->udata = id; @@ -1571,8 +1570,6 @@ int acsmAddKey2( plist->n = klen; plist->nocase = nocase; - plist->offset = 0; - plist->depth = 0; plist->iid = 0; plist->udata = 0; @@ -1612,40 +1609,7 @@ static void acsmUpdateMatchStates( ACSM_STRUCT2 *acsm) } } -static int acsmBuildMatchStateTrees2( ACSM_STRUCT2 * acsm, - int (*build_tree)(void * id, void **existing_tree), - int (*neg_list_func)(void *id, void **list) ) -{ - int i, cnt = 0; - ACSM_PATTERN2 ** MatchList = acsm->acsmMatchList; - ACSM_PATTERN2 * mlist; - - /* Find the states that have a MatchList */ - for (i = 0; i < acsm->acsmNumStates; i++) { - for ( mlist=MatchList[i]; - mlist!=NULL; - mlist=mlist->next ) { - if (mlist->udata) { - if (mlist->negative) { - neg_list_func(mlist->udata, &MatchList[i]->neg_list); - } else { - build_tree(mlist->udata, &MatchList[i]->rule_option_tree); - } - } - - cnt++; - } - - if (MatchList[i]) { - /* Last call to finalize the tree */ - build_tree(NULL, &MatchList[i]->rule_option_tree); - } - } - - return cnt; -} - -static int acsmBuildMatchStateTrees2WithSnortConf( +static int acsmBuildMatchStateTrees2( SnortConfig* sc, ACSM_STRUCT2 * acsm, int (*build_tree)(SnortConfig*, void * id, void **existing_tree), @@ -1707,7 +1671,7 @@ static inline int _acsmCompile2( ACSM_STRUCT2* acsm) acsm->acsmTransTable = (trans_node_t**)AC_MALLOC(sizeof(trans_node_t*) * acsm->acsmMaxStates, ACSM2_MEMORY_TYPE__TRANSTABLE); - MEMASSERT(acsm->acsmTransTable, "acsmCompile"); + MEMASSERT(acsm->acsmTransTable, "_acsmCompile2"); if (s_verbose) { printf("ACSMX-Max Memory-TransTable Setup: %d bytes, %d states, " @@ -1719,7 +1683,7 @@ static inline int _acsmCompile2( ACSM_STRUCT2* acsm) acsm->acsmMatchList = (ACSM_PATTERN2 **)AC_MALLOC(sizeof(ACSM_PATTERN2*) * acsm->acsmMaxStates, ACSM2_MEMORY_TYPE__MATCHLIST); - MEMASSERT(acsm->acsmMatchList, "acsmCompile"); + MEMASSERT(acsm->acsmMatchList, "_acsmCompile2"); if (s_verbose) { printf("ACSMX-Max Memory- MatchList Table Setup: %d bytes, %d states, " @@ -1761,13 +1725,13 @@ static inline int _acsmCompile2( ACSM_STRUCT2* acsm) acsm->acsmFailState = (acstate_t*)AC_MALLOC(sizeof(acstate_t) * acsm->acsmNumStates, ACSM2_MEMORY_TYPE__FAILSTATE); - MEMASSERT(acsm->acsmFailState, "acsmCompile"); + MEMASSERT(acsm->acsmFailState, "_acsmCompile2"); /* Alloc a separate state transition table == in state 's' due to event 'k', transition to 'next' state */ acsm->acsmNextState = (acstate_t**)AC_MALLOC_DFA(acsm->acsmNumStates * sizeof(acstate_t*), acsm->sizeofstate); - MEMASSERT(acsm->acsmNextState, "acsmCompile-NextState"); + MEMASSERT(acsm->acsmNextState, "_acsmCompile2-NextState"); if (s_verbose) { printf("ACSMX-Max Trie List Memory : %d bytes, %d states, %d " @@ -1891,24 +1855,6 @@ static inline int _acsmCompile2( ACSM_STRUCT2* acsm) } int acsmCompile2( - ACSM_STRUCT2* acsm, - int (*build_tree)(void* id, void** existing_tree), - int (*neg_list_func)(void* id, void** list) -) -{ - int rval; - - if ((rval = _acsmCompile2(acsm))) - return rval; - - if (build_tree && neg_list_func) { - acsmBuildMatchStateTrees2(acsm, build_tree, neg_list_func); - } - - return 0; -} - -int acsmCompile2WithSnortConf( SnortConfig* sc, ACSM_STRUCT2* acsm, int (*build_tree)(SnortConfig*, void* id, void** existing_tree), @@ -1921,7 +1867,7 @@ int acsmCompile2WithSnortConf( return rval; if (build_tree && neg_list_func) { - acsmBuildMatchStateTrees2WithSnortConf(sc, acsm, build_tree, neg_list_func); + acsmBuildMatchStateTrees2(sc, acsm, build_tree, neg_list_func); } return 0; @@ -2107,9 +2053,9 @@ static inline acstate_t SparseGetNextStateDFA( * * Sparse & Sparse-Banded Matrix search */ -int acsmSearchSparseDFA(ACSM_STRUCT2 * acsm, unsigned char *Tx, int n, - int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), - void *data, int* current_state ) +int acsmSearchSparseDFA( + ACSM_STRUCT2 * acsm, unsigned char *Tx, int n, MpseCallback Match, + void *data, int* current_state ) { acstate_t state; ACSM_PATTERN2 * mlist; @@ -2197,9 +2143,8 @@ static inline int _add_queue(PMQ * b, void * p ) return 0; } -static inline unsigned _process_queue( PMQ * q, - int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), - void *data ) +static inline unsigned _process_queue( + PMQ * q, MpseCallback Match, void *data ) { ACSM_PATTERN2 * mlist; unsigned int i; @@ -2255,8 +2200,7 @@ static inline unsigned _process_queue( PMQ * q, } int acsmSearchSparseDFA_Full_q( - ACSM_STRUCT2 *acsm, unsigned char *T, int n, - int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), + ACSM_STRUCT2 *acsm, unsigned char *T, int n, MpseCallback Match, void *data, int *current_state) { unsigned char *Tend; @@ -2304,6 +2248,110 @@ int acsmSearchSparseDFA_Full_q( return 0; } +/* + * Matching states are queued, duplicate matches are dropped, + * and after the complete buffer scan, the queued matches are + * processed. This improves cacheing performance, and reduces + * duplicate rule processing. The queue is limited in size and + * is flushed if it becomes full during the scan. This allows + * simple insertions. Tracking queue ops is optional, as this can + * impose a modest performance hit of a few percent. + */ +#define AC_SEARCH_Q_ALL \ + for (; T < Tend; T++) \ + { \ + ps = NextState[state]; \ + sindex = xlatcase[T[0]]; \ + if (ps[1]) \ + { \ + for( mlist = MatchList[state]; \ + mlist!= NULL; \ + mlist = mlist->next ) \ + { \ + if( mlist->nocase || (memcmp (mlist->casepatrn, T - mlist->n, mlist->n ) == 0)) \ + { \ + if (_add_queue(&acsm->q,mlist)) \ + { \ + if (_process_queue(&acsm->q, Match,data)) \ + { \ + *current_state = state; \ + return 1; \ + } \ + } \ + } \ + } \ + } \ + state = ps[2 + sindex]; \ + } + +int acsmSearchSparseDFA_Full_q_all( + ACSM_STRUCT2 *acsm, const unsigned char *T, int n, MpseCallback Match, + void *data, int *current_state) +{ + const unsigned char *Tend; + int sindex; + acstate_t state; + ACSM_PATTERN2 **MatchList = acsm->acsmMatchList; + ACSM_PATTERN2 *mlist; + + Tend = T + n; + + if (current_state == NULL) + return 0; + + _init_queue(&acsm->q); + + state = *current_state; + + switch (acsm->sizeofstate) + { + case 1: + { + uint8_t *ps; + uint8_t **NextState = (uint8_t **)acsm->acsmNextState; + AC_SEARCH_Q_ALL; + } + break; + case 2: + { + uint16_t *ps; + uint16_t **NextState = (uint16_t **)acsm->acsmNextState; + AC_SEARCH_Q_ALL; + } + break; + default: + { + acstate_t *ps; + acstate_t **NextState = acsm->acsmNextState; + AC_SEARCH_Q_ALL; + } + break; + } + + *current_state = state; + + for( mlist = MatchList[state]; + mlist!= NULL; + mlist = mlist->next ) + { + if( mlist->nocase || (memcmp (mlist->casepatrn, T - mlist->n, mlist->n ) == 0)) + { + if (_add_queue(&acsm->q,mlist)) + { + if (_process_queue(&acsm->q, Match,data)) + { + *current_state = state; + return 1; + } + } + } + } + + _process_queue(&acsm->q,Match,data); + + return 0; +} + /* * Full format DFA search * Do not change anything here without testing, caching and prefetching @@ -2337,8 +2385,7 @@ int acsmSearchSparseDFA_Full_q( } int acsmSearchSparseDFA_Full( - ACSM_STRUCT2 *acsm, unsigned char *Tx, int n, - int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), + ACSM_STRUCT2 *acsm, unsigned char *Tx, int n, MpseCallback Match, void *data, int *current_state ) { @@ -2395,6 +2442,111 @@ int acsmSearchSparseDFA_Full( return nfound; } +/* +* Full format DFA search +* Do not change anything here without testing, caching and prefetching +* performance is very sensitive to any changes. +* +* Perf-Notes: +* 1) replaced ConvertCaseEx with inline xlatcase - this improves performance 5-10% +* 2) using 'nocase' improves performance again by 10-15%, since memcmp is not needed +* 3) +*/ +#define AC_SEARCH_ALL \ + for( ; T < Tend; T++ ) \ + { \ + ps = NextState[ state ]; \ + sindex = xlatcase[T[0]]; \ + if (ps[1]) \ + { \ + for( mlist = MatchList[state]; \ + mlist!= NULL; \ + mlist = mlist->next ) \ + { \ + index = T - mlist->n - Tx; \ + if( mlist->nocase || (memcmp (mlist->casepatrn, Tx + index, mlist->n ) == 0)) \ + { \ + nfound++; \ + if (Match (mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) \ + { \ + *current_state = state; \ + return nfound; \ + } \ + } \ + } \ + } \ + state = ps[2u + sindex]; \ + } + +int acsmSearchSparseDFA_Full_All( + ACSM_STRUCT2 *acsm, const unsigned char *Tx, int n, MpseCallback Match, + void *data, int *current_state) +{ + ACSM_PATTERN2 *mlist; + const unsigned char * Tend; + const unsigned char * T; + int index; + int sindex; + int nfound = 0; + acstate_t state; + ACSM_PATTERN2 **MatchList = acsm->acsmMatchList; + + T = Tx; + Tend = Tx + n; + + if (current_state == NULL) + return 0; + + state = *current_state; + + switch (acsm->sizeofstate) + { + case 1: + { + uint8_t *ps; + uint8_t **NextState = (uint8_t **)acsm->acsmNextState; + AC_SEARCH_ALL; + } + break; + case 2: + { + uint16_t *ps; + uint16_t **NextState = (uint16_t **)acsm->acsmNextState; + AC_SEARCH_ALL; + } + break; + default: + { + acstate_t *ps; + acstate_t **NextState = acsm->acsmNextState; + AC_SEARCH_ALL; + } + break; + } + + /* Check the last state for a pattern match */ + for( mlist = MatchList[state]; + mlist!= NULL; + mlist = mlist->next ) + { + index = T - mlist->n - Tx; + + if( mlist->nocase || (memcmp (mlist->casepatrn, Tx + index, mlist->n) == 0)) + { + nfound++; + if (Match(mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) + { + *current_state = state; + return nfound; + } + } + } + + + *current_state = state; + return nfound; +} + /* * Banded-Row format DFA search * Do not change anything here, caching and prefetching @@ -2405,9 +2557,9 @@ int acsmSearchSparseDFA_Full( * ps[2] = # elements in band * ps[3] = index of 1st element */ -int acsmSearchSparseDFA_Banded(ACSM_STRUCT2 * acsm, unsigned char *Tx, int n, - int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), - void *data, int* current_state ) +int acsmSearchSparseDFA_Banded( + ACSM_STRUCT2 * acsm, unsigned char *Tx, int n, MpseCallback Match, + void *data, int* current_state ) { acstate_t state; unsigned char * Tend; @@ -2473,9 +2625,9 @@ int acsmSearchSparseDFA_Banded(ACSM_STRUCT2 * acsm, unsigned char *Tx, int n, * * Sparse Storage Version */ -int acsmSearchSparseNFA(ACSM_STRUCT2 * acsm, unsigned char *Tx, int n, - int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), - void *data, int* current_state ) +int acsmSearchSparseNFA( + ACSM_STRUCT2 * acsm, unsigned char *Tx, int n, MpseCallback Match, + void *data, int* current_state ) { acstate_t state; ACSM_PATTERN2 * mlist; @@ -2521,44 +2673,6 @@ int acsmSearchSparseNFA(ACSM_STRUCT2 * acsm, unsigned char *Tx, int n, return nfound; } -/* -* Search Function -*/ -int acsmSearch2(ACSM_STRUCT2 * acsm, unsigned char *Tx, int n, - int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), - void *data, int* current_state ) -{ - - switch( acsm->acsmFSA ) { - case FSA_DFA: - - if( acsm->acsmFormat == ACF_FULL ) { - return acsmSearchSparseDFA_Full( acsm, Tx, n, Match, data, - current_state ); - } else if( acsm->acsmFormat == ACF_FULLQ ) { - return acsmSearchSparseDFA_Full_q( acsm, Tx, n, Match, data, - current_state ); - } else if( acsm->acsmFormat == ACF_BANDED ) { - return acsmSearchSparseDFA_Banded( acsm, Tx, n, Match, data, - current_state ); - } else { - return acsmSearchSparseDFA( acsm, Tx, n, Match, data, - current_state ); - } - - case FSA_NFA: - - return acsmSearchSparseNFA( acsm, Tx, n, Match, data, - current_state ); - - case FSA_TRIE: - - return 0; - } - return 0; -} - - /* * Free all memory */ @@ -2760,10 +2874,83 @@ int acsmPrintSummaryInfo2(void) return 0; } +#ifdef ACSMX2S_MAIN +static int acsmSearch2( + ACSM_STRUCT2 * acsm, unsigned char *Tx, int n, MpseCallback Match, + void *data, int* current_state ) +{ + + switch( acsm->acsmFSA ) { + case FSA_DFA: + + if( acsm->acsmFormat == ACF_FULL ) { + return acsmSearchSparseDFA_Full( acsm, Tx, n, Match, data, + current_state ); + } else if( acsm->acsmFormat == ACF_FULLQ ) { + return acsmSearchSparseDFA_Full_q( acsm, Tx, n, Match, data, + current_state ); + } else if( acsm->acsmFormat == ACF_BANDED ) { + return acsmSearchSparseDFA_Banded( acsm, Tx, n, Match, data, + current_state ); + } else { + return acsmSearchSparseDFA( acsm, Tx, n, Match, data, + current_state ); + } + + case FSA_NFA: + + return acsmSearchSparseNFA( acsm, Tx, n, Match, data, + current_state ); + + case FSA_TRIE: + + return 0; + } + return 0; +} + +static int acsmSearchAll2( + ACSM_STRUCT2 * acsm, unsigned char *Tx, int n, MpseCallback Match, + void *data, int* current_state ) +{ + switch( acsm->acsmFSA ) + { + case FSA_DFA: + if( acsm->acsmFormat == ACF_FULL ) + { + return acsmSearchSparseDFA_Full_All( acsm, Tx, n, Match, data, + current_state ); + } + else if( acsm->acsmFormat == ACF_FULLQ ) + { + return acsmSearchSparseDFA_Full_q_all( acsm, Tx, n, Match, data, + current_state ); + } + else if( acsm->acsmFormat == ACF_BANDED ) + { + return acsmSearchSparseDFA_Banded( acsm, Tx, n, Match, data, + current_state ); + } + else + { + return acsmSearchSparseDFA( acsm, Tx, n, Match, data, + current_state ); + } + + case FSA_NFA: + + return acsmSearchSparseNFA( acsm, Tx, n, Match, data, + current_state ); + + case FSA_TRIE: + + return 0; + } + return 0; +} -#ifdef ACSMX2S_MAIN /* * Text Data Buffer @@ -2773,8 +2960,7 @@ unsigned char text[512]; /* * A Match is found */ -int -MatchFound (void* id, int index, void *data) +int MatchFound (void* id, int index, void *data) { fprintf (stdout, "%s\n", (char *) id); return 0; @@ -2863,7 +3049,7 @@ main (int argc, char **argv) nc = nocase; } - acsmAddPattern2 (acsm, p, strlen(p), nc, 0, 0,(void*)p, i - 2); + acsmAddPattern2 (acsm, (uint8_t*)p, strlen(p), nc, 0, 0,(void*)p, i - 2); } if(s_verbose)printf("Patterns added\n"); diff --git a/src/search_engines/acsmx2.h b/src/search_engines/acsmx2.h index 3b0e0f407..a188e2c0c 100644 --- a/src/search_engines/acsmx2.h +++ b/src/search_engines/acsmx2.h @@ -30,8 +30,10 @@ #endif #include +#include #include #include +#include "search_common.h" #ifndef ACSMX2_H #define ACSMX2_H @@ -74,11 +76,9 @@ struct _acsm_pattern2 unsigned char *casepatrn; int n; int nocase; - int offset; - int depth; int negative; - void *udata; int iid; + void *udata; void * rule_option_tree; void * neg_list; @@ -177,8 +177,8 @@ ACSM_STRUCT2* acsmNew2( void (*neg_list_free)(void **p)); int acsmAddPattern2( - ACSM_STRUCT2 * p, unsigned char * pat, int n, - int nocase, int offset, int depth, int negative, void * id, int iid ); + ACSM_STRUCT2 * p, const uint8_t* pat, unsigned n, + bool nocase, bool negative, void * id, int iid ); int acsmCompile2( ACSM_STRUCT2 * acsm, @@ -187,42 +187,40 @@ int acsmCompile2( struct SnortConfig; -int acsmCompile2WithSnortConf( +int acsmCompile2( SnortConfig*, ACSM_STRUCT2 * acsm, int (*build_tree)(SnortConfig*, void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list)); -int acsmSearch2( - ACSM_STRUCT2 * acsm,unsigned char * T, int n, - int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), - void * data, int* current_state ); - int acsmSearchSparseDFA_Full( - ACSM_STRUCT2 * acsm,unsigned char * T, int n, - int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), + ACSM_STRUCT2 * acsm,unsigned char * T, int n, MpseCallback Match, void * data, int* current_state ); int acsmSearchSparseDFA_Full_q( - ACSM_STRUCT2 * acsm,unsigned char * T, int n, - int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), + ACSM_STRUCT2 * acsm,unsigned char * T, int n, MpseCallback Match, void * data, int* current_state ); int acsmSearchSparseDFA_Banded( - ACSM_STRUCT2 * acsm,unsigned char * T, int n, - int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), + ACSM_STRUCT2 * acsm,unsigned char * T, int n, MpseCallback Match, void * data, int* current_state ); int acsmSearchSparseDFA( - ACSM_STRUCT2 * acsm,unsigned char * T, int n, - int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), + ACSM_STRUCT2 * acsm,unsigned char * T, int n, MpseCallback Match, void * data, int* current_state ); int acsmSearchSparseNFA( - ACSM_STRUCT2 * acsm,unsigned char * T, int n, - int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), + ACSM_STRUCT2 * acsm,unsigned char * T, int n, MpseCallback Match, void * data, int* current_state ); +int acsmSearchSparseDFA_Full_All( + ACSM_STRUCT2 *acsm, const unsigned char *Tx, int n, MpseCallback Match, + void *data, int *current_state); + +int acsmSearchSparseDFA_Full_q_all( + ACSM_STRUCT2 *acsm, const unsigned char *T, int n, MpseCallback Match, + void *data, int *current_state); + void acsmFree2( ACSM_STRUCT2 * acsm ); int acsmPatternCount2 ( ACSM_STRUCT2 * acsm ); void acsmCompressStates(ACSM_STRUCT2 *, int); diff --git a/src/search_engines/bnfa_search.cc b/src/search_engines/bnfa_search.cc index 7e137d411..bbd3cb6f0 100644 --- a/src/search_engines/bnfa_search.cc +++ b/src/search_engines/bnfa_search.cc @@ -162,6 +162,7 @@ #include "pat_stats.h" #include "snort_debug.h" #include "util.h" +#include "search_common.h" /* * Used to initialize last state, states are limited to 0-16M @@ -170,6 +171,7 @@ #define LAST_STATE_INIT 0xffffffff #define printf LogMessage + /* * Case Translation Table - this guarantees we use * indexed lookups for case conversion @@ -425,41 +427,7 @@ static int _bnfa_list_free_table( bnfa_struct_t * bnfa ) return 0; } -static int bnfaBuildMatchStateTrees(bnfa_struct_t *bnfa, - int (*build_tree)(void *id, void **existing_tree), - int (*neg_list_func)(void *id, void **list)) -{ - int i,cnt = 0; - bnfa_match_node_t * mn; - bnfa_match_node_t ** MatchList = bnfa->bnfaMatchList; - bnfa_pattern_t * patrn; - - for (i=0; ibnfaNumStates; i++) { - for(mn = MatchList[i]; - mn!= NULL; - mn = mn->next ) { - patrn = (bnfa_pattern_t *)mn->data; - if (patrn->userdata) { - if (patrn->negative) { - neg_list_func(patrn->userdata, &MatchList[i]->neg_list); - } else { - build_tree(patrn->userdata, &MatchList[i]->rule_option_tree); - } - } - - cnt++; - } - - /* Last call to finalize the tree */ - if (MatchList[i]) { - build_tree(NULL, &MatchList[i]->rule_option_tree); - } - } - - return cnt; -} - -static int bnfaBuildMatchStateTreesWithSnortConf( +static int bnfaBuildMatchStateTrees( SnortConfig* sc, bnfa_struct_t *bnfa, int (*build_tree)(SnortConfig*, void *id, void **existing_tree), @@ -538,7 +506,6 @@ static int _bnfa_list_print_table( bnfa_struct_t * bnfa ) t = t->next; } } - mn =bnfa->bnfaMatchList[i]; while( mn ) { patrn =(bnfa_pattern_t *)mn->data; @@ -1304,12 +1271,13 @@ void bnfaFree (bnfa_struct_t * bnfa) /* * Add a pattern to the pattern list */ -int bnfaAddPattern (bnfa_struct_t * p, - unsigned char *pat, - int n, - int nocase, - int negative, - void * userdata ) +int bnfaAddPattern( + bnfa_struct_t * p, + const uint8_t* pat, + unsigned n, + bool nocase, + bool negative, + void * userdata ) { bnfa_pattern_t * plist; @@ -1454,22 +1422,7 @@ static inline int _bnfaCompile (bnfa_struct_t * bnfa) return 0; } -int bnfaCompile (bnfa_struct_t * bnfa, - int (*build_tree)(void * id, void **existing_tree), - int (*neg_list_func )(void *id, void **list)) -{ - int rval; - - if ((rval = _bnfaCompile (bnfa))) - return rval; - - if (build_tree && neg_list_func) { - bnfaBuildMatchStateTrees( bnfa, build_tree, neg_list_func ); - } - return 0; -} - -int bnfaCompileWithSnortConf ( +int bnfaCompile( SnortConfig* sc, bnfa_struct_t * bnfa, int (*build_tree)(SnortConfig*, void * id, void **existing_tree), @@ -1481,7 +1434,7 @@ int bnfaCompileWithSnortConf ( return rval; if (build_tree && neg_list_func) { - bnfaBuildMatchStateTreesWithSnortConf( sc, bnfa, build_tree, neg_list_func ); + bnfaBuildMatchStateTrees( sc, bnfa, build_tree, neg_list_func ); } return 0; } @@ -1491,9 +1444,9 @@ int bnfaCompileWithSnortConf ( /* * Full Matrix Format Search */ -static inline unsigned _bnfa_search_full_nfa( bnfa_struct_t * bnfa, unsigned char *Tx, int n, - int (*Match)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list), - void *data, bnfa_state_t state, int *current_state ) +static inline unsigned _bnfa_search_full_nfa( + bnfa_struct_t * bnfa, unsigned char *Tx, int n, bnfa_match_f Match, + void *data, bnfa_state_t state, int *current_state ) { unsigned char * Tend; unsigned char * T; @@ -1564,9 +1517,9 @@ static inline unsigned _bnfa_search_full_nfa( bnfa_struct_t * bnfa, unsigned /* * Full Matrix Format Search - Exact matching patterns only */ -static inline unsigned _bnfa_search_full_nfa_case( bnfa_struct_t * bnfa, unsigned char *Tx, int n, - int (*Match)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list), - void *data, bnfa_state_t state, int *current_state ) +static inline unsigned _bnfa_search_full_nfa_case( + bnfa_struct_t * bnfa, unsigned char *Tx, int n, bnfa_match_f Match, + void *data, bnfa_state_t state, int *current_state ) { unsigned char * Tend; unsigned char * T; @@ -1637,9 +1590,9 @@ static inline unsigned _bnfa_search_full_nfa_case( bnfa_struct_t * bnfa, unsi /* * Full Matrix Format Search - no case */ -static inline unsigned _bnfa_search_full_nfa_nocase( bnfa_struct_t * bnfa, unsigned char *Tx, int n, - int (*Match)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list), - void *data, bnfa_state_t state, int *current_state ) +static inline unsigned _bnfa_search_full_nfa_nocase( + bnfa_struct_t * bnfa, unsigned char *Tx, int n, bnfa_match_f Match, + void *data, bnfa_state_t state, int *current_state ) { unsigned char * Tend; unsigned char * T; @@ -1905,9 +1858,8 @@ static inline int _add_queue(bnfa_struct_t* b, bnfa_match_node_t * p ) return 0; } -static inline unsigned _process_queue( bnfa_struct_t * bnfa, - int (*Match)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list), - void *data ) +static inline unsigned _process_queue( + bnfa_struct_t * bnfa, bnfa_match_f Match, void *data ) { bnfa_match_node_t * mlist; bnfa_pattern_t * patrn; @@ -1937,9 +1889,8 @@ static inline unsigned _process_queue( bnfa_struct_t * bnfa, return 0; } -static inline unsigned _bnfa_search_csparse_nfa_qx(bnfa_struct_t * bnfa, unsigned char *T, int n, - int (*Match)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list), - void *data ) +static inline unsigned _bnfa_search_csparse_nfa_qx( + bnfa_struct_t * bnfa, unsigned char *T, int n, bnfa_match_f Match, void *data ) { bnfa_match_node_t * mlist; unsigned char * Tend; @@ -1973,8 +1924,7 @@ static inline unsigned _bnfa_search_csparse_nfa_qx(bnfa_struct_t * bnfa, unsigne } unsigned _bnfa_search_csparse_nfa_q( - bnfa_struct_t * bnfa, unsigned char *T, int n, - int (*Match)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list), + bnfa_struct_t * bnfa, unsigned char *T, int n, bnfa_match_f Match, void *data, unsigned sindex, int *current_state ) { bnfa_match_node_t * mlist; @@ -2022,13 +1972,12 @@ unsigned _bnfa_search_csparse_nfa_q( * note: index is not used by snort, so it's commented */ unsigned _bnfa_search_csparse_nfa( - bnfa_struct_t * bnfa, unsigned char *Tx, int n, - int (*Match)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list), + bnfa_struct_t * bnfa, const uint8_t* Tx, int n, bnfa_match_f Match, void *data, unsigned sindex, int *current_state ) { bnfa_match_node_t * mlist; - unsigned char * Tend; - unsigned char * T; + const unsigned char * Tend; + const unsigned char * T; unsigned char Tchar; unsigned index; bnfa_match_node_t ** MatchList = bnfa->bnfaMatchList; @@ -2096,9 +2045,9 @@ unsigned _bnfa_search_csparse_nfa( * * note: index is not used by snort, so it's commented */ -static inline unsigned _bnfa_search_csparse_nfa_case( bnfa_struct_t * bnfa, unsigned char *Tx, int n, - int (*Match)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list), - void *data, unsigned sindex, int *current_state ) +static inline unsigned _bnfa_search_csparse_nfa_case( + bnfa_struct_t * bnfa, unsigned char *Tx, int n, bnfa_match_f Match, + void *data, unsigned sindex, int *current_state ) { bnfa_match_node_t * mlist; unsigned char * Tend; @@ -2157,9 +2106,9 @@ static inline unsigned _bnfa_search_csparse_nfa_case( bnfa_struct_t * bnfa, un * * note: index is not used by snort, so it's commented */ -static inline unsigned _bnfa_search_csparse_nfa_nocase( bnfa_struct_t * bnfa, unsigned char *Tx, int n, - int (*Match)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list), - void *data, unsigned sindex, int *current_state ) +static inline unsigned _bnfa_search_csparse_nfa_nocase( + bnfa_struct_t * bnfa, unsigned char *Tx, int n, bnfa_match_f Match, + void *data, unsigned sindex, int *current_state ) { bnfa_match_node_t * mlist; unsigned char * Tend; @@ -2217,144 +2166,6 @@ static inline unsigned _bnfa_search_csparse_nfa_nocase( bnfa_struct_t * bnfa, return nfound; } -/* -* BNFA Search Function -* -* bnfa - state machine -* Tx - text buffer to search -* n - number of bytes in Tx -* Match - function to call when a match is found -* data - user supplied data that is passed to the Match function -* sindex - state tracker, set value to zero to reset the state machine, -* zero should be the value passed in on the 1st buffer or each buffer -* that is to be analyzed on its own, the state machine updates this -* during searches. This allows for sequential buffer searchs without -* reseting the state machine. Save this value as returned from the -* previous search for the next search. -* -* returns -* The state or sindex of the state machine. This can than be passed back -* in on the next search, if desired. -*/ -unsigned bnfaSearchX( - bnfa_struct_t * bnfa, unsigned char *T, int n, - int (*Match)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list), - void *data, unsigned, int*) -{ - int ret; - - _init_queue(bnfa); - while( n > 0) { - ret = _bnfa_search_csparse_nfa_qx( bnfa, T++, n--, Match, data ); - - if( ret ) - return 0; - } - return _process_queue( bnfa, Match, data ); -} - -// FIXIT-L eliminate the if-else- -unsigned bnfaSearch( bnfa_struct_t * bnfa, unsigned char *Tx, int n, - int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), - void *data, unsigned sindex, int* current_state ) -{ - assert(current_state); - int ret = 0; - - if (current_state) { - sindex = (unsigned)*current_state; - } - -#ifdef ALLOW_NFA_FULL - if( bnfa->bnfaFormat == BNFA_SPARSE ) - { - if( bnfa->bnfaCaseMode == BNFA_PER_PAT_CASE ) - { - if (bnfa->bnfaMethod) - { - ret = _bnfa_search_csparse_nfa( - bnfa, Tx, n, - (int (*)(bnfa_pattern_t* id, void* tree, int index, void *data, void *neg_list)) - Match, data, sindex, current_state ); - } else { - ret = _bnfa_search_csparse_nfa_q( - bnfa, Tx, n, - (int (*)(bnfa_pattern_t* id, void *tree, int index, void *data, void *neg_list)) - Match, data, sindex, current_state ); - } - } - else if( bnfa->bnfaCaseMode == BNFA_CASE ) - { - ret = _bnfa_search_csparse_nfa_case( - bnfa, Tx, n, - (int (*)(bnfa_pattern_t* id, void *tree, int index, void *data, void *neg_list)) - Match, data, sindex, current_state ); - - } else { /* NOCASE */ - ret = _bnfa_search_csparse_nfa_nocase( - bnfa, Tx, n, - (int (*)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list)) - Match, data, sindex, current_state ); - } - } - else if( bnfa->bnfaFormat == BNFA_FULL ) - { - if( bnfa->bnfaCaseMode == BNFA_PER_PAT_CASE ) - { - ret = _bnfa_search_full_nfa( - bnfa, Tx, n, - (int (*)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list)) - Match, data, (bnfa_state_t) sindex, current_state ); - - } - else if( bnfa->bnfaCaseMode == BNFA_CASE ) - { - ret = _bnfa_search_full_nfa_case( - bnfa, Tx, n, - (int (*)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list)) - Match, data, (bnfa_state_t) sindex, current_state ); - - } else { - ret = _bnfa_search_full_nfa_nocase( - bnfa, Tx, n, - (int (*)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list)) - Match, data, (bnfa_state_t) sindex, current_state ); - } - } -#else - if( bnfa->bnfaCaseMode == BNFA_PER_PAT_CASE ) { - - if (bnfa->bnfaMethod) - { - ret = _bnfa_search_csparse_nfa( - bnfa, Tx, n, - (int (*)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list)) - Match, data, sindex, current_state ); - - } else { - ret = _bnfa_search_csparse_nfa_q( - bnfa, Tx, n, - (int (*)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list)) - Match, data, sindex, current_state ); - } - } - else if( bnfa->bnfaCaseMode == BNFA_CASE ) - { - ret = _bnfa_search_csparse_nfa_case( - bnfa, Tx, n, - (int (*)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list)) - Match, data, sindex, current_state ); - - } else { /* NOCASE */ - ret = _bnfa_search_csparse_nfa_nocase( - bnfa, Tx, n, - (int (*)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list)) - Match, data, sindex, current_state ); - } -#endif - return ret; -} - int bnfaPatternCount( bnfa_struct_t * p) { return p->bnfaPatternCnt; @@ -2463,6 +2274,121 @@ void bnfaPrintMatchListCnt( bnfa_struct_t * p ) #ifdef BNFA_MAIN #include +/* +* BNFA Search Function +* +* bnfa - state machine +* Tx - text buffer to search +* n - number of bytes in Tx +* Match - function to call when a match is found +* data - user supplied data that is passed to the Match function +* sindex - state tracker, set value to zero to reset the state machine, +* zero should be the value passed in on the 1st buffer or each buffer +* that is to be analyzed on its own, the state machine updates this +* during searches. This allows for sequential buffer searchs without +* reseting the state machine. Save this value as returned from the +* previous search for the next search. +* +* returns +* The state or sindex of the state machine. This can than be passed back +* in on the next search, if desired. +*/ +unsigned bnfaSearchX( + bnfa_struct_t * bnfa, unsigned char *T, int n, bnfa_match_f Match, + void *data, unsigned, int*) +{ + int ret; + + _init_queue(bnfa); + while( n > 0) { + ret = _bnfa_search_csparse_nfa_qx( bnfa, T++, n--, Match, data ); + + if( ret ) + return 0; + } + return _process_queue( bnfa, Match, data ); +} + +// FIXIT-L eliminate the if-else- +unsigned bnfaSearch( + bnfa_struct_t * bnfa, unsigned char *Tx, int n, bnfa_match_f Match, + void *data, unsigned sindex, int* current_state ) +{ + assert(current_state); + int ret = 0; + + if (current_state) { + sindex = (unsigned)*current_state; + } + +#ifdef ALLOW_NFA_FULL + if( bnfa->bnfaFormat == BNFA_SPARSE ) + { + if( bnfa->bnfaCaseMode == BNFA_PER_PAT_CASE ) + { + if (bnfa->bnfaMethod) + { + ret = _bnfa_search_csparse_nfa( + bnfa, Tx, n, Match, data, sindex, current_state ); + } else { + ret = _bnfa_search_csparse_nfa_q( + bnfa, Tx, n, Match, data, sindex, current_state ); + } + } + else if( bnfa->bnfaCaseMode == BNFA_CASE ) + { + ret = _bnfa_search_csparse_nfa_case( + bnfa, Tx, n, Match, data, sindex, current_state ); + + } else { /* NOCASE */ + ret = _bnfa_search_csparse_nfa_nocase( + bnfa, Tx, n, Match, data, sindex, current_state ); + } + } + else if( bnfa->bnfaFormat == BNFA_FULL ) + { + if( bnfa->bnfaCaseMode == BNFA_PER_PAT_CASE ) + { + ret = _bnfa_search_full_nfa( + bnfa, Tx, n, Match, data, (bnfa_state_t) sindex, current_state ); + + } + else if( bnfa->bnfaCaseMode == BNFA_CASE ) + { + ret = _bnfa_search_full_nfa_case( + bnfa, Tx, n, Match, data, (bnfa_state_t) sindex, current_state ); + + } else { + ret = _bnfa_search_full_nfa_nocase( + bnfa, Tx, n, Match, data, (bnfa_state_t) sindex, current_state ); + } + } +#else + if( bnfa->bnfaCaseMode == BNFA_PER_PAT_CASE ) { + + if (bnfa->bnfaMethod) + { + ret = _bnfa_search_csparse_nfa( + bnfa, Tx, n, Match, data, sindex, current_state ); + + } else { + ret = _bnfa_search_csparse_nfa_q( + bnfa, Tx, n, Match, data, sindex, current_state ); + } + } + else if( bnfa->bnfaCaseMode == BNFA_CASE ) + { + ret = _bnfa_search_csparse_nfa_case( + bnfa, Tx, n, Match, data, sindex, current_state ); + + } else { /* NOCASE */ + ret = _bnfa_search_csparse_nfa_nocase( + bnfa, Tx, n, Match, data, sindex, current_state ); + } +#endif + return ret; +} + /* * Text Data Buffer */ @@ -2571,7 +2497,7 @@ int main (int argc, char **argv) nc = nocase; } - bnfaAddPattern (bnfa, p, strlen(p), nc, 0, (void*)NULL); + bnfaAddPattern (bnfa, (uint8_t*)p, strlen(p), nc, 0, (void*)NULL); } if(s_verbose)printf("Patterns added\n"); diff --git a/src/search_engines/bnfa_search.h b/src/search_engines/bnfa_search.h index e15d28d83..b87da20d1 100644 --- a/src/search_engines/bnfa_search.h +++ b/src/search_engines/bnfa_search.h @@ -29,6 +29,7 @@ */ #include +#include #include #include @@ -69,7 +70,7 @@ typedef struct bnfa_pattern struct bnfa_pattern * next; unsigned char * casepatrn; /* case specific */ - int n; /* pattern len */ + unsigned n; /* pattern len */ int nocase; /* nocase flag */ int negative; /* pattern is negated */ void * userdata; /* ptr to users pattern data/info */ @@ -170,30 +171,25 @@ void bnfaSetOpt(bnfa_struct_t * p, int flag); void bnfaSetCase(bnfa_struct_t * p, int flag); void bnfaFree( bnfa_struct_t * pstruct ); -int bnfaAddPattern( bnfa_struct_t * pstruct, - unsigned char * pat, int patlen, int nocase, - int negative, void * userdata); +int bnfaAddPattern( + bnfa_struct_t * pstruct, const uint8_t* pat, unsigned patlen, + bool nocase, bool negative, void * userdata); int bnfaCompile( bnfa_struct_t * pstruct, int (*build_tree)(void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list)); struct SnortConfig; -int bnfaCompileWithSnortConf( +int bnfaCompile( SnortConfig*, bnfa_struct_t * pstruct, int (*build_tree)(SnortConfig*, void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list)); -unsigned bnfaSearch( - bnfa_struct_t * pstruct, unsigned char * t, int tlen, - int (*match)(void * id, void *tree, int index, void *data, void *neg_list), - void * sdata, unsigned sindex, int* current_state ); - typedef int (*bnfa_match_f)( - bnfa_pattern_t*, void *tree, int index, void *data, void *neg_list); + bnfa_pattern_t*, void* tree, int index, void* data, void* neg_list); unsigned _bnfa_search_csparse_nfa( - bnfa_struct_t * pstruct, unsigned char * t, int tlen, bnfa_match_f, + bnfa_struct_t * pstruct, const uint8_t* t, int tlen, bnfa_match_f, void * sdata, unsigned sindex, int* current_state ); unsigned _bnfa_search_csparse_nfa_q( diff --git a/src/search_engines/intel_cpm.cc b/src/search_engines/intel_cpm.cc index 6ac869e2e..6496d3e0a 100644 --- a/src/search_engines/intel_cpm.cc +++ b/src/search_engines/intel_cpm.cc @@ -68,13 +68,10 @@ public: }; int add_pattern( - SnortConfig* sc, void* P, int m, - unsigned noCase, unsigned offset, unsigned depth, - unsigned negative, void* ID, int IID) override + SnortConfig* sc, const uint8_t* P, unsigned m, + bool noCase, bool negative, void* ID, int IID) override { - return IntelPmAddPattern( - sc, obj, (unsigned char *)P, m, - noCase, negative, ID, IID); + return IntelPmAddPattern(sc, obj, P, m, noCase, negative, ID, IID); }; int prep_patterns( diff --git a/src/search_engines/intel_soft_cpm.cc b/src/search_engines/intel_soft_cpm.cc index 904da72e0..373d68081 100644 --- a/src/search_engines/intel_soft_cpm.cc +++ b/src/search_engines/intel_soft_cpm.cc @@ -72,12 +72,8 @@ typedef struct _IntelPmHandles } IntelPmHandles; -typedef int (*MatchFunc)(void * id, void *tree, int index, void *data, void *neg_list); - - /* GLOBALS ********************************************************************/ static CpaInstanceHandle ipm_instance = NULL; /* instance handle */ -static IntelPmHandles *ipm_handles = NULL; /* XXX Temporary stat for Intel */ //static uint64_t intel_pm_search_buf_sizes[65536]; @@ -141,8 +137,8 @@ static inline int IntelPmAddQueue(IntelPmMatchQueue *q, void *p) return 0; } -static inline unsigned int IntelPmProcessQueue(IntelPmMatchQueue *q, - MatchFunc match, void *data) +static inline unsigned int IntelPmProcessQueue( + IntelPmMatchQueue *q, MatchFunc match, void *data) { unsigned int i; @@ -204,7 +200,7 @@ void * IntelPmNew( CpaStatus status; IntelPm *ipm = (IntelPm *)SnortAlloc(sizeof(IntelPm)); - if (ipm_handles == NULL) + if (sc->ipm_handles == NULL) { CpaPmPdbPatternSetHandle patternSetHandle; @@ -212,11 +208,12 @@ void * IntelPmNew( if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmPdbCreatePatternSet() failed: %s\n", GetCpaStatusStr(status)); - ipm_handles = (IntelPmHandles *)SnortAlloc(sizeof(IntelPmHandles)); - ipm_handles->psh = patternSetHandle; - ipm_handles->pdbh = NULL; - ipm_handles->pgids = 1; - ipm_handles->pids = 0; + sc->ipm_handles = (IntelPmHandles *)SnortAlloc(sizeof(IntelPmHandles)); + sc->ipm_handles->psh = patternSetHandle; + sc->ipm_handles->pdbh = NULL; + sc->ipm_handles->pgids = 1; + sc->ipm_handles->pids = 0; + sc->ipm_handles->refs = 1; //sc has a reference //memset(intel_pm_search_buf_sizes, 0, sizeof(intel_pm_search_buf_sizes)); } @@ -226,15 +223,14 @@ void * IntelPmNew( ipm->neg_list_free = neg_list_free; ipm->match_queue = SnortAlloc(sizeof(IntelPmMatchQueue)); - ipm->handles = ipm_handles; - ipm_handles->refs++; + ipm->handles = sc->ipm_handles; + sc->ipm_handles->refs++; return (void *)ipm; } void IntelPmDelete(IntelPm *ipm) { - IntelPmHandles *handles; int i; if (ipm == NULL) @@ -258,22 +254,21 @@ void IntelPmDelete(IntelPm *ipm) } free(ipm->pattern_array); - - handles = (IntelPmHandles *)ipm->handles; - handles->refs--; - if (handles->refs == 0) - IntelPmRelease(handles); - + IntelPmRelease(ipm->handles); free(ipm); } -static void IntelPmRelease(IntelPmHandles *handles) +int IntelPmRelease(IntelPmHandles *handles) { CpaStatus status; int i; if (handles == NULL) - return; + return -1; + + handles->refs--; + if (handles->refs != 0) + return handles->refs; for (i = 0; i < handles->pm_mtchs_len; i++) { @@ -304,17 +299,16 @@ static void IntelPmRelease(IntelPmHandles *handles) free(handles->pm_mtchs); free(handles); - if ( handles == ipm_handles ) - ipm_handles = NULL; + return 0; } int IntelPmAddPattern( SnortConfig *sc, IntelPm *ipm, - unsigned char *pat, - int pat_len, - unsigned no_case, - unsigned negative, + const uint8_t *pat, + unsigned pat_len, + bool no_case, + bool negative, void *pat_data, int pat_id) { @@ -323,18 +317,18 @@ int IntelPmAddPattern( CpaStatus status; IntelPmPattern *ipp; - if ((ipm == NULL) || (ipm_handles == NULL)) + if ((ipm == NULL) || (sc->ipm_handles == NULL)) return -1; if (!ipm->patternGroupId) { - ipm->patternGroupId = ipm_handles->pgids++; + ipm->patternGroupId = sc->ipm_handles->pgids++; ipm->patternIds = 1; } status = cpaPmPdbAddPattern( ipm_instance, - ipm_handles->psh, + sc->ipm_handles->psh, ipm->patternIds, patternOptions, pat_len, @@ -373,8 +367,8 @@ int IntelPmAddPattern( ipp->id = pat_id; ipp->patternId = ipm->patternIds++; - ipm_handles->pids++; - ipm_handles->pcs += pat_len; + sc->ipm_handles->pids++; + sc->ipm_handles->pcs += pat_len; return 0; } @@ -411,66 +405,66 @@ int IntelPmFinishGroup( if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmCreateSessionCtx() failed: %s\n", GetCpaStatusStr(status)); - if (ipm_handles->ipms == NULL) + if (sc->ipm_handles->ipms == NULL) { - ipm_handles->ipms = (IntelPm **)SnortAlloc( + sc->ipm_handles->ipms = (IntelPm **)SnortAlloc( sizeof(IntelPm *) * GROUP_ARRAY_ALLOC_SIZE); - ipm_handles->ipms_len = GROUP_ARRAY_ALLOC_SIZE; + sc->ipm_handles->ipms_len = GROUP_ARRAY_ALLOC_SIZE; } - else if (ipm->patternGroupId >= ipm_handles->ipms_len) + else if (ipm->patternGroupId >= sc->ipm_handles->ipms_len) { IntelPm **tmp = (IntelPm **)SnortAlloc( sizeof(IntelPm *) * (ipm->patternGroupId + GROUP_ARRAY_ALLOC_SIZE)); - memcpy((void *)tmp, ipm_handles->ipms, ipm_handles->ipms_len * sizeof(IntelPm *)); - free(ipm_handles->ipms); - ipm_handles->ipms = tmp; - ipm_handles->ipms_len = ipm->patternGroupId + GROUP_ARRAY_ALLOC_SIZE; + memcpy((void *)tmp, sc->ipm_handles->ipms, sc->ipm_handles->ipms_len * sizeof(IntelPm *)); + free(sc->ipm_handles->ipms); + sc->ipm_handles->ipms = tmp; + sc->ipm_handles->ipms_len = ipm->patternGroupId + GROUP_ARRAY_ALLOC_SIZE; } - ipm_handles->ipms[ipm->patternGroupId] = ipm; + sc->ipm_handles->ipms[ipm->patternGroupId] = ipm; return 0; } void IntelPmCompile(SnortConfig *sc) { - if ((ipm_instance == NULL) || (ipm_handles == NULL) - || (ipm_handles->psh == NULL)) + if ((ipm_instance == NULL) || (sc->ipm_handles == NULL) + || (sc->ipm_handles->psh == NULL)) { return; } - if (ipm_handles->pdbh == NULL) + if (sc->ipm_handles->pdbh == NULL) { CpaStatus status; Cpa16U patternGroup; Cpa32U numMatchStates; - status = cpaPmPdbCompile(ipm_instance, ipm_handles->psh, - CPA_PM_COMPILE_OPTION_CONSOLIDATE, NULL, &ipm_handles->pdbh); + status = cpaPmPdbCompile(ipm_instance, sc->ipm_handles->psh, + CPA_PM_COMPILE_OPTION_CONSOLIDATE, NULL, &sc->ipm_handles->pdbh); if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmPdbCompile() failed: %s\n", GetCpaStatusStr(status)); - status = cpaPmMsoGetNumMatchStates(ipm_instance, ipm_handles->pdbh, &numMatchStates); + status = cpaPmMsoGetNumMatchStates(ipm_instance, sc->ipm_handles->pdbh, &numMatchStates); if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmMsoGetNumMatchStates() failed: %s\n", GetCpaStatusStr(status)); /* Hack because the last match state is returned instead of the * number of match states */ numMatchStates += 1; - ipm_handles->pm_mtchs = (IntelPmMatchState *)SnortAlloc(numMatchStates * sizeof(IntelPmMatchState)); - ipm_handles->pm_mtchs_len = numMatchStates; + sc->ipm_handles->pm_mtchs = (IntelPmMatchState *)SnortAlloc(numMatchStates * sizeof(IntelPmMatchState)); + sc->ipm_handles->pm_mtchs_len = numMatchStates; - for (patternGroup = 1; patternGroup < ipm_handles->pgids; patternGroup++) + for (patternGroup = 1; patternGroup < sc->ipm_handles->pgids; patternGroup++) { CpaPmMsoMatchStateIter matchStateIter = NULL; Cpa32U matchStateId; - IntelPm *ipm = ipm_handles->ipms[patternGroup]; + IntelPm *ipm = sc->ipm_handles->ipms[patternGroup]; if (ipm == NULL) continue; - status = cpaPmMsoGetFirstMatchState(ipm_instance, ipm_handles->pdbh, + status = cpaPmMsoGetFirstMatchState(ipm_instance, sc->ipm_handles->pdbh, patternGroup, &matchStateIter, &matchStateId); if (status != CPA_STATUS_SUCCESS) @@ -485,7 +479,7 @@ void IntelPmCompile(SnortConfig *sc) void *neg_list = NULL; void *user_data = NULL; - status = cpaPmMsoGetFirstPatternId(ipm_instance, ipm_handles->pdbh, + status = cpaPmMsoGetFirstPatternId(ipm_instance, sc->ipm_handles->pdbh, matchStateIter, &patternIdIter, &patternID); if (status != CPA_STATUS_SUCCESS) @@ -502,7 +496,7 @@ void IntelPmCompile(SnortConfig *sc) else ipm->build_tree(sc, ipp->user_data, &rule_option_tree); - status = cpaPmMsoGetNextPatternId(ipm_instance, ipm_handles->pdbh, + status = cpaPmMsoGetNextPatternId(ipm_instance, sc->ipm_handles->pdbh, &patternIdIter, &patternID); if (status != CPA_STATUS_SUCCESS) @@ -513,16 +507,16 @@ void IntelPmCompile(SnortConfig *sc) { ipm->build_tree(sc, NULL, &rule_option_tree); - ipm_handles->pm_mtchs[matchStateId].user_data = user_data; - ipm_handles->pm_mtchs[matchStateId].neg_list = neg_list; - ipm_handles->pm_mtchs[matchStateId].rule_option_tree = rule_option_tree; + sc->ipm_handles->pm_mtchs[matchStateId].user_data = user_data; + sc->ipm_handles->pm_mtchs[matchStateId].neg_list = neg_list; + sc->ipm_handles->pm_mtchs[matchStateId].rule_option_tree = rule_option_tree; - ipm_handles->pm_mtchs[matchStateId].user_free = ipm->user_free; - ipm_handles->pm_mtchs[matchStateId].option_tree_free = ipm->option_tree_free; - ipm_handles->pm_mtchs[matchStateId].neg_list_free = ipm->neg_list_free; + sc->ipm_handles->pm_mtchs[matchStateId].user_free = ipm->user_free; + sc->ipm_handles->pm_mtchs[matchStateId].option_tree_free = ipm->option_tree_free; + sc->ipm_handles->pm_mtchs[matchStateId].neg_list_free = ipm->neg_list_free; } - status = cpaPmMsoGetNextMatchState(ipm_instance, ipm_handles->pdbh, + status = cpaPmMsoGetNextMatchState(ipm_instance, sc->ipm_handles->pdbh, patternGroup, &matchStateIter, &matchStateId); if (status != CPA_STATUS_SUCCESS) @@ -536,15 +530,15 @@ void IntelPmActivate(SnortConfig *sc) { CpaStatus status; - if ((ipm_instance == NULL) || (ipm_handles == NULL)) + if ((ipm_instance == NULL) || (sc->ipm_handles == NULL)) return; - status = cpaPmActivatePdb(ipm_instance, ipm_handles->pdbh, NULL); + status = cpaPmActivatePdb(ipm_instance, sc->ipm_handles->pdbh, NULL); if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmPdbActivate() failed: %s\n", GetCpaStatusStr(status)); /* All ipms should have a reference to this now. Need this for reloading */ - ipm_handles = NULL; + sc->ipm_handles = NULL; } static void IntelPmSearchCallback(const CpaInstanceHandle instanceHandle, @@ -575,8 +569,9 @@ static void IntelPmSearchCallback(const CpaInstanceHandle instanceHandle, } } -int IntelPmSearch(IntelPm *ipm, unsigned char *buffer, int buffer_len, - MatchFunc match, void *data) +int IntelPmSearch( + IntelPm *ipm, unsigned char *buffer, int buffer_len, + MatchFunc match, void *data) { CpaFlatBuffer flat_buffer = {buffer_len, buffer}; CpaBufferList buffer_list = {1, &flat_buffer, NULL, NULL}; @@ -629,13 +624,13 @@ int IntelPmPrintInfo(IntelPm *ipm) void IntelPmPrintSummary(SnortConfig *sc) { - if (ipm_handles == NULL) + if (sc->ipm_handles == NULL) return; LogMessage("+-[Intel PM Search Info Summary]------------------\n"); - LogMessage("| Instances : %u\n", ipm_handles->pgids - 1); /* pattern groups start at 1 */ - LogMessage("| Patterns : %u\n", ipm_handles->pids); - LogMessage("| Pattern Chars : %u\n", ipm_handles->pcs); + LogMessage("| Instances : %u\n", sc->ipm_handles->pgids - 1); /* pattern groups start at 1 */ + LogMessage("| Patterns : %u\n", sc->ipm_handles->pids); + LogMessage("| Pattern Chars : %u\n", sc->ipm_handles->pcs); LogMessage("+-------------------------------------------------\n"); } diff --git a/src/search_engines/intel_soft_cpm.h b/src/search_engines/intel_soft_cpm.h index 3337d7789..23ddf4bee 100644 --- a/src/search_engines/intel_soft_cpm.h +++ b/src/search_engines/intel_soft_cpm.h @@ -58,7 +58,7 @@ typedef struct _IntelPm /* Temporary data for match callback */ void *data; - int (*match)(void *id, void *tree, int index, void *data, void *neg_list); + MpseCallback match; void (*user_free)(void *); void (*option_tree_free)(void **); @@ -88,10 +88,10 @@ void IntelPmDelete(IntelPm *ipm); int IntelPmAddPattern( SnortConfig* sc, IntelPm *ipm, - unsigned char *pat, - int pat_len, - unsigned no_case, - unsigned negative, + const uint8_t *pat, + unsigned pat_len, + bool no_case, + bool negative, void *pat_data, int pat_id); @@ -105,13 +105,13 @@ void IntelPmCompile(SnortConfig*); void IntelPmActivate(SnortConfig*); void IntelPmDeactivate(void); -int IntelPmSearch(IntelPm *ipm, unsigned char *buffer, int buffer_len, - int (*match)(void * id, void *tree, int index, void *data, void *neg_list), - void *data); +int IntelPmSearch( + IntelPm *ipm, unsigned char *buffer, int buffer_len, MpseCallback, void *data); int IntelGetPatternCount(IntelPm *ipm); int IntelPmPrintInfo(IntelPm *ipm); void IntelPmPrintSummary(SnortConfig*); void IntelPmPrintBufferStats(void); +int IntelPmRelease(struct _IntelPmHandles*); #endif /* INTEL_SOFT_CPM_H */ diff --git a/src/search_engines/str_search.h b/src/search_engines/search_common.h similarity index 55% rename from src/search_engines/str_search.h rename to src/search_engines/search_common.h index 9e6a781e0..625278e2f 100644 --- a/src/search_engines/str_search.h +++ b/src/search_engines/search_common.h @@ -1,6 +1,5 @@ //-------------------------------------------------------------------------- -// Copyright (C) 2014-2015 Cisco and/or its affiliates. All rights reserved. -// Copyright (C) 2005-2013 Sourcefire, Inc. +// Copyright (C) 2015-2015 Cisco and/or its affiliates. All rights reserved. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License Version 2 as published @@ -17,23 +16,10 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -#ifndef STR_SEARCH_H -#define STR_SEARCH_H +#ifndef SEARCH_COMMON_H +#define SEARCH_COMMON_H -typedef int (*MatchFunction)(void *, void *, int, void *, void *); - -typedef struct _search_api -{ - void * (*search_instance_new)(void); - void (*search_instance_free)(void * instance); - void (*search_instance_add) (void * instance, const char *s, unsigned int s_len, int s_id); - void (*search_instance_prep)(void * instance ); - int (*search_instance_find)(void * instance, const char *s, unsigned int s_len, int confine, MatchFunction); - -} SearchAPI; - -// FIXIT-L search_api should be turned into a class -// (constructed of an Mpse, not subclassed) -extern SearchAPI *search_api; +typedef int (*MpseCallback)(void* id, void* tree, int index, void* data, void* neg_list); #endif + diff --git a/src/search_engines/search_tool.cc b/src/search_engines/search_tool.cc new file mode 100644 index 000000000..69576b8a2 --- /dev/null +++ b/src/search_engines/search_tool.cc @@ -0,0 +1,117 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2015-2015 Cisco and/or its affiliates. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License Version 2 as published +// by the Free Software Foundation. You may not use, modify or distribute +// this program under any other version of the GNU General Public License. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +//-------------------------------------------------------------------------- +// search_tool.cc author Russ Combs + +#include "search_tool.h" + +#include +#include +#include + +#include "main/thread.h" +#include "framework/mpse.h" +#include "managers/mpse_manager.h" + +SearchTool::SearchTool() +{ + mpse = MpseManager::get_search_engine("ac_bnfa"); + max_len = 0; +} + +SearchTool::~SearchTool() +{ + MpseManager::delete_search_engine(mpse); +} + +void SearchTool::add(const char* pat, unsigned len, int id, bool no_case) +{ + add((uint8_t*)pat, len, id, no_case); +} + +void SearchTool::add(const uint8_t* pat, unsigned len, int id, bool no_case) +{ + if ( mpse ) + mpse->add_pattern( + nullptr, pat, len, no_case, false, (void *)(long) id, 0); + + if ( len > max_len ) + max_len = len; +} + +void SearchTool::prep() +{ + if ( mpse ) + mpse->prep_patterns(nullptr, nullptr, nullptr); +} + +int SearchTool::find( + const char* str, + unsigned len, + mpse_action_f mf, + int& state, + bool confine, + void* user_data) +{ + if ( confine && max_len > 0 ) + { + if ( max_len < len ) + len = max_len; + } + if ( !user_data ) + user_data = (void*)str; + + int num = mpse->search( + (const unsigned char*)str, len, mf, user_data, &state); + + return num; +} + +int SearchTool::find( + const char* str, + unsigned len, + mpse_action_f mf, + bool confine, + void* user_data) +{ + int state = 0; + return find(str, len, mf, state, confine, user_data); +} + +int SearchTool::find_all( + const char* str, + unsigned len, + mpse_action_f mf, + bool confine, + void* user_data) +{ + if ( confine && max_len > 0 ) + { + if ( max_len < len ) + len = max_len; + } + if ( !user_data ) + user_data = (void*)str; + + int state = 0; + + int num = mpse->search_all( + (const unsigned char*)str, len, mf, user_data, &state); + + return num; +} + diff --git a/src/search_engines/search_tool.h b/src/search_engines/search_tool.h new file mode 100644 index 000000000..e21ab26f1 --- /dev/null +++ b/src/search_engines/search_tool.h @@ -0,0 +1,51 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2015-2015 Cisco and/or its affiliates. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License Version 2 as published +// by the Free Software Foundation. You may not use, modify or distribute +// this program under any other version of the GNU General Public License. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +//-------------------------------------------------------------------------- +// search_tool.h author Russ Combs + +#ifndef SEARCH_TOOL_H +#define SEARCH_TOOL_H + +#include "framework/mpse.h" + +class SearchTool +{ +public: + SearchTool(); + ~SearchTool(); + + void add(const char* pattern, unsigned len, int s_id, bool no_case = true); + void add(const uint8_t* pattern, unsigned len, int s_id, bool no_case = true); + + void prep(); + + // set state to zero on first call + int find(const char* s, unsigned s_len, mpse_action_f, int& state, + bool confine = false, void* user_data = nullptr); + + int find(const char* s, unsigned s_len, mpse_action_f, + bool confine = false, void* user_data = nullptr); + + int find_all(const char* s, unsigned s_len, mpse_action_f, + bool confine = false, void* user_data = nullptr); + +private: + class Mpse* mpse; + unsigned max_len; +}; + +#endif diff --git a/src/search_engines/str_search.cc b/src/search_engines/str_search.cc deleted file mode 100644 index b58d148c0..000000000 --- a/src/search_engines/str_search.cc +++ /dev/null @@ -1,123 +0,0 @@ -//-------------------------------------------------------------------------- -// Copyright (C) 2014-2015 Cisco and/or its affiliates. All rights reserved. -// Copyright (C) 2005-2013 Sourcefire, Inc. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License Version 2 as published -// by the Free Software Foundation. You may not use, modify or distribute -// this program under any other version of the GNU General Public License. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -//-------------------------------------------------------------------------- - -#include "str_search.h" - -#include -#include -#include - -#include "main/thread.h" -#include "framework/mpse.h" -#include "managers/mpse_manager.h" - -typedef struct tag_search -{ - Mpse* mpse; - unsigned int max_len; -} t_search; - -static void* SearchInstanceNew(void) -{ - t_search * search = (t_search*)malloc(sizeof(t_search)); - if( !search ) - return NULL; - - search->mpse = MpseManager::get_search_engine("ac_bnfa"); - - if (search->mpse == NULL ) - { - free(search); - return NULL; - } - search->max_len=0; - - return search; -} - -static void SearchInstanceFree( void * instance ) -{ - t_search * search = (t_search*)instance; - if( instance ) - { - MpseManager::delete_search_engine(search->mpse); - free( instance ); - } -} - -static void SearchInstanceAdd( - void*instance, const char *pat, unsigned int pat_len, int id) -{ - t_search * search = (t_search*)instance; - - if( search && search->mpse ) - search->mpse->add_pattern( - NULL, (void *)pat, pat_len, 1, 0, 0, 0, (void *)(long) id, 0); - - if ( search && pat_len > search->max_len ) - search->max_len = pat_len; - -} - -static void SearchInstancePrepPatterns(void * instance) -{ - t_search * search = (t_search*)instance; - if( search && search->mpse ) - { - search->mpse->prep_patterns(NULL, NULL, NULL); - } -} - -static int SearchInstanceFindString( - void * instance, - const char *str, - unsigned int str_len, - int confine, - int (*Match) (void *, void *, int, void *, void *)) -{ - int num; - int start_state = 0; - t_search * search = (t_search*)instance; - - if ( confine && (search->max_len > 0) ) - { - if ( search->max_len < str_len ) - { - str_len = search->max_len; - } - } - num = search->mpse->search( - (unsigned char*)str, str_len, Match, (void *) str, &start_state); - - return num; - -} - -/* API exported by this module */ -SearchAPI searchAPI = -{ - SearchInstanceNew, - SearchInstanceFree, - SearchInstanceAdd, - SearchInstancePrepPatterns, - SearchInstanceFindString, -}; - -SearchAPI *search_api = &searchAPI; - diff --git a/src/service_inspectors/http_inspect/hi_main.cc b/src/service_inspectors/http_inspect/hi_main.cc index 9391281a4..ab0001482 100644 --- a/src/service_inspectors/http_inspect/hi_main.cc +++ b/src/service_inspectors/http_inspect/hi_main.cc @@ -94,8 +94,8 @@ const HiSearchToken html_patterns[] = {NULL, 0, 0} }; -void *hi_javascript_search_mpse = NULL; -void *hi_htmltype_search_mpse = NULL; +SearchTool* hi_javascript_search_mpse = nullptr; +SearchTool* hi_htmltype_search_mpse = nullptr; static uint32_t xtra_trueip_id; static uint32_t xtra_uri_id; @@ -1232,7 +1232,7 @@ int GetHttpHostnameData(Flow* flow, uint8_t **buf, uint32_t *len, uint32_t *type void HI_SearchInit(void) { const HiSearchToken *tmp; - hi_javascript_search_mpse = search_api->search_instance_new(); + hi_javascript_search_mpse = new SearchTool(); if (hi_javascript_search_mpse == NULL) { FatalError("%s(%d) Could not allocate memory for HTTP