50 #ifdef BUILD_HYPERSCAN
54 void SCHSInitCtx(
MpmCtx *);
56 void SCHSDestroyCtx(
MpmCtx *);
58 int SCHSAddPatternCI(
MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_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(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, uint8_t *pat,
153 uint16_t patlen, uint16_t
offset,
154 uint16_t depth,
char flags,
157 uint32_t hash = SCHSInitHashRaw(pat, patlen);
159 if (
ctx->init_hash == NULL) {
163 SCHSPattern *t =
ctx->init_hash[hash];
164 for (; t != NULL; t = t->next) {
167 if (t->id == pid && t->offset ==
offset && t->depth == depth) {
185 static inline SCHSPattern *SCHSAllocPattern(
MpmCtx *mpm_ctx)
187 SCHSPattern *p =
SCCalloc(1,
sizeof(SCHSPattern));
206 static inline void SCHSFreePattern(
MpmCtx *mpm_ctx, SCHSPattern *p)
208 if (p != NULL && p->original_pat != NULL) {
214 if (p != NULL && p->sids != NULL) {
225 static inline uint32_t SCHSInitHash(SCHSPattern *p)
227 uint32_t hash = p->len * p->original_pat[0];
229 hash += p->original_pat[1];
231 return (hash % INIT_HASH_SIZE);
234 static inline int SCHSInitHashAdd(SCHSCtx *
ctx, SCHSPattern *p)
236 uint32_t hash = SCHSInitHash(p);
238 if (
ctx->init_hash == NULL) {
242 if (
ctx->init_hash[hash] == NULL) {
243 ctx->init_hash[hash] = p;
247 SCHSPattern *tt = NULL;
248 SCHSPattern *t =
ctx->init_hash[hash];
275 static int SCHSAddPattern(
MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen,
276 uint16_t
offset, uint16_t depth, uint32_t pid,
279 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
300 p = SCHSAllocPattern(mpm_ctx);
310 if (p->original_pat == NULL)
314 memcpy(p->original_pat, pat, patlen);
317 if (SCHSInitHashAdd(
ctx, p) != 0)
329 SCLogDebug(
"%p: alas, no depth for us", mpm_ctx);
333 if (mpm_ctx->
maxlen < patlen)
336 if (mpm_ctx->
minlen == 0) {
339 if (mpm_ctx->
minlen > patlen)
352 for (x = 0; x < p->sids_size; x++) {
353 if (p->sids[x] == sid) {
362 p->sids[p->sids_size] = sid;
370 SCHSFreePattern(mpm_ctx, p);
378 typedef struct SCHSCompileData_ {
383 unsigned int pattern_cnt;
386 static SCHSCompileData *CompileDataAlloc(
unsigned int pattern_cnt)
388 SCHSCompileData *cd =
SCCalloc(pattern_cnt,
sizeof(SCHSCompileData));
393 cd->pattern_cnt = pattern_cnt;
395 cd->ids =
SCCalloc(pattern_cnt,
sizeof(
unsigned int));
396 if (cd->ids == NULL) {
400 cd->flags =
SCCalloc(pattern_cnt,
sizeof(
unsigned int));
401 if (cd->flags == NULL) {
405 cd->expressions =
SCCalloc(pattern_cnt,
sizeof(
char *));
406 if (cd->expressions == NULL) {
410 cd->ext =
SCCalloc(pattern_cnt,
sizeof(hs_expr_ext_t *));
411 if (cd->ext == NULL) {
429 static void CompileDataFree(SCHSCompileData *cd)
437 if (cd->expressions) {
438 for (
unsigned int i = 0; i < cd->pattern_cnt; i++) {
439 SCFree(cd->expressions[i]);
444 for (
unsigned int i = 0; i < cd->pattern_cnt; i++) {
452 static uint32_t SCHSPatternHash(
const SCHSPattern *p, uint32_t hash)
454 BUG_ON(p->original_pat == NULL);
468 static char SCHSPatternCompare(
const SCHSPattern *p1,
const SCHSPattern *p2)
470 if ((p1->len != p2->len) || (p1->flags != p2->flags) ||
471 (p1->id != p2->id) || (p1->offset != p2->offset) ||
472 (p1->depth != p2->depth) || (p1->sids_size != p2->sids_size)) {
476 if (
SCMemcmp(p1->original_pat, p2->original_pat, p1->len) != 0) {
480 if (
SCMemcmp(p1->sids, p2->sids, p1->sids_size *
sizeof(p1->sids[0])) !=
488 static uint32_t PatternDatabaseHash(
HashTable *ht,
void *data, uint16_t
len)
490 const PatternDatabase *pd = data;
492 hash =
hashword(&pd->pattern_cnt, 1, hash);
494 for (uint32_t i = 0; i < pd->pattern_cnt; i++) {
495 hash = SCHSPatternHash(pd->parray[i], hash);
502 static char PatternDatabaseCompare(
void *data1, uint16_t len1,
void *data2,
505 const PatternDatabase *pd1 = data1;
506 const PatternDatabase *pd2 = data2;
508 if (pd1->pattern_cnt != pd2->pattern_cnt) {
512 for (uint32_t i = 0; i < pd1->pattern_cnt; i++) {
513 if (SCHSPatternCompare(pd1->parray[i], pd2->parray[i]) == 0) {
521 static void PatternDatabaseFree(PatternDatabase *pd)
525 if (pd->parray != NULL) {
526 for (uint32_t i = 0; i < pd->pattern_cnt; i++) {
527 SCHSPattern *p = pd->parray[i];
537 hs_free_database(pd->hs_db);
542 static void PatternDatabaseTableFree(
void *data)
548 static PatternDatabase *PatternDatabaseAlloc(uint32_t pattern_cnt)
550 PatternDatabase *pd =
SCCalloc(1,
sizeof(PatternDatabase));
554 pd->pattern_cnt = pattern_cnt;
560 pd->parray = (SCHSPattern **)
SCCalloc(pd->pattern_cnt,
sizeof(SCHSPattern *));
561 if (pd->parray == NULL) {
569 static int HSCheckPatterns(
MpmCtx *mpm_ctx, SCHSCtx *
ctx)
572 SCLogDebug(
"no patterns supplied to this mpm_ctx");
578 static void HSPatternArrayPopulate(SCHSCtx *
ctx, PatternDatabase *pd)
580 for (uint32_t i = 0, p = 0; i < INIT_HASH_SIZE; i++) {
581 SCHSPattern *node =
ctx->init_hash[i];
582 SCHSPattern *nnode = NULL;
583 while (node != NULL) {
586 pd->parray[p++] = node;
592 static void HSPatternArrayInit(SCHSCtx *
ctx, PatternDatabase *pd)
594 HSPatternArrayPopulate(
ctx, pd);
597 ctx->init_hash = NULL;
600 static int HSGlobalPatternDatabaseInit(
void)
602 if (g_db_table == NULL) {
603 g_db_table =
HashTableInit(INIT_DB_HASH_SIZE, PatternDatabaseHash,
604 PatternDatabaseCompare,
605 PatternDatabaseTableFree);
606 if (g_db_table == NULL) {
613 static void HSLogCompileError(hs_compile_error_t *compile_err)
615 SCLogError(
"failed to compile hyperscan database");
617 SCLogError(
"compile error: %s", compile_err->message);
618 hs_free_compile_error(compile_err);
622 static int HSScratchAlloc(
const hs_database_t *db)
625 hs_error_t err = hs_alloc_scratch(db, &g_scratch_proto);
627 if (err != HS_SUCCESS) {
634 static int PatternDatabaseGetSize(PatternDatabase *pd,
size_t *db_size)
636 hs_error_t err = hs_database_size(pd->hs_db, db_size);
637 if (err != HS_SUCCESS) {
638 SCLogError(
"failed to query database size: %s", HSErrorToStr(err));
644 static void SCHSCleanupOnError(PatternDatabase *pd, SCHSCompileData *cd)
647 PatternDatabaseFree(pd);
654 static int CompileDataExtensionsInit(hs_expr_ext_t **ext,
const SCHSPattern *p)
657 *ext =
SCCalloc(1,
sizeof(hs_expr_ext_t));
658 if ((*ext) == NULL) {
662 (*ext)->flags |= HS_EXT_FLAG_MIN_OFFSET;
663 (*ext)->min_offset = p->offset + p->len;
666 (*ext)->flags |= HS_EXT_FLAG_MAX_OFFSET;
667 (*ext)->max_offset = p->offset + p->depth;
682 static int PatternDatabaseGetCached(
683 PatternDatabase **pd, SCHSCompileData *cd,
const char *cache_dir_path)
688 if (pd_cached != NULL) {
689 SCLogDebug(
"Reusing cached database %p with %" PRIu32
690 " patterns (ref_cnt=%" PRIu32
")",
691 pd_cached->hs_db, pd_cached->pattern_cnt,
693 pd_cached->ref_cnt++;
694 PatternDatabaseFree(*pd);
698 }
else if (cache_dir_path) {
700 uint64_t db_lookup_hash = HSHashDb(pd_cached);
701 if (HSLoadCache(&pd_cached->hs_db, db_lookup_hash, cache_dir_path) == 0) {
702 pd_cached->ref_cnt = 1;
703 pd_cached->cached =
true;
704 if (HSScratchAlloc(pd_cached->hs_db) != 0) {
714 pd_cached->ref_cnt = 0;
715 pd_cached->cached =
false;
723 static int PatternDatabaseCompile(PatternDatabase *pd, SCHSCompileData *cd)
725 for (uint32_t i = 0; i < pd->pattern_cnt; i++) {
726 const SCHSPattern *p = pd->parray[i];
728 cd->flags[i] = HS_FLAG_SINGLEMATCH;
730 cd->flags[i] |= HS_FLAG_CASELESS;
733 if (CompileDataExtensionsInit(&cd->ext[i], p) != 0) {
738 hs_compile_error_t *compile_err = NULL;
739 hs_error_t err = hs_compile_ext_multi((
const char *
const *)cd->expressions, cd->flags, cd->ids,
740 (
const hs_expr_ext_t *
const *)cd->ext, cd->pattern_cnt, HS_MODE_BLOCK, NULL, &pd->hs_db,
742 if (err != HS_SUCCESS) {
743 HSLogCompileError(compile_err);
747 if (HSScratchAlloc(pd->hs_db) != 0) {
766 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
768 if (HSCheckPatterns(mpm_ctx,
ctx) == 0) {
772 SCHSCompileData *cd = CompileDataAlloc(mpm_ctx->
pattern_cnt);
773 PatternDatabase *pd = PatternDatabaseAlloc(mpm_ctx->
pattern_cnt);
774 if (cd == NULL || pd == NULL) {
778 HSPatternArrayInit(
ctx, pd);
783 if (HSGlobalPatternDatabaseInit() == -1) {
788 const char *cache_path = pd->no_cache || !mpm_conf ? NULL : mpm_conf->
cache_dir_path;
789 if (PatternDatabaseGetCached(&pd, cd, cache_path) == 0 && pd != NULL) {
791 ctx->pattern_db = pd;
792 if (PatternDatabaseGetSize(pd, &
ctx->hs_db_size) != 0) {
797 if (pd->ref_cnt == 1) {
809 if (PatternDatabaseCompile(pd, cd) != 0) {
814 ctx->pattern_db = pd;
815 if (PatternDatabaseGetSize(pd, &
ctx->hs_db_size) != 0) {
828 SCHSCleanupOnError(pd, cd);
835 static int SCHSCacheRuleset(
MpmConfig *mpm_conf)
843 SCLogWarning(
"Failed to create Hyperscan cache folder, make sure "
844 "the parent folder is writeable "
845 "or adjust sgh-mpm-caching-path setting (%s)",
849 PatternDatabaseCache pd_stats = { 0 };
850 struct HsIteratorData iter_data = { .pd_stats = &pd_stats,
855 SCLogNotice(
"Rule group caching - loaded: %u newly cached: %u total cacheable: %u",
856 pd_stats.hs_dbs_cache_loaded_cnt, pd_stats.hs_dbs_cache_saved_cnt,
857 pd_stats.hs_cacheable_dbs_cnt);
871 SCHSThreadCtx *
ctx =
SCCalloc(1,
sizeof(SCHSThreadCtx));
875 mpm_thread_ctx->
ctx =
ctx;
878 mpm_thread_ctx->
memory_size +=
sizeof(SCHSThreadCtx);
881 ctx->scratch_size = 0;
885 if (g_scratch_proto == NULL) {
893 hs_error_t err = hs_clone_scratch(g_scratch_proto,
894 (hs_scratch_t **)&
ctx->scratch);
898 if (err != HS_SUCCESS) {
899 FatalError(
"Unable to clone scratch prototype");
902 err = hs_scratch_size(
ctx->scratch, &
ctx->scratch_size);
903 if (err != HS_SUCCESS) {
916 void SCHSInitCtx(
MpmCtx *mpm_ctx)
918 if (mpm_ctx->
ctx != NULL)
922 if (mpm_ctx->
ctx == NULL) {
930 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
931 ctx->init_hash =
SCCalloc(INIT_HASH_SIZE,
sizeof(SCHSPattern *));
932 if (
ctx->init_hash == NULL) {
945 SCHSPrintSearchStats(mpm_thread_ctx);
947 if (mpm_thread_ctx->
ctx != NULL) {
948 SCHSThreadCtx *thr_ctx = (SCHSThreadCtx *)mpm_thread_ctx->
ctx;
950 if (thr_ctx->scratch != NULL) {
951 hs_free_scratch(thr_ctx->scratch);
953 mpm_thread_ctx->
memory_size -= thr_ctx->scratch_size;
957 mpm_thread_ctx->
ctx = NULL;
959 mpm_thread_ctx->
memory_size -=
sizeof(SCHSThreadCtx);
968 void SCHSDestroyCtx(
MpmCtx *mpm_ctx)
970 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
974 if (
ctx->init_hash != NULL) {
976 ctx->init_hash = NULL;
978 mpm_ctx->
memory_size -= (INIT_HASH_SIZE *
sizeof(SCHSPattern *));
984 PatternDatabase *pd =
ctx->pattern_db;
988 if (pd->ref_cnt == 0) {
990 PatternDatabaseFree(pd);
1001 typedef struct SCHSCallbackCtx_ {
1004 uint32_t match_count;
1008 static int SCHSMatchEvent(
unsigned int id,
unsigned long long from,
1009 unsigned long long to,
unsigned int flags,
1012 SCHSCallbackCtx *cctx =
ctx;
1014 const PatternDatabase *pd = cctx->ctx->pattern_db;
1015 const SCHSPattern *pat = pd->parray[
id];
1017 SCLogDebug(
"Hyperscan Match %" PRIu32
": id=%" PRIu32
" @ %" PRIuMAX
1018 " (pat id=%" PRIu32
")",
1019 cctx->match_count, (uint32_t)
id, (uintmax_t)to, pat->id);
1021 PrefilterAddSids(pmq, pat->sids, pat->sids_size);
1023 cctx->match_count++;
1043 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
1044 SCHSThreadCtx *hs_thread_ctx = (SCHSThreadCtx *)(mpm_thread_ctx->
ctx);
1045 const PatternDatabase *pd =
ctx->pattern_db;
1051 SCHSCallbackCtx cctx = {.ctx =
ctx, .pmq = pmq, .match_count = 0};
1054 hs_scratch_t *scratch = hs_thread_ctx->scratch;
1055 BUG_ON(pd->hs_db == NULL);
1058 hs_error_t err = hs_scan(pd->hs_db, (
const char *)buf, buflen, 0, scratch,
1059 SCHSMatchEvent, &cctx);
1060 if (err != HS_SUCCESS) {
1064 SCLogError(
"Hyperscan returned error %d", err);
1067 ret = cctx.match_count;
1090 int SCHSAddPatternCI(
MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen,
1091 uint16_t
offset, uint16_t depth, uint32_t pid,
1095 return SCHSAddPattern(mpm_ctx, pat, patlen,
offset, depth, pid, sid,
flags);
1115 int SCHSAddPatternCS(
MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen,
1116 uint16_t
offset, uint16_t depth, uint32_t pid,
1119 return SCHSAddPattern(mpm_ctx, pat, patlen,
offset, depth, pid, sid,
flags);
1122 void SCHSPrintSearchStats(
MpmThreadCtx *mpm_thread_ctx)
1126 void SCHSPrintInfo(
MpmCtx *mpm_ctx)
1128 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
1130 printf(
"MPM HS Information:\n");
1131 printf(
"Memory allocs: %" PRIu32
"\n", mpm_ctx->
memory_cnt);
1132 printf(
"Memory alloced: %" PRIu32
"\n", mpm_ctx->
memory_size);
1133 printf(
" Sizeof:\n");
1134 printf(
" MpmCtx %" PRIuMAX
"\n", (uintmax_t)
sizeof(
MpmCtx));
1135 printf(
" SCHSCtx: %" PRIuMAX
"\n", (uintmax_t)
sizeof(SCHSCtx));
1136 printf(
" SCHSPattern %" PRIuMAX
"\n", (uintmax_t)
sizeof(SCHSPattern));
1137 printf(
"Unique Patterns: %" PRIu32
"\n", mpm_ctx->
pattern_cnt);
1138 printf(
"Smallest: %" PRIu32
"\n", mpm_ctx->
minlen);
1139 printf(
"Largest: %" PRIu32
"\n", mpm_ctx->
maxlen);
1143 PatternDatabase *pd =
ctx->pattern_db;
1144 char *db_info = NULL;
1145 if (hs_database_info(pd->hs_db, &db_info) == HS_SUCCESS) {
1146 printf(
"HS Database Info: %s\n", db_info);
1149 printf(
"HS Database Size: %" PRIuMAX
" bytes\n",
1150 (uintmax_t)
ctx->hs_db_size);
1162 static void SCHSConfigDeinit(
MpmConfig **c)
1170 static void SCHSConfigCacheDirSet(
MpmConfig *c,
const char *dir_path)
1202 SCHSSetAllocators();
1213 if (g_scratch_proto) {
1214 SCLogDebug(
"Cleaning up Hyperscan global scratch");
1215 hs_free_scratch(g_scratch_proto);
1216 g_scratch_proto = NULL;
1221 if (g_db_table != NULL) {
1222 SCLogDebug(
"Clearing Hyperscan database cache");
1234 static int SCHSTest01(
void)
1241 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1249 SCHSPreparePatterns(NULL, &mpm_ctx);
1250 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1252 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1254 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1260 printf(
"1 != %" PRIu32
" ",
cnt);
1262 SCHSDestroyCtx(&mpm_ctx);
1263 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1268 static int SCHSTest02(
void)
1275 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1283 SCHSPreparePatterns(NULL, &mpm_ctx);
1284 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1286 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1287 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1293 printf(
"0 != %" PRIu32
" ",
cnt);
1295 SCHSDestroyCtx(&mpm_ctx);
1296 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1301 static int SCHSTest03(
void)
1308 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1320 SCHSPreparePatterns(NULL, &mpm_ctx);
1321 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1323 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1324 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1330 printf(
"3 != %" PRIu32
" ",
cnt);
1332 SCHSDestroyCtx(&mpm_ctx);
1333 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1338 static int SCHSTest04(
void)
1345 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1354 SCHSPreparePatterns(NULL, &mpm_ctx);
1355 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1357 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1358 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1364 printf(
"1 != %" PRIu32
" ",
cnt);
1366 SCHSDestroyCtx(&mpm_ctx);
1367 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1372 static int SCHSTest05(
void)
1379 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1388 SCHSPreparePatterns(NULL, &mpm_ctx);
1389 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1391 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1392 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1398 printf(
"3 != %" PRIu32
" ",
cnt);
1400 SCHSDestroyCtx(&mpm_ctx);
1401 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1406 static int SCHSTest06(
void)
1413 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1420 SCHSPreparePatterns(NULL, &mpm_ctx);
1421 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1423 const char *buf =
"abcd";
1424 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1430 printf(
"1 != %" PRIu32
" ",
cnt);
1432 SCHSDestroyCtx(&mpm_ctx);
1433 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1438 static int SCHSTest07(
void)
1445 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1458 MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"AAAAAAAAAA", 10, 0, 0, 4, 0, 0);
1460 MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30,
1464 SCHSPreparePatterns(NULL, &mpm_ctx);
1465 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1467 const char *buf =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1468 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1474 printf(
"6 != %" PRIu32
" ",
cnt);
1476 SCHSDestroyCtx(&mpm_ctx);
1477 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1482 static int SCHSTest08(
void)
1489 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1497 SCHSPreparePatterns(NULL, &mpm_ctx);
1498 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1501 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"a", 1);
1506 printf(
"0 != %" PRIu32
" ",
cnt);
1508 SCHSDestroyCtx(&mpm_ctx);
1509 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1514 static int SCHSTest09(
void)
1521 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1529 SCHSPreparePatterns(NULL, &mpm_ctx);
1530 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1533 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"ab", 2);
1538 printf(
"1 != %" PRIu32
" ",
cnt);
1540 SCHSDestroyCtx(&mpm_ctx);
1541 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1546 static int SCHSTest10(
void)
1553 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1561 SCHSPreparePatterns(NULL, &mpm_ctx);
1562 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1564 const char *buf =
"01234567890123456789012345678901234567890123456789"
1565 "01234567890123456789012345678901234567890123456789"
1567 "01234567890123456789012345678901234567890123456789"
1568 "01234567890123456789012345678901234567890123456789";
1569 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1575 printf(
"1 != %" PRIu32
" ",
cnt);
1577 SCHSDestroyCtx(&mpm_ctx);
1578 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1583 static int SCHSTest11(
void)
1590 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1594 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"he", 2, 0, 0, 1, 0, 0) == -1)
1596 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"she", 3, 0, 0, 2, 0, 0) == -1)
1598 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"his", 3, 0, 0, 3, 0, 0) == -1)
1600 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"hers", 4, 0, 0, 4, 0, 0) == -1)
1604 if (SCHSPreparePatterns(NULL, &mpm_ctx) == -1)
1607 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1611 const char *buf =
"he";
1612 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1615 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1618 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1621 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1625 SCHSDestroyCtx(&mpm_ctx);
1626 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1631 static int SCHSTest12(
void)
1638 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1648 SCHSPreparePatterns(NULL, &mpm_ctx);
1649 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1651 const char *buf =
"abcdefghijklmnopqrstuvwxyz";
1652 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1658 printf(
"2 != %" PRIu32
" ",
cnt);
1660 SCHSDestroyCtx(&mpm_ctx);
1661 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1666 static int SCHSTest13(
void)
1673 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1678 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABCD";
1679 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1682 SCHSPreparePatterns(NULL, &mpm_ctx);
1683 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1685 const char *buf =
"abcdefghijklmnopqrstuvwxyzABCD";
1686 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1692 printf(
"1 != %" PRIu32
" ",
cnt);
1694 SCHSDestroyCtx(&mpm_ctx);
1695 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1700 static int SCHSTest14(
void)
1707 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1712 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABCDE";
1713 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1716 SCHSPreparePatterns(NULL, &mpm_ctx);
1717 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1719 const char *buf =
"abcdefghijklmnopqrstuvwxyzABCDE";
1720 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1726 printf(
"1 != %" PRIu32
" ",
cnt);
1728 SCHSDestroyCtx(&mpm_ctx);
1729 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1734 static int SCHSTest15(
void)
1741 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1746 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABCDEF";
1747 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1750 SCHSPreparePatterns(NULL, &mpm_ctx);
1751 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1753 const char *buf =
"abcdefghijklmnopqrstuvwxyzABCDEF";
1754 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1760 printf(
"1 != %" PRIu32
" ",
cnt);
1762 SCHSDestroyCtx(&mpm_ctx);
1763 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1768 static int SCHSTest16(
void)
1775 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1780 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABC";
1781 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1784 SCHSPreparePatterns(NULL, &mpm_ctx);
1785 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1787 const char *buf =
"abcdefghijklmnopqrstuvwxyzABC";
1788 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1794 printf(
"1 != %" PRIu32
" ",
cnt);
1796 SCHSDestroyCtx(&mpm_ctx);
1797 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1802 static int SCHSTest17(
void)
1809 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1814 const char pat[] =
"abcdefghijklmnopqrstuvwxyzAB";
1815 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1818 SCHSPreparePatterns(NULL, &mpm_ctx);
1819 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1821 const char *buf =
"abcdefghijklmnopqrstuvwxyzAB";
1822 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1828 printf(
"1 != %" PRIu32
" ",
cnt);
1830 SCHSDestroyCtx(&mpm_ctx);
1831 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1836 static int SCHSTest18(
void)
1843 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1848 const char pat[] =
"abcde"
1854 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1857 SCHSPreparePatterns(NULL, &mpm_ctx);
1858 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1860 const char *buf =
"abcde"
1866 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1872 printf(
"1 != %" PRIu32
" ",
cnt);
1874 SCHSDestroyCtx(&mpm_ctx);
1875 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1880 static int SCHSTest19(
void)
1887 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1892 const char pat[] =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1893 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1896 SCHSPreparePatterns(NULL, &mpm_ctx);
1897 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1899 const char *buf =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1900 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1906 printf(
"1 != %" PRIu32
" ",
cnt);
1908 SCHSDestroyCtx(&mpm_ctx);
1909 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1914 static int SCHSTest20(
void)
1921 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1926 const char pat[] =
"AAAAA"
1933 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1936 SCHSPreparePatterns(NULL, &mpm_ctx);
1937 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1939 const char *buf =
"AAAAA"
1946 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1952 printf(
"1 != %" PRIu32
" ",
cnt);
1954 SCHSDestroyCtx(&mpm_ctx);
1955 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1960 static int SCHSTest21(
void)
1967 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1975 SCHSPreparePatterns(NULL, &mpm_ctx);
1976 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1979 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"AA", 2);
1984 printf(
"1 != %" PRIu32
" ",
cnt);
1986 SCHSDestroyCtx(&mpm_ctx);
1987 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1992 static int SCHSTest22(
void)
1999 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2009 SCHSPreparePatterns(NULL, &mpm_ctx);
2010 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2012 const char *buf =
"abcdefghijklmnopqrstuvwxyz";
2013 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2019 printf(
"2 != %" PRIu32
" ",
cnt);
2021 SCHSDestroyCtx(&mpm_ctx);
2022 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2027 static int SCHSTest23(
void)
2034 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2042 SCHSPreparePatterns(NULL, &mpm_ctx);
2043 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2046 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"aa", 2);
2051 printf(
"1 != %" PRIu32
" ",
cnt);
2053 SCHSDestroyCtx(&mpm_ctx);
2054 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2059 static int SCHSTest24(
void)
2066 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2074 SCHSPreparePatterns(NULL, &mpm_ctx);
2075 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2078 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"aa", 2);
2083 printf(
"1 != %" PRIu32
" ",
cnt);
2085 SCHSDestroyCtx(&mpm_ctx);
2086 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2091 static int SCHSTest25(
void)
2098 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2107 SCHSPreparePatterns(NULL, &mpm_ctx);
2108 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2110 const char *buf =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
2111 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2117 printf(
"3 != %" PRIu32
" ",
cnt);
2119 SCHSDestroyCtx(&mpm_ctx);
2120 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2125 static int SCHSTest26(
void)
2132 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2140 SCHSPreparePatterns(NULL, &mpm_ctx);
2141 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2143 const char *buf =
"works";
2144 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2150 printf(
"3 != %" PRIu32
" ",
cnt);
2152 SCHSDestroyCtx(&mpm_ctx);
2153 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2158 static int SCHSTest27(
void)
2165 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
2173 SCHSPreparePatterns(NULL, &mpm_ctx);
2174 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2176 const char *buf =
"tone";
2177 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2183 printf(
"0 != %" PRIu32
" ",
cnt);
2185 SCHSDestroyCtx(&mpm_ctx);
2186 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2191 static int SCHSTest28(
void)
2198 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
2206 SCHSPreparePatterns(NULL, &mpm_ctx);
2207 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2209 const char *buf =
"tONE";
2210 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2216 printf(
"0 != %" PRIu32
" ",
cnt);
2218 SCHSDestroyCtx(&mpm_ctx);
2219 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2224 static int SCHSTest29(
void)
2226 uint8_t buf[] =
"onetwothreefourfivesixseveneightnine";
2227 uint16_t buflen =
sizeof(buf) - 1;
2233 memset(&th_v, 0,
sizeof(th_v));
2244 de_ctx,
"alert tcp any any -> any any "
2245 "(content:\"onetwothreefourfivesixseveneightnine\"; sid:1;)");
2250 "(content:\"onetwothreefourfivesixseveneightnine\"; "
2251 "fast_pattern:3,3; sid:2;)");
2260 printf(
"if (PacketAlertCheck(p, 1) != 1) failure\n");
2264 printf(
"if (PacketAlertCheck(p, 1) != 2) failure\n");
2282 static void SCHSRegisterTests(
void)