63 #define PARSE_REGEX "^\\s*(track|type|count|seconds)\\s+(limit|both|threshold|by_dst|by_src|by_both|by_rule|\\d+)\\s*,\\s*(track|type|count|seconds)\\s+(limit|both|threshold|by_dst|by_src|by_both|by_rule|\\d+)\\s*,\\s*(track|type|count|seconds)\\s+(limit|both|threshold|by_dst|by_src|by_both|by_rule|\\d+)\\s*,\\s*(track|type|count|seconds)\\s+(limit|both|threshold|by_dst|by_src|by_both|by_rule|\\d+)\\s*"
72 static void ThresholdRegisterTests(
void);
114 int ret = 0, res = 0;
116 const char *str_ptr = NULL;
117 char *args[9] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
118 char *copy_str = NULL, *threshold_opt = NULL;
119 int second_found = 0, count_found = 0;
120 int type_found = 0, track_found = 0;
121 int second_pos = 0, count_pos = 0;
130 char *saveptr = NULL;
131 for (pos = 0, threshold_opt = strtok_r(copy_str,
",", &saveptr);
132 pos < strlen(copy_str) && threshold_opt != NULL;
133 pos++, threshold_opt = strtok_r(NULL,
"," , &saveptr))
135 if(strstr(threshold_opt,
"count"))
137 if(strstr(threshold_opt,
"second"))
139 if(strstr(threshold_opt,
"type"))
141 if(strstr(threshold_opt,
"track"))
147 if(count_found != 1 || second_found != 1 || type_found != 1 || track_found != 1)
152 SCLogError(
"pcre_exec parse error, ret %" PRId32
", string %s", ret, rawstr);
162 for (i = 0; i < (ret - 1); i++) {
164 res = pcre2_substring_get_bynumber(
165 parse_regex.
match, i + 1, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
168 SCLogError(
"pcre2_substring_get_bynumber failed");
172 args[i] = (
char *)str_ptr;
174 if (strncasecmp(args[i],
"limit",strlen(
"limit")) == 0)
176 if (strncasecmp(args[i],
"both",strlen(
"both")) == 0)
178 if (strncasecmp(args[i],
"threshold",strlen(
"threshold")) == 0)
180 if (strncasecmp(args[i],
"by_dst",strlen(
"by_dst")) == 0)
182 if (strncasecmp(args[i],
"by_src",strlen(
"by_src")) == 0)
184 if (strncasecmp(args[i],
"by_both",strlen(
"by_both")) == 0)
186 if (strncasecmp(args[i],
"by_rule",strlen(
"by_rule")) == 0)
188 if (strncasecmp(args[i],
"count",strlen(
"count")) == 0)
190 if (strncasecmp(args[i],
"seconds",strlen(
"seconds")) == 0)
194 if (args[count_pos] == NULL || args[second_pos] == NULL) {
199 args[count_pos]) <= 0) {
204 args[second_pos]) <= 0) {
208 for (i = 0; i < (ret - 1); i++){
210 pcre2_substring_free((PCRE2_UCHAR8 *)args[i]);
215 for (i = 0; i < (ret - 1); i++){
217 pcre2_substring_free((PCRE2_UCHAR8 *)args[i]);
246 "\"threshold\" are not allowed in the same rule");
249 "options are not allowed in the same rule");
254 de = DetectThresholdParse(rawstr);
305 for (
DetectAddress *last = NULL, *tmp_ad =
de->addrs.ipv4_head; tmp_ad; tmp_ad = tmp_ad->next) {
317 for (
DetectAddress *last = NULL, *tmp_ad =
de->addrs.ipv6_head; tmp_ad; tmp_ad = tmp_ad->next) {
333 DetectThresholdFree(NULL, new_de);
354 static int ThresholdTestParse01(
void)
357 de = DetectThresholdParse(
"type limit,track by_dst,count 10,seconds 60");
359 DetectThresholdFree(NULL,
de);
372 static int ThresholdTestParse02(
void)
375 de = DetectThresholdParse(
"type any,track by_dst,count 10,seconds 60");
377 DetectThresholdFree(NULL,
de);
390 static int ThresholdTestParse03(
void)
393 de = DetectThresholdParse(
"track by_dst, type limit, seconds 60, count 10");
395 DetectThresholdFree(NULL,
de);
409 static int ThresholdTestParse04(
void)
412 de = DetectThresholdParse(
"count 10, track by_dst, seconds 60, type both, count 10");
414 DetectThresholdFree(NULL,
de);
427 static int ThresholdTestParse05(
void)
430 de = DetectThresholdParse(
"count 10, track by_dst, seconds 60, type both");
432 DetectThresholdFree(NULL,
de);
445 static int ThresholdTestParse06(
void)
448 de = DetectThresholdParse(
"count 10, track by_both, seconds 60, type limit");
454 DetectThresholdFree(NULL,
de);
464 static int ThresholdTestParse07(
void)
467 de = DetectThresholdParse(
"count 10, track by_rule, seconds 60, type limit");
473 DetectThresholdFree(NULL,
de);
486 static int DetectThresholdTestSig1(
void)
497 memset(&th_v, 0,
sizeof(th_v));
508 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"alert tcp any any -> any 80 (msg:\"Threshold limit\"; content:\"A\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)");
516 printf(
"signature is ip-only: ");
525 printf(
"alerts %"PRIi32
", expected 1: ", alerts);
530 printf(
"alerts %"PRIi32
", expected 2: ", alerts);
535 printf(
"alerts %"PRIi32
", expected 3: ", alerts);
540 printf(
"alerts %"PRIi32
", expected 4: ", alerts);
545 printf(
"alerts %"PRIi32
", expected 5: ", alerts);
550 printf(
"alerts %"PRIi32
", expected 5: ", alerts);
555 printf(
"alerts %"PRIi32
", expected 5: ", alerts);
560 printf(
"alerts %"PRIi32
", expected 5: ", alerts);
566 printf(
"alerts %"PRIi32
", expected 5: ", alerts);
590 static int DetectThresholdTestSig2(
void)
601 memset(&th_v, 0,
sizeof(th_v));
612 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"alert tcp any any -> any 80 (msg:\"Threshold\"; threshold: type threshold, track by_dst, count 5, seconds 60; sid:1;)");
668 static int DetectThresholdTestSig3(
void)
680 memset(&th_v, 0,
sizeof(th_v));
691 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"alert tcp any any -> any 80 (msg:\"Threshold limit\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:10;)");
707 printf(
"host not found: ");
713 printf(
"host has no threshold: ");
727 printf(
"host not found: ");
733 if (lookup_tsh == NULL) {
735 printf(
"lookup_tsh is NULL: ");
744 printf(
"alerts %u != 3: ", alerts);
769 static int DetectThresholdTestSig4(
void)
780 memset(&th_v, 0,
sizeof(th_v));
791 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"alert tcp any any -> any 80 (msg:\"Threshold both\"; threshold: type both, track by_dst, count 2, seconds 60; sid:10;)");
843 static int DetectThresholdTestSig5(
void)
854 memset(&th_v, 0,
sizeof(th_v));
864 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)");
869 s = s->
next =
SigInit(
de_ctx,
"alert tcp any any -> any 80 (msg:\"Threshold limit sid 1000\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:1000;)");
905 printf(
"alerts %d != 10: ", alerts);
922 static int DetectThresholdTestSig6Ticks(
void)
933 memset(&th_v, 0,
sizeof(th_v));
943 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)");
948 s = s->
next =
SigInit(
de_ctx,
"alert tcp any any -> any 80 (msg:\"Threshold limit sid 1000\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:1000;)");
956 uint64_t ticks_start = 0;
957 uint64_t ticks_end = 0;
985 printf(
"test run %"PRIu64
"\n", (ticks_end - ticks_start));
1008 static int DetectThresholdTestSig7(
void)
1020 memset(&th_v, 0,
sizeof(th_v));
1022 p =
UTHBuildPacketReal((uint8_t *)
"A",1,IPPROTO_TCP,
"1.1.1.1",
"2.2.2.2", 1024, 80);
1031 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"drop tcp any any -> any 80 (threshold: type limit, track by_src, count 1, seconds 300; sid:10;)");
1042 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1047 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1052 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1060 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1065 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1070 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1073 if (alerts == 1 && drops == 6)
1077 printf(
"alerts: %d != 1: ", alerts);
1079 printf(
"drops: %d != 6: ", drops);
1098 static int DetectThresholdTestSig8(
void)
1110 memset(&th_v, 0,
sizeof(th_v));
1112 p =
UTHBuildPacketReal((uint8_t *)
"A",1,IPPROTO_TCP,
"1.1.1.1",
"2.2.2.2", 1024, 80);
1121 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"drop tcp any any -> any 80 (threshold: type limit, track by_src, count 2, seconds 300; sid:10;)");
1132 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1137 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1142 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1150 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1155 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1160 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1163 if (alerts == 2 && drops == 6)
1167 printf(
"alerts: %d != 1: ", alerts);
1169 printf(
"drops: %d != 6: ", drops);
1188 static int DetectThresholdTestSig9(
void)
1200 memset(&th_v, 0,
sizeof(th_v));
1202 p =
UTHBuildPacketReal((uint8_t *)
"A",1,IPPROTO_TCP,
"1.1.1.1",
"2.2.2.2", 1024, 80);
1211 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"drop tcp any any -> any 80 (threshold: type threshold, track by_src, count 3, seconds 100; sid:10;)");
1222 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1227 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1232 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1240 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1245 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1250 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1253 if (alerts == 2 && drops == 2)
1257 printf(
"alerts: %d != 2: ", alerts);
1259 printf(
"drops: %d != 2: ", drops);
1278 static int DetectThresholdTestSig10(
void)
1290 memset(&th_v, 0,
sizeof(th_v));
1292 p =
UTHBuildPacketReal((uint8_t *)
"A",1,IPPROTO_TCP,
"1.1.1.1",
"2.2.2.2", 1024, 80);
1301 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"drop tcp any any -> any 80 (threshold: type threshold, track by_src, count 5, seconds 300; sid:10;)");
1312 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1317 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1322 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1330 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1335 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1340 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1343 if (alerts == 1 && drops == 1)
1347 printf(
"alerts: %d != 1: ", alerts);
1349 printf(
"drops: %d != 1: ", drops);
1368 static int DetectThresholdTestSig11(
void)
1380 memset(&th_v, 0,
sizeof(th_v));
1382 p =
UTHBuildPacketReal((uint8_t *)
"A",1,IPPROTO_TCP,
"1.1.1.1",
"2.2.2.2", 1024, 80);
1391 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"drop tcp any any -> any 80 (threshold: type both, track by_src, count 3, seconds 300; sid:10;)");
1402 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1407 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1412 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1420 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1425 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1430 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1433 if (alerts == 1 && drops == 4)
1437 printf(
"alerts: %d != 1: ", alerts);
1439 printf(
"drops: %d != 4: ", drops);
1458 static int DetectThresholdTestSig12(
void)
1470 memset(&th_v, 0,
sizeof(th_v));
1472 p =
UTHBuildPacketReal((uint8_t *)
"A",1,IPPROTO_TCP,
"1.1.1.1",
"2.2.2.2", 1024, 80);
1481 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"drop tcp any any -> any 80 (threshold: type both, track by_src, count 5, seconds 300; sid:10;)");
1492 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1497 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1502 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1510 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1515 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1520 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1523 if (alerts == 1 && drops == 2)
1527 printf(
"alerts: %d != 1: ", alerts);
1529 printf(
"drops: %d != 2: ", drops);
1554 static int DetectThresholdTestSig13(
void)
1564 memset(&th_v, 0,
sizeof(th_v));
1565 p =
UTHBuildPacketReal((uint8_t *)
"A",1,IPPROTO_TCP,
"1.1.1.1",
"2.2.2.2", 1024, 80);
1573 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; threshold: type limit, track by_rule, count 2, seconds 60; sid:1;)");
1623 static int DetectThresholdTestSig14(
void)
1636 memset(&th_v, 0,
sizeof(th_v));
1637 p1 =
UTHBuildPacketReal((uint8_t *)
"A",1,IPPROTO_TCP,
"1.1.1.1",
"2.2.2.2", 1024, 80);
1638 p2 =
UTHBuildPacketReal((uint8_t *)
"A",1,IPPROTO_TCP,
"1.1.1.1",
"3.3.3.3", 1024, 80);
1647 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; threshold: type limit, track by_both, count 2, seconds 60; sid:1;)");
1698 static void ThresholdRegisterTests(
void)
1707 UtRegisterTest(
"DetectThresholdTestSig1", DetectThresholdTestSig1);
1708 UtRegisterTest(
"DetectThresholdTestSig2", DetectThresholdTestSig2);
1709 UtRegisterTest(
"DetectThresholdTestSig3", DetectThresholdTestSig3);
1710 UtRegisterTest(
"DetectThresholdTestSig4", DetectThresholdTestSig4);
1711 UtRegisterTest(
"DetectThresholdTestSig5", DetectThresholdTestSig5);
1713 DetectThresholdTestSig6Ticks);
1714 UtRegisterTest(
"DetectThresholdTestSig7", DetectThresholdTestSig7);
1715 UtRegisterTest(
"DetectThresholdTestSig8", DetectThresholdTestSig8);
1716 UtRegisterTest(
"DetectThresholdTestSig9", DetectThresholdTestSig9);
1717 UtRegisterTest(
"DetectThresholdTestSig10", DetectThresholdTestSig10);
1718 UtRegisterTest(
"DetectThresholdTestSig11", DetectThresholdTestSig11);
1719 UtRegisterTest(
"DetectThresholdTestSig12", DetectThresholdTestSig12);
1720 UtRegisterTest(
"DetectThresholdTestSig13", DetectThresholdTestSig13);
1721 UtRegisterTest(
"DetectThresholdTestSig14", DetectThresholdTestSig14);