50 "^\\s*(track|count|seconds)\\s+(by_src|by_dst|by_flow|\\d+)\\s*,\\s*(track|count|seconds)\\s+" \
52 "by_dst|by_flow|\\d+)\\s*,\\s*(track|count|seconds)\\s+(by_src|by_dst|by_flow|\\d+)\\s*$"
56static int DetectDetectionFilterMatch(
60static void DetectDetectionFilterRegisterTests(
void);
71 "alert on every match after a threshold has been reached";
85static int DetectDetectionFilterMatch(
106 const char *str_ptr = NULL;
107 char *args[6] = { NULL, NULL, NULL, NULL, NULL, NULL };
108 char *copy_str = NULL, *df_opt = NULL;
109 int seconds_found = 0, count_found = 0, track_found = 0;
110 int seconds_pos = 0, count_pos = 0;
113 char *saveptr = NULL;
114 pcre2_match_data *match = NULL;
121 for (pos = 0, df_opt = strtok_r(copy_str,
",", &saveptr);
122 pos < strlen(copy_str) && df_opt != NULL;
123 pos++, df_opt = strtok_r(NULL,
",", &saveptr)) {
124 if (strstr(df_opt,
"count"))
126 if (strstr(df_opt,
"second"))
128 if (strstr(df_opt,
"track"))
134 if (count_found != 1 || seconds_found != 1 || track_found != 1)
139 SCLogError(
"pcre_exec parse error, ret %" PRId32
", string %s", ret, rawstr);
149 for (i = 0; i < (ret - 1); i++) {
150 res = pcre2_substring_get_bynumber(match, i + 1, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
152 SCLogError(
"pcre2_substring_get_bynumber failed");
156 args[i] = (
char *)str_ptr;
158 if (strncasecmp(args[i],
"by_dst", strlen(
"by_dst")) == 0)
160 if (strncasecmp(args[i],
"by_src", strlen(
"by_src")) == 0)
162 if (strncasecmp(args[i],
"by_flow", strlen(
"by_flow")) == 0)
164 if (strncasecmp(args[i],
"count", strlen(
"count")) == 0)
166 if (strncasecmp(args[i],
"seconds", strlen(
"seconds")) == 0)
170 if (args[count_pos] == NULL || args[seconds_pos] == NULL) {
187 for (i = 0; i < 6; i++) {
189 pcre2_substring_free((PCRE2_UCHAR *)args[i]);
192 pcre2_match_data_free(match);
196 for (i = 0; i < 6; i++) {
198 pcre2_substring_free((PCRE2_UCHAR *)args[i]);
203 pcre2_match_data_free(match);
229 SCLogError(
"\"detection_filter\" and \"threshold\" are not allowed in the same rule");
235 SCLogError(
"At most one \"detection_filter\" is allowed per rule");
239 df = DetectDetectionFilterParse(rawstr);
286static int DetectDetectionFilterTestParse01(
void)
293 DetectDetectionFilterFree(NULL, df);
302static int DetectDetectionFilterTestParse02(
void)
315static int DetectDetectionFilterTestParse03(
void)
317 DetectThresholdData *df = DetectDetectionFilterParse(
"track by_dst, seconds 60, count 10");
322 DetectDetectionFilterFree(NULL, df);
332static int DetectDetectionFilterTestParse04(
void)
335 DetectDetectionFilterParse(
"count 10, track by_dst, seconds 60, count 10");
346static int DetectDetectionFilterTestParse05(
void)
348 DetectThresholdData *df = DetectDetectionFilterParse(
"count 10, track by_dst, seconds 60");
353 DetectDetectionFilterFree(NULL, df);
362static int DetectDetectionFilterTestParse06(
void)
376static int DetectDetectionFilterTestSig1(
void)
383 memset(&th_v, 0,
sizeof(th_v));
393 "alert tcp any any -> any 80 (msg:\"detection_filter Test\"; detection_filter: "
394 "track by_dst, count 4, seconds 60; sid:1;)");
433static int DetectDetectionFilterTestSig2(
void)
440 memset(&th_v, 0,
sizeof(th_v));
451 "alert tcp any any -> any 80 (msg:\"detection_filter Test 2\"; "
452 "detection_filter: track by_dst, count 4, seconds 60; sid:10;)");
491static int DetectDetectionFilterTestSig3(
void)
498 memset(&th_v, 0,
sizeof(th_v));
508 "drop tcp any any -> any 80 (msg:\"detection_filter Test 2\"; "
509 "detection_filter: track by_dst, count 2, seconds 60; sid:10;)");
564static void DetectDetectionFilterRegisterTests(
void)
566 UtRegisterTest(
"DetectDetectionFilterTestParse01", DetectDetectionFilterTestParse01);
567 UtRegisterTest(
"DetectDetectionFilterTestParse02", DetectDetectionFilterTestParse02);
568 UtRegisterTest(
"DetectDetectionFilterTestParse03", DetectDetectionFilterTestParse03);
569 UtRegisterTest(
"DetectDetectionFilterTestParse04", DetectDetectionFilterTestParse04);
570 UtRegisterTest(
"DetectDetectionFilterTestParse05", DetectDetectionFilterTestParse05);
571 UtRegisterTest(
"DetectDetectionFilterTestParse06", DetectDetectionFilterTestParse06);
572 UtRegisterTest(
"DetectDetectionFilterTestSig1", DetectDetectionFilterTestSig1);
573 UtRegisterTest(
"DetectDetectionFilterTestSig2", DetectDetectionFilterTestSig2);
574 UtRegisterTest(
"DetectDetectionFilterTestSig3", DetectDetectionFilterTestSig3);
void DetectDetectionFilterRegister(void)
Registration function for detection_filter: keyword.
#define PARSE_REGEX
Regex for parsing our detection_filter options.
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.
@ 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)
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
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.
SigMatch * DetectGetLastSMFromLists(const Signature *s,...)
Returns the sm with the largest index (added latest) from the lists passed to us.
SigTableElmt * sigmatch_table
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
#define SIGMATCH_IPONLY_COMPAT
@ DETECT_SM_LIST_THRESHOLD
#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
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
void(* Free)(DetectEngineCtx *, void *)
void(* RegisterTests)(void)
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Per thread variable structure.
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
#define SCLogError(...)
Macro used to log ERROR messages.
void TimeSetIncrementTime(uint32_t tv_sec)
increment the time in the engine
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself.
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...