63static FILE *g_ut_threshold_fp = NULL;
67#define DETECT_BASE_REGEX "^\\s*(event_filter|threshold|rate_filter|suppress)\\s*gen_id\\s*(\\d+)\\s*,\\s*sig_id\\s*(\\d+)\\s*(.*)\\s*$"
69#define DETECT_THRESHOLD_REGEX \
70 "^,\\s*type\\s*(limit|both|threshold)\\s*,\\s*track\\s*(by_dst|by_src|by_both|by_rule|by_" \
72 "\\s*count\\s*(\\d+)\\s*,\\s*seconds\\s*(\\d+)\\s*$"
75#define DETECT_RATE_REGEX \
76 "^,\\s*track\\s*(by_dst|by_src|by_both|by_rule|by_flow)\\s*,\\s*count\\s*(\\d+)\\s*,\\s*" \
77 "seconds\\s*(\\d+)\\s*,\\s*new_action\\s*(alert|drop|pass|log|sdrop|reject)\\s*,\\s*" \
78 "timeout\\s*(\\d+)\\s*$"
86#define DETECT_SUPPRESS_REGEX "^,\\s*track\\s*(by_dst|by_src|by_either)\\s*,\\s*ip\\s*([\\[\\],\\$\\s\\da-zA-Z.:/_]+)*\\s*$"
89#if defined OS_WIN32 || defined __CYGWIN__
90#define THRESHOLD_CONF_DEF_CONF_FILEPATH CONFIG_DIR "\\\\threshold.config"
92#define THRESHOLD_CONF_DEF_CONF_FILEPATH CONFIG_DIR "/threshold.config"
105 if (regex_base == NULL) {
106 FatalError(
"classification base regex setup failed");
109 if (regex_threshold == NULL) {
110 FatalError(
"classification threshold regex setup failed");
113 if (regex_rate == NULL) {
114 FatalError(
"classification rate_filter regex setup failed");
117 if (regex_suppress == NULL) {
118 FatalError(
"classification suppress regex setup failed");
133 const char *log_filename = NULL;
136 char config_value[256];
137 snprintf(config_value,
sizeof(config_value),
142 if (
SCConfGet(config_value, &log_filename) != 1) {
143 if (
SCConfGet(
"threshold-file", &log_filename) != 1) {
148 if (
SCConfGet(
"threshold-file", &log_filename) != 1) {
171 const char *filename = NULL;
176 FILE *fd = g_ut_threshold_fp;
179 filename = SCThresholdConfGetConfFilename(
de_ctx);
180 if ( (fd = fopen(filename,
"r")) == NULL) {
181 SCLogWarning(
"Error opening file: \"%s\": %s", filename, strerror(errno));
182 SCThresholdConfDeInitContext(
de_ctx, fd);
190 SCLogWarning(
"Error loading threshold configuration from %s", filename);
191 SCThresholdConfDeInitContext(
de_ctx, fd);
198 SCThresholdConfDeInitContext(
de_ctx, fd);
201 g_ut_threshold_fp = NULL;
203 SCLogDebug(
"Global thresholding options defined");
225 uint8_t parsed_type, uint8_t parsed_track, uint32_t parsed_count,
226 uint32_t parsed_seconds, uint32_t parsed_timeout, uint8_t parsed_new_action,
241 orig_de->
track = parsed_track;
242 orig_de->
count = parsed_count;
243 orig_de->
seconds = parsed_seconds;
245 orig_de->
timeout = parsed_timeout;
254 if (
id == 0 && gid == 0) {
263 s->
action &= ~ACTION_ALERT;
276 }
else if (
id == 0 && gid > 0) {
278 SCLogWarning(
"suppressing all rules with gid %" PRIu32, gid);
287 s->
action &= ~ACTION_ALERT;
300 }
else if (
id > 0 && gid == 0) {
301 SCLogError(
"Can't use a event config that has "
302 "sid > 0 and gid == 0. Please fix this "
303 "in your threshold.config file");
309 "%" PRIu32
", gid %" PRIu32
": unknown rule",
313 s->
action &= ~ACTION_ALERT;
329 if (orig_de != NULL) {
335 if (orig_de != NULL) {
352 uint8_t parsed_type, uint8_t parsed_track, uint32_t parsed_count, uint32_t parsed_seconds,
353 uint32_t parsed_timeout, uint8_t parsed_new_action)
362 if (
id == 0 && gid == 0) {
367 "an event var set. The signature event var is "
368 "given precedence over the threshold.conf one. "
369 "We'll change this in the future though.",
378 "an event var set. The signature event var is "
379 "given precedence over the threshold.conf one. "
380 "We'll change this in the future though.",
389 de->
type = parsed_type;
390 de->
track = parsed_track;
391 de->
count = parsed_count;
406 }
else if (
id == 0 && gid > 0) {
413 "an event var set. The signature event var is "
414 "given precedence over the threshold.conf one. "
415 "We'll change this in the future though.",
424 de->
type = parsed_type;
425 de->
track = parsed_track;
426 de->
count = parsed_count;
441 }
else if (
id > 0 && gid == 0) {
442 SCLogError(
"Can't use a event config that has "
443 "sid > 0 and gid == 0. Please fix this "
444 "in your threshold.conf file");
449 "%" PRIu32
", gid %" PRIu32
": unknown rule",
459 "a threshold set. The signature event var is "
460 "given precedence over the threshold.conf one. "
470 "a detection_filter set. The signature event var is "
471 "given precedence over the threshold.conf one. "
491 de->
type = parsed_type;
492 de->
track = parsed_track;
493 de->
count = parsed_count;
519 uint32_t *ret_gid, uint8_t *ret_parsed_type, uint8_t *ret_parsed_track,
520 uint32_t *ret_parsed_count, uint32_t *ret_parsed_seconds, uint32_t *ret_parsed_timeout,
521 uint8_t *ret_parsed_new_action,
char **ret_th_ip)
523 char th_rule_type[32];
526 const char *rule_extend = NULL;
527 char th_type[16] =
"";
528 char th_track[16] =
"";
529 char th_count[16] =
"";
530 char th_seconds[16] =
"";
531 char th_new_action[16] =
"";
532 char th_timeout[16] =
"";
533 const char *th_ip = NULL;
535 uint8_t parsed_type = 0;
536 uint8_t parsed_track = 0;
537 uint8_t parsed_new_action = 0;
538 uint32_t parsed_count = 0;
539 uint32_t parsed_seconds = 0;
540 uint32_t parsed_timeout = 0;
543 uint32_t
id = 0, gid = 0;
549 pcre2_match_data *regex_base_match = NULL;
552 SCLogError(
"pcre2_match parse error, ret %" PRId32
", string %s", ret, rawstr);
553 pcre2_match_data_free(regex_base_match);
558 size_t copylen =
sizeof(th_rule_type);
559 ret = pcre2_substring_copy_bynumber(
560 regex_base_match, 1, (PCRE2_UCHAR8 *)th_rule_type, ©len);
562 SCLogError(
"pcre2_substring_copy_bynumber failed");
563 pcre2_match_data_free(regex_base_match);
568 copylen =
sizeof(th_gid);
569 ret = pcre2_substring_copy_bynumber(regex_base_match, 2, (PCRE2_UCHAR8 *)th_gid, ©len);
571 SCLogError(
"pcre2_substring_copy_bynumber failed");
572 pcre2_match_data_free(regex_base_match);
576 copylen =
sizeof(th_sid);
577 ret = pcre2_substring_copy_bynumber(regex_base_match, 3, (PCRE2_UCHAR8 *)th_sid, ©len);
579 SCLogError(
"pcre2_substring_copy_bynumber failed");
580 pcre2_match_data_free(regex_base_match);
585 ret = pcre2_substring_get_bynumber(
586 regex_base_match, 4, (PCRE2_UCHAR8 **)&rule_extend, ©len);
588 SCLogError(
"pcre2_substring_get_bynumber failed");
589 pcre2_match_data_free(regex_base_match);
592 pcre2_match_data_free(regex_base_match);
593 regex_base_match = NULL;
596 if (strcasecmp(th_rule_type,
"event_filter") == 0) {
598 }
else if (strcasecmp(th_rule_type,
"threshold") == 0) {
600 }
else if (strcasecmp(th_rule_type,
"rate_filter") == 0) {
602 }
else if (strcasecmp(th_rule_type,
"suppress") == 0) {
605 SCLogError(
"rule type %s is unknown", th_rule_type);
613 if (strlen(rule_extend) > 0) {
614 pcre2_match_data *match = NULL;
618 SCLogError(
"pcre2_match parse error, ret %" PRId32
", string %s", ret,
620 pcre2_match_data_free(match);
624 copylen =
sizeof(th_type);
625 ret = pcre2_substring_copy_bynumber(match, 1, (PCRE2_UCHAR8 *)th_type, ©len);
627 SCLogError(
"pcre2_substring_copy_bynumber failed");
628 pcre2_match_data_free(match);
632 copylen =
sizeof(th_track);
633 ret = pcre2_substring_copy_bynumber(match, 2, (PCRE2_UCHAR8 *)th_track, ©len);
635 SCLogError(
"pcre2_substring_copy_bynumber failed");
636 pcre2_match_data_free(match);
640 copylen =
sizeof(th_count);
641 ret = pcre2_substring_copy_bynumber(match, 3, (PCRE2_UCHAR8 *)th_count, ©len);
643 SCLogError(
"pcre2_substring_copy_bynumber failed");
644 pcre2_match_data_free(match);
648 copylen =
sizeof(th_seconds);
649 ret = pcre2_substring_copy_bynumber(match, 4, (PCRE2_UCHAR8 *)th_seconds, ©len);
651 SCLogError(
"pcre2_substring_copy_bynumber failed");
652 pcre2_match_data_free(match);
655 pcre2_match_data_free(match);
657 if (strcasecmp(th_type,
"limit") == 0)
659 else if (strcasecmp(th_type,
"both") == 0)
661 else if (strcasecmp(th_type,
"threshold") == 0)
664 SCLogError(
"limit type not supported: %s", th_type);
673 if (strlen(rule_extend) > 0) {
674 pcre2_match_data *match = NULL;
677 SCLogError(
"pcre2_match parse error, ret %" PRId32
", string %s", ret,
679 pcre2_match_data_free(match);
683 copylen =
sizeof(th_seconds);
684 ret = pcre2_substring_copy_bynumber(match, 1, (PCRE2_UCHAR8 *)th_track, ©len);
686 SCLogError(
"pcre2_substring_copy_bynumber failed");
687 pcre2_match_data_free(match);
691 ret = pcre2_substring_get_bynumber(match, 2, (PCRE2_UCHAR8 **)&th_ip, ©len);
693 SCLogError(
"pcre2_substring_get_bynumber failed");
694 pcre2_match_data_free(match);
697 pcre2_match_data_free(match);
704 if (strlen(rule_extend) > 0) {
705 pcre2_match_data *match = NULL;
708 SCLogError(
"pcre2_match parse error, ret %" PRId32
", string %s", ret,
710 pcre2_match_data_free(match);
714 copylen =
sizeof(th_track);
715 ret = pcre2_substring_copy_bynumber(match, 1, (PCRE2_UCHAR8 *)th_track, ©len);
717 SCLogError(
"pcre2_substring_copy_bynumber failed");
718 pcre2_match_data_free(match);
722 copylen =
sizeof(th_count);
723 ret = pcre2_substring_copy_bynumber(match, 2, (PCRE2_UCHAR8 *)th_count, ©len);
725 SCLogError(
"pcre2_substring_copy_bynumber failed");
726 pcre2_match_data_free(match);
730 copylen =
sizeof(th_seconds);
731 ret = pcre2_substring_copy_bynumber(match, 3, (PCRE2_UCHAR8 *)th_seconds, ©len);
733 SCLogError(
"pcre2_substring_copy_bynumber failed");
734 pcre2_match_data_free(match);
738 copylen =
sizeof(th_new_action);
739 ret = pcre2_substring_copy_bynumber(
740 match, 4, (PCRE2_UCHAR8 *)th_new_action, ©len);
742 SCLogError(
"pcre2_substring_copy_bynumber failed");
743 pcre2_match_data_free(match);
747 copylen =
sizeof(th_timeout);
748 ret = pcre2_substring_copy_bynumber(match, 5, (PCRE2_UCHAR8 *)th_timeout, ©len);
750 SCLogError(
"pcre2_substring_copy_bynumber failed");
751 pcre2_match_data_free(match);
754 pcre2_match_data_free(match);
758 if (
StringParseUint32(&parsed_timeout, 10,
sizeof(th_timeout), th_timeout) <= 0) {
763 if (strcasecmp(th_new_action,
"alert") == 0)
765 if (strcasecmp(th_new_action,
"drop") == 0)
767 if (strcasecmp(th_new_action,
"pass") == 0)
769 if (strcasecmp(th_new_action,
"reject") == 0)
771 if (strcasecmp(th_new_action,
"log") == 0) {
772 SCLogInfo(
"log action for rate_filter not supported yet");
775 if (strcasecmp(th_new_action,
"sdrop") == 0) {
776 SCLogInfo(
"sdrop action for rate_filter not supported yet");
792 if (strcasecmp(th_track,
"by_dst") == 0)
794 else if (strcasecmp(th_track,
"by_src") == 0)
796 else if (strcasecmp(th_track,
"by_both") == 0) {
799 else if (strcasecmp(th_track,
"by_rule") == 0)
801 else if (strcasecmp(th_track,
"by_flow") == 0)
804 SCLogError(
"Invalid track parameter %s in %s", th_track, rawstr);
811 if (parsed_count == 0) {
812 SCLogError(
"rate filter count should be > 0");
816 if (
StringParseUint32(&parsed_seconds, 10,
sizeof(th_seconds), th_seconds) <= 0) {
823 if (strcmp(
"", th_track) != 0) {
824 if (strcasecmp(th_track,
"by_dst") == 0)
826 else if (strcasecmp(th_track,
"by_src") == 0)
828 else if (strcasecmp(th_track,
"by_either") == 0) {
832 SCLogError(
"Invalid track parameter %s in %s", th_track, rule_extend);
849 *ret_parsed_type = parsed_type;
850 *ret_parsed_track = parsed_track;
851 *ret_parsed_new_action = parsed_new_action;
852 *ret_parsed_count = parsed_count;
853 *ret_parsed_seconds = parsed_seconds;
854 *ret_parsed_timeout = parsed_timeout;
857 *ret_th_ip = (
char *)th_ip;
859 pcre2_substring_free((PCRE2_UCHAR8 *)rule_extend);
863 if (rule_extend != NULL) {
864 pcre2_substring_free((PCRE2_UCHAR8 *)rule_extend);
867 pcre2_substring_free((PCRE2_UCHAR8 *)th_ip);
884 uint8_t parsed_type = 0;
885 uint8_t parsed_track = 0;
886 uint8_t parsed_new_action = 0;
887 uint32_t parsed_count = 0;
888 uint32_t parsed_seconds = 0;
889 uint32_t parsed_timeout = 0;
891 uint32_t
id = 0, gid = 0;
893 int r = ParseThresholdRule(
de_ctx, rawstr, &
id, &gid, &parsed_type, &parsed_track,
894 &parsed_count, &parsed_seconds, &parsed_timeout, &parsed_new_action, &th_ip);
899 r = SetupSuppressRule(
de_ctx,
id, gid, parsed_type, parsed_track,
900 parsed_count, parsed_seconds, parsed_timeout, parsed_new_action,
903 r = SetupThresholdRule(
de_ctx,
id, gid, parsed_type, parsed_track, parsed_count,
904 parsed_seconds, parsed_timeout, parsed_new_action);
910 pcre2_substring_free((PCRE2_UCHAR8 *)th_ip);
914 pcre2_substring_free((PCRE2_UCHAR8 *)th_ip);
930static int SCThresholdConfIsLineBlankOrComment(
char *line)
932 while (*line !=
'\0') {
938 if (!isspace((
unsigned char)*line))
956static int SCThresholdConfLineIsMultiline(
char *line)
960 size_t len = strlen(line);
962 while (line < rline +
len && *line !=
'\n') {
965 flag = (int)(line - rline);
967 if (!isspace((
unsigned char)*line))
985 char line[8192] =
"";
994 while (fgets(line + esc_pos, (
int)
sizeof(line) - esc_pos, fp) != NULL) {
995 if (SCThresholdConfIsLineBlankOrComment(line)) {
999 esc_pos = SCThresholdConfLineIsMultiline(line);
1001 if (SCThresholdConfAddThresholdtype(line,
de_ctx) < 0) {
1005 SCLogDebug(
"Adding threshold.config rule num %" PRIu32
"( %s )", rule_num, line);
1015 SCLogInfo(
"Threshold config parsed: %d rule(s) found", rule_num);
1029static FILE *SCThresholdConfGenerateValidDummyFD01(
void)
1032 const char *buffer =
1033 "event_filter gen_id 1, sig_id 10, type limit, track by_src, count 1, seconds 60\n"
1034 "threshold gen_id 1, sig_id 100, type both, track by_dst, count 10, seconds 60\n"
1035 "event_filter gen_id 1, sig_id 1000, type threshold, track by_src, count 100, seconds 60\n";
1037 fd =
SCFmemopen((
void *)buffer, strlen(buffer),
"r");
1039 SCLogDebug(
"Error with SCFmemopen() called by Threshold Config test code");
1050static FILE *SCThresholdConfGenerateInvalidDummyFD02(
void)
1053 const char *buffer =
1054 "event_filter gen_id 1, sig_id 1000, type invalid, track by_src, count 100, seconds 60\n";
1056 fd =
SCFmemopen((
void *)buffer, strlen(buffer),
"r");
1058 SCLogDebug(
"Error with SCFmemopen() called by Threshold Config test code");
1068static FILE *SCThresholdConfGenerateValidDummyFD03(
void)
1071 const char *buffer =
1072 "event_filter gen_id 0, sig_id 0, type threshold, track by_src, count 100, seconds 60\n";
1074 fd =
SCFmemopen((
void *)buffer, strlen(buffer),
"r");
1076 SCLogDebug(
"Error with SCFmemopen() called by Threshold Config test code");
1087static FILE *SCThresholdConfGenerateValidDummyFD04(
void)
1090 const char *buffer =
1091 "event_filter gen_id 1 \\\n, sig_id 10, type limit, track by_src, \\\ncount 1, seconds 60\n"
1092 "threshold gen_id 1, \\\nsig_id 100, type both\\\n, track by_dst, count 10, \\\n seconds 60\n"
1093 "event_filter gen_id 1, sig_id 1000, \\\ntype threshold, track \\\nby_src, count 100, seconds 60\n";
1095 fd =
SCFmemopen((
void *)buffer, strlen(buffer),
"r");
1097 SCLogDebug(
"Error with SCFmemopen() called by Threshold Config test code");
1107static FILE *SCThresholdConfGenerateValidDummyFD05(
void)
1110 const char *buffer =
1111 "rate_filter gen_id 1, sig_id 10, track by_src, count 1, seconds 60, new_action drop, timeout 10\n"
1112 "rate_filter gen_id 1, sig_id 100, track by_dst, count 10, seconds 60, new_action pass, timeout 5\n"
1113 "rate_filter gen_id 1, sig_id 1000, track by_rule, count 100, seconds 60, new_action alert, timeout 30\n"
1114 "rate_filter gen_id 1, sig_id 10000, track by_both, count 1000, seconds 60, new_action reject, timeout 21\n";
1116 fd =
SCFmemopen((
void *)buffer, strlen(buffer),
"r");
1118 SCLogDebug(
"Error with SCFmemopen() called by Threshold Config test code");
1129static FILE *SCThresholdConfGenerateValidDummyFD06(
void)
1132 const char *buffer =
1133 "rate_filter \\\ngen_id 1, sig_id 10, track by_src, count 1, seconds 60\\\n, new_action drop, timeout 10\n"
1134 "rate_filter gen_id 1, \\\nsig_id 100, track by_dst, \\\ncount 10, seconds 60, new_action pass, timeout 5\n"
1135 "rate_filter gen_id 1, sig_id 1000, \\\ntrack by_rule, count 100, seconds 60, new_action alert, timeout 30\n"
1136 "rate_filter gen_id 1, sig_id 10000, track by_both, count 1000, \\\nseconds 60, new_action reject, timeout 21\n";
1138 fd =
SCFmemopen((
void *)buffer, strlen(buffer),
"r");
1140 SCLogDebug(
"Error with SCFmemopen() called by Threshold Config test code");
1151static FILE *SCThresholdConfGenerateValidDummyFD07(
void)
1154 const char *buffer =
1155 "rate_filter gen_id 1, sig_id 10, track by_src, count 3, seconds 3, new_action drop, timeout 10\n"
1156 "rate_filter gen_id 1, sig_id 11, track by_src, count 3, seconds 1, new_action drop, timeout 5\n";
1158 fd =
SCFmemopen((
void *)buffer, strlen(buffer),
"r");
1160 SCLogDebug(
"Error with SCFmemopen() called by Threshold Config test code");
1170static FILE *SCThresholdConfGenerateValidDummyFD08(
void)
1173 const char *buffer =
1174 "rate_filter gen_id 1, sig_id 10, track by_rule, count 3, seconds 3, new_action drop, timeout 10\n";
1176 fd =
SCFmemopen((
void *)buffer, strlen(buffer),
"r");
1178 SCLogDebug(
"Error with SCFmemopen() called by Threshold Config test code");
1189static FILE *SCThresholdConfGenerateValidDummyFD09(
void)
1192 const char *buffer =
1193 "event_filter gen_id 1 \\\n, sig_id 10, type limit, track by_src, \\\ncount 2, seconds 60\n"
1194 "threshold gen_id 1, \\\nsig_id 11, type threshold\\\n, track by_dst, count 3, \\\n seconds 60\n"
1195 "event_filter gen_id 1, sig_id 12, \\\ntype both, track \\\nby_src, count 2, seconds 60\n";
1197 fd =
SCFmemopen((
void *)buffer, strlen(buffer),
"r");
1199 SCLogDebug(
"Error with SCFmemopen() called by Threshold Config test code");
1210static FILE *SCThresholdConfGenerateValidDummyFD10(
void)
1213 const char *buffer =
1214 "event_filter gen_id 1 \\\n, sig_id 10, type limit, track by_src, \\\ncount 5, seconds 2\n"
1215 "threshold gen_id 1, \\\nsig_id 11, type threshold\\\n, track by_dst, count 5, \\\n seconds 2\n"
1216 "event_filter gen_id 1, sig_id 12, \\\ntype both, track \\\nby_src, count 5, seconds 2\n";
1218 fd =
SCFmemopen((
void *)buffer, strlen(buffer),
"r");
1220 SCLogDebug(
"Error with SCFmemopen() called by Threshold Config test code");
1230static FILE *SCThresholdConfGenerateValidDummyFD11(
void)
1233 const char *buffer =
1234 "suppress gen_id 1, sig_id 10000\n"
1235 "suppress gen_id 1, sig_id 1000, track by_src, ip 192.168.1.1\n";
1237 fd =
SCFmemopen((
void *)buffer, strlen(buffer),
"r");
1239 SCLogDebug(
"Error with SCFmemopen() called by Threshold Config test code");
1250static int SCThresholdConfTest01(
void)
1257 "alert tcp any any -> any any (msg:\"Threshold limit\"; gid:1; sid:10;)");
1261 g_ut_threshold_fp = SCThresholdConfGenerateValidDummyFD01();
1283static int SCThresholdConfTest02(
void)
1290 "alert tcp any any -> any any (msg:\"Threshold limit\"; gid:1; sid:100;)");
1294 g_ut_threshold_fp = SCThresholdConfGenerateValidDummyFD01();
1316static int SCThresholdConfTest03(
void)
1323 "alert tcp any any -> any any (msg:\"Threshold limit\"; gid:1; sid:1000;)");
1327 g_ut_threshold_fp = SCThresholdConfGenerateValidDummyFD01();
1349static int SCThresholdConfTest04(
void)
1356 "alert tcp any any -> any any (msg:\"Threshold limit\"; gid:1; sid:1000;)");
1360 g_ut_threshold_fp = SCThresholdConfGenerateInvalidDummyFD02();
1378static int SCThresholdConfTest05(
void)
1385 "alert tcp any any -> any any (msg:\"Threshold limit\"; gid:1; sid:1;)");
1388 "alert tcp any any -> any 80 (msg:\"Threshold limit\"; gid:1; sid:10;)");
1392 "alert tcp any any -> any 80 (msg:\"Threshold limit\"; gid:1; sid:100;)");
1396 g_ut_threshold_fp = SCThresholdConfGenerateValidDummyFD03();
1433static int SCThresholdConfTest06(
void)
1440 "alert tcp any any -> any any (msg:\"Threshold limit\"; gid:1; sid:10;)");
1444 g_ut_threshold_fp = SCThresholdConfGenerateValidDummyFD04();
1466static int SCThresholdConfTest07(
void)
1473 "alert tcp any any -> any any (msg:\"Threshold limit\"; gid:1; sid:10;)");
1477 g_ut_threshold_fp = SCThresholdConfGenerateValidDummyFD05();
1500static int SCThresholdConfTest08(
void)
1507 "alert tcp any any -> any any (msg:\"Threshold limit\"; gid:1; sid:10;)");
1511 g_ut_threshold_fp = SCThresholdConfGenerateValidDummyFD06();
1533static int SCThresholdConfTest09(
void)
1536 memset(&th_v, 0,
sizeof(th_v));
1550 "alert tcp any any -> any any (msg:\"ratefilter test\"; gid:1; sid:10;)");
1554 g_ut_threshold_fp = SCThresholdConfGenerateValidDummyFD07();
1617static int SCThresholdConfTest10(
void)
1625 "172.26.0.2",
"172.26.0.11");
1628 "172.26.0.1",
"172.26.0.10");
1632 memset(&th_v, 0,
sizeof(th_v));
1640 "alert tcp any any -> any any (msg:\"ratefilter test\"; gid:1; sid:10;)");
1644 g_ut_threshold_fp = SCThresholdConfGenerateValidDummyFD08();
1707static int SCThresholdConfTest11(
void)
1715 memset(&th_v, 0,
sizeof(th_v));
1723 "alert tcp any any -> any any (msg:\"event_filter test limit\"; gid:1; sid:10;)");
1726 "alert tcp any any -> any any (msg:\"event_filter test threshold\"; gid:1; sid:11;)");
1729 "alert tcp any any -> any any (msg:\"event_filter test both\"; gid:1; sid:12;)");
1733 g_ut_threshold_fp = SCThresholdConfGenerateValidDummyFD09();
1812static int SCThresholdConfTest12(
void)
1820 memset(&th_v, 0,
sizeof(th_v));
1828 "alert tcp any any -> any any (msg:\"event_filter test limit\"; gid:1; sid:10;)");
1831 "alert tcp any any -> any any (msg:\"event_filter test threshold\"; gid:1; sid:11;)");
1834 "alert tcp any any -> any any (msg:\"event_filter test both\"; gid:1; sid:12;)");
1838 g_ut_threshold_fp = SCThresholdConfGenerateValidDummyFD10();
1917static int SCThresholdConfTest13(
void)
1924 "alert tcp any any -> any any (msg:\"Threshold limit\"; gid:1; sid:1000;)");
1928 g_ut_threshold_fp = SCThresholdConfGenerateValidDummyFD11();
1950static int SCThresholdConfTest14(
void)
1955 "192.168.0.100", 1234, 24);
1958 "192.168.0.100", 1234, 24);
1967 "alert tcp any any -> any any (msg:\"suppress test\"; gid:1; sid:10000;)");
1970 "alert tcp any any -> any any (msg:\"suppress test 2\"; gid:1; sid:10;)");
1973 "alert tcp any any -> any any (msg:\"suppress test 3\"; gid:1; sid:1000;)");
1977 memset(&th_v, 0,
sizeof(th_v));
1980 g_ut_threshold_fp = SCThresholdConfGenerateValidDummyFD11();
2011static int SCThresholdConfTest15(
void)
2016 "192.168.0.100", 1234, 24);
2020 memset(&th_v, 0,
sizeof(th_v));
2028 "drop tcp any any -> any any (msg:\"suppress test\"; content:\"lalala\"; gid:1; sid:10000;)");
2032 g_ut_threshold_fp = SCThresholdConfGenerateValidDummyFD11();
2059static int SCThresholdConfTest16(
void)
2064 "192.168.0.100", 1234, 24);
2068 memset(&th_v, 0,
sizeof(th_v));
2076 "drop tcp any any -> any any (msg:\"suppress test\"; gid:1; sid:1000;)");
2080 g_ut_threshold_fp = SCThresholdConfGenerateValidDummyFD11();
2106static int SCThresholdConfTest17(
void)
2111 "192.168.0.100", 1234, 24);
2115 memset(&th_v, 0,
sizeof(th_v));
2123 "drop tcp 192.168.0.10 any -> 192.168.0.100 any (msg:\"suppress test\"; gid:1; sid:10000;)");
2127 g_ut_threshold_fp = SCThresholdConfGenerateValidDummyFD11();
2153static FILE *SCThresholdConfGenerateInvalidDummyFD12(
void)
2156 const char *buffer =
2157 "suppress gen_id 1, sig_id 2200029, track by_dst, ip fe80::/16\n"
2158 "suppress gen_id 1, sig_id 2200029, track by_stc, ip fe80::/16\n";
2160 fd =
SCFmemopen((
void *)buffer, strlen(buffer),
"r");
2162 SCLogDebug(
"Error with SCFmemopen() called by Threshold Config test code");
2173static int SCThresholdConfTest18(
void)
2181 "alert tcp 192.168.0.10 any -> 192.168.0.100 any (msg:\"suppress test\"; gid:1; sid:2200029;)");
2184 g_ut_threshold_fp = SCThresholdConfGenerateInvalidDummyFD12();
2205static FILE *SCThresholdConfGenerateInvalidDummyFD13(
void)
2208 const char *buffer =
2209 "suppress gen_id 1, sig_id 2200029, track by_stc, ip fe80::/16\n"
2210 "suppress gen_id 1, sig_id 2200029, track by_dst, ip fe80::/16\n";
2212 fd =
SCFmemopen((
void *)buffer, strlen(buffer),
"r");
2214 SCLogDebug(
"Error with SCFmemopen() called by Threshold Config test code");
2225static int SCThresholdConfTest19(
void)
2232 "alert tcp 192.168.0.10 any -> 192.168.0.100 any (msg:\"suppress test\"; gid:1; sid:2200029;)");
2235 g_ut_threshold_fp = SCThresholdConfGenerateInvalidDummyFD13();
2254static FILE *SCThresholdConfGenerateValidDummyFD20(
void)
2257 const char *buffer =
2258 "suppress gen_id 1, sig_id 1000, track by_src, ip 2.2.3.4\n"
2259 "suppress gen_id 1, sig_id 1000, track by_src, ip 1.2.3.4\n"
2260 "suppress gen_id 1, sig_id 1000, track by_src, ip 192.168.1.1\n";
2262 fd =
SCFmemopen((
void *)buffer, strlen(buffer),
"r");
2264 SCLogDebug(
"Error with SCFmemopen() called by Threshold Config test code");
2275static int SCThresholdConfTest20(
void)
2282 "alert tcp any any -> any any (msg:\"Threshold limit\"; content:\"abc\"; sid:1000;)");
2285 g_ut_threshold_fp = SCThresholdConfGenerateValidDummyFD20();
2321static int SCThresholdConfTest21(
void)
2328 "alert tcp any any -> any any (msg:\"Threshold limit\"; content:\"abc\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:1000;)");
2330 g_ut_threshold_fp = SCThresholdConfGenerateValidDummyFD20();
2364static FILE *SCThresholdConfGenerateValidDummyFD22(
void)
2367 const char *buffer =
2368 "rate_filter gen_id 1, sig_id 10, track by_both, count 2, seconds 5, new_action drop, timeout 6\n";
2370 fd =
SCFmemopen((
void *)buffer, strlen(buffer),
"r");
2372 SCLogDebug(
"Error with SCFmemopen() called by Threshold Config test code");
2383static int SCThresholdConfTest22(
void)
2386 memset(&th_v, 0,
sizeof(th_v));
2409 "alert tcp any any -> any any (msg:\"ratefilter by_both test\"; gid:1; sid:10;)");
2413 g_ut_threshold_fp = SCThresholdConfGenerateValidDummyFD22();
2421 p2->
ts = p3->
ts = p1->
ts;
2440 p2->
ts = p3->
ts = p1->
ts;
2451 p2->
ts = p3->
ts = p1->
ts;
2470 p2->
ts = p3->
ts = p1->
ts;
2500static FILE *SCThresholdConfGenerateValidDummyFD23(
void)
2503 const char *buffer =
2504 "rate_filter gen_id 1, sig_id 10, track by_both, count 1, seconds 5, new_action drop, timeout 6\n";
2506 fd =
SCFmemopen((
void *)buffer, strlen(buffer),
"r");
2508 SCLogDebug(
"Error with SCFmemopen() called by Threshold Config test code");
2520static int SCThresholdConfTest23(
void)
2523 memset(&th_v, 0,
sizeof(th_v));
2541 "alert tcp any any -> any any (msg:\"ratefilter by_both test\"; gid:1; sid:10;)");
2545 g_ut_threshold_fp = SCThresholdConfGenerateValidDummyFD23();
2592 SCThresholdConfTest09);
2594 SCThresholdConfTest10);
2596 SCThresholdConfTest11);
2598 SCThresholdConfTest12);
2600 UtRegisterTest(
"SCThresholdConfTest14 - suppress", SCThresholdConfTest14);
2602 SCThresholdConfTest15);
2604 SCThresholdConfTest16);
2606 SCThresholdConfTest17);
2609 SCThresholdConfTest18);
2611 SCThresholdConfTest19);
2613 SCThresholdConfTest20);
2615 SCThresholdConfTest21);
2617 SCThresholdConfTest22);
2618 UtRegisterTest(
"SCThresholdConfTest23 - rate_filter by_both opposite",
2619 SCThresholdConfTest23);
int SCConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
int DetectAddressParse(const DetectEngineCtx *de_ctx, DetectAddressHead *gh, const char *str)
Parses an address group sent as a character string and updates the DetectAddressHead sent as the argu...
void DetectAddressHeadCleanup(DetectAddressHead *gh)
Cleans a DetectAddressHead. The functions frees the address group heads(ipv4 and ipv6) inside the Det...
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.
Signature * SigFindSignatureBySidGid(DetectEngineCtx *de_ctx, uint32_t sid, uint32_t gid)
Find a specific signature by sid and gid.
@ DETECT_DETECTION_FILTER
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)
SigMatch * DetectGetLastSMByListId(const Signature *s, int list_id,...)
Returns the sm with the largest index (added last) from the list passed to us as an id.
DetectParseRegex * DetectSetupPCRE2(const char *parse_str, int opts)
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
void SigMatchRemoveSMFromList(Signature *s, SigMatch *sm, int sm_list)
void SigMatchFree(DetectEngineCtx *de_ctx, SigMatch *sm)
free a SigMatch
DetectThresholdData * DetectThresholdDataCopy(DetectThresholdData *de)
Make a deep-copy of an extant DetectTHresholdData object.
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
@ DETECT_SM_LIST_THRESHOLD
@ DETECT_SM_LIST_SUPPRESS
#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.
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
void ThresholdDestroy(void)
main detection engine ctx
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
a single match condition for a signature
SigMatchData * sm_arrays[DETECT_SM_LIST_MAX]
Per thread variable structure.
SCRunMode SCRunmodeGet(void)
Get the current run mode.
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
#define SCLogWarning(...)
Macro used to log WARNING messages.
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
#define SCLogError(...)
Macro used to log ERROR messages.
#define DETECT_SUPPRESS_REGEX
#define THRESHOLD_CONF_DEF_CONF_FILEPATH
int SCThresholdConfParseFile(DetectEngineCtx *de_ctx, FILE *fp)
Parses the Threshold Config file.
#define DETECT_RATE_REGEX
#define DETECT_THRESHOLD_REGEX
int SCThresholdConfInitContext(DetectEngineCtx *de_ctx)
Inits the context to be used by the Threshold Config parsing API.
#define DETECT_BASE_REGEX
void SCThresholdConfGlobalInit(void)
void SCThresholdConfRegisterTests(void)
This function registers unit tests for Classification Config API.
@ THRESHOLD_TYPE_EVENT_FILTER
@ THRESHOLD_TYPE_THRESHOLD
@ THRESHOLD_TYPE_SUPPRESS
void TimeSetIncrementTime(uint32_t tv_sec)
increment the time in the engine
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.
Packet * UTHBuildPacketSrcDst(uint8_t *payload, uint16_t payload_len, uint8_t ipproto, const char *src, const char *dst)
UTHBuildPacketSrcDst is a wrapper that build packets specifying IPs and defaulting ports.
Packet * UTHBuildPacketReal(uint8_t *payload, uint16_t payload_len, uint8_t ipproto, const char *src, const char *dst, uint16_t sport, uint16_t dport)
UTHBuildPacketReal is a function that create tcp/udp packets for unittests specifying ip and port sou...
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.