Bug #68 ยป 0001-Allow-threshold-options-in-any-order.patch
src/detect-threshold.c | ||
---|---|---|
#include "util-byte.h"
|
||
#include "util-debug.h"
|
||
#define PARSE_REGEX "^\\s*type\\s+(limit|both|threshold)\\s*,\\s*track\\s+(by_src|by_dst)\\s*,\\s*count\\s+(\\d+)\\s*,\\s*seconds\\s+(\\d+)\\s*"
|
||
#define PARSE_REGEX "^\\s*(track|type|count|seconds)\\s+(limit|both|threshold|by_dst|by_src|\\d+)\\s*,\\s*(track|type|count|seconds)\\s+(limit|both|threshold|by_dst|by_src|\\d+)\\s*,\\s*(track|type|count|seconds)\\s+(limit|both|threshold|by_dst|by_src|\\d+)\\s*,\\s*(track|type|count|seconds)\\s+(limit|both|threshold|by_dst|by_src|\\d+)\\s*"
|
||
static pcre *parse_regex;
|
||
static pcre_extra *parse_regex_study;
|
||
... | ... | |
int ret = 0, res = 0;
|
||
int ov[MAX_SUBSTRINGS];
|
||
const char *str_ptr = NULL;
|
||
char *args[4] = { NULL, NULL, NULL, NULL };
|
||
int i;
|
||
char *args[9] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
||
char *copy_str = NULL, *threshold_opt = NULL;
|
||
int second_found = 0, count_found = 0;
|
||
int type_found = 0, track_found = 0;
|
||
int second_pos = 0, count_pos = 0;
|
||
uint16_t pos = 0;
|
||
int i = 0;
|
||
copy_str = strdup(rawstr);
|
||
for(pos = 0, threshold_opt = strtok(copy_str,","); pos < strlen(copy_str) && threshold_opt != NULL; pos++, threshold_opt = strtok(NULL,",")) {
|
||
if(strstr(threshold_opt,"count"))
|
||
count_found++;
|
||
if(strstr(threshold_opt,"second"))
|
||
second_found++;
|
||
if(strstr(threshold_opt,"type"))
|
||
type_found++;
|
||
if(strstr(threshold_opt,"track"))
|
||
track_found++;
|
||
}
|
||
if(copy_str)
|
||
free(copy_str);
|
||
if(count_found != 1 || second_found != 1 || type_found != 1 || track_found != 1)
|
||
goto error;
|
||
ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS);
|
||
... | ... | |
de->track = TRACK_DST;
|
||
if (strncasecmp(args[i],"by_src",strlen("by_src")) == 0)
|
||
de->track = TRACK_SRC;
|
||
if (strncasecmp(args[i],"count",strlen("seconds")) == 0)
|
||
count_pos = i+1;
|
||
if (strncasecmp(args[i],"seconds",strlen("seconds")) == 0)
|
||
second_pos = i+1;
|
||
}
|
||
if (ByteExtractStringUint32(&de->count, 10, strlen(args[2]), args[2]) <= 0) {
|
||
if (ByteExtractStringUint32(&de->count, 10, strlen(args[count_pos]), args[count_pos]) <= 0) {
|
||
goto error;
|
||
}
|
||
if (ByteExtractStringUint32(&de->seconds, 10, strlen(args[3]), args[3]) <= 0) {
|
||
if (ByteExtractStringUint32(&de->seconds, 10, strlen(args[second_pos]), args[second_pos]) <= 0) {
|
||
goto error;
|
||
}
|
||
... | ... | |
}
|
||
/**
|
||
* \test ThresholdTestParse03 is a test for a valid threshold options in any order
|
||
*
|
||
* \retval 1 on succces
|
||
* \retval 0 on failure
|
||
*/
|
||
static int ThresholdTestParse03 (void) {
|
||
DetectThresholdData *de = NULL;
|
||
de = DetectThresholdParse("track by_dst, type limit, seconds 60, count 10");
|
||
if (de && (de->type == TYPE_LIMIT) && (de->track == TRACK_DST) && (de->count == 10) && (de->seconds == 60)) {
|
||
DetectThresholdFree(de);
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
/**
|
||
* \test ThresholdTestParse04 is a test for an invalid threshold options in any order
|
||
*
|
||
* \retval 1 on succces
|
||
* \retval 0 on failure
|
||
*/
|
||
static int ThresholdTestParse04 (void) {
|
||
DetectThresholdData *de = NULL;
|
||
de = DetectThresholdParse("count 10, track by_dst, seconds 60, type both, count 10");
|
||
if (de && (de->type == TYPE_BOTH) && (de->track == TRACK_DST) && (de->count == 10) && (de->seconds == 60)) {
|
||
DetectThresholdFree(de);
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
/**
|
||
* \test ThresholdTestParse05 is a test for a valid threshold options in any order
|
||
*
|
||
* \retval 1 on succces
|
||
* \retval 0 on failure
|
||
*/
|
||
static int ThresholdTestParse05 (void) {
|
||
DetectThresholdData *de = NULL;
|
||
de = DetectThresholdParse("count 10, track by_dst, seconds 60, type both");
|
||
if (de && (de->type == TYPE_BOTH) && (de->track == TRACK_DST) && (de->count == 10) && (de->seconds == 60)) {
|
||
DetectThresholdFree(de);
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
/**
|
||
* \test DetectThresholdTestSig1 is a test for checking the working of limit keyword
|
||
* by setting up the signature and later testing its working by matching
|
||
* the received packet against the sig.
|
||
... | ... | |
#ifdef UNITTESTS
|
||
UtRegisterTest("ThresholdTestParse01", ThresholdTestParse01, 1);
|
||
UtRegisterTest("ThresholdTestParse02", ThresholdTestParse02, 0);
|
||
UtRegisterTest("ThresholdTestParse03", ThresholdTestParse03, 1);
|
||
UtRegisterTest("ThresholdTestParse04", ThresholdTestParse04, 0);
|
||
UtRegisterTest("ThresholdTestParse05", ThresholdTestParse05, 1);
|
||
UtRegisterTest("DetectThresholdTestSig1", DetectThresholdTestSig1, 1);
|
||
UtRegisterTest("DetectThresholdTestSig2", DetectThresholdTestSig2, 1);
|
||
UtRegisterTest("DetectThresholdTestSig3", DetectThresholdTestSig3, 1);
|