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));
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);
1184 static void SCHSConfigDeinit(
MpmConfig **c)
1192 static void SCHSConfigCacheDirSet(
MpmConfig *c,
const char *dir_path)
1228 SCHSSetAllocators();
1239 if (g_scratch_proto) {
1240 SCLogDebug(
"Cleaning up Hyperscan global scratch");
1241 hs_free_scratch(g_scratch_proto);
1242 g_scratch_proto = NULL;
1247 if (g_db_table != NULL) {
1248 SCLogDebug(
"Clearing Hyperscan database cache");
1262 static int SCHSTest01(
void)
1269 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1277 SCHSPreparePatterns(NULL, &mpm_ctx);
1278 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1280 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1282 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1288 printf(
"1 != %" PRIu32
" ",
cnt);
1290 SCHSDestroyCtx(&mpm_ctx);
1291 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1296 static int SCHSTest02(
void)
1303 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1311 SCHSPreparePatterns(NULL, &mpm_ctx);
1312 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1314 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1315 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1321 printf(
"0 != %" PRIu32
" ",
cnt);
1323 SCHSDestroyCtx(&mpm_ctx);
1324 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1329 static int SCHSTest03(
void)
1336 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1348 SCHSPreparePatterns(NULL, &mpm_ctx);
1349 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1351 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1352 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1358 printf(
"3 != %" PRIu32
" ",
cnt);
1360 SCHSDestroyCtx(&mpm_ctx);
1361 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1366 static int SCHSTest04(
void)
1373 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1382 SCHSPreparePatterns(NULL, &mpm_ctx);
1383 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1385 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1386 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1392 printf(
"1 != %" PRIu32
" ",
cnt);
1394 SCHSDestroyCtx(&mpm_ctx);
1395 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1400 static int SCHSTest05(
void)
1407 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1416 SCHSPreparePatterns(NULL, &mpm_ctx);
1417 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1419 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1420 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1426 printf(
"3 != %" PRIu32
" ",
cnt);
1428 SCHSDestroyCtx(&mpm_ctx);
1429 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1434 static int SCHSTest06(
void)
1441 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1448 SCHSPreparePatterns(NULL, &mpm_ctx);
1449 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1451 const char *buf =
"abcd";
1452 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1458 printf(
"1 != %" PRIu32
" ",
cnt);
1460 SCHSDestroyCtx(&mpm_ctx);
1461 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1466 static int SCHSTest07(
void)
1473 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1486 MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"AAAAAAAAAA", 10, 0, 0, 4, 0, 0);
1488 MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30,
1492 SCHSPreparePatterns(NULL, &mpm_ctx);
1493 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1495 const char *buf =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1496 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1502 printf(
"6 != %" PRIu32
" ",
cnt);
1504 SCHSDestroyCtx(&mpm_ctx);
1505 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1510 static int SCHSTest08(
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 *)
"a", 1);
1534 printf(
"0 != %" PRIu32
" ",
cnt);
1536 SCHSDestroyCtx(&mpm_ctx);
1537 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1542 static int SCHSTest09(
void)
1549 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1557 SCHSPreparePatterns(NULL, &mpm_ctx);
1558 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1561 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"ab", 2);
1566 printf(
"1 != %" PRIu32
" ",
cnt);
1568 SCHSDestroyCtx(&mpm_ctx);
1569 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1574 static int SCHSTest10(
void)
1581 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1589 SCHSPreparePatterns(NULL, &mpm_ctx);
1590 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1592 const char *buf =
"01234567890123456789012345678901234567890123456789"
1593 "01234567890123456789012345678901234567890123456789"
1595 "01234567890123456789012345678901234567890123456789"
1596 "01234567890123456789012345678901234567890123456789";
1597 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1603 printf(
"1 != %" PRIu32
" ",
cnt);
1605 SCHSDestroyCtx(&mpm_ctx);
1606 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1611 static int SCHSTest11(
void)
1618 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1622 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"he", 2, 0, 0, 1, 0, 0) == -1)
1624 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"she", 3, 0, 0, 2, 0, 0) == -1)
1626 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"his", 3, 0, 0, 3, 0, 0) == -1)
1628 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"hers", 4, 0, 0, 4, 0, 0) == -1)
1632 if (SCHSPreparePatterns(NULL, &mpm_ctx) == -1)
1635 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1639 const char *buf =
"he";
1640 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1643 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1646 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1649 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1653 SCHSDestroyCtx(&mpm_ctx);
1654 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1659 static int SCHSTest12(
void)
1666 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1676 SCHSPreparePatterns(NULL, &mpm_ctx);
1677 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1679 const char *buf =
"abcdefghijklmnopqrstuvwxyz";
1680 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1686 printf(
"2 != %" PRIu32
" ",
cnt);
1688 SCHSDestroyCtx(&mpm_ctx);
1689 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1694 static int SCHSTest13(
void)
1701 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1706 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABCD";
1707 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1710 SCHSPreparePatterns(NULL, &mpm_ctx);
1711 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1713 const char *buf =
"abcdefghijklmnopqrstuvwxyzABCD";
1714 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1720 printf(
"1 != %" PRIu32
" ",
cnt);
1722 SCHSDestroyCtx(&mpm_ctx);
1723 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1728 static int SCHSTest14(
void)
1735 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1740 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABCDE";
1741 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1744 SCHSPreparePatterns(NULL, &mpm_ctx);
1745 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1747 const char *buf =
"abcdefghijklmnopqrstuvwxyzABCDE";
1748 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1754 printf(
"1 != %" PRIu32
" ",
cnt);
1756 SCHSDestroyCtx(&mpm_ctx);
1757 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1762 static int SCHSTest15(
void)
1769 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1774 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABCDEF";
1775 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1778 SCHSPreparePatterns(NULL, &mpm_ctx);
1779 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1781 const char *buf =
"abcdefghijklmnopqrstuvwxyzABCDEF";
1782 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1788 printf(
"1 != %" PRIu32
" ",
cnt);
1790 SCHSDestroyCtx(&mpm_ctx);
1791 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1796 static int SCHSTest16(
void)
1803 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1808 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABC";
1809 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1812 SCHSPreparePatterns(NULL, &mpm_ctx);
1813 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1815 const char *buf =
"abcdefghijklmnopqrstuvwxyzABC";
1816 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1822 printf(
"1 != %" PRIu32
" ",
cnt);
1824 SCHSDestroyCtx(&mpm_ctx);
1825 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1830 static int SCHSTest17(
void)
1837 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1842 const char pat[] =
"abcdefghijklmnopqrstuvwxyzAB";
1843 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1846 SCHSPreparePatterns(NULL, &mpm_ctx);
1847 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1849 const char *buf =
"abcdefghijklmnopqrstuvwxyzAB";
1850 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1856 printf(
"1 != %" PRIu32
" ",
cnt);
1858 SCHSDestroyCtx(&mpm_ctx);
1859 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1864 static int SCHSTest18(
void)
1871 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1876 const char pat[] =
"abcde"
1882 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1885 SCHSPreparePatterns(NULL, &mpm_ctx);
1886 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1888 const char *buf =
"abcde"
1894 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1900 printf(
"1 != %" PRIu32
" ",
cnt);
1902 SCHSDestroyCtx(&mpm_ctx);
1903 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1908 static int SCHSTest19(
void)
1915 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1920 const char pat[] =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1921 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1924 SCHSPreparePatterns(NULL, &mpm_ctx);
1925 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1927 const char *buf =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1928 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1934 printf(
"1 != %" PRIu32
" ",
cnt);
1936 SCHSDestroyCtx(&mpm_ctx);
1937 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1942 static int SCHSTest20(
void)
1949 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1954 const char pat[] =
"AAAAA"
1961 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1964 SCHSPreparePatterns(NULL, &mpm_ctx);
1965 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1967 const char *buf =
"AAAAA"
1974 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1980 printf(
"1 != %" PRIu32
" ",
cnt);
1982 SCHSDestroyCtx(&mpm_ctx);
1983 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1988 static int SCHSTest21(
void)
1995 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2003 SCHSPreparePatterns(NULL, &mpm_ctx);
2004 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2007 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"AA", 2);
2012 printf(
"1 != %" PRIu32
" ",
cnt);
2014 SCHSDestroyCtx(&mpm_ctx);
2015 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2020 static int SCHSTest22(
void)
2027 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2037 SCHSPreparePatterns(NULL, &mpm_ctx);
2038 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2040 const char *buf =
"abcdefghijklmnopqrstuvwxyz";
2041 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2047 printf(
"2 != %" PRIu32
" ",
cnt);
2049 SCHSDestroyCtx(&mpm_ctx);
2050 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2055 static int SCHSTest23(
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 SCHSTest24(
void)
2094 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2102 SCHSPreparePatterns(NULL, &mpm_ctx);
2103 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2106 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"aa", 2);
2111 printf(
"1 != %" PRIu32
" ",
cnt);
2113 SCHSDestroyCtx(&mpm_ctx);
2114 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2119 static int SCHSTest25(
void)
2126 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2135 SCHSPreparePatterns(NULL, &mpm_ctx);
2136 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2138 const char *buf =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
2139 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2145 printf(
"3 != %" PRIu32
" ",
cnt);
2147 SCHSDestroyCtx(&mpm_ctx);
2148 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2153 static int SCHSTest26(
void)
2160 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2168 SCHSPreparePatterns(NULL, &mpm_ctx);
2169 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2171 const char *buf =
"works";
2172 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2178 printf(
"3 != %" PRIu32
" ",
cnt);
2180 SCHSDestroyCtx(&mpm_ctx);
2181 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2186 static int SCHSTest27(
void)
2193 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
2201 SCHSPreparePatterns(NULL, &mpm_ctx);
2202 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2204 const char *buf =
"tone";
2205 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2211 printf(
"0 != %" PRIu32
" ",
cnt);
2213 SCHSDestroyCtx(&mpm_ctx);
2214 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2219 static int SCHSTest28(
void)
2226 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
2234 SCHSPreparePatterns(NULL, &mpm_ctx);
2235 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2237 const char *buf =
"tONE";
2238 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2244 printf(
"0 != %" PRIu32
" ",
cnt);
2246 SCHSDestroyCtx(&mpm_ctx);
2247 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2252 static int SCHSTest29(
void)
2254 uint8_t buf[] =
"onetwothreefourfivesixseveneightnine";
2255 uint16_t buflen =
sizeof(buf) - 1;
2273 de_ctx,
"alert tcp any any -> any any "
2274 "(content:\"onetwothreefourfivesixseveneightnine\"; sid:1;)");
2279 "(content:\"onetwothreefourfivesixseveneightnine\"; "
2280 "fast_pattern:3,3; sid:2;)");
2289 printf(
"if (PacketAlertCheck(p, 1) != 1) failure\n");
2293 printf(
"if (PacketAlertCheck(p, 1) != 2) failure\n");
2309 static void SCHSRegisterTests(
void)