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) {
790 ctx->pattern_db = pd;
791 if (PatternDatabaseGetSize(pd, &
ctx->hs_db_size) != 0) {
796 if (pd->ref_cnt == 1) {
808 if (PatternDatabaseCompile(pd, cd) != 0) {
813 ctx->pattern_db = pd;
814 if (PatternDatabaseGetSize(pd, &
ctx->hs_db_size) != 0) {
827 SCHSCleanupOnError(pd, cd);
834 static int SCHSCacheRuleset(
MpmConfig *mpm_conf)
842 SCLogWarning(
"Failed to create Hyperscan cache folder, make sure "
843 "the parent folder is writeable "
844 "or adjust sgh-mpm-caching-path setting (%s)",
848 PatternDatabaseCache pd_stats = { 0 };
849 struct HsIteratorData iter_data = { .pd_stats = &pd_stats,
854 SCLogNotice(
"Rule group caching - loaded: %u newly cached: %u total cacheable: %u",
855 pd_stats.hs_dbs_cache_loaded_cnt, pd_stats.hs_dbs_cache_saved_cnt,
856 pd_stats.hs_cacheable_dbs_cnt);
870 SCHSThreadCtx *
ctx =
SCCalloc(1,
sizeof(SCHSThreadCtx));
874 mpm_thread_ctx->
ctx =
ctx;
877 mpm_thread_ctx->
memory_size +=
sizeof(SCHSThreadCtx);
880 ctx->scratch_size = 0;
884 if (g_scratch_proto == NULL) {
892 hs_error_t err = hs_clone_scratch(g_scratch_proto,
893 (hs_scratch_t **)&
ctx->scratch);
897 if (err != HS_SUCCESS) {
898 FatalError(
"Unable to clone scratch prototype");
901 err = hs_scratch_size(
ctx->scratch, &
ctx->scratch_size);
902 if (err != HS_SUCCESS) {
915 void SCHSInitCtx(
MpmCtx *mpm_ctx)
917 if (mpm_ctx->
ctx != NULL)
921 if (mpm_ctx->
ctx == NULL) {
929 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
930 ctx->init_hash =
SCCalloc(INIT_HASH_SIZE,
sizeof(SCHSPattern *));
931 if (
ctx->init_hash == NULL) {
944 SCHSPrintSearchStats(mpm_thread_ctx);
946 if (mpm_thread_ctx->
ctx != NULL) {
947 SCHSThreadCtx *thr_ctx = (SCHSThreadCtx *)mpm_thread_ctx->
ctx;
949 if (thr_ctx->scratch != NULL) {
950 hs_free_scratch(thr_ctx->scratch);
952 mpm_thread_ctx->
memory_size -= thr_ctx->scratch_size;
956 mpm_thread_ctx->
ctx = NULL;
958 mpm_thread_ctx->
memory_size -=
sizeof(SCHSThreadCtx);
967 void SCHSDestroyCtx(
MpmCtx *mpm_ctx)
969 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
973 if (
ctx->init_hash != NULL) {
975 ctx->init_hash = NULL;
977 mpm_ctx->
memory_size -= (INIT_HASH_SIZE *
sizeof(SCHSPattern *));
983 PatternDatabase *pd =
ctx->pattern_db;
987 if (pd->ref_cnt == 0) {
989 PatternDatabaseFree(pd);
1000 typedef struct SCHSCallbackCtx_ {
1003 uint32_t match_count;
1007 static int SCHSMatchEvent(
unsigned int id,
unsigned long long from,
1008 unsigned long long to,
unsigned int flags,
1011 SCHSCallbackCtx *cctx =
ctx;
1013 const PatternDatabase *pd = cctx->ctx->pattern_db;
1014 const SCHSPattern *pat = pd->parray[id];
1016 SCLogDebug(
"Hyperscan Match %" PRIu32
": id=%" PRIu32
" @ %" PRIuMAX
1017 " (pat id=%" PRIu32
")",
1018 cctx->match_count, (uint32_t)
id, (uintmax_t)to, pat->id);
1020 PrefilterAddSids(pmq, pat->sids, pat->sids_size);
1022 cctx->match_count++;
1042 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
1043 SCHSThreadCtx *hs_thread_ctx = (SCHSThreadCtx *)(mpm_thread_ctx->
ctx);
1044 const PatternDatabase *pd =
ctx->pattern_db;
1050 SCHSCallbackCtx cctx = {.ctx =
ctx, .pmq = pmq, .match_count = 0};
1053 hs_scratch_t *scratch = hs_thread_ctx->scratch;
1054 BUG_ON(pd->hs_db == NULL);
1057 hs_error_t err = hs_scan(pd->hs_db, (
const char *)buf, buflen, 0, scratch,
1058 SCHSMatchEvent, &cctx);
1059 if (err != HS_SUCCESS) {
1063 SCLogError(
"Hyperscan returned error %d", err);
1066 ret = cctx.match_count;
1089 int SCHSAddPatternCI(
MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen,
1090 uint16_t
offset, uint16_t depth, uint32_t pid,
1094 return SCHSAddPattern(mpm_ctx, pat, patlen,
offset, depth, pid, sid,
flags);
1114 int SCHSAddPatternCS(
MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen,
1115 uint16_t
offset, uint16_t depth, uint32_t pid,
1118 return SCHSAddPattern(mpm_ctx, pat, patlen,
offset, depth, pid, sid,
flags);
1121 void SCHSPrintSearchStats(
MpmThreadCtx *mpm_thread_ctx)
1125 void SCHSPrintInfo(
MpmCtx *mpm_ctx)
1127 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
1129 printf(
"MPM HS Information:\n");
1130 printf(
"Memory allocs: %" PRIu32
"\n", mpm_ctx->
memory_cnt);
1131 printf(
"Memory alloced: %" PRIu32
"\n", mpm_ctx->
memory_size);
1132 printf(
" Sizeof:\n");
1133 printf(
" MpmCtx %" PRIuMAX
"\n", (uintmax_t)
sizeof(
MpmCtx));
1134 printf(
" SCHSCtx: %" PRIuMAX
"\n", (uintmax_t)
sizeof(SCHSCtx));
1135 printf(
" SCHSPattern %" PRIuMAX
"\n", (uintmax_t)
sizeof(SCHSPattern));
1136 printf(
"Unique Patterns: %" PRIu32
"\n", mpm_ctx->
pattern_cnt);
1137 printf(
"Smallest: %" PRIu32
"\n", mpm_ctx->
minlen);
1138 printf(
"Largest: %" PRIu32
"\n", mpm_ctx->
maxlen);
1142 PatternDatabase *pd =
ctx->pattern_db;
1143 char *db_info = NULL;
1144 if (hs_database_info(pd->hs_db, &db_info) == HS_SUCCESS) {
1145 printf(
"HS Database Info: %s\n", db_info);
1148 printf(
"HS Database Size: %" PRIuMAX
" bytes\n",
1149 (uintmax_t)
ctx->hs_db_size);
1161 static void SCHSConfigDeinit(
MpmConfig **c)
1169 static void SCHSConfigCacheDirSet(
MpmConfig *c,
const char *dir_path)
1201 SCHSSetAllocators();
1212 if (g_scratch_proto) {
1213 SCLogDebug(
"Cleaning up Hyperscan global scratch");
1214 hs_free_scratch(g_scratch_proto);
1215 g_scratch_proto = NULL;
1220 if (g_db_table != NULL) {
1221 SCLogDebug(
"Clearing Hyperscan database cache");
1233 static int SCHSTest01(
void)
1240 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1248 SCHSPreparePatterns(NULL, &mpm_ctx);
1249 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1251 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1253 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1259 printf(
"1 != %" PRIu32
" ",
cnt);
1261 SCHSDestroyCtx(&mpm_ctx);
1262 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1267 static int SCHSTest02(
void)
1274 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1282 SCHSPreparePatterns(NULL, &mpm_ctx);
1283 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1285 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1286 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1292 printf(
"0 != %" PRIu32
" ",
cnt);
1294 SCHSDestroyCtx(&mpm_ctx);
1295 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1300 static int SCHSTest03(
void)
1307 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1319 SCHSPreparePatterns(NULL, &mpm_ctx);
1320 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1322 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1323 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1329 printf(
"3 != %" PRIu32
" ",
cnt);
1331 SCHSDestroyCtx(&mpm_ctx);
1332 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1337 static int SCHSTest04(
void)
1344 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1353 SCHSPreparePatterns(NULL, &mpm_ctx);
1354 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1356 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1357 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1363 printf(
"1 != %" PRIu32
" ",
cnt);
1365 SCHSDestroyCtx(&mpm_ctx);
1366 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1371 static int SCHSTest05(
void)
1378 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1387 SCHSPreparePatterns(NULL, &mpm_ctx);
1388 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1390 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1391 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1397 printf(
"3 != %" PRIu32
" ",
cnt);
1399 SCHSDestroyCtx(&mpm_ctx);
1400 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1405 static int SCHSTest06(
void)
1412 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1419 SCHSPreparePatterns(NULL, &mpm_ctx);
1420 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1422 const char *buf =
"abcd";
1423 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1429 printf(
"1 != %" PRIu32
" ",
cnt);
1431 SCHSDestroyCtx(&mpm_ctx);
1432 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1437 static int SCHSTest07(
void)
1444 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1457 MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"AAAAAAAAAA", 10, 0, 0, 4, 0, 0);
1459 MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30,
1463 SCHSPreparePatterns(NULL, &mpm_ctx);
1464 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1466 const char *buf =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1467 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1473 printf(
"6 != %" PRIu32
" ",
cnt);
1475 SCHSDestroyCtx(&mpm_ctx);
1476 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1481 static int SCHSTest08(
void)
1488 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1496 SCHSPreparePatterns(NULL, &mpm_ctx);
1497 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1500 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"a", 1);
1505 printf(
"0 != %" PRIu32
" ",
cnt);
1507 SCHSDestroyCtx(&mpm_ctx);
1508 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1513 static int SCHSTest09(
void)
1520 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1528 SCHSPreparePatterns(NULL, &mpm_ctx);
1529 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1532 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"ab", 2);
1537 printf(
"1 != %" PRIu32
" ",
cnt);
1539 SCHSDestroyCtx(&mpm_ctx);
1540 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1545 static int SCHSTest10(
void)
1552 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1560 SCHSPreparePatterns(NULL, &mpm_ctx);
1561 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1563 const char *buf =
"01234567890123456789012345678901234567890123456789"
1564 "01234567890123456789012345678901234567890123456789"
1566 "01234567890123456789012345678901234567890123456789"
1567 "01234567890123456789012345678901234567890123456789";
1568 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1574 printf(
"1 != %" PRIu32
" ",
cnt);
1576 SCHSDestroyCtx(&mpm_ctx);
1577 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1582 static int SCHSTest11(
void)
1589 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1593 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"he", 2, 0, 0, 1, 0, 0) == -1)
1595 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"she", 3, 0, 0, 2, 0, 0) == -1)
1597 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"his", 3, 0, 0, 3, 0, 0) == -1)
1599 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"hers", 4, 0, 0, 4, 0, 0) == -1)
1603 if (SCHSPreparePatterns(NULL, &mpm_ctx) == -1)
1606 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1610 const char *buf =
"he";
1611 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1614 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1617 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1620 result &= (SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1624 SCHSDestroyCtx(&mpm_ctx);
1625 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1630 static int SCHSTest12(
void)
1637 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1647 SCHSPreparePatterns(NULL, &mpm_ctx);
1648 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1650 const char *buf =
"abcdefghijklmnopqrstuvwxyz";
1651 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1657 printf(
"2 != %" PRIu32
" ",
cnt);
1659 SCHSDestroyCtx(&mpm_ctx);
1660 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1665 static int SCHSTest13(
void)
1672 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1677 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABCD";
1678 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1681 SCHSPreparePatterns(NULL, &mpm_ctx);
1682 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1684 const char *buf =
"abcdefghijklmnopqrstuvwxyzABCD";
1685 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1691 printf(
"1 != %" PRIu32
" ",
cnt);
1693 SCHSDestroyCtx(&mpm_ctx);
1694 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1699 static int SCHSTest14(
void)
1706 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1711 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABCDE";
1712 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1715 SCHSPreparePatterns(NULL, &mpm_ctx);
1716 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1718 const char *buf =
"abcdefghijklmnopqrstuvwxyzABCDE";
1719 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1725 printf(
"1 != %" PRIu32
" ",
cnt);
1727 SCHSDestroyCtx(&mpm_ctx);
1728 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1733 static int SCHSTest15(
void)
1740 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1745 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABCDEF";
1746 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1749 SCHSPreparePatterns(NULL, &mpm_ctx);
1750 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1752 const char *buf =
"abcdefghijklmnopqrstuvwxyzABCDEF";
1753 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1759 printf(
"1 != %" PRIu32
" ",
cnt);
1761 SCHSDestroyCtx(&mpm_ctx);
1762 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1767 static int SCHSTest16(
void)
1774 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1779 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABC";
1780 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1783 SCHSPreparePatterns(NULL, &mpm_ctx);
1784 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1786 const char *buf =
"abcdefghijklmnopqrstuvwxyzABC";
1787 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1793 printf(
"1 != %" PRIu32
" ",
cnt);
1795 SCHSDestroyCtx(&mpm_ctx);
1796 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1801 static int SCHSTest17(
void)
1808 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1813 const char pat[] =
"abcdefghijklmnopqrstuvwxyzAB";
1814 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1817 SCHSPreparePatterns(NULL, &mpm_ctx);
1818 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1820 const char *buf =
"abcdefghijklmnopqrstuvwxyzAB";
1821 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1827 printf(
"1 != %" PRIu32
" ",
cnt);
1829 SCHSDestroyCtx(&mpm_ctx);
1830 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1835 static int SCHSTest18(
void)
1842 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1847 const char pat[] =
"abcde"
1853 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1856 SCHSPreparePatterns(NULL, &mpm_ctx);
1857 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1859 const char *buf =
"abcde"
1865 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1871 printf(
"1 != %" PRIu32
" ",
cnt);
1873 SCHSDestroyCtx(&mpm_ctx);
1874 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1879 static int SCHSTest19(
void)
1886 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1891 const char pat[] =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1892 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1895 SCHSPreparePatterns(NULL, &mpm_ctx);
1896 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1898 const char *buf =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1899 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1905 printf(
"1 != %" PRIu32
" ",
cnt);
1907 SCHSDestroyCtx(&mpm_ctx);
1908 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1913 static int SCHSTest20(
void)
1920 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1925 const char pat[] =
"AAAAA"
1932 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1935 SCHSPreparePatterns(NULL, &mpm_ctx);
1936 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1938 const char *buf =
"AAAAA"
1945 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1951 printf(
"1 != %" PRIu32
" ",
cnt);
1953 SCHSDestroyCtx(&mpm_ctx);
1954 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1959 static int SCHSTest21(
void)
1966 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1974 SCHSPreparePatterns(NULL, &mpm_ctx);
1975 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1978 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"AA", 2);
1983 printf(
"1 != %" PRIu32
" ",
cnt);
1985 SCHSDestroyCtx(&mpm_ctx);
1986 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1991 static int SCHSTest22(
void)
1998 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2008 SCHSPreparePatterns(NULL, &mpm_ctx);
2009 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2011 const char *buf =
"abcdefghijklmnopqrstuvwxyz";
2012 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2018 printf(
"2 != %" PRIu32
" ",
cnt);
2020 SCHSDestroyCtx(&mpm_ctx);
2021 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2026 static int SCHSTest23(
void)
2033 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2041 SCHSPreparePatterns(NULL, &mpm_ctx);
2042 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2045 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"aa", 2);
2050 printf(
"1 != %" PRIu32
" ",
cnt);
2052 SCHSDestroyCtx(&mpm_ctx);
2053 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2058 static int SCHSTest24(
void)
2065 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2073 SCHSPreparePatterns(NULL, &mpm_ctx);
2074 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2077 SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)
"aa", 2);
2082 printf(
"1 != %" PRIu32
" ",
cnt);
2084 SCHSDestroyCtx(&mpm_ctx);
2085 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2090 static int SCHSTest25(
void)
2097 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2106 SCHSPreparePatterns(NULL, &mpm_ctx);
2107 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2109 const char *buf =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
2110 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2116 printf(
"3 != %" PRIu32
" ",
cnt);
2118 SCHSDestroyCtx(&mpm_ctx);
2119 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2124 static int SCHSTest26(
void)
2131 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
2139 SCHSPreparePatterns(NULL, &mpm_ctx);
2140 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2142 const char *buf =
"works";
2143 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2149 printf(
"3 != %" PRIu32
" ",
cnt);
2151 SCHSDestroyCtx(&mpm_ctx);
2152 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2157 static int SCHSTest27(
void)
2164 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
2172 SCHSPreparePatterns(NULL, &mpm_ctx);
2173 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2175 const char *buf =
"tone";
2176 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2182 printf(
"0 != %" PRIu32
" ",
cnt);
2184 SCHSDestroyCtx(&mpm_ctx);
2185 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2190 static int SCHSTest28(
void)
2197 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
2205 SCHSPreparePatterns(NULL, &mpm_ctx);
2206 SCHSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2208 const char *buf =
"tONE";
2209 uint32_t
cnt = SCHSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
2215 printf(
"0 != %" PRIu32
" ",
cnt);
2217 SCHSDestroyCtx(&mpm_ctx);
2218 SCHSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2223 static int SCHSTest29(
void)
2225 uint8_t buf[] =
"onetwothreefourfivesixseveneightnine";
2226 uint16_t buflen =
sizeof(buf) - 1;
2232 memset(&th_v, 0,
sizeof(th_v));
2243 de_ctx,
"alert tcp any any -> any any "
2244 "(content:\"onetwothreefourfivesixseveneightnine\"; sid:1;)");
2249 "(content:\"onetwothreefourfivesixseveneightnine\"; "
2250 "fast_pattern:3,3; sid:2;)");
2259 printf(
"if (PacketAlertCheck(p, 1) != 1) failure\n");
2263 printf(
"if (PacketAlertCheck(p, 1) != 2) failure\n");
2281 static void SCHSRegisterTests(
void)