49 #ifdef BUILD_HYPERSCAN
51 void SCHSInitCtx(
MpmCtx *);
53 void SCHSDestroyCtx(
MpmCtx *);
56 MpmCtx *,
const uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t,
SigIntId, uint8_t);
57 int SCHSAddPatternCS(
MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t,
62 void SCHSPrintInfo(
MpmCtx *mpm_ctx);
65 static void SCHSRegisterTests(
void);
69 #define INIT_HASH_SIZE 65536
72 #define INIT_DB_HASH_SIZE 1000
77 static hs_scratch_t *g_scratch_proto = NULL;
90 static void *SCHSMalloc(
size_t size)
100 static void SCHSFree(
void *ptr)
110 static void SCHSSetAllocators(
void)
112 hs_error_t err = hs_set_allocator(SCHSMalloc, SCHSFree);
113 if (err != HS_SUCCESS) {
114 FatalError(
"Failed to set Hyperscan allocator.");
128 static inline uint32_t SCHSInitHashRaw(
const uint8_t *pat, uint16_t patlen)
130 uint32_t hash = patlen * pat[0];
134 return (hash % INIT_HASH_SIZE);
149 static inline SCHSPattern *SCHSInitHashLookup(SCHSCtx *
ctx,
const uint8_t *pat, uint16_t patlen,
150 uint16_t
offset, uint16_t depth,
char flags, uint32_t pid)
152 uint32_t hash = SCHSInitHashRaw(pat, patlen);
154 if (
ctx->init_hash == NULL) {
158 SCHSPattern *t =
ctx->init_hash[hash];
159 for (; t != NULL; t = t->next) {
162 if (t->id == pid && t->offset ==
offset && t->depth == depth) {
180 static inline SCHSPattern *SCHSAllocPattern(
MpmCtx *mpm_ctx)
182 SCHSPattern *
p =
SCCalloc(1,
sizeof(SCHSPattern));
201 static inline void SCHSFreePattern(
MpmCtx *mpm_ctx, SCHSPattern *
p)
203 if (
p != NULL &&
p->original_pat != NULL) {
209 if (
p != NULL &&
p->sids != NULL) {
220 static inline uint32_t SCHSInitHash(SCHSPattern *
p)
222 uint32_t hash =
p->len *
p->original_pat[0];
224 hash +=
p->original_pat[1];
226 return (hash % INIT_HASH_SIZE);
229 static inline int SCHSInitHashAdd(SCHSCtx *
ctx, SCHSPattern *
p)
231 uint32_t hash = SCHSInitHash(
p);
233 if (
ctx->init_hash == NULL) {
237 if (
ctx->init_hash[hash] == NULL) {
238 ctx->init_hash[hash] =
p;
242 SCHSPattern *tt = NULL;
243 SCHSPattern *t =
ctx->init_hash[hash];
270 static int SCHSAddPattern(
MpmCtx *mpm_ctx,
const uint8_t *pat, uint16_t patlen, uint16_t
offset,
273 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
294 p = SCHSAllocPattern(mpm_ctx);
304 if (
p->original_pat == NULL)
308 memcpy(
p->original_pat, pat, patlen);
311 if (SCHSInitHashAdd(
ctx,
p) != 0)
323 SCLogDebug(
"%p: alas, no depth for us", mpm_ctx);
327 if (mpm_ctx->
maxlen < patlen)
330 if (mpm_ctx->
minlen == 0) {
333 if (mpm_ctx->
minlen > patlen)
346 for (x = 0; x <
p->sids_size; x++) {
347 if (
p->sids[x] == sid) {
356 p->sids[
p->sids_size] = sid;
364 SCHSFreePattern(mpm_ctx,
p);
372 typedef struct SCHSCompileData_ {
377 unsigned int pattern_cnt;
380 static SCHSCompileData *CompileDataAlloc(
unsigned int pattern_cnt)
382 SCHSCompileData *cd =
SCCalloc(pattern_cnt,
sizeof(SCHSCompileData));
387 cd->pattern_cnt = pattern_cnt;
389 cd->ids =
SCCalloc(pattern_cnt,
sizeof(
unsigned int));
390 if (cd->ids == NULL) {
394 cd->flags =
SCCalloc(pattern_cnt,
sizeof(
unsigned int));
395 if (cd->flags == NULL) {
399 cd->expressions =
SCCalloc(pattern_cnt,
sizeof(
char *));
400 if (cd->expressions == NULL) {
404 cd->ext =
SCCalloc(pattern_cnt,
sizeof(hs_expr_ext_t *));
405 if (cd->ext == NULL) {
423 static void CompileDataFree(SCHSCompileData *cd)
431 if (cd->expressions) {
432 for (
unsigned int i = 0; i < cd->pattern_cnt; i++) {
433 SCFree(cd->expressions[i]);
438 for (
unsigned int i = 0; i < cd->pattern_cnt; i++) {
446 static uint32_t SCHSPatternHash(
const SCHSPattern *
p, uint32_t hash)
448 BUG_ON(
p->original_pat == NULL);
462 static char SCHSPatternCompare(
const SCHSPattern *p1,
const SCHSPattern *p2)
464 if ((p1->len != p2->len) || (p1->flags != p2->flags) ||
465 (p1->id != p2->id) || (p1->offset != p2->offset) ||
466 (p1->depth != p2->depth) || (p1->sids_size != p2->sids_size)) {
470 if (
SCMemcmp(p1->original_pat, p2->original_pat, p1->len) != 0) {
474 if (
SCMemcmp(p1->sids, p2->sids, p1->sids_size *
sizeof(p1->sids[0])) !=
482 static uint32_t PatternDatabaseHash(
HashTable *ht,
void *data, uint16_t
len)
484 const PatternDatabase *pd = data;
486 hash =
hashword(&pd->pattern_cnt, 1, hash);
488 for (uint32_t i = 0; i < pd->pattern_cnt; i++) {
489 hash = SCHSPatternHash(pd->parray[i], hash);
496 static char PatternDatabaseCompare(
void *data1, uint16_t len1,
void *data2,
499 const PatternDatabase *pd1 = data1;
500 const PatternDatabase *pd2 = data2;
502 if (pd1->pattern_cnt != pd2->pattern_cnt) {
506 for (uint32_t i = 0; i < pd1->pattern_cnt; i++) {
507 if (SCHSPatternCompare(pd1->parray[i], pd2->parray[i]) == 0) {
515 static void PatternDatabaseFree(PatternDatabase *pd)
519 if (pd->parray != NULL) {
520 for (uint32_t i = 0; i < pd->pattern_cnt; i++) {
521 SCHSPattern *
p = pd->parray[i];
531 hs_free_database(pd->hs_db);
536 static void PatternDatabaseTableFree(
void *data)
542 static PatternDatabase *PatternDatabaseAlloc(uint32_t pattern_cnt)
544 PatternDatabase *pd =
SCCalloc(1,
sizeof(PatternDatabase));
548 pd->pattern_cnt = pattern_cnt;
554 pd->parray = (SCHSPattern **)
SCCalloc(pd->pattern_cnt,
sizeof(SCHSPattern *));
555 if (pd->parray == NULL) {
563 static int HSCheckPatterns(
MpmCtx *mpm_ctx, SCHSCtx *
ctx)
566 SCLogDebug(
"no patterns supplied to this mpm_ctx");
572 static void HSPatternArrayPopulate(SCHSCtx *
ctx, PatternDatabase *pd)
574 for (uint32_t i = 0,
p = 0; i < INIT_HASH_SIZE; i++) {
575 SCHSPattern *node =
ctx->init_hash[i];
576 SCHSPattern *nnode = NULL;
577 while (node != NULL) {
580 pd->parray[
p++] = node;
586 static void HSPatternArrayInit(SCHSCtx *
ctx, PatternDatabase *pd)
588 HSPatternArrayPopulate(
ctx, pd);
591 ctx->init_hash = NULL;
594 static int HSGlobalPatternDatabaseInit(
void)
596 if (g_db_table == NULL) {
597 g_db_table =
HashTableInit(INIT_DB_HASH_SIZE, PatternDatabaseHash,
598 PatternDatabaseCompare,
599 PatternDatabaseTableFree);
600 if (g_db_table == NULL) {
607 static int HSScratchAlloc(
const hs_database_t *db)
610 hs_error_t err = hs_alloc_scratch(db, &g_scratch_proto);
612 if (err != HS_SUCCESS) {
619 static int PatternDatabaseGetSize(PatternDatabase *pd,
size_t *db_size)
621 hs_error_t err = hs_database_size(pd->hs_db, db_size);
622 if (err != HS_SUCCESS) {
623 SCLogError(
"failed to query database size: %s", HSErrorToStr(err));
629 static void SCHSCleanupOnError(PatternDatabase *pd, SCHSCompileData *cd)
632 PatternDatabaseFree(pd);
639 static int CompileDataExtensionsInit(hs_expr_ext_t **ext,
const SCHSPattern *
p)
642 *ext =
SCCalloc(1,
sizeof(hs_expr_ext_t));
647 (*ext)->flags |= HS_EXT_FLAG_MIN_OFFSET;
648 (*ext)->min_offset =
p->offset +
p->len;
651 (*ext)->
flags |= HS_EXT_FLAG_MAX_OFFSET;
652 (*ext)->max_offset =
p->offset +
p->depth;
667 static int PatternDatabaseGetCached(
668 PatternDatabase **pd, SCHSCompileData *cd,
const char *cache_dir_path)
673 if (pd_cached != NULL) {
674 SCLogDebug(
"Reusing cached database %p with %" PRIu32
675 " patterns (ref_cnt=%" PRIu32
")",
676 pd_cached->hs_db, pd_cached->pattern_cnt,
678 pd_cached->ref_cnt++;
679 PatternDatabaseFree(*pd);
683 }
else if (cache_dir_path) {
686 if (HSHashDb(pd_cached, hs_db_hash,
ARRAY_SIZE(hs_db_hash)) != 0) {
689 if (HSLoadCache(&pd_cached->hs_db, hs_db_hash, cache_dir_path) == 0) {
690 pd_cached->ref_cnt = 1;
691 pd_cached->cached =
true;
692 if (HSScratchAlloc(pd_cached->hs_db) != 0) {
702 pd_cached->ref_cnt = 0;
703 pd_cached->cached =
false;
711 static int PatternDatabaseCompile(PatternDatabase *pd, SCHSCompileData *cd)
713 for (uint32_t i = 0; i < pd->pattern_cnt; i++) {
714 const SCHSPattern *
p = pd->parray[i];
716 cd->
flags[i] = HS_FLAG_SINGLEMATCH;
718 cd->flags[i] |= HS_FLAG_CASELESS;
720 cd->expressions[i] = HSRenderPattern(
p->original_pat,
p->len);
721 if (CompileDataExtensionsInit(&cd->ext[i],
p) != 0) {
726 hs_compile_error_t *compile_err = NULL;
727 hs_error_t err = hs_compile_ext_multi((
const char *
const *)cd->expressions, cd->flags, cd->ids,
728 (
const hs_expr_ext_t *
const *)cd->ext, cd->pattern_cnt, HS_MODE_BLOCK, NULL, &pd->hs_db,
730 if (err != HS_SUCCESS) {
731 HSLogCompileError(
"multiple patterns", compile_err, err);
735 if (HSScratchAlloc(pd->hs_db) != 0) {
754 SCHSCtx *
ctx = (SCHSCtx *)mpm_ctx->
ctx;
756 if (HSCheckPatterns(mpm_ctx,
ctx) == 0) {
760 SCHSCompileData *cd = CompileDataAlloc(mpm_ctx->
pattern_cnt);
761 PatternDatabase *pd = PatternDatabaseAlloc(mpm_ctx->
pattern_cnt);
762 if (cd == NULL || pd == NULL) {
766 HSPatternArrayInit(
ctx, pd);
771 if (HSGlobalPatternDatabaseInit() == -1) {
776 const char *cache_path = pd->no_cache || !mpm_conf ? NULL : mpm_conf->
cache_dir_path;
777 if (PatternDatabaseGetCached(&pd, cd, cache_path) == 0) {
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)