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");
1261 static int SCHSTest01(
void)
1268 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1276 SCHSPreparePatterns(NULL, &mpm_ctx);
1277 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1279 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1281 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1287 printf(
"1 != %" PRIu32
" ",
cnt);
1289 SCHSDestroyCtx(&mpm_ctx);
1290 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1295 static int SCHSTest02(
void)
1302 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1310 SCHSPreparePatterns(NULL, &mpm_ctx);
1311 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1313 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1314 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1320 printf(
"0 != %" PRIu32
" ",
cnt);
1322 SCHSDestroyCtx(&mpm_ctx);
1323 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1328 static int SCHSTest03(
void)
1335 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1347 SCHSPreparePatterns(NULL, &mpm_ctx);
1348 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1350 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1351 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1357 printf(
"3 != %" PRIu32
" ",
cnt);
1359 SCHSDestroyCtx(&mpm_ctx);
1360 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1365 static int SCHSTest04(
void)
1372 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1381 SCHSPreparePatterns(NULL, &mpm_ctx);
1382 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1384 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1385 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1391 printf(
"1 != %" PRIu32
" ",
cnt);
1393 SCHSDestroyCtx(&mpm_ctx);
1394 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1399 static int SCHSTest05(
void)
1406 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1415 SCHSPreparePatterns(NULL, &mpm_ctx);
1416 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1418 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1419 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1425 printf(
"3 != %" PRIu32
" ",
cnt);
1427 SCHSDestroyCtx(&mpm_ctx);
1428 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1433 static int SCHSTest06(
void)
1440 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1447 SCHSPreparePatterns(NULL, &mpm_ctx);
1448 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1450 const char *buf =
"abcd";
1451 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1457 printf(
"1 != %" PRIu32
" ",
cnt);
1459 SCHSDestroyCtx(&mpm_ctx);
1460 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1465 static int SCHSTest07(
void)
1472 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1485 MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"AAAAAAAAAA", 10, 0, 0, 4, 0, 0);
1487 MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30,
1491 SCHSPreparePatterns(NULL, &mpm_ctx);
1492 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1494 const char *buf =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1495 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1501 printf(
"6 != %" PRIu32
" ",
cnt);
1503 SCHSDestroyCtx(&mpm_ctx);
1504 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1509 static int SCHSTest08(
void)
1516 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1524 SCHSPreparePatterns(NULL, &mpm_ctx);
1525 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1528 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"a", 1);
1533 printf(
"0 != %" PRIu32
" ",
cnt);
1535 SCHSDestroyCtx(&mpm_ctx);
1536 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1541 static int SCHSTest09(
void)
1548 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1556 SCHSPreparePatterns(NULL, &mpm_ctx);
1557 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1560 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"ab", 2);
1565 printf(
"1 != %" PRIu32
" ",
cnt);
1567 SCHSDestroyCtx(&mpm_ctx);
1568 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1573 static int SCHSTest10(
void)
1580 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1588 SCHSPreparePatterns(NULL, &mpm_ctx);
1589 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1591 const char *buf =
"01234567890123456789012345678901234567890123456789"
1592 "01234567890123456789012345678901234567890123456789"
1594 "01234567890123456789012345678901234567890123456789"
1595 "01234567890123456789012345678901234567890123456789";
1596 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1602 printf(
"1 != %" PRIu32
" ",
cnt);
1604 SCHSDestroyCtx(&mpm_ctx);
1605 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1610 static int SCHSTest11(
void)
1617 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1621 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"he", 2, 0, 0, 1, 0, 0) == -1)
1623 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"she", 3, 0, 0, 2, 0, 0) == -1)
1625 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"his", 3, 0, 0, 3, 0, 0) == -1)
1627 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"hers", 4, 0, 0, 4, 0, 0) == -1)
1631 if (SCHSPreparePatterns(NULL, &mpm_ctx) == -1)
1634 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1638 const char *buf =
"he";
1639 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1642 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1645 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1648 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1652 SCHSDestroyCtx(&mpm_ctx);
1653 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1658 static int SCHSTest12(
void)
1665 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1675 SCHSPreparePatterns(NULL, &mpm_ctx);
1676 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1678 const char *buf =
"abcdefghijklmnopqrstuvwxyz";
1679 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1685 printf(
"2 != %" PRIu32
" ",
cnt);
1687 SCHSDestroyCtx(&mpm_ctx);
1688 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1693 static int SCHSTest13(
void)
1700 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1705 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABCD";
1706 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1709 SCHSPreparePatterns(NULL, &mpm_ctx);
1710 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1712 const char *buf =
"abcdefghijklmnopqrstuvwxyzABCD";
1713 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1719 printf(
"1 != %" PRIu32
" ",
cnt);
1721 SCHSDestroyCtx(&mpm_ctx);
1722 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1727 static int SCHSTest14(
void)
1734 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1739 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABCDE";
1740 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1743 SCHSPreparePatterns(NULL, &mpm_ctx);
1744 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1746 const char *buf =
"abcdefghijklmnopqrstuvwxyzABCDE";
1747 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1753 printf(
"1 != %" PRIu32
" ",
cnt);
1755 SCHSDestroyCtx(&mpm_ctx);
1756 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1761 static int SCHSTest15(
void)
1768 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1773 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABCDEF";
1774 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1777 SCHSPreparePatterns(NULL, &mpm_ctx);
1778 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1780 const char *buf =
"abcdefghijklmnopqrstuvwxyzABCDEF";
1781 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1787 printf(
"1 != %" PRIu32
" ",
cnt);
1789 SCHSDestroyCtx(&mpm_ctx);
1790 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1795 static int SCHSTest16(
void)
1802 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1807 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABC";
1808 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1811 SCHSPreparePatterns(NULL, &mpm_ctx);
1812 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1814 const char *buf =
"abcdefghijklmnopqrstuvwxyzABC";
1815 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1821 printf(
"1 != %" PRIu32
" ",
cnt);
1823 SCHSDestroyCtx(&mpm_ctx);
1824 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1829 static int SCHSTest17(
void)
1836 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1841 const char pat[] =
"abcdefghijklmnopqrstuvwxyzAB";
1842 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1845 SCHSPreparePatterns(NULL, &mpm_ctx);
1846 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1848 const char *buf =
"abcdefghijklmnopqrstuvwxyzAB";
1849 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1855 printf(
"1 != %" PRIu32
" ",
cnt);
1857 SCHSDestroyCtx(&mpm_ctx);
1858 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1863 static int SCHSTest18(
void)
1870 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1875 const char pat[] =
"abcde"
1881 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1884 SCHSPreparePatterns(NULL, &mpm_ctx);
1885 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1887 const char *buf =
"abcde"
1893 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1899 printf(
"1 != %" PRIu32
" ",
cnt);
1901 SCHSDestroyCtx(&mpm_ctx);
1902 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1907 static int SCHSTest19(
void)
1914 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1919 const char pat[] =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1920 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1923 SCHSPreparePatterns(NULL, &mpm_ctx);
1924 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1926 const char *buf =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1927 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1933 printf(
"1 != %" PRIu32
" ",
cnt);
1935 SCHSDestroyCtx(&mpm_ctx);
1936 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1941 static int SCHSTest20(
void)
1948 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1953 const char pat[] =
"AAAAA"
1960 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1963 SCHSPreparePatterns(NULL, &mpm_ctx);
1964 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1966 const char *buf =
"AAAAA"
1973 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1979 printf(
"1 != %" PRIu32
" ",
cnt);
1981 SCHSDestroyCtx(&mpm_ctx);
1982 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1987 static int SCHSTest21(
void)
1994 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2002 SCHSPreparePatterns(NULL, &mpm_ctx);
2003 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2006 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"AA", 2);
2011 printf(
"1 != %" PRIu32
" ",
cnt);
2013 SCHSDestroyCtx(&mpm_ctx);
2014 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2019 static int SCHSTest22(
void)
2026 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2036 SCHSPreparePatterns(NULL, &mpm_ctx);
2037 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2039 const char *buf =
"abcdefghijklmnopqrstuvwxyz";
2040 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2046 printf(
"2 != %" PRIu32
" ",
cnt);
2048 SCHSDestroyCtx(&mpm_ctx);
2049 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2054 static int SCHSTest23(
void)
2061 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2069 SCHSPreparePatterns(NULL, &mpm_ctx);
2070 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2073 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"aa", 2);
2078 printf(
"1 != %" PRIu32
" ",
cnt);
2080 SCHSDestroyCtx(&mpm_ctx);
2081 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2086 static int SCHSTest24(
void)
2093 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2101 SCHSPreparePatterns(NULL, &mpm_ctx);
2102 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2105 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"aa", 2);
2110 printf(
"1 != %" PRIu32
" ",
cnt);
2112 SCHSDestroyCtx(&mpm_ctx);
2113 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2118 static int SCHSTest25(
void)
2125 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2134 SCHSPreparePatterns(NULL, &mpm_ctx);
2135 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2137 const char *buf =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
2138 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2144 printf(
"3 != %" PRIu32
" ",
cnt);
2146 SCHSDestroyCtx(&mpm_ctx);
2147 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2152 static int SCHSTest26(
void)
2159 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2167 SCHSPreparePatterns(NULL, &mpm_ctx);
2168 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2170 const char *buf =
"works";
2171 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2177 printf(
"3 != %" PRIu32
" ",
cnt);
2179 SCHSDestroyCtx(&mpm_ctx);
2180 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2185 static int SCHSTest27(
void)
2192 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
2200 SCHSPreparePatterns(NULL, &mpm_ctx);
2201 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2203 const char *buf =
"tone";
2204 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2210 printf(
"0 != %" PRIu32
" ",
cnt);
2212 SCHSDestroyCtx(&mpm_ctx);
2213 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2218 static int SCHSTest28(
void)
2225 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
2233 SCHSPreparePatterns(NULL, &mpm_ctx);
2234 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2236 const char *buf =
"tONE";
2237 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2243 printf(
"0 != %" PRIu32
" ",
cnt);
2245 SCHSDestroyCtx(&mpm_ctx);
2246 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2251 static int SCHSTest29(
void)
2253 uint8_t buf[] =
"onetwothreefourfivesixseveneightnine";
2254 uint16_t buflen =
sizeof(buf) - 1;
2260 memset(&th_v, 0,
sizeof(th_v));
2272 de_ctx,
"alert tcp any any -> any any "
2273 "(content:\"onetwothreefourfivesixseveneightnine\"; sid:1;)");
2278 "(content:\"onetwothreefourfivesixseveneightnine\"; "
2279 "fast_pattern:3,3; sid:2;)");
2288 printf(
"if (PacketAlertCheck(p, 1) != 1) failure\n");
2292 printf(
"if (PacketAlertCheck(p, 1) != 2) failure\n");
2308 static void SCHSRegisterTests(
void)