50 #ifdef BUILD_HYPERSCAN
54 void SCHSInitCtx(
MpmCtx *);
56 void SCHSDestroyCtx(
MpmCtx *);
59 MpmCtx *,
const uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t,
SigIntId, uint8_t);
60 int SCHSAddPatternCS(
MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t,
65 void SCHSPrintInfo(
MpmCtx *mpm_ctx);
68 static void SCHSRegisterTests(
void);
72 #define INIT_HASH_SIZE 65536
75 #define INIT_DB_HASH_SIZE 1000
80 static hs_scratch_t *g_scratch_proto = NULL;
93 static void *SCHSMalloc(
size_t size)
103 static void SCHSFree(
void *ptr)
113 static void SCHSSetAllocators(
void)
115 hs_error_t err = hs_set_allocator(SCHSMalloc, SCHSFree);
116 if (err != HS_SUCCESS) {
117 FatalError(
"Failed to set Hyperscan allocator.");
131 static inline uint32_t SCHSInitHashRaw(
const uint8_t *pat, uint16_t patlen)
133 uint32_t hash = patlen * pat[0];
137 return (hash % INIT_HASH_SIZE);
152 static inline SCHSPattern *SCHSInitHashLookup(SCHSCtx *
ctx,
const uint8_t *pat, uint16_t patlen,
153 uint16_t
offset, uint16_t depth,
char flags, uint32_t pid)
155 uint32_t hash = SCHSInitHashRaw(pat, patlen);
157 if (
ctx->init_hash == NULL) {
161 SCHSPattern *t =
ctx->init_hash[hash];
162 for (; t != NULL; t = t->next) {
165 if (t->id == pid && t->offset ==
offset && t->depth == depth) {
183 static inline SCHSPattern *SCHSAllocPattern(
MpmCtx *mpm_ctx)
185 SCHSPattern *p =
SCCalloc(1,
sizeof(SCHSPattern));
204 static inline void SCHSFreePattern(
MpmCtx *mpm_ctx, SCHSPattern *p)
206 if (p != NULL && p->original_pat != NULL) {
212 if (p != NULL && p->sids != NULL) {
223 static inline uint32_t SCHSInitHash(SCHSPattern *p)
225 uint32_t hash = p->len * p->original_pat[0];
227 hash += p->original_pat[1];
229 return (hash % INIT_HASH_SIZE);
232 static inline int SCHSInitHashAdd(SCHSCtx *
ctx, SCHSPattern *p)
234 uint32_t hash = SCHSInitHash(p);
236 if (
ctx->init_hash == NULL) {
240 if (
ctx->init_hash[hash] == NULL) {
241 ctx->init_hash[hash] = p;
245 SCHSPattern *tt = NULL;
246 SCHSPattern *t =
ctx->init_hash[hash];
273 static int SCHSAddPattern(
MpmCtx *mpm_ctx,
const uint8_t *pat, uint16_t patlen, uint16_t
offset,
276 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
297 p = SCHSAllocPattern(mpm_ctx);
307 if (p->original_pat == NULL)
311 memcpy(p->original_pat, pat, patlen);
314 if (SCHSInitHashAdd(
ctx, p) != 0)
326 SCLogDebug(
"%p: alas, no depth for us", mpm_ctx);
330 if (mpm_ctx->
maxlen < patlen)
333 if (mpm_ctx->
minlen == 0) {
336 if (mpm_ctx->
minlen > patlen)
349 for (x = 0; x < p->sids_size; x++) {
350 if (p->sids[x] == sid) {
359 p->sids[p->sids_size] = sid;
367 SCHSFreePattern(mpm_ctx, p);
375 typedef struct SCHSCompileData_ {
380 unsigned int pattern_cnt;
383 static SCHSCompileData *CompileDataAlloc(
unsigned int pattern_cnt)
385 SCHSCompileData *cd =
SCCalloc(pattern_cnt,
sizeof(SCHSCompileData));
390 cd->pattern_cnt = pattern_cnt;
392 cd->ids =
SCCalloc(pattern_cnt,
sizeof(
unsigned int));
393 if (cd->ids == NULL) {
397 cd->flags =
SCCalloc(pattern_cnt,
sizeof(
unsigned int));
398 if (cd->flags == NULL) {
402 cd->expressions =
SCCalloc(pattern_cnt,
sizeof(
char *));
403 if (cd->expressions == NULL) {
407 cd->ext =
SCCalloc(pattern_cnt,
sizeof(hs_expr_ext_t *));
408 if (cd->ext == NULL) {
426 static void CompileDataFree(SCHSCompileData *cd)
434 if (cd->expressions) {
435 for (
unsigned int i = 0; i < cd->pattern_cnt; i++) {
436 SCFree(cd->expressions[i]);
441 for (
unsigned int i = 0; i < cd->pattern_cnt; i++) {
449 static uint32_t SCHSPatternHash(
const SCHSPattern *p, uint32_t hash)
451 BUG_ON(p->original_pat == NULL);
465 static char SCHSPatternCompare(
const SCHSPattern *p1,
const SCHSPattern *p2)
467 if ((p1->len != p2->len) || (p1->flags != p2->flags) ||
468 (p1->id != p2->id) || (p1->offset != p2->offset) ||
469 (p1->depth != p2->depth) || (p1->sids_size != p2->sids_size)) {
473 if (
SCMemcmp(p1->original_pat, p2->original_pat, p1->len) != 0) {
477 if (
SCMemcmp(p1->sids, p2->sids, p1->sids_size *
sizeof(p1->sids[0])) !=
485 static uint32_t PatternDatabaseHash(
HashTable *ht,
void *data, uint16_t
len)
487 const PatternDatabase *pd = data;
489 hash =
hashword(&pd->pattern_cnt, 1, hash);
491 for (uint32_t i = 0; i < pd->pattern_cnt; i++) {
492 hash = SCHSPatternHash(pd->parray[i], hash);
499 static char PatternDatabaseCompare(
void *data1, uint16_t len1,
void *data2,
502 const PatternDatabase *pd1 = data1;
503 const PatternDatabase *pd2 = data2;
505 if (pd1->pattern_cnt != pd2->pattern_cnt) {
509 for (uint32_t i = 0; i < pd1->pattern_cnt; i++) {
510 if (SCHSPatternCompare(pd1->parray[i], pd2->parray[i]) == 0) {
518 static void PatternDatabaseFree(PatternDatabase *pd)
522 if (pd->parray != NULL) {
523 for (uint32_t i = 0; i < pd->pattern_cnt; i++) {
524 SCHSPattern *p = pd->parray[i];
534 hs_free_database(pd->hs_db);
539 static void PatternDatabaseTableFree(
void *data)
545 static PatternDatabase *PatternDatabaseAlloc(uint32_t pattern_cnt)
547 PatternDatabase *pd =
SCCalloc(1,
sizeof(PatternDatabase));
551 pd->pattern_cnt = pattern_cnt;
557 pd->parray = (SCHSPattern **)
SCCalloc(pd->pattern_cnt,
sizeof(SCHSPattern *));
558 if (pd->parray == NULL) {
566 static int HSCheckPatterns(
MpmCtx *mpm_ctx, SCHSCtx *
ctx)
569 SCLogDebug(
"no patterns supplied to this mpm_ctx");
575 static void HSPatternArrayPopulate(SCHSCtx *
ctx, PatternDatabase *pd)
577 for (uint32_t i = 0, p = 0; i < INIT_HASH_SIZE; i++) {
578 SCHSPattern *node =
ctx->init_hash[i];
579 SCHSPattern *nnode = NULL;
580 while (node != NULL) {
583 pd->parray[p++] = node;
589 static void HSPatternArrayInit(SCHSCtx *
ctx, PatternDatabase *pd)
591 HSPatternArrayPopulate(
ctx, pd);
594 ctx->init_hash = NULL;
597 static int HSGlobalPatternDatabaseInit(
void)
599 if (g_db_table == NULL) {
600 g_db_table =
HashTableInit(INIT_DB_HASH_SIZE, PatternDatabaseHash,
601 PatternDatabaseCompare,
602 PatternDatabaseTableFree);
603 if (g_db_table == NULL) {
610 static void HSLogCompileError(hs_compile_error_t *compile_err)
612 SCLogError(
"failed to compile hyperscan database");
614 SCLogError(
"compile error: %s", compile_err->message);
615 hs_free_compile_error(compile_err);
619 static int HSScratchAlloc(
const hs_database_t *db)
622 hs_error_t err = hs_alloc_scratch(db, &g_scratch_proto);
624 if (err != HS_SUCCESS) {
631 static int PatternDatabaseGetSize(PatternDatabase *pd,
size_t *db_size)
633 hs_error_t err = hs_database_size(pd->hs_db, db_size);
634 if (err != HS_SUCCESS) {
635 SCLogError(
"failed to query database size: %s", HSErrorToStr(err));
641 static void SCHSCleanupOnError(PatternDatabase *pd, SCHSCompileData *cd)
644 PatternDatabaseFree(pd);
651 static int CompileDataExtensionsInit(hs_expr_ext_t **ext,
const SCHSPattern *p)
654 *ext =
SCCalloc(1,
sizeof(hs_expr_ext_t));
655 if ((*ext) == NULL) {
659 (*ext)->flags |= HS_EXT_FLAG_MIN_OFFSET;
660 (*ext)->min_offset = p->offset + p->len;
663 (*ext)->flags |= HS_EXT_FLAG_MAX_OFFSET;
664 (*ext)->max_offset = p->offset + p->depth;
679 static int PatternDatabaseGetCached(
680 PatternDatabase **pd, SCHSCompileData *cd,
const char *cache_dir_path)
685 if (pd_cached != NULL) {
686 SCLogDebug(
"Reusing cached database %p with %" PRIu32
687 " patterns (ref_cnt=%" PRIu32
")",
688 pd_cached->hs_db, pd_cached->pattern_cnt,
690 pd_cached->ref_cnt++;
691 PatternDatabaseFree(*pd);
695 }
else if (cache_dir_path) {
697 uint64_t db_lookup_hash = HSHashDb(pd_cached);
698 if (HSLoadCache(&pd_cached->hs_db, db_lookup_hash, cache_dir_path) == 0) {
699 pd_cached->ref_cnt = 1;
700 pd_cached->cached =
true;
701 if (HSScratchAlloc(pd_cached->hs_db) != 0) {
711 pd_cached->ref_cnt = 0;
712 pd_cached->cached =
false;
720 static int PatternDatabaseCompile(PatternDatabase *pd, SCHSCompileData *cd)
722 for (uint32_t i = 0; i < pd->pattern_cnt; i++) {
723 const SCHSPattern *p = pd->parray[i];
725 cd->flags[i] = HS_FLAG_SINGLEMATCH;
727 cd->flags[i] |= HS_FLAG_CASELESS;
730 if (CompileDataExtensionsInit(&cd->ext[i], p) != 0) {
735 hs_compile_error_t *compile_err = NULL;
736 hs_error_t err = hs_compile_ext_multi((
const char *
const *)cd->expressions, cd->flags, cd->ids,
737 (
const hs_expr_ext_t *
const *)cd->ext, cd->pattern_cnt, HS_MODE_BLOCK, NULL, &pd->hs_db,
739 if (err != HS_SUCCESS) {
740 HSLogCompileError(compile_err);
744 if (HSScratchAlloc(pd->hs_db) != 0) {
763 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
765 if (HSCheckPatterns(mpm_ctx,
ctx) == 0) {
769 SCHSCompileData *cd = CompileDataAlloc(mpm_ctx->
pattern_cnt);
770 PatternDatabase *pd = PatternDatabaseAlloc(mpm_ctx->
pattern_cnt);
771 if (cd == NULL || pd == NULL) {
775 HSPatternArrayInit(
ctx, pd);
780 if (HSGlobalPatternDatabaseInit() == -1) {
785 const char *cache_path = pd->no_cache || !mpm_conf ? NULL : mpm_conf->
cache_dir_path;
786 if (PatternDatabaseGetCached(&pd, cd, cache_path) == 0 && pd != NULL) {
788 ctx->pattern_db = pd;
789 if (PatternDatabaseGetSize(pd, &
ctx->hs_db_size) != 0) {
794 if (pd->ref_cnt == 1) {
806 if (PatternDatabaseCompile(pd, cd) != 0) {
811 ctx->pattern_db = pd;
812 if (PatternDatabaseGetSize(pd, &
ctx->hs_db_size) != 0) {
825 SCHSCleanupOnError(pd, cd);
832 static int SCHSCacheRuleset(
MpmConfig *mpm_conf)
840 SCLogWarning(
"Failed to create Hyperscan cache folder, make sure "
841 "the parent folder is writeable "
842 "or adjust sgh-mpm-caching-path setting (%s)",
846 PatternDatabaseCache pd_stats = { 0 };
847 struct HsIteratorData iter_data = { .pd_stats = &pd_stats,
852 SCLogNotice(
"Rule group caching - loaded: %u newly cached: %u total cacheable: %u",
853 pd_stats.hs_dbs_cache_loaded_cnt, pd_stats.hs_dbs_cache_saved_cnt,
854 pd_stats.hs_cacheable_dbs_cnt);
868 SCHSThreadCtx *
ctx =
SCCalloc(1,
sizeof(SCHSThreadCtx));
872 mpm_thread_ctx->
ctx =
ctx;
875 mpm_thread_ctx->
memory_size +=
sizeof(SCHSThreadCtx);
878 ctx->scratch_size = 0;
882 if (g_scratch_proto == NULL) {
890 hs_error_t err = hs_clone_scratch(g_scratch_proto,
891 (hs_scratch_t **)&
ctx->scratch);
895 if (err != HS_SUCCESS) {
896 FatalError(
"Unable to clone scratch prototype");
899 err = hs_scratch_size(
ctx->scratch, &
ctx->scratch_size);
900 if (err != HS_SUCCESS) {
913 void SCHSInitCtx(
MpmCtx *mpm_ctx)
915 if (mpm_ctx->
ctx != NULL)
919 if (mpm_ctx->
ctx == NULL) {
927 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
928 ctx->init_hash =
SCCalloc(INIT_HASH_SIZE,
sizeof(SCHSPattern *));
929 if (
ctx->init_hash == NULL) {
942 SCHSPrintSearchStats(mpm_thread_ctx);
944 if (mpm_thread_ctx->
ctx != NULL) {
945 SCHSThreadCtx *thr_ctx = (SCHSThreadCtx *)mpm_thread_ctx->
ctx;
947 if (thr_ctx->scratch != NULL) {
948 hs_free_scratch(thr_ctx->scratch);
950 mpm_thread_ctx->
memory_size -= thr_ctx->scratch_size;
954 mpm_thread_ctx->
ctx = NULL;
956 mpm_thread_ctx->
memory_size -=
sizeof(SCHSThreadCtx);
965 void SCHSDestroyCtx(
MpmCtx *mpm_ctx)
967 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
971 if (
ctx->init_hash != NULL) {
973 ctx->init_hash = NULL;
975 mpm_ctx->
memory_size -= (INIT_HASH_SIZE *
sizeof(SCHSPattern *));
981 PatternDatabase *pd =
ctx->pattern_db;
985 if (pd->ref_cnt == 0) {
987 PatternDatabaseFree(pd);
998 typedef struct SCHSCallbackCtx_ {
1001 uint32_t match_count;
1005 static int SCHSMatchEvent(
unsigned int id,
unsigned long long from,
1006 unsigned long long to,
unsigned int flags,
1009 SCHSCallbackCtx *cctx =
ctx;
1011 const PatternDatabase *pd = cctx->ctx->pattern_db;
1012 const SCHSPattern *pat = pd->parray[
id];
1014 SCLogDebug(
"Hyperscan Match %" PRIu32
": id=%" PRIu32
" @ %" PRIuMAX
1015 " (pat id=%" PRIu32
")",
1016 cctx->match_count, (uint32_t)
id, (uintmax_t)to, pat->id);
1018 PrefilterAddSids(pmq, pat->sids, pat->sids_size);
1020 cctx->match_count++;
1040 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
1041 SCHSThreadCtx *hs_thread_ctx = (SCHSThreadCtx *)(mpm_thread_ctx->
ctx);
1042 const PatternDatabase *pd =
ctx->pattern_db;
1048 SCHSCallbackCtx cctx = {.ctx =
ctx, .pmq = pmq, .match_count = 0};
1051 hs_scratch_t *scratch = hs_thread_ctx->scratch;
1052 BUG_ON(pd->hs_db == NULL);
1055 hs_error_t err = hs_scan(pd->hs_db, (
const char *)buf, buflen, 0, scratch,
1056 SCHSMatchEvent, &cctx);
1057 if (err != HS_SUCCESS) {
1061 SCLogError(
"Hyperscan returned error %d", err);
1064 ret = cctx.match_count;
1087 int SCHSAddPatternCI(
MpmCtx *mpm_ctx,
const uint8_t *pat, uint16_t patlen, uint16_t
offset,
1091 return SCHSAddPattern(mpm_ctx, pat, patlen,
offset, depth, pid, sid,
flags);
1111 int SCHSAddPatternCS(
MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen,
1112 uint16_t
offset, uint16_t depth, uint32_t pid,
1115 return SCHSAddPattern(mpm_ctx, pat, patlen,
offset, depth, pid, sid,
flags);
1118 void SCHSPrintSearchStats(
MpmThreadCtx *mpm_thread_ctx)
1122 void SCHSPrintInfo(
MpmCtx *mpm_ctx)
1124 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
1126 printf(
"MPM HS Information:\n");
1127 printf(
"Memory allocs: %" PRIu32
"\n", mpm_ctx->
memory_cnt);
1128 printf(
"Memory alloced: %" PRIu32
"\n", mpm_ctx->
memory_size);
1129 printf(
" Sizeof:\n");
1130 printf(
" MpmCtx %" PRIuMAX
"\n", (uintmax_t)
sizeof(
MpmCtx));
1131 printf(
" SCHSCtx: %" PRIuMAX
"\n", (uintmax_t)
sizeof(SCHSCtx));
1132 printf(
" SCHSPattern %" PRIuMAX
"\n", (uintmax_t)
sizeof(SCHSPattern));
1133 printf(
"Unique Patterns: %" PRIu32
"\n", mpm_ctx->
pattern_cnt);
1134 printf(
"Smallest: %" PRIu32
"\n", mpm_ctx->
minlen);
1135 printf(
"Largest: %" PRIu32
"\n", mpm_ctx->
maxlen);
1139 PatternDatabase *pd =
ctx->pattern_db;
1140 char *db_info = NULL;
1141 if (hs_database_info(pd->hs_db, &db_info) == HS_SUCCESS) {
1142 printf(
"HS Database Info: %s\n", db_info);
1145 printf(
"HS Database Size: %" PRIuMAX
" bytes\n",
1146 (uintmax_t)
ctx->hs_db_size);
1158 static void SCHSConfigDeinit(
MpmConfig **c)
1166 static void SCHSConfigCacheDirSet(
MpmConfig *c,
const char *dir_path)
1198 SCHSSetAllocators();
1209 if (g_scratch_proto) {
1210 SCLogDebug(
"Cleaning up Hyperscan global scratch");
1211 hs_free_scratch(g_scratch_proto);
1212 g_scratch_proto = NULL;
1217 if (g_db_table != NULL) {
1218 SCLogDebug(
"Clearing Hyperscan database cache");
1230 static int SCHSTest01(
void)
1237 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1245 SCHSPreparePatterns(NULL, &mpm_ctx);
1246 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1248 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1250 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1256 printf(
"1 != %" PRIu32
" ",
cnt);
1258 SCHSDestroyCtx(&mpm_ctx);
1259 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1264 static int SCHSTest02(
void)
1271 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1279 SCHSPreparePatterns(NULL, &mpm_ctx);
1280 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1282 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1283 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1289 printf(
"0 != %" PRIu32
" ",
cnt);
1291 SCHSDestroyCtx(&mpm_ctx);
1292 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1297 static int SCHSTest03(
void)
1304 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1316 SCHSPreparePatterns(NULL, &mpm_ctx);
1317 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1319 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1320 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1326 printf(
"3 != %" PRIu32
" ",
cnt);
1328 SCHSDestroyCtx(&mpm_ctx);
1329 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1334 static int SCHSTest04(
void)
1341 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1350 SCHSPreparePatterns(NULL, &mpm_ctx);
1351 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1353 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1354 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1360 printf(
"1 != %" PRIu32
" ",
cnt);
1362 SCHSDestroyCtx(&mpm_ctx);
1363 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1368 static int SCHSTest05(
void)
1375 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1384 SCHSPreparePatterns(NULL, &mpm_ctx);
1385 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1387 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1388 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1394 printf(
"3 != %" PRIu32
" ",
cnt);
1396 SCHSDestroyCtx(&mpm_ctx);
1397 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1402 static int SCHSTest06(
void)
1409 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1416 SCHSPreparePatterns(NULL, &mpm_ctx);
1417 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1419 const char *buf =
"abcd";
1420 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1426 printf(
"1 != %" PRIu32
" ",
cnt);
1428 SCHSDestroyCtx(&mpm_ctx);
1429 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1434 static int SCHSTest07(
void)
1441 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1454 MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"AAAAAAAAAA", 10, 0, 0, 4, 0, 0);
1456 MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30,
1460 SCHSPreparePatterns(NULL, &mpm_ctx);
1461 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1463 const char *buf =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1464 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1470 printf(
"6 != %" PRIu32
" ",
cnt);
1472 SCHSDestroyCtx(&mpm_ctx);
1473 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1478 static int SCHSTest08(
void)
1485 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1493 SCHSPreparePatterns(NULL, &mpm_ctx);
1494 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1497 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"a", 1);
1502 printf(
"0 != %" PRIu32
" ",
cnt);
1504 SCHSDestroyCtx(&mpm_ctx);
1505 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1510 static int SCHSTest09(
void)
1517 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1525 SCHSPreparePatterns(NULL, &mpm_ctx);
1526 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1529 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"ab", 2);
1534 printf(
"1 != %" PRIu32
" ",
cnt);
1536 SCHSDestroyCtx(&mpm_ctx);
1537 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1542 static int SCHSTest10(
void)
1549 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1557 SCHSPreparePatterns(NULL, &mpm_ctx);
1558 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1560 const char *buf =
"01234567890123456789012345678901234567890123456789"
1561 "01234567890123456789012345678901234567890123456789"
1563 "01234567890123456789012345678901234567890123456789"
1564 "01234567890123456789012345678901234567890123456789";
1565 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1571 printf(
"1 != %" PRIu32
" ",
cnt);
1573 SCHSDestroyCtx(&mpm_ctx);
1574 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1579 static int SCHSTest11(
void)
1586 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1590 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"he", 2, 0, 0, 1, 0, 0) == -1)
1592 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"she", 3, 0, 0, 2, 0, 0) == -1)
1594 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"his", 3, 0, 0, 3, 0, 0) == -1)
1596 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"hers", 4, 0, 0, 4, 0, 0) == -1)
1600 if (SCHSPreparePatterns(NULL, &mpm_ctx) == -1)
1603 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1607 const char *buf =
"he";
1608 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1611 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1614 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1617 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1621 SCHSDestroyCtx(&mpm_ctx);
1622 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1627 static int SCHSTest12(
void)
1634 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1644 SCHSPreparePatterns(NULL, &mpm_ctx);
1645 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1647 const char *buf =
"abcdefghijklmnopqrstuvwxyz";
1648 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1654 printf(
"2 != %" PRIu32
" ",
cnt);
1656 SCHSDestroyCtx(&mpm_ctx);
1657 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1662 static int SCHSTest13(
void)
1669 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1674 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABCD";
1675 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1678 SCHSPreparePatterns(NULL, &mpm_ctx);
1679 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1681 const char *buf =
"abcdefghijklmnopqrstuvwxyzABCD";
1682 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1688 printf(
"1 != %" PRIu32
" ",
cnt);
1690 SCHSDestroyCtx(&mpm_ctx);
1691 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1696 static int SCHSTest14(
void)
1703 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1708 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABCDE";
1709 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1712 SCHSPreparePatterns(NULL, &mpm_ctx);
1713 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1715 const char *buf =
"abcdefghijklmnopqrstuvwxyzABCDE";
1716 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1722 printf(
"1 != %" PRIu32
" ",
cnt);
1724 SCHSDestroyCtx(&mpm_ctx);
1725 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1730 static int SCHSTest15(
void)
1737 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1742 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABCDEF";
1743 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1746 SCHSPreparePatterns(NULL, &mpm_ctx);
1747 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1749 const char *buf =
"abcdefghijklmnopqrstuvwxyzABCDEF";
1750 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1756 printf(
"1 != %" PRIu32
" ",
cnt);
1758 SCHSDestroyCtx(&mpm_ctx);
1759 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1764 static int SCHSTest16(
void)
1771 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1776 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABC";
1777 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1780 SCHSPreparePatterns(NULL, &mpm_ctx);
1781 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1783 const char *buf =
"abcdefghijklmnopqrstuvwxyzABC";
1784 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1790 printf(
"1 != %" PRIu32
" ",
cnt);
1792 SCHSDestroyCtx(&mpm_ctx);
1793 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1798 static int SCHSTest17(
void)
1805 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1810 const char pat[] =
"abcdefghijklmnopqrstuvwxyzAB";
1811 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1814 SCHSPreparePatterns(NULL, &mpm_ctx);
1815 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1817 const char *buf =
"abcdefghijklmnopqrstuvwxyzAB";
1818 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1824 printf(
"1 != %" PRIu32
" ",
cnt);
1826 SCHSDestroyCtx(&mpm_ctx);
1827 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1832 static int SCHSTest18(
void)
1839 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1844 const char pat[] =
"abcde"
1850 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1853 SCHSPreparePatterns(NULL, &mpm_ctx);
1854 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1856 const char *buf =
"abcde"
1862 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1868 printf(
"1 != %" PRIu32
" ",
cnt);
1870 SCHSDestroyCtx(&mpm_ctx);
1871 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1876 static int SCHSTest19(
void)
1883 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1888 const char pat[] =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1889 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1892 SCHSPreparePatterns(NULL, &mpm_ctx);
1893 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1895 const char *buf =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1896 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1902 printf(
"1 != %" PRIu32
" ",
cnt);
1904 SCHSDestroyCtx(&mpm_ctx);
1905 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1910 static int SCHSTest20(
void)
1917 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1922 const char pat[] =
"AAAAA"
1929 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1932 SCHSPreparePatterns(NULL, &mpm_ctx);
1933 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1935 const char *buf =
"AAAAA"
1942 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1948 printf(
"1 != %" PRIu32
" ",
cnt);
1950 SCHSDestroyCtx(&mpm_ctx);
1951 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1956 static int SCHSTest21(
void)
1963 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1971 SCHSPreparePatterns(NULL, &mpm_ctx);
1972 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1975 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"AA", 2);
1980 printf(
"1 != %" PRIu32
" ",
cnt);
1982 SCHSDestroyCtx(&mpm_ctx);
1983 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1988 static int SCHSTest22(
void)
1995 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2005 SCHSPreparePatterns(NULL, &mpm_ctx);
2006 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2008 const char *buf =
"abcdefghijklmnopqrstuvwxyz";
2009 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2015 printf(
"2 != %" PRIu32
" ",
cnt);
2017 SCHSDestroyCtx(&mpm_ctx);
2018 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2023 static int SCHSTest23(
void)
2030 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2038 SCHSPreparePatterns(NULL, &mpm_ctx);
2039 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2042 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"aa", 2);
2047 printf(
"1 != %" PRIu32
" ",
cnt);
2049 SCHSDestroyCtx(&mpm_ctx);
2050 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2055 static int SCHSTest24(
void)
2062 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2070 SCHSPreparePatterns(NULL, &mpm_ctx);
2071 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2074 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"aa", 2);
2079 printf(
"1 != %" PRIu32
" ",
cnt);
2081 SCHSDestroyCtx(&mpm_ctx);
2082 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2087 static int SCHSTest25(
void)
2094 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2103 SCHSPreparePatterns(NULL, &mpm_ctx);
2104 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2106 const char *buf =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
2107 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2113 printf(
"3 != %" PRIu32
" ",
cnt);
2115 SCHSDestroyCtx(&mpm_ctx);
2116 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2121 static int SCHSTest26(
void)
2128 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2136 SCHSPreparePatterns(NULL, &mpm_ctx);
2137 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2139 const char *buf =
"works";
2140 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2146 printf(
"3 != %" PRIu32
" ",
cnt);
2148 SCHSDestroyCtx(&mpm_ctx);
2149 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2154 static int SCHSTest27(
void)
2161 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
2169 SCHSPreparePatterns(NULL, &mpm_ctx);
2170 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2172 const char *buf =
"tone";
2173 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2179 printf(
"0 != %" PRIu32
" ",
cnt);
2181 SCHSDestroyCtx(&mpm_ctx);
2182 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2187 static int SCHSTest28(
void)
2194 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
2202 SCHSPreparePatterns(NULL, &mpm_ctx);
2203 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2205 const char *buf =
"tONE";
2206 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2212 printf(
"0 != %" PRIu32
" ",
cnt);
2214 SCHSDestroyCtx(&mpm_ctx);
2215 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2220 static int SCHSTest29(
void)
2222 uint8_t buf[] =
"onetwothreefourfivesixseveneightnine";
2223 uint16_t buflen =
sizeof(buf) - 1;
2229 memset(&th_v, 0,
sizeof(th_v));
2240 de_ctx,
"alert tcp any any -> any any "
2241 "(content:\"onetwothreefourfivesixseveneightnine\"; sid:1;)");
2246 "(content:\"onetwothreefourfivesixseveneightnine\"; "
2247 "fast_pattern:3,3; sid:2;)");
2256 printf(
"if (PacketAlertCheck(p, 1) != 1) failure\n");
2260 printf(
"if (PacketAlertCheck(p, 1) != 2) failure\n");
2278 static void SCHSRegisterTests(
void)