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;
124 pcre2_match_data *match = NULL;
131 char *saveptr = NULL;
132 for (pos = 0, threshold_opt = strtok_r(copy_str,
",", &saveptr);
133 pos < strlen(copy_str) && threshold_opt != NULL;
134 pos++, threshold_opt = strtok_r(NULL,
"," , &saveptr))
136 if(strstr(threshold_opt,
"count"))
138 if(strstr(threshold_opt,
"second"))
140 if(strstr(threshold_opt,
"type"))
142 if(strstr(threshold_opt,
"track"))
148 if(count_found != 1 || second_found != 1 || type_found != 1 || track_found != 1)
153 SCLogError(
"pcre_exec parse error, ret %" PRId32
", string %s", ret, rawstr);
161 for (i = 0; i < (ret - 1); i++) {
163 res = pcre2_substring_get_bynumber(match, i + 1, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
166 SCLogError(
"pcre2_substring_get_bynumber failed");
170 args[i] = (
char *)str_ptr;
172 if (strncasecmp(args[i],
"limit",strlen(
"limit")) == 0)
174 if (strncasecmp(args[i],
"both",strlen(
"both")) == 0)
176 if (strncasecmp(args[i],
"threshold",strlen(
"threshold")) == 0)
178 if (strncasecmp(args[i],
"by_dst",strlen(
"by_dst")) == 0)
180 if (strncasecmp(args[i],
"by_src",strlen(
"by_src")) == 0)
182 if (strncasecmp(args[i],
"by_both",strlen(
"by_both")) == 0)
184 if (strncasecmp(args[i],
"by_rule",strlen(
"by_rule")) == 0)
186 if (strncasecmp(args[i],
"count",strlen(
"count")) == 0)
188 if (strncasecmp(args[i],
"seconds",strlen(
"seconds")) == 0)
192 if (args[count_pos] == NULL || args[second_pos] == NULL) {
197 args[count_pos]) <= 0) {
202 args[second_pos]) <= 0) {
206 for (i = 0; i < (ret - 1); i++){
208 pcre2_substring_free((PCRE2_UCHAR8 *)args[i]);
210 pcre2_match_data_free(match);
215 pcre2_match_data_free(match);
217 for (i = 0; i < (ret - 1); i++){
219 pcre2_substring_free((PCRE2_UCHAR8 *)args[i]);
247 "\"threshold\" are not allowed in the same rule");
250 "options are not allowed in the same rule");
255 de = DetectThresholdParse(rawstr);
302 for (
DetectAddress *last = NULL, *tmp_ad =
de->addrs.ipv4_head; tmp_ad; tmp_ad = tmp_ad->next) {
314 for (
DetectAddress *last = NULL, *tmp_ad =
de->addrs.ipv6_head; tmp_ad; tmp_ad = tmp_ad->next) {
330 DetectThresholdFree(NULL, new_de);
351 static int ThresholdTestParse01(
void)
354 de = DetectThresholdParse(
"type limit,track by_dst,count 10,seconds 60");
356 DetectThresholdFree(NULL,
de);
369 static int ThresholdTestParse02(
void)
372 de = DetectThresholdParse(
"type any,track by_dst,count 10,seconds 60");
374 DetectThresholdFree(NULL,
de);
387 static int ThresholdTestParse03(
void)
390 de = DetectThresholdParse(
"track by_dst, type limit, seconds 60, count 10");
392 DetectThresholdFree(NULL,
de);
406 static int ThresholdTestParse04(
void)
409 de = DetectThresholdParse(
"count 10, track by_dst, seconds 60, type both, count 10");
411 DetectThresholdFree(NULL,
de);
424 static int ThresholdTestParse05(
void)
427 de = DetectThresholdParse(
"count 10, track by_dst, seconds 60, type both");
429 DetectThresholdFree(NULL,
de);
442 static int ThresholdTestParse06(
void)
445 de = DetectThresholdParse(
"count 10, track by_both, seconds 60, type limit");
451 DetectThresholdFree(NULL,
de);
461 static int ThresholdTestParse07(
void)
464 de = DetectThresholdParse(
"count 10, track by_rule, seconds 60, type limit");
470 DetectThresholdFree(NULL,
de);
483 static int DetectThresholdTestSig1(
void)
494 memset(&th_v, 0,
sizeof(th_v));
505 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;)");
519 printf(
"alerts %"PRIi32
", expected 1: ", alerts);
524 printf(
"alerts %"PRIi32
", expected 2: ", alerts);
529 printf(
"alerts %"PRIi32
", expected 3: ", alerts);
534 printf(
"alerts %"PRIi32
", expected 4: ", alerts);
539 printf(
"alerts %"PRIi32
", expected 5: ", alerts);
544 printf(
"alerts %"PRIi32
", expected 5: ", alerts);
549 printf(
"alerts %"PRIi32
", expected 5: ", alerts);
554 printf(
"alerts %"PRIi32
", expected 5: ", alerts);
560 printf(
"alerts %"PRIi32
", expected 5: ", alerts);
584 static int DetectThresholdTestSig2(
void)
595 memset(&th_v, 0,
sizeof(th_v));
606 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;)");
662 static int DetectThresholdTestSig3(
void)
674 memset(&th_v, 0,
sizeof(th_v));
685 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;)");
701 printf(
"host not found: ");
707 printf(
"host has no threshold: ");
721 printf(
"host not found: ");
727 if (lookup_tsh == NULL) {
729 printf(
"lookup_tsh is NULL: ");
738 printf(
"alerts %u != 3: ", alerts);
763 static int DetectThresholdTestSig4(
void)
774 memset(&th_v, 0,
sizeof(th_v));
785 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;)");
837 static int DetectThresholdTestSig5(
void)
848 memset(&th_v, 0,
sizeof(th_v));
858 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;)");
863 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;)");
899 printf(
"alerts %d != 10: ", alerts);
916 static int DetectThresholdTestSig6Ticks(
void)
927 memset(&th_v, 0,
sizeof(th_v));
937 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;)");
942 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;)");
950 uint64_t ticks_start = 0;
951 uint64_t ticks_end = 0;
979 printf(
"test run %"PRIu64
"\n", (ticks_end - ticks_start));
1002 static int DetectThresholdTestSig7(
void)
1014 memset(&th_v, 0,
sizeof(th_v));
1016 p =
UTHBuildPacketReal((uint8_t *)
"A",1,IPPROTO_TCP,
"1.1.1.1",
"2.2.2.2", 1024, 80);
1025 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;)");
1036 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1041 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1046 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1054 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1059 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1064 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1067 if (alerts == 1 && drops == 6)
1071 printf(
"alerts: %d != 1: ", alerts);
1073 printf(
"drops: %d != 6: ", drops);
1092 static int DetectThresholdTestSig8(
void)
1104 memset(&th_v, 0,
sizeof(th_v));
1106 p =
UTHBuildPacketReal((uint8_t *)
"A",1,IPPROTO_TCP,
"1.1.1.1",
"2.2.2.2", 1024, 80);
1115 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;)");
1126 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1131 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1136 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1144 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1149 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1154 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1157 if (alerts == 2 && drops == 6)
1161 printf(
"alerts: %d != 1: ", alerts);
1163 printf(
"drops: %d != 6: ", drops);
1182 static int DetectThresholdTestSig9(
void)
1194 memset(&th_v, 0,
sizeof(th_v));
1196 p =
UTHBuildPacketReal((uint8_t *)
"A",1,IPPROTO_TCP,
"1.1.1.1",
"2.2.2.2", 1024, 80);
1205 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;)");
1216 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1221 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1226 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1234 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1239 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1244 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1247 if (alerts == 2 && drops == 2)
1251 printf(
"alerts: %d != 2: ", alerts);
1253 printf(
"drops: %d != 2: ", drops);
1272 static int DetectThresholdTestSig10(
void)
1284 memset(&th_v, 0,
sizeof(th_v));
1286 p =
UTHBuildPacketReal((uint8_t *)
"A",1,IPPROTO_TCP,
"1.1.1.1",
"2.2.2.2", 1024, 80);
1295 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;)");
1306 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1311 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1316 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1324 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1329 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1334 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1337 if (alerts == 1 && drops == 1)
1341 printf(
"alerts: %d != 1: ", alerts);
1343 printf(
"drops: %d != 1: ", drops);
1362 static int DetectThresholdTestSig11(
void)
1374 memset(&th_v, 0,
sizeof(th_v));
1376 p =
UTHBuildPacketReal((uint8_t *)
"A",1,IPPROTO_TCP,
"1.1.1.1",
"2.2.2.2", 1024, 80);
1385 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;)");
1396 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1401 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1406 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1414 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1419 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1424 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1427 if (alerts == 1 && drops == 4)
1431 printf(
"alerts: %d != 1: ", alerts);
1433 printf(
"drops: %d != 4: ", drops);
1452 static int DetectThresholdTestSig12(
void)
1464 memset(&th_v, 0,
sizeof(th_v));
1466 p =
UTHBuildPacketReal((uint8_t *)
"A",1,IPPROTO_TCP,
"1.1.1.1",
"2.2.2.2", 1024, 80);
1475 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;)");
1486 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1491 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1496 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1504 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1509 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1514 drops += ((PacketTestAction(p,
ACTION_DROP)) ? 1 : 0);
1517 if (alerts == 1 && drops == 2)
1521 printf(
"alerts: %d != 1: ", alerts);
1523 printf(
"drops: %d != 2: ", drops);
1548 static int DetectThresholdTestSig13(
void)
1558 memset(&th_v, 0,
sizeof(th_v));
1559 p =
UTHBuildPacketReal((uint8_t *)
"A",1,IPPROTO_TCP,
"1.1.1.1",
"2.2.2.2", 1024, 80);
1567 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;)");
1617 static int DetectThresholdTestSig14(
void)
1630 memset(&th_v, 0,
sizeof(th_v));
1631 p1 =
UTHBuildPacketReal((uint8_t *)
"A",1,IPPROTO_TCP,
"1.1.1.1",
"2.2.2.2", 1024, 80);
1632 p2 =
UTHBuildPacketReal((uint8_t *)
"A",1,IPPROTO_TCP,
"1.1.1.1",
"3.3.3.3", 1024, 80);
1641 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;)");
1692 static void ThresholdRegisterTests(
void)
1701 UtRegisterTest(
"DetectThresholdTestSig1", DetectThresholdTestSig1);
1702 UtRegisterTest(
"DetectThresholdTestSig2", DetectThresholdTestSig2);
1703 UtRegisterTest(
"DetectThresholdTestSig3", DetectThresholdTestSig3);
1704 UtRegisterTest(
"DetectThresholdTestSig4", DetectThresholdTestSig4);
1705 UtRegisterTest(
"DetectThresholdTestSig5", DetectThresholdTestSig5);
1707 DetectThresholdTestSig6Ticks);
1708 UtRegisterTest(
"DetectThresholdTestSig7", DetectThresholdTestSig7);
1709 UtRegisterTest(
"DetectThresholdTestSig8", DetectThresholdTestSig8);
1710 UtRegisterTest(
"DetectThresholdTestSig9", DetectThresholdTestSig9);
1711 UtRegisterTest(
"DetectThresholdTestSig10", DetectThresholdTestSig10);
1712 UtRegisterTest(
"DetectThresholdTestSig11", DetectThresholdTestSig11);
1713 UtRegisterTest(
"DetectThresholdTestSig12", DetectThresholdTestSig12);
1714 UtRegisterTest(
"DetectThresholdTestSig13", DetectThresholdTestSig13);
1715 UtRegisterTest(
"DetectThresholdTestSig14", DetectThresholdTestSig14);