69 MpmCtx *,
const uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t,
SigIntId, uint8_t);
77static void SCACRegisterTests(
void);
81#define SC_AC_FAIL (-1)
83#define AC_CASE_MASK 0x80000000
84#define AC_PID_MASK 0x7FFFFFFF
87static int construct_both_16_and_32_state_tables = 0;
95static void SCACGetConfig(
void)
113static inline size_t SCACCheckSafeSizetMult(
size_t a,
size_t b)
116 if (b > 0 && a > SIZE_MAX / b) {
117 SCLogError(
"%" PRIuMAX
" * %" PRIuMAX
" > %" PRIuMAX
118 " would overflow size_t calculating buffer size",
119 (uintmax_t)a, (uintmax_t)b, (uintmax_t)SIZE_MAX);
133static inline int SCACReallocState(
SCACCtx *
ctx, uint32_t cnt)
139 size = SCACCheckSafeSizetMult((
size_t) cnt, (
size_t)
ctx->single_state_size);
144 ctx->goto_table = NULL;
147 ctx->goto_table = ptmp;
150 size_t oldsize = SCACCheckSafeSizetMult((
size_t)
ctx->state_count,
153 SCLogDebug(
"oldsize %"PRIuMAX
" size %"PRIuMAX
" cnt %d ctx->state_count %u",
154 (uintmax_t) oldsize, (uintmax_t) size, cnt,
ctx->state_count);
161 ctx->output_table = NULL;
164 ctx->output_table = ptmp;
166 memset(((uint8_t *)
ctx->output_table + oldsize), 0, (size - oldsize));
191 SCLogDebug(
"oldsize %d newsize %d ctx->allocated_state_count %u "
192 "ctx->state_count %u: shrink by %d bytes", oldsize,
193 newsize,
ctx->allocated_state_count,
ctx->state_count,
199 ctx->output_table = NULL;
202 ctx->output_table = ptmp;
205static inline int SCACInitNewState(
MpmCtx *mpm_ctx)
210 if (
ctx->allocated_state_count <
ctx->state_count + 1) {
211 if (
ctx->allocated_state_count == 0)
212 ctx->allocated_state_count = 256;
214 ctx->allocated_state_count *= 2;
216 SCACReallocState(
ctx,
ctx->allocated_state_count);
220 if (
ctx->allocated_state_count > 260) {
227 for (ascii_code = 0; ascii_code < 256; ascii_code++) {
231 return ctx->state_count++;
242static void SCACSetOutputState(int32_t state, uint32_t pid,
MpmCtx *mpm_ctx)
250 if (output_state->
pids[i] == pid)
259 output_state->
pids = NULL;
262 output_state->
pids = ptmp;
277static inline void SCACEnter(uint8_t *pattern, uint16_t pattern_len, uint32_t pid,
282 int32_t newstate = 0;
288 for (i = 0; i < pattern_len; i++) {
290 state =
ctx->goto_table[state][pattern[i]];
298 for (p = i; p < pattern_len; p++) {
299 newstate = SCACInitNewState(mpm_ctx);
300 ctx->goto_table[state][pattern[p]] = newstate;
306 SCACSetOutputState(state, pid, mpm_ctx);
315static inline void SCACCreateGotoTable(
MpmCtx *mpm_ctx)
321 for (i = 0; i < mpm_ctx->pattern_cnt; i++) {
322 SCACEnter(
ctx->parray[i]->ci,
ctx->parray[i]->len,
323 ctx->parray[i]->id, mpm_ctx);
327 for (ascii_code = 0; ascii_code < 256; ascii_code++) {
329 ctx->goto_table[0][ascii_code] = 0;
334static inline void SCACDetermineLevel1Gap(
MpmCtx *mpm_ctx)
340 memset(map, 0,
sizeof(map));
342 for (u = 0; u < mpm_ctx->pattern_cnt; u++)
343 map[
ctx->parray[u]->ci[0]] = 1;
345 for (u = 0; u < 256; u++) {
348 int32_t newstate = SCACInitNewState(mpm_ctx);
349 ctx->goto_table[0][u] = newstate;
362static inline void SCACClubOutputStates(int32_t dst_state, int32_t src_state,
375 if (output_src_state->
pids[i] == output_dst_state->
pids[j]) {
386 output_dst_state->
pids = NULL;
389 output_dst_state->
pids = ptmp;
392 output_src_state->
pids[i];
403static inline void SCACCreateFailureTable(
MpmCtx *mpm_ctx)
415 if (
ctx->failure_table == NULL) {
422 for (ascii_code = 0; ascii_code < 256; ascii_code++) {
423 int32_t temp_state =
ctx->goto_table[0][ascii_code];
424 if (temp_state != 0) {
425 SCACEnqueue(q, temp_state);
426 ctx->failure_table[temp_state] = 0;
430 while (!SCACStateQueueIsEmpty(q)) {
432 r_state = SCACDequeue(q);
433 for (ascii_code = 0; ascii_code < 256; ascii_code++) {
434 int32_t temp_state =
ctx->goto_table[r_state][ascii_code];
437 SCACEnqueue(q, temp_state);
438 state =
ctx->failure_table[r_state];
441 state =
ctx->failure_table[state];
442 ctx->failure_table[temp_state] =
ctx->goto_table[state][ascii_code];
443 SCACClubOutputStates(temp_state,
ctx->failure_table[temp_state],
456static inline void SCACCreateDeltaTable(
MpmCtx *mpm_ctx)
462 if ((
ctx->state_count < 32767) || construct_both_16_and_32_state_tables) {
463 ctx->state_table_u16 =
SCCalloc(
ctx->state_count,
sizeof(*
ctx->state_table_u16));
464 if (
ctx->state_table_u16 == NULL) {
467 mpm_ctx->memory_cnt++;
468 mpm_ctx->memory_size += (
ctx->state_count *
sizeof(*
ctx->state_table_u16));
472 for (ascii_code = 0; ascii_code < 256; ascii_code++) {
475 ctx->state_table_u16[0][ascii_code] = temp_state;
477 SCACEnqueue(q, temp_state);
480 while (!SCACStateQueueIsEmpty(q)) {
481 r_state = SCACDequeue(q);
483 for (ascii_code = 0; ascii_code < 256; ascii_code++) {
484 int32_t temp_state =
ctx->goto_table[r_state][ascii_code];
486 SCACEnqueue(q, temp_state);
488 ctx->state_table_u16[r_state][ascii_code] = (uint16_t)temp_state;
490 ctx->state_table_u16[r_state][ascii_code] =
491 ctx->state_table_u16[
ctx->failure_table[r_state]][ascii_code];
498 if (!(
ctx->state_count < 32767) || construct_both_16_and_32_state_tables) {
502 ctx->state_table_u32 =
SCCalloc(
ctx->state_count,
sizeof(*
ctx->state_table_u32));
503 if (
ctx->state_table_u32 == NULL) {
506 mpm_ctx->memory_cnt++;
507 mpm_ctx->memory_size += (
ctx->state_count *
sizeof(*
ctx->state_table_u32));
511 for (ascii_code = 0; ascii_code < 256; ascii_code++) {
513 ctx->state_table_u32[0][ascii_code] = temp_state;
515 SCACEnqueue(q, temp_state);
518 while (!SCACStateQueueIsEmpty(q)) {
519 r_state = SCACDequeue(q);
521 for (ascii_code = 0; ascii_code < 256; ascii_code++) {
522 int32_t temp_state =
ctx->goto_table[r_state][ascii_code];
524 SCACEnqueue(q, temp_state);
525 ctx->state_table_u32[r_state][ascii_code] = temp_state;
527 ctx->state_table_u32[r_state][ascii_code] =
528 ctx->state_table_u32[
ctx->failure_table[r_state]][ascii_code];
536static inline void SCACClubOutputStatePresenceWithDeltaTable(
MpmCtx *mpm_ctx)
541 uint32_t temp_state = 0;
543 if ((
ctx->state_count < 32767) || construct_both_16_and_32_state_tables) {
544 for (state = 0; state <
ctx->state_count; state++) {
545 for (ascii_code = 0; ascii_code < 256; ascii_code++) {
546 temp_state =
ctx->state_table_u16[state & 0x7FFF][ascii_code];
547 if (
ctx->output_table[temp_state & 0x7FFF].no_of_entries != 0)
548 ctx->state_table_u16[state & 0x7FFF][ascii_code] |= (1 << 15);
553 if (!(
ctx->state_count < 32767) || construct_both_16_and_32_state_tables) {
554 for (state = 0; state <
ctx->state_count; state++) {
555 for (ascii_code = 0; ascii_code < 256; ascii_code++) {
556 temp_state =
ctx->state_table_u32[state & 0x00FFFFFF][ascii_code];
557 if (
ctx->output_table[temp_state & 0x00FFFFFF].no_of_entries != 0)
558 ctx->state_table_u32[state & 0x00FFFFFF][ascii_code] |= (1 << 24);
564static inline void SCACInsertCaseSensitiveEntriesForPatterns(
MpmCtx *mpm_ctx)
570 for (state = 0; state <
ctx->state_count; state++) {
571 if (
ctx->output_table[state].no_of_entries == 0)
574 for (k = 0; k <
ctx->output_table[state].no_of_entries; k++) {
575 if (
ctx->pid_pat_list[
ctx->output_table[state].pids[k]].cs != NULL) {
584static void SCACPrintDeltaTable(
MpmCtx *mpm_ctx)
589 printf(
"##############Delta Table##############\n");
590 for (i = 0; i <
ctx->state_count; i++) {
592 for (j = 0; j < 256; j++) {
593 if (SCACGetDelta(i, j, mpm_ctx) != 0) {
594 printf(
" %c -> %d\n", j, SCACGetDelta(i, j, mpm_ctx));
606static void SCACPrepareStateTable(
MpmCtx *mpm_ctx)
611 SCACInitNewState(mpm_ctx);
613 SCACDetermineLevel1Gap(mpm_ctx);
616 SCACCreateGotoTable(mpm_ctx);
618 SCACCreateFailureTable(mpm_ctx);
620 SCACCreateDeltaTable(mpm_ctx);
622 SCACClubOutputStatePresenceWithDeltaTable(mpm_ctx);
625 SCACInsertCaseSensitiveEntriesForPatterns(mpm_ctx);
628 SCACShrinkState(
ctx);
631 SCACPrintDeltaTable(mpm_ctx);
636 ctx->goto_table = NULL;
638 ctx->failure_table = NULL;
652 SCLogDebug(
"no patterns supplied to this mpm_ctx");
658 if (
ctx->parray == NULL)
664 uint32_t i = 0, p = 0;
667 while(node != NULL) {
670 ctx->parray[p++] = node;
680 ctx->single_state_size =
sizeof(int32_t) * 256;
684 if (
ctx->pid_pat_list == NULL) {
691 if (
ctx->pid_pat_list[
ctx->parray[i]->id].cs == NULL) {
694 memcpy(
ctx->pid_pat_list[
ctx->parray[i]->id].cs,
695 ctx->parray[i]->original_pat,
ctx->parray[i]->len);
696 ctx->pid_pat_list[
ctx->parray[i]->id].patlen =
ctx->parray[i]->len;
698 ctx->pid_pat_list[
ctx->parray[i]->id].offset =
ctx->parray[i]->offset;
699 ctx->pid_pat_list[
ctx->parray[i]->id].depth =
ctx->parray[i]->depth;
700 ctx->pid_pat_list[
ctx->parray[i]->id].endswith =
705 ctx->pid_pat_list[
ctx->parray[i]->id].sids_size =
ctx->parray[i]->sids_size;
706 ctx->pid_pat_list[
ctx->parray[i]->id].sids =
ctx->parray[i]->sids;
708 ctx->parray[i]->sids_size = 0;
709 ctx->parray[i]->sids = NULL;
713 SCACPrepareStateTable(mpm_ctx);
717 if (
ctx->parray[i] != NULL) {
726 ctx->pattern_id_bitarray_size = (mpm_ctx->
max_pat_id / 8) + 1;
727 SCLogDebug(
"ctx->pattern_id_bitarray_size %u",
ctx->pattern_id_bitarray_size);
742 if (mpm_ctx->
ctx != NULL)
746 if (mpm_ctx->
ctx == NULL) {
784 if (
ctx->parray != NULL) {
787 if (
ctx->parray[i] != NULL) {
798 if (
ctx->state_table_u16 != NULL) {
800 ctx->state_table_u16 = NULL;
806 if (
ctx->state_table_u32 != NULL) {
808 ctx->state_table_u32 = NULL;
815 if (
ctx->output_table != NULL) {
816 uint32_t state_count;
817 for (state_count = 0; state_count <
ctx->state_count; state_count++) {
818 if (
ctx->output_table[state_count].pids != NULL) {
819 SCFree(
ctx->output_table[state_count].pids);
825 if (
ctx->pid_pat_list != NULL) {
827 for (i = 0; i < (mpm_ctx->
max_pat_id + 1); i++) {
828 if (
ctx->pid_pat_list[i].cs != NULL)
830 if (
ctx->pid_pat_list[i].sids != NULL)
865 uint8_t bitarray[
ctx->pattern_id_bitarray_size];
866 memset(bitarray, 0,
ctx->pattern_id_bitarray_size);
868 if (
ctx->state_count < 32767) {
871 for (uint32_t i = 0; i < buflen; i++) {
872 state = state_table_u16[state & 0x7FFF][
u8_tolower(buf[i])];
873 if (state & 0x8000) {
874 const uint32_t no_of_entries =
ctx->output_table[state & 0x7FFF].no_of_entries;
875 const uint32_t *pids =
ctx->output_table[state & 0x7FFF].pids;
876 for (uint32_t k = 0; k < no_of_entries; k++) {
891 if (!(bitarray[(lower_pid) / 8] & (1 << ((lower_pid) % 8)))) {
892 bitarray[(lower_pid) / 8] |= (1 << ((lower_pid) % 8));
905 if (!(bitarray[pids[k] / 8] & (1 << (pids[k] % 8)))) {
906 bitarray[pids[k] / 8] |= (1 << (pids[k] % 8));
917 for (uint32_t i = 0; i < buflen; i++) {
918 state = state_table_u32[state & 0x00FFFFFF][
u8_tolower(buf[i])];
919 if (state & 0xFF000000) {
920 const uint32_t no_of_entries =
ctx->output_table[state & 0x00FFFFFF].no_of_entries;
921 const uint32_t *pids =
ctx->output_table[state & 0x00FFFFFF].pids;
922 for (uint32_t k = 0; k < no_of_entries; k++) {
924 const uint32_t lower_pid = pids[k] & 0x0000FFFF;
938 if (!(bitarray[(lower_pid) / 8] & (1 << ((lower_pid) % 8)))) {
939 bitarray[(lower_pid) / 8] |= (1 << ((lower_pid) % 8));
952 if (!(bitarray[pids[k] / 8] & (1 << (pids[k] % 8)))) {
953 bitarray[pids[k] / 8] |= (1 << (pids[k] % 8));
1007 uint16_t
offset, uint16_t depth, uint32_t pid,
1017 printf(
"MPM AC Information:\n");
1018 printf(
"Memory allocs: %" PRIu32
"\n", mpm_ctx->
memory_cnt);
1019 printf(
"Memory alloced: %" PRIu32
"\n", mpm_ctx->
memory_size);
1020 printf(
" Sizeof:\n");
1021 printf(
" MpmCtx %" PRIuMAX
"\n", (uintmax_t)
sizeof(
MpmCtx));
1022 printf(
" SCACCtx: %" PRIuMAX
"\n", (uintmax_t)
sizeof(
SCACCtx));
1023 printf(
" MpmPattern %" PRIuMAX
"\n", (uintmax_t)
sizeof(
MpmPattern));
1024 printf(
" MpmPattern %" PRIuMAX
"\n", (uintmax_t)
sizeof(
MpmPattern));
1025 printf(
"Unique Patterns: %" PRIu32
"\n", mpm_ctx->
pattern_cnt);
1026 printf(
"Smallest: %" PRIu32
"\n", mpm_ctx->
minlen);
1027 printf(
"Largest: %" PRIu32
"\n", mpm_ctx->
maxlen);
1028 printf(
"Total states in the state table: %" PRIu32
"\n",
ctx->state_count);
1063static int SCACTest01(
void)
1070 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1080 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1083 (uint8_t *)buf, strlen(buf));
1088 printf(
"1 != %" PRIu32
" ",cnt);
1095static int SCACTest02(
void)
1102 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1112 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1114 (uint8_t *)buf, strlen(buf));
1119 printf(
"0 != %" PRIu32
" ",cnt);
1126static int SCACTest03(
void)
1133 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1147 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1149 (uint8_t *)buf, strlen(buf));
1154 printf(
"3 != %" PRIu32
" ",cnt);
1161static int SCACTest04(
void)
1168 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1179 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1181 (uint8_t *)buf, strlen(buf));
1186 printf(
"1 != %" PRIu32
" ",cnt);
1193static int SCACTest05(
void)
1200 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1211 const char *buf =
"abcdefghjiklmnopqrstuvwxyz";
1213 (uint8_t *)buf, strlen(buf));
1218 printf(
"3 != %" PRIu32
" ",cnt);
1225static int SCACTest06(
void)
1232 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1241 const char *buf =
"abcd";
1243 (uint8_t *)buf, strlen(buf));
1248 printf(
"1 != %" PRIu32
" ",cnt);
1255static int SCACTest07(
void)
1261 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1274 MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"AAAAAAAAAA", 10, 0, 0, 4, 0, 0);
1276 MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
1283 const char *buf =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1285 (uint8_t *)buf, strlen(buf));
1293static int SCACTest08(
void)
1300 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1316 printf(
"0 != %" PRIu32
" ",cnt);
1323static int SCACTest09(
void)
1330 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1341 (uint8_t *)
"ab", 2);
1346 printf(
"1 != %" PRIu32
" ",cnt);
1353static int SCACTest10(
void)
1360 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1370 const char *buf =
"01234567890123456789012345678901234567890123456789"
1371 "01234567890123456789012345678901234567890123456789"
1373 "01234567890123456789012345678901234567890123456789"
1374 "01234567890123456789012345678901234567890123456789";
1376 (uint8_t *)buf, strlen(buf));
1381 printf(
"1 != %" PRIu32
" ",cnt);
1388static int SCACTest11(
void)
1395 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1399 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"he", 2, 0, 0, 1, 0, 0) == -1)
1401 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"she", 3, 0, 0, 2, 0, 0) == -1)
1403 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"his", 3, 0, 0, 3, 0, 0) == -1)
1405 if (
MpmAddPatternCS(&mpm_ctx, (uint8_t *)
"hers", 4, 0, 0, 4, 0, 0) == -1)
1414 const char *buf =
"he";
1415 result &= (
SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1418 result &= (
SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1421 result &= (
SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1424 result &= (
SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1433static int SCACTest12(
void)
1440 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1452 const char *buf =
"abcdefghijklmnopqrstuvwxyz";
1454 (uint8_t *)buf, strlen(buf));
1459 printf(
"2 != %" PRIu32
" ",cnt);
1466static int SCACTest13(
void)
1473 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1478 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABCD";
1479 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1484 const char *buf =
"abcdefghijklmnopqrstuvwxyzABCD";
1486 (uint8_t *)buf, strlen(buf));
1491 printf(
"1 != %" PRIu32
" ",cnt);
1498static int SCACTest14(
void)
1505 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1510 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABCDE";
1511 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1516 const char *buf =
"abcdefghijklmnopqrstuvwxyzABCDE";
1518 (uint8_t *)buf, strlen(buf));
1523 printf(
"1 != %" PRIu32
" ",cnt);
1530static int SCACTest15(
void)
1537 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1542 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABCDEF";
1543 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1548 const char *buf =
"abcdefghijklmnopqrstuvwxyzABCDEF";
1550 (uint8_t *)buf, strlen(buf));
1555 printf(
"1 != %" PRIu32
" ",cnt);
1562static int SCACTest16(
void)
1569 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1574 const char pat[] =
"abcdefghijklmnopqrstuvwxyzABC";
1575 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1580 const char *buf =
"abcdefghijklmnopqrstuvwxyzABC";
1582 (uint8_t *)buf, strlen(buf));
1587 printf(
"1 != %" PRIu32
" ",cnt);
1594static int SCACTest17(
void)
1601 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1606 const char pat[] =
"abcdefghijklmnopqrstuvwxyzAB";
1607 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1612 const char *buf =
"abcdefghijklmnopqrstuvwxyzAB";
1614 (uint8_t *)buf, strlen(buf));
1619 printf(
"1 != %" PRIu32
" ",cnt);
1626static int SCACTest18(
void)
1633 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1638 const char pat[] =
"abcde"
1644 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1649 const char *buf =
"abcde""fghij""klmno""pqrst""uvwxy""z";
1651 (uint8_t *)buf, strlen(buf));
1656 printf(
"1 != %" PRIu32
" ",cnt);
1663static int SCACTest19(
void)
1670 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1675 const char pat[] =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1676 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1681 const char *buf =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1683 (uint8_t *)buf, strlen(buf));
1688 printf(
"1 != %" PRIu32
" ",cnt);
1695static int SCACTest20(
void)
1702 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1707 const char pat[] =
"AAAAA"
1714 MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat,
sizeof(pat) - 1, 0, 0, 0, 0, 0);
1719 const char *buf =
"AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AA";
1721 (uint8_t *)buf, strlen(buf));
1726 printf(
"1 != %" PRIu32
" ",cnt);
1733static int SCACTest21(
void)
1740 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1751 (uint8_t *)
"AA", 2);
1756 printf(
"1 != %" PRIu32
" ",cnt);
1763static int SCACTest22(
void)
1770 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1782 const char *buf =
"abcdefghijklmnopqrstuvwxyz";
1784 (uint8_t *)buf, strlen(buf));
1789 printf(
"2 != %" PRIu32
" ",cnt);
1796static int SCACTest23(
void)
1803 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1814 (uint8_t *)
"aa", 2);
1819 printf(
"1 != %" PRIu32
" ",cnt);
1826static int SCACTest24(
void)
1833 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1844 (uint8_t *)
"aa", 2);
1849 printf(
"1 != %" PRIu32
" ",cnt);
1856static int SCACTest25(
void)
1863 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1874 const char *buf =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1876 (uint8_t *)buf, strlen(buf));
1881 printf(
"3 != %" PRIu32
" ",cnt);
1888static int SCACTest26(
void)
1895 memset(&mpm_ctx, 0x00,
sizeof(
MpmCtx));
1905 const char *buf =
"works";
1907 (uint8_t *)buf, strlen(buf));
1912 printf(
"3 != %" PRIu32
" ",cnt);
1919static int SCACTest27(
void)
1926 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1936 const char *buf =
"tone";
1938 (uint8_t *)buf, strlen(buf));
1943 printf(
"0 != %" PRIu32
" ",cnt);
1950static int SCACTest28(
void)
1956 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
1966 const char *buf =
"tONE";
1968 (uint8_t *)buf, strlen(buf));
1976static int SCACTest29(
void)
1978 uint8_t buf[] =
"onetwothreefourfivesixseveneightnine";
1979 uint16_t buflen =
sizeof(buf) - 1;
1983 memset(&th_v, 0,
sizeof(th_v));
1992 "alert tcp any any -> any any "
1993 "(content:\"onetwothreefourfivesixseveneightnine\"; sid:1;)");
1996 "alert tcp any any -> any any "
1997 "(content:\"onetwothreefourfivesixseveneightnine\"; fast_pattern:3,3; sid:2;)");
2017static int SCACTest30(
void)
2023 memset(&mpm_ctx, 0,
sizeof(
MpmCtx));
2033 const char *buf1 =
"abcdefghijklmnopqrstuvwxyz";
2034 uint32_t
cnt =
SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf1, strlen(buf1));
2036 const char *buf2 =
"xyzxyzxyzxyzxyzxyzxyza";
2037 cnt =
SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf2, strlen(buf2));
2045void SCACRegisterTests(
void)
void StatsThreadCleanup(ThreadVars *tv)
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
DetectEngineCtx * DetectEngineCtxInit(void)
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data)
initialize thread specific detection engine context
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
#define PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
main detection engine ctx
struct MpmPattern_ * next
void(* RegisterUnittests)(void)
int(* Prepare)(MpmConfig *, struct MpmCtx_ *)
int(* AddPattern)(struct MpmCtx_ *, uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t, SigIntId, uint8_t)
void(* InitCtx)(struct MpmCtx_ *)
void(* PrintCtx)(struct MpmCtx_ *)
uint32_t(* Search)(const struct MpmCtx_ *, struct MpmThreadCtx_ *, PrefilterRuleStore *, const uint8_t *, uint32_t)
void(* DestroyCtx)(struct MpmCtx_ *)
int(* AddPatternNocase)(struct MpmCtx_ *, const uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t, SigIntId, uint8_t)
int(* CacheRuleset)(MpmConfig *)
void(* ConfigDeinit)(MpmConfig **)
MpmConfig *(* ConfigInit)(void)
void(* ConfigCacheDirSet)(MpmConfig *, const char *dir_path)
structure for storing potential rule matches
Helper structure used by AC during state table creation.
Per thread variable structure.
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
#define SCLogError(...)
Macro used to log ERROR messages.
#define SCRealloc(ptr, sz)
#define SCMemcmp(a, b, c)
StateQueue * SCACStateQueueAlloc(void)
void SCACStateQueueFree(StateQueue *q)
int SCACAddPatternCI(MpmCtx *, const uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t, SigIntId, uint8_t)
Add a case insensitive pattern. Although we have different calls for adding case sensitive and insens...
void SCACPrintInfo(MpmCtx *mpm_ctx)
int SCACPreparePatterns(MpmConfig *, MpmCtx *mpm_ctx)
Process the patterns added to the mpm, and create the internal tables.
void SCACDestroyCtx(MpmCtx *)
Destroy the mpm context.
void MpmACRegister(void)
Register the aho-corasick mpm.
int SCACAddPatternCS(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t, SigIntId, uint8_t)
Add a case sensitive pattern. Although we have different calls for adding case sensitive and insensit...
void SCACInitCtx(MpmCtx *)
Initialize the AC context.
uint32_t SCACSearch(const MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen)
The aho corasick search function.
#define SC_AC_STATE_TYPE_U32
struct SCACOutputTable_ SCACOutputTable
#define SC_AC_STATE_TYPE_U16
void MpmFreePattern(MpmCtx *mpm_ctx, MpmPattern *p)
MpmTableElmt mpm_table[MPM_TABLE_SIZE]
int MpmAddPatternCS(struct MpmCtx_ *mpm_ctx, uint8_t *pat, uint16_t patlen, uint16_t offset, uint16_t depth, uint32_t pid, SigIntId sid, uint8_t flags)
int MpmAddPatternCI(MpmCtx *mpm_ctx, const uint8_t *pat, uint16_t patlen, uint16_t offset, uint16_t depth, uint32_t pid, SigIntId sid, uint8_t flags)
int MpmAddPattern(MpmCtx *mpm_ctx, const uint8_t *pat, uint16_t patlen, uint16_t offset, uint16_t depth, uint32_t pid, SigIntId sid, uint8_t flags)
void MpmInitCtx(MpmCtx *mpm_ctx, uint8_t matcher)
#define MPM_PATTERN_FLAG_NOCASE
#define MPM_FEATURE_FLAG_OFFSET
#define MPM_INIT_HASH_SIZE
#define MPM_FEATURE_FLAG_DEPTH
#define MPM_PATTERN_FLAG_ENDSWITH
int PmqSetup(PrefilterRuleStore *pmq)
Setup a pmq.
void PmqFree(PrefilterRuleStore *pmq)
Cleanup and free a Pmq.
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself.
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
#define DEBUG_VALIDATE_BUG_ON(exp)