-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
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
{ 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(
};
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(
/*
*
*/
-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++ ) {
/*
*
*/
-static KTRIEPATTERN * KTrieNewPattern(unsigned char * P, int n)
+static KTRIEPATTERN * KTrieNewPattern(const uint8_t* P, unsigned n)
{
KTRIEPATTERN *p;
int ret;
/*
* 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;
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");
#include "config.h"
#endif
+#include <stdint.h>
+
#define ALPHABET_SIZE 256
#define KTRIEMETHOD_STD 0
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,
*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;
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;
{
char boundary[2 + MAX_MIME_BOUNDARY_LEN + 1]; /* '--' + MIME boundary string + '\0' */
int boundary_len;
- void *boundary_search;
+ class SearchTool* boundary_search;
};
#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"
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;
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;
}
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))
/* 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;
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
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;
}
* 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)
{
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
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
{
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);
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;
}
#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
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;
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;
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; };
#include "process.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <fcntl.h>
#include <stdio.h>
#include <sys/wait.h>
#include <malloc.h>
#endif
+#ifdef HAVE_MALLOC_TRIM
+#include <malloc.h>
+#endif
+
#include <iostream>
using namespace std;
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "main.h"
#include "main/analyzer.h"
#include "main/thread.h"
// heap stats
//-------------------------------------------------------------------------
+void trim_heap()
+{
+#ifdef HAVE_MALLOC_TRIM
+ malloc_trim(0);
+#endif
+}
+
void log_malloc_info()
{
#ifdef HAVE_MALLINFO
void daemonize();
void set_quick_exit(bool);
void init_main_thread_sig();
+
+void trim_heap();
void log_malloc_info();
#endif
# include "config.h"
#endif
+#ifdef HAVE_MALLOC_TRIM
+#include <malloc.h>
+#endif
+
#include <mutex>
#include <string>
using namespace std;
{
snort_reloading = true;
ModuleManager::reset_errors();
+ trim_heap();
SnortConfig *sc = ParseSnortConf(snort_cmd_line_conf);
sc = MergeSnortConfs(snort_cmd_line_conf, sc);
#include "config.h"
#endif
+#ifdef HAVE_MALLOC_TRIM
+#include <malloc.h>
+#endif
+
#include "snort_types.h"
#include "detection/treenodes.h"
#include "events/event_queue.h"
#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"
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)
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
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}
)
$(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)
};
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(
};
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);
};
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(
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(
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);
{
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,
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(
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);
{
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,
{ 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(
};
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(
};
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(
/*
*
*/
-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++)
* 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));
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;
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),
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);
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),
if (build_tree && neg_list_func)
{
- acsmBuildMatchStateTreesWithSnortConf(sc, acsm, build_tree, neg_list_func);
+ acsmBuildMatchStateTrees(sc, acsm, build_tree, neg_list_func);
}
return 0;
/*
* 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;
{
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);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include "search_common.h"
#ifndef ACSMX_H
#define ACSMX_H
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;
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),
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 );
/*
* 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
* 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;
plist->n = n;
plist->nocase = nocase;
- plist->offset = offset;
- plist->depth = depth;
plist->negative = negative;
plist->iid = iid;
plist->udata = id;
plist->n = klen;
plist->nocase = nocase;
- plist->offset = 0;
- plist->depth = 0;
plist->iid = 0;
plist->udata = 0;
}
}
-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),
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, "
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, "
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 "
}
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),
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;
*
* 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;
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;
}
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;
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
}
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
)
{
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
* 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;
*
* 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;
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
*/
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
/*
* 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;
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");
#endif
#include <stdio.h>
+#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include "search_common.h"
#ifndef ACSMX2_H
#define ACSMX2_H
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;
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,
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);
#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
#define LAST_STATE_INIT 0xffffffff
#define printf LogMessage
+
/*
* Case Translation Table - this guarantees we use
* indexed lookups for case conversion
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; i<bnfa->bnfaNumStates; 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),
t = t->next;
}
}
-
mn =bnfa->bnfaMatchList[i];
while( mn ) {
patrn =(bnfa_pattern_t *)mn->data;
/*
* 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;
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),
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;
}
/*
* 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;
/*
* 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;
/*
* 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;
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;
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;
}
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;
* 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;
*
* 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;
*
* 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;
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;
#ifdef BNFA_MAIN
#include <stdarg.h>
+/*
+* 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
*/
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");
*/
#include <stdio.h>
+#include <stdint.h>
#include <stdlib.h>
#include <string.h>
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 */
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(
};
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(
} 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];
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;
CpaStatus status;
IntelPm *ipm = (IntelPm *)SnortAlloc(sizeof(IntelPm));
- if (ipm_handles == NULL)
+ if (sc->ipm_handles == NULL)
{
CpaPmPdbPatternSetHandle patternSetHandle;
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));
}
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)
}
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++)
{
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)
{
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,
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;
}
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)
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)
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)
{
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)
{
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,
}
}
-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};
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");
}
/* 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 **);
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);
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 */
//--------------------------------------------------------------------------
-// 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
// 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
+
--- /dev/null
+//--------------------------------------------------------------------------
+// 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 <rucombs@cisco.com>
+
+#include "search_tool.h"
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#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;
+}
+
--- /dev/null
+//--------------------------------------------------------------------------
+// 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 <rucombs@cicso.com>
+
+#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
+++ /dev/null
-//--------------------------------------------------------------------------
-// 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 <sys/types.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-#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;
-
{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;
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 <script> tag search.\n",
{
hi_js_search[tmp->search_id].name = tmp->name;
hi_js_search[tmp->search_id].name_len = tmp->name_len;
- search_api->search_instance_add(hi_javascript_search_mpse, tmp->name, tmp->name_len, tmp->search_id);
+ hi_javascript_search_mpse->add(tmp->name, tmp->name_len, tmp->search_id);
}
- search_api->search_instance_prep(hi_javascript_search_mpse);
+ hi_javascript_search_mpse->prep();
- hi_htmltype_search_mpse = search_api->search_instance_new();
+ hi_htmltype_search_mpse = new SearchTool();
if (hi_htmltype_search_mpse == NULL)
{
FatalError("%s(%d) Could not allocate memory for HTTP <script> type search.\n",
{
hi_html_search[tmp->search_id].name = tmp->name;
hi_html_search[tmp->search_id].name_len = tmp->name_len;
- search_api->search_instance_add(hi_htmltype_search_mpse, tmp->name, tmp->name_len, tmp->search_id);
+ hi_htmltype_search_mpse->add(tmp->name, tmp->name_len, tmp->search_id);
}
- search_api->search_instance_prep(hi_htmltype_search_mpse);
+ hi_htmltype_search_mpse->prep();
}
void HI_SearchFree(void)
{
if (hi_javascript_search_mpse != NULL)
- search_api->search_instance_free(hi_javascript_search_mpse);
+ delete hi_javascript_search_mpse;
if (hi_htmltype_search_mpse != NULL)
- search_api->search_instance_free(hi_htmltype_search_mpse);
+ delete hi_htmltype_search_mpse;
}
int HI_SearchStrFound(void* id, void*, int index, void*, void*)
#include "hi_ui_config.h"
#include "util_utf.h"
#include "detection_util.h"
-#include "search_engines/str_search.h"
+#include "search_engines/search_tool.h"
#include "util_jsnorm.h"
#include "profiler.h"
HTML_LAST
} HtmlSearchId;
-extern void *hi_javascript_search_mpse;
-extern void *hi_htmltype_search_mpse;
+extern class SearchTool* hi_javascript_search_mpse;
+extern class SearchTool* hi_htmltype_search_mpse;
extern THREAD_LOCAL HISearch hi_js_search[HI_LAST];
extern THREAD_LOCAL HISearch hi_html_search[HTML_LAST];
bytes_copied = 0;
type_js = 0;
hi_current_search = &hi_js_search[0];
- script_found = search_api->search_instance_find(hi_javascript_search_mpse, (const char *)ptr,
- (end-ptr), 0 , HI_SearchStrFound);
+
+ script_found = hi_javascript_search_mpse->find(
+ (const char *)ptr, (end-ptr), HI_SearchStrFound);
+
if (script_found > 0)
{
js_start = ptr + hi_search_info.index;
if(angle_bracket > js_start)
{
- script_found = search_api->search_instance_find(hi_htmltype_search_mpse, (const char *)js_start,
- (angle_bracket-js_start), 0 , HI_SearchStrFound);
+ script_found = hi_htmltype_search_mpse->find(
+ (const char *)js_start, (angle_bracket-js_start), HI_SearchStrFound);
+
js_start = angle_bracket;
if(script_found > 0)
{