50 #ifdef BUILD_HYPERSCAN
52 void SCHSInitCtx(
MpmCtx *);
54 void SCHSDestroyCtx(
MpmCtx *);
57 MpmCtx *,
const uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t,
SigIntId, uint8_t);
58 int SCHSAddPatternCS(
MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t,
63 void SCHSPrintInfo(
MpmCtx *mpm_ctx);
66 static void SCHSRegisterTests(
void);
70 #define INIT_HASH_SIZE 65536
73 #define INIT_DB_HASH_SIZE 1000
78 static hs_scratch_t *g_scratch_proto = NULL;
91 static void *SCHSMalloc(
size_t size)
101 static void SCHSFree(
void *ptr)
111 static void SCHSSetAllocators(
void)
113 hs_error_t err = hs_set_allocator(SCHSMalloc, SCHSFree);
114 if (err != HS_SUCCESS) {
115 FatalError(
"Failed to set Hyperscan allocator.");
129 static inline uint32_t SCHSInitHashRaw(
const uint8_t *pat, uint16_t patlen)
131 uint32_t hash = patlen * pat[0];
135 return (hash % INIT_HASH_SIZE);
150 static inline SCHSPattern *SCHSInitHashLookup(SCHSCtx *
ctx,
const uint8_t *pat, uint16_t patlen,
151 uint16_t
offset, uint16_t depth,
char flags, uint32_t pid)
153 uint32_t hash = SCHSInitHashRaw(pat, patlen);
155 if (
ctx->init_hash == NULL) {
159 SCHSPattern *t =
ctx->init_hash[hash];
160 for (; t != NULL; t = t->next) {
163 if (t->id == pid && t->offset ==
offset && t->depth == depth) {
181 static inline SCHSPattern *SCHSAllocPattern(
MpmCtx *mpm_ctx)
183 SCHSPattern *p =
SCCalloc(1,
sizeof(SCHSPattern));
202 static inline void SCHSFreePattern(
MpmCtx *mpm_ctx, SCHSPattern *p)
204 if (p != NULL && p->original_pat != NULL) {
210 if (p != NULL && p->sids != NULL) {
221 static inline uint32_t SCHSInitHash(SCHSPattern *p)
223 uint32_t hash = p->len * p->original_pat[0];
225 hash += p->original_pat[1];
227 return (hash % INIT_HASH_SIZE);
230 static inline int SCHSInitHashAdd(SCHSCtx *
ctx, SCHSPattern *p)
232 uint32_t hash = SCHSInitHash(p);
234 if (
ctx->init_hash == NULL) {
238 if (
ctx->init_hash[hash] == NULL) {
239 ctx->init_hash[hash] = p;
243 SCHSPattern *tt = NULL;
244 SCHSPattern *t =
ctx->init_hash[hash];
271 static int SCHSAddPattern(
MpmCtx *mpm_ctx,
const uint8_t *pat, uint16_t patlen, uint16_t
offset,
274 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
295 p = SCHSAllocPattern(mpm_ctx);
305 if (p->original_pat == NULL)
309 memcpy(p->original_pat, pat, patlen);
312 if (SCHSInitHashAdd(
ctx, p) != 0)
324 SCLogDebug(
"%p: alas, no depth for us", mpm_ctx);
328 if (mpm_ctx->
maxlen < patlen)
331 if (mpm_ctx->
minlen == 0) {
334 if (mpm_ctx->
minlen > patlen)
347 for (x = 0; x < p->sids_size; x++) {
348 if (p->sids[x] == sid) {
357 p->sids[p->sids_size] = sid;
365 SCHSFreePattern(mpm_ctx, p);
373 typedef struct SCHSCompileData_ {
378 unsigned int pattern_cnt;
381 static SCHSCompileData *CompileDataAlloc(
unsigned int pattern_cnt)
383 SCHSCompileData *cd =
SCCalloc(pattern_cnt,
sizeof(SCHSCompileData));
388 cd->pattern_cnt = pattern_cnt;
390 cd->ids =
SCCalloc(pattern_cnt,
sizeof(
unsigned int));
391 if (cd->ids == NULL) {
395 cd->flags =
SCCalloc(pattern_cnt,
sizeof(
unsigned int));
396 if (cd->flags == NULL) {
400 cd->expressions =
SCCalloc(pattern_cnt,
sizeof(
char *));
401 if (cd->expressions == NULL) {
405 cd->ext =
SCCalloc(pattern_cnt,
sizeof(hs_expr_ext_t *));
406 if (cd->ext == NULL) {
424 static void CompileDataFree(SCHSCompileData *cd)
432 if (cd->expressions) {
433 for (
unsigned int i = 0; i < cd->pattern_cnt; i++) {
434 SCFree(cd->expressions[i]);
439 for (
unsigned int i = 0; i < cd->pattern_cnt; i++) {
447 static uint32_t SCHSPatternHash(
const SCHSPattern *p, uint32_t hash)
449 BUG_ON(p->original_pat == NULL);
463 static char SCHSPatternCompare(
const SCHSPattern *p1,
const SCHSPattern *p2)
465 if ((p1->len != p2->len) || (p1->flags != p2->flags) ||
466 (p1->id != p2->id) || (p1->offset != p2->offset) ||
467 (p1->depth != p2->depth) || (p1->sids_size != p2->sids_size)) {
471 if (
SCMemcmp(p1->original_pat, p2->original_pat, p1->len) != 0) {
475 if (
SCMemcmp(p1->sids, p2->sids, p1->sids_size *
sizeof(p1->sids[0])) !=
483 static uint32_t PatternDatabaseHash(
HashTable *ht,
void *data, uint16_t
len)
485 const PatternDatabase *pd = data;
487 hash =
hashword(&pd->pattern_cnt, 1, hash);
489 for (uint32_t i = 0; i < pd->pattern_cnt; i++) {
490 hash = SCHSPatternHash(pd->parray[i], hash);
497 static char PatternDatabaseCompare(
void *data1, uint16_t len1,
void *data2,
500 const PatternDatabase *pd1 = data1;
501 const PatternDatabase *pd2 = data2;
503 if (pd1->pattern_cnt != pd2->pattern_cnt) {
507 for (uint32_t i = 0; i < pd1->pattern_cnt; i++) {
508 if (SCHSPatternCompare(pd1->parray[i], pd2->parray[i]) == 0) {
516 static void PatternDatabaseFree(PatternDatabase *pd)
520 if (pd->parray != NULL) {
521 for (uint32_t i = 0; i < pd->pattern_cnt; i++) {
522 SCHSPattern *p = pd->parray[i];
532 hs_free_database(pd->hs_db);
537 static void PatternDatabaseTableFree(
void *data)
543 static PatternDatabase *PatternDatabaseAlloc(uint32_t pattern_cnt)
545 PatternDatabase *pd =
SCCalloc(1,
sizeof(PatternDatabase));
549 pd->pattern_cnt = pattern_cnt;
555 pd->parray = (SCHSPattern **)
SCCalloc(pd->pattern_cnt,
sizeof(SCHSPattern *));
556 if (pd->parray == NULL) {
564 static int HSCheckPatterns(
MpmCtx *mpm_ctx, SCHSCtx *
ctx)
567 SCLogDebug(
"no patterns supplied to this mpm_ctx");
573 static void HSPatternArrayPopulate(SCHSCtx *
ctx, PatternDatabase *pd)
575 for (uint32_t i = 0, p = 0; i < INIT_HASH_SIZE; i++) {
576 SCHSPattern *node =
ctx->init_hash[i];
577 SCHSPattern *nnode = NULL;
578 while (node != NULL) {
581 pd->parray[p++] = node;
587 static void HSPatternArrayInit(SCHSCtx *
ctx, PatternDatabase *pd)
589 HSPatternArrayPopulate(
ctx, pd);
592 ctx->init_hash = NULL;
595 static int HSGlobalPatternDatabaseInit(
void)
597 if (g_db_table == NULL) {
598 g_db_table =
HashTableInit(INIT_DB_HASH_SIZE, PatternDatabaseHash,
599 PatternDatabaseCompare,
600 PatternDatabaseTableFree);
601 if (g_db_table == NULL) {
608 static int HSScratchAlloc(
const hs_database_t *db)
611 hs_error_t err = hs_alloc_scratch(db, &g_scratch_proto);
613 if (err != HS_SUCCESS) {
620 static int PatternDatabaseGetSize(PatternDatabase *pd,
size_t *db_size)
622 hs_error_t err = hs_database_size(pd->hs_db, db_size);
623 if (err != HS_SUCCESS) {
624 SCLogError(
"failed to query database size: %s", HSErrorToStr(err));
630 static void SCHSCleanupOnError(PatternDatabase *pd, SCHSCompileData *cd)
633 PatternDatabaseFree(pd);
640 static int CompileDataExtensionsInit(hs_expr_ext_t **ext,
const SCHSPattern *p)
643 *ext =
SCCalloc(1,
sizeof(hs_expr_ext_t));
644 if ((*ext) == NULL) {
648 (*ext)->flags |= HS_EXT_FLAG_MIN_OFFSET;
649 (*ext)->min_offset = p->offset + p->len;
652 (*ext)->flags |= HS_EXT_FLAG_MAX_OFFSET;
653 (*ext)->max_offset = p->offset + p->depth;
668 static int PatternDatabaseGetCached(
669 PatternDatabase **pd, SCHSCompileData *cd,
const char *cache_dir_path)
674 if (pd_cached != NULL) {
675 SCLogDebug(
"Reusing cached database %p with %" PRIu32
676 " patterns (ref_cnt=%" PRIu32
")",
677 pd_cached->hs_db, pd_cached->pattern_cnt,
679 pd_cached->ref_cnt++;
680 PatternDatabaseFree(*pd);
684 }
else if (cache_dir_path) {
687 if (HSHashDb(pd_cached, hs_db_hash,
ARRAY_SIZE(hs_db_hash)) != 0) {
690 if (HSLoadCache(&pd_cached->hs_db, hs_db_hash, cache_dir_path) == 0) {
691 pd_cached->ref_cnt = 1;
692 pd_cached->cached =
true;
693 if (HSScratchAlloc(pd_cached->hs_db) != 0) {
703 pd_cached->ref_cnt = 0;
704 pd_cached->cached =
false;
712 static int PatternDatabaseCompile(PatternDatabase *pd, SCHSCompileData *cd)
714 for (uint32_t i = 0; i < pd->pattern_cnt; i++) {
715 const SCHSPattern *p = pd->parray[i];
717 cd->flags[i] = HS_FLAG_SINGLEMATCH;
719 cd->flags[i] |= HS_FLAG_CASELESS;
721 cd->expressions[i] = HSRenderPattern(p->original_pat, p->len);
722 if (CompileDataExtensionsInit(&cd->ext[i], p) != 0) {
727 hs_compile_error_t *compile_err = NULL;
728 hs_error_t err = hs_compile_ext_multi((
const char *
const *)cd->expressions, cd->flags, cd->ids,
729 (
const hs_expr_ext_t *
const *)cd->ext, cd->pattern_cnt, HS_MODE_BLOCK, NULL, &pd->hs_db,
731 if (err != HS_SUCCESS) {
732 HSLogCompileError(
"multiple patterns", compile_err, err);
736 if (HSScratchAlloc(pd->hs_db) != 0) {
755 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
757 if (HSCheckPatterns(mpm_ctx,
ctx) == 0) {
761 SCHSCompileData *cd = CompileDataAlloc(mpm_ctx->
pattern_cnt);
762 PatternDatabase *pd = PatternDatabaseAlloc(mpm_ctx->
pattern_cnt);
763 if (cd == NULL || pd == NULL) {
767 HSPatternArrayInit(
ctx, pd);
772 if (HSGlobalPatternDatabaseInit() == -1) {
777 const char *cache_path = pd->no_cache || !mpm_conf ? NULL : mpm_conf->
cache_dir_path;
778 if (PatternDatabaseGetCached(&pd, cd, cache_path) == 0 && pd != NULL) {
780 ctx->pattern_db = pd;
781 if (PatternDatabaseGetSize(pd, &
ctx->hs_db_size) != 0) {
786 if (pd->ref_cnt == 1) {
798 if (PatternDatabaseCompile(pd, cd) != 0) {
803 ctx->pattern_db = pd;
804 if (PatternDatabaseGetSize(pd, &
ctx->hs_db_size) != 0) {
817 SCHSCleanupOnError(pd, cd);
824 static int SCHSCacheRuleset(
MpmConfig *mpm_conf)
832 SCLogWarning(
"Failed to create Hyperscan cache folder, make sure "
833 "the parent folder is writeable "
834 "or adjust sgh-mpm-caching-path setting (%s)",
838 PatternDatabaseCache *pd_stats = mpm_conf->
cache_stats;
839 struct HsIteratorData iter_data = { .pd_stats = pd_stats,
847 static uint32_t FilenameTableHash(
HashTable *ht,
void *data, uint16_t
len)
849 const char *fname = data;
855 static void FilenameTableFree(
void *data)
860 static int SCHSCachePrune(
MpmConfig *mpm_conf)
869 HashTableInit(INIT_DB_HASH_SIZE, FilenameTableHash, NULL, FilenameTableFree);
870 if (inuse_caches == NULL) {
873 struct HsInUseCacheFilesIteratorData iter_data = { .tbl = inuse_caches,
880 int r = SCHSCachePruneEvaluate(mpm_conf, inuse_caches);
895 SCHSThreadCtx *
ctx =
SCCalloc(1,
sizeof(SCHSThreadCtx));
899 mpm_thread_ctx->
ctx =
ctx;
902 mpm_thread_ctx->
memory_size +=
sizeof(SCHSThreadCtx);
905 ctx->scratch_size = 0;
909 if (g_scratch_proto == NULL) {
917 hs_error_t err = hs_clone_scratch(g_scratch_proto,
918 (hs_scratch_t **)&
ctx->scratch);
922 if (err != HS_SUCCESS) {
923 FatalError(
"Unable to clone scratch prototype");
926 err = hs_scratch_size(
ctx->scratch, &
ctx->scratch_size);
927 if (err != HS_SUCCESS) {
940 void SCHSInitCtx(
MpmCtx *mpm_ctx)
942 if (mpm_ctx->
ctx != NULL)
946 if (mpm_ctx->
ctx == NULL) {
954 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
955 ctx->init_hash =
SCCalloc(INIT_HASH_SIZE,
sizeof(SCHSPattern *));
956 if (
ctx->init_hash == NULL) {
969 SCHSPrintSearchStats(mpm_thread_ctx);
971 if (mpm_thread_ctx->
ctx != NULL) {
972 SCHSThreadCtx *thr_ctx = (SCHSThreadCtx *)mpm_thread_ctx->
ctx;
974 if (thr_ctx->scratch != NULL) {
975 hs_free_scratch(thr_ctx->scratch);
977 mpm_thread_ctx->
memory_size -= thr_ctx->scratch_size;
981 mpm_thread_ctx->
ctx = NULL;
983 mpm_thread_ctx->
memory_size -=
sizeof(SCHSThreadCtx);
992 void SCHSDestroyCtx(
MpmCtx *mpm_ctx)
994 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
998 if (
ctx->init_hash != NULL) {
1000 ctx->init_hash = NULL;
1002 mpm_ctx->
memory_size -= (INIT_HASH_SIZE *
sizeof(SCHSPattern *));
1008 PatternDatabase *pd =
ctx->pattern_db;
1010 BUG_ON(pd->ref_cnt == 0);
1012 if (pd->ref_cnt == 0) {
1014 PatternDatabaseFree(pd);
1020 mpm_ctx->
ctx = NULL;
1025 typedef struct SCHSCallbackCtx_ {
1028 uint32_t match_count;
1032 static int SCHSMatchEvent(
unsigned int id,
unsigned long long from,
1033 unsigned long long to,
unsigned int flags,
1036 SCHSCallbackCtx *cctx =
ctx;
1038 const PatternDatabase *pd = cctx->ctx->pattern_db;
1039 const SCHSPattern *pat = pd->parray[id];
1041 SCLogDebug(
"Hyperscan Match %" PRIu32
": id=%" PRIu32
" @ %" PRIuMAX
1042 " (pat id=%" PRIu32
")",
1043 cctx->match_count, (uint32_t)
id, (uintmax_t)to, pat->id);
1045 PrefilterAddSids(pmq, pat->sids, pat->sids_size);
1047 cctx->match_count++;
1067 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
1068 SCHSThreadCtx *hs_thread_ctx = (SCHSThreadCtx *)(mpm_thread_ctx->
ctx);
1069 const PatternDatabase *pd =
ctx->pattern_db;
1075 SCHSCallbackCtx cctx = {.ctx =
ctx, .pmq = pmq, .match_count = 0};
1078 hs_scratch_t *scratch = hs_thread_ctx->scratch;
1082 hs_error_t err = hs_scan(pd->hs_db, (
const char *)buf, buflen, 0, scratch,
1083 SCHSMatchEvent, &cctx);
1084 if (err != HS_SUCCESS) {
1088 SCLogError(
"Hyperscan returned error %d", err);
1091 ret = cctx.match_count;
1114 int SCHSAddPatternCI(
MpmCtx *mpm_ctx,
const uint8_t *pat, uint16_t patlen, uint16_t
offset,
1118 return SCHSAddPattern(mpm_ctx, pat, patlen,
offset, depth, pid, sid,
flags);
1138 int SCHSAddPatternCS(
MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen,
1139 uint16_t
offset, uint16_t depth, uint32_t pid,
1142 return SCHSAddPattern(mpm_ctx, pat, patlen,
offset, depth, pid, sid,
flags);
1145 void SCHSPrintSearchStats(
MpmThreadCtx *mpm_thread_ctx)
1149 void SCHSPrintInfo(
MpmCtx *mpm_ctx)
1151 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
1153 printf(
"MPM HS Information:\n");
1154 printf(
"Memory allocs: %" PRIu32
"\n", mpm_ctx->
memory_cnt);
1155 printf(
"Memory alloced: %" PRIu32
"\n", mpm_ctx->
memory_size);
1156 printf(
" Sizeof:\n");
1157 printf(
" MpmCtx %" PRIuMAX
"\n", (uintmax_t)
sizeof(
MpmCtx));
1158 printf(
" SCHSCtx: %" PRIuMAX
"\n", (uintmax_t)
sizeof(SCHSCtx));
1159 printf(
" SCHSPattern %" PRIuMAX
"\n", (uintmax_t)
sizeof(SCHSPattern));
1160 printf(
"Unique Patterns: %" PRIu32
"\n", mpm_ctx->
pattern_cnt);
1161 printf(
"Smallest: %" PRIu32
"\n", mpm_ctx->
minlen);
1162 printf(
"Largest: %" PRIu32
"\n", mpm_ctx->
maxlen);
1166 PatternDatabase *pd =
ctx->pattern_db;
1167 char *db_info = NULL;
1168 if (hs_database_info(pd->hs_db, &db_info) == HS_SUCCESS) {
1169 printf(
"HS Database Info: %s\n", db_info);
1172 printf(
"HS Database Size: %" PRIuMAX
" bytes\n",
1173 (uintmax_t)
ctx->hs_db_size);
1185 static void SCHSConfigDeinit(
MpmConfig **c)
1193 static void SCHSConfigCacheDirSet(
MpmConfig *c,
const char *dir_path)
1229 SCHSSetAllocators();
1240 if (g_scratch_proto) {
1241 SCLogDebug(
"Cleaning up Hyperscan global scratch");
1242 hs_free_scratch(g_scratch_proto);
1243 g_scratch_proto = NULL;
1248 if (g_db_table != NULL) {
1249 SCLogDebug(
"Clearing Hyperscan database cache");
1263 static int SCHSTest01(
void)
1270 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1278 SCHSPreparePatterns(NULL, &mpm_ctx);
1279 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1281 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1283 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1289 printf(
"1 != %" PRIu32
" ",
cnt);
1291 SCHSDestroyCtx(&mpm_ctx);
1292 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1297 static int SCHSTest02(
void)
1304 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1312 SCHSPreparePatterns(NULL, &mpm_ctx);
1313 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1315 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1316 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1322 printf(
"0 != %" PRIu32
" ",
cnt);
1324 SCHSDestroyCtx(&mpm_ctx);
1325 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1330 static int SCHSTest03(
void)
1337 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1349 SCHSPreparePatterns(NULL, &mpm_ctx);
1350 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1352 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1353 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1359 printf(
"3 != %" PRIu32
" ",
cnt);
1361 SCHSDestroyCtx(&mpm_ctx);
1362 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1367 static int SCHSTest04(
void)
1374 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1383 SCHSPreparePatterns(NULL, &mpm_ctx);
1384 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1386 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1387 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1393 printf(
"1 != %" PRIu32
" ",
cnt);
1395 SCHSDestroyCtx(&mpm_ctx);
1396 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1401 static int SCHSTest05(
void)
1408 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1417 SCHSPreparePatterns(NULL, &mpm_ctx);
1418 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1420 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1421 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1427 printf(
"3 != %" PRIu32
" ",
cnt);
1429 SCHSDestroyCtx(&mpm_ctx);
1430 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1435 static int SCHSTest06(
void)
1442 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1449 SCHSPreparePatterns(NULL, &mpm_ctx);
1450 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1452 const char *buf =
"abcd";
1453 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1459 printf(
"1 != %" PRIu32
" ",
cnt);
1461 SCHSDestroyCtx(&mpm_ctx);
1462 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1467 static int SCHSTest07(
void)
1474 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1487 MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"AAAAAAAAAA", 10, 0, 0, 4, 0, 0);
1489 MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30,
1493 SCHSPreparePatterns(NULL, &mpm_ctx);
1494 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1496 const char *buf =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1497 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1503 printf(
"6 != %" PRIu32
" ",
cnt);
1505 SCHSDestroyCtx(&mpm_ctx);
1506 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1511 static int SCHSTest08(
void)
1518 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1526 SCHSPreparePatterns(NULL, &mpm_ctx);
1527 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1530 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"a", 1);
1535 printf(
"0 != %" PRIu32
" ",
cnt);
1537 SCHSDestroyCtx(&mpm_ctx);
1538 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1543 static int SCHSTest09(
void)
1550 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1558 SCHSPreparePatterns(NULL, &mpm_ctx);
1559 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1562 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"ab", 2);
1567 printf(
"1 != %" PRIu32
" ",
cnt);
1569 SCHSDestroyCtx(&mpm_ctx);
1570 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1575 static int SCHSTest10(
void)
1582 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1590 SCHSPreparePatterns(NULL, &mpm_ctx);
1591 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1593 const char *buf =
"01234567890123456789012345678901234567890123456789"
1594 "01234567890123456789012345678901234567890123456789"
1596 "01234567890123456789012345678901234567890123456789"
1597 "01234567890123456789012345678901234567890123456789";
1598 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1604 printf(
"1 != %" PRIu32
" ",
cnt);
1606 SCHSDestroyCtx(&mpm_ctx);
1607 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1612 static int SCHSTest11(
void)
1619 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1623 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"he", 2, 0, 0, 1, 0, 0) == -1)
1625 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"she", 3, 0, 0, 2, 0, 0) == -1)
1627 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"his", 3, 0, 0, 3, 0, 0) == -1)
1629 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"hers", 4, 0, 0, 4, 0, 0) == -1)
1633 if (SCHSPreparePatterns(NULL, &mpm_ctx) == -1)
1636 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1640 const char *buf =
"he";
1641 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1644 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1647 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1650 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1654 SCHSDestroyCtx(&mpm_ctx);
1655 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1660 static int SCHSTest12(
void)
1667 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1677 SCHSPreparePatterns(NULL, &mpm_ctx);
1678 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1680 const char *buf =
"abcdefghijklmnopqrstuvwxyz";
1681 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1687 printf(
"2 != %" PRIu32
" ",
cnt);
1689 SCHSDestroyCtx(&mpm_ctx);
1690 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1695 static int SCHSTest13(
void)
1702 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1707 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABCD";
1708 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1711 SCHSPreparePatterns(NULL, &mpm_ctx);
1712 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1714 const char *buf =
"abcdefghijklmnopqrstuvwxyzABCD";
1715 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1721 printf(
"1 != %" PRIu32
" ",
cnt);
1723 SCHSDestroyCtx(&mpm_ctx);
1724 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1729 static int SCHSTest14(
void)
1736 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1741 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABCDE";
1742 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1745 SCHSPreparePatterns(NULL, &mpm_ctx);
1746 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1748 const char *buf =
"abcdefghijklmnopqrstuvwxyzABCDE";
1749 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1755 printf(
"1 != %" PRIu32
" ",
cnt);
1757 SCHSDestroyCtx(&mpm_ctx);
1758 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1763 static int SCHSTest15(
void)
1770 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1775 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABCDEF";
1776 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1779 SCHSPreparePatterns(NULL, &mpm_ctx);
1780 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1782 const char *buf =
"abcdefghijklmnopqrstuvwxyzABCDEF";
1783 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1789 printf(
"1 != %" PRIu32
" ",
cnt);
1791 SCHSDestroyCtx(&mpm_ctx);
1792 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1797 static int SCHSTest16(
void)
1804 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1809 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABC";
1810 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1813 SCHSPreparePatterns(NULL, &mpm_ctx);
1814 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1816 const char *buf =
"abcdefghijklmnopqrstuvwxyzABC";
1817 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1823 printf(
"1 != %" PRIu32
" ",
cnt);
1825 SCHSDestroyCtx(&mpm_ctx);
1826 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1831 static int SCHSTest17(
void)
1838 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1843 const char pat[] =
"abcdefghijklmnopqrstuvwxyzAB";
1844 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1847 SCHSPreparePatterns(NULL, &mpm_ctx);
1848 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1850 const char *buf =
"abcdefghijklmnopqrstuvwxyzAB";
1851 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1857 printf(
"1 != %" PRIu32
" ",
cnt);
1859 SCHSDestroyCtx(&mpm_ctx);
1860 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1865 static int SCHSTest18(
void)
1872 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1877 const char pat[] =
"abcde"
1883 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1886 SCHSPreparePatterns(NULL, &mpm_ctx);
1887 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1889 const char *buf =
"abcde"
1895 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1901 printf(
"1 != %" PRIu32
" ",
cnt);
1903 SCHSDestroyCtx(&mpm_ctx);
1904 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1909 static int SCHSTest19(
void)
1916 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1921 const char pat[] =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1922 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1925 SCHSPreparePatterns(NULL, &mpm_ctx);
1926 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1928 const char *buf =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1929 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1935 printf(
"1 != %" PRIu32
" ",
cnt);
1937 SCHSDestroyCtx(&mpm_ctx);
1938 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1943 static int SCHSTest20(
void)
1950 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1955 const char pat[] =
"AAAAA"
1962 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1965 SCHSPreparePatterns(NULL, &mpm_ctx);
1966 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1968 const char *buf =
"AAAAA"
1975 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1981 printf(
"1 != %" PRIu32
" ",
cnt);
1983 SCHSDestroyCtx(&mpm_ctx);
1984 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1989 static int SCHSTest21(
void)
1996 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2004 SCHSPreparePatterns(NULL, &mpm_ctx);
2005 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2008 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"AA", 2);
2013 printf(
"1 != %" PRIu32
" ",
cnt);
2015 SCHSDestroyCtx(&mpm_ctx);
2016 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2021 static int SCHSTest22(
void)
2028 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2038 SCHSPreparePatterns(NULL, &mpm_ctx);
2039 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2041 const char *buf =
"abcdefghijklmnopqrstuvwxyz";
2042 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2048 printf(
"2 != %" PRIu32
" ",
cnt);
2050 SCHSDestroyCtx(&mpm_ctx);
2051 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2056 static int SCHSTest23(
void)
2063 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2071 SCHSPreparePatterns(NULL, &mpm_ctx);
2072 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2075 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"aa", 2);
2080 printf(
"1 != %" PRIu32
" ",
cnt);
2082 SCHSDestroyCtx(&mpm_ctx);
2083 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2088 static int SCHSTest24(
void)
2095 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2103 SCHSPreparePatterns(NULL, &mpm_ctx);
2104 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2107 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"aa", 2);
2112 printf(
"1 != %" PRIu32
" ",
cnt);
2114 SCHSDestroyCtx(&mpm_ctx);
2115 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2120 static int SCHSTest25(
void)
2127 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2136 SCHSPreparePatterns(NULL, &mpm_ctx);
2137 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2139 const char *buf =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
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 SCHSTest26(
void)
2161 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2169 SCHSPreparePatterns(NULL, &mpm_ctx);
2170 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2172 const char *buf =
"works";
2173 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2179 printf(
"3 != %" PRIu32
" ",
cnt);
2181 SCHSDestroyCtx(&mpm_ctx);
2182 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2187 static int SCHSTest27(
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 SCHSTest28(
void)
2227 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
2235 SCHSPreparePatterns(NULL, &mpm_ctx);
2236 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2238 const char *buf =
"tONE";
2239 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2245 printf(
"0 != %" PRIu32
" ",
cnt);
2247 SCHSDestroyCtx(&mpm_ctx);
2248 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2253 static int SCHSTest29(
void)
2255 uint8_t buf[] =
"onetwothreefourfivesixseveneightnine";
2256 uint16_t buflen =
sizeof(buf) - 1;
2262 memset(&th_v, 0,
sizeof(th_v));
2274 de_ctx,
"alert tcp any any -> any any "
2275 "(content:\"onetwothreefourfivesixseveneightnine\"; sid:1;)");
2280 "(content:\"onetwothreefourfivesixseveneightnine\"; "
2281 "fast_pattern:3,3; sid:2;)");
2290 printf(
"if (PacketAlertCheck(p, 1) != 1) failure\n");
2294 printf(
"if (PacketAlertCheck(p, 1) != 2) failure\n");
2310 static void SCHSRegisterTests(
void)