Adding rate_filter support for threshold.config, multiline support and unittests

remotes/origin/master-1.0.x
Pablo Rincon 15 years ago committed by Victor Julien
parent ca7f54de25
commit 1ae36b9a6a

@ -59,7 +59,7 @@ int PacketAlertRemove(Packet *p, uint16_t pos)
{
uint16_t i = 0;
int match = 0;
if (pos >= p->alerts.cnt)
if (pos > p->alerts.cnt)
return 0;
for (i = pos; i <= p->alerts.cnt - 1; i++) {

@ -270,6 +270,7 @@ static inline DetectThresholdEntry *DetectThresholdEntryAlloc(DetectThresholdDat
ste->track = td->track;
ste->seconds = td->seconds;
ste->tv_timeout = 0;
SCReturnPtr(ste, "DetectThresholdEntry");
}
@ -453,6 +454,99 @@ int PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx
}
break;
}
/* rate_filter */
case TYPE_RATE:
{
SCLogDebug("rate_filter");
/* tracking by src/dst or by rule? */
if (td->track != TRACK_RULE)
lookup_tsh = ThresholdHashSearch(de_ctx, &ste, p);
else
lookup_tsh = s->th_entry;
if (lookup_tsh != NULL) {
/* Check if we have a timeout enabled, if so,
* we still matching (and enabling the new_action) */
if ( (p->ts.tv_sec - lookup_tsh->tv_timeout) > td->timeout) {
/* Ok, we are done, timeout reached */
td->timeout = 0;
} else {
/* Already matching */
/* Take the action to perform */
switch (td->new_action) {
case TH_ACTION_ALERT:
p->action |= ACTION_ALERT;
break;
case TH_ACTION_DROP:
p->action |= ACTION_DROP;
break;
case TH_ACTION_REJECT:
p->action |= ACTION_REJECT;
break;
case TH_ACTION_PASS:
p->action |= ACTION_PASS;
break;
default:
/* Weird, leave the default action */
break;
}
ret = 1;
}
/* Update the matching state with the timeout interval */
if ( (p->ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) {
lookup_tsh->current_count++;
if (lookup_tsh->current_count >= td->count) {
/* Then we must enable the new action by setting a
* timeout */
lookup_tsh->tv_timeout = p->ts.tv_sec;
/* Take the action to perform */
switch (td->new_action) {
case TH_ACTION_ALERT:
p->action |= ACTION_ALERT;
break;
case TH_ACTION_DROP:
p->action |= ACTION_DROP;
break;
case TH_ACTION_REJECT:
p->action |= ACTION_REJECT;
break;
case TH_ACTION_PASS:
p->action |= ACTION_PASS;
break;
default:
/* Weird, leave the default action */
break;
}
ret = 1;
}
} else {
lookup_tsh->tv_sec1 = p->ts.tv_sec;
lookup_tsh->current_count = 1;
}
} else {
if (td->count == 1) {
ret = 1;
}
DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, s);
if (e == NULL) {
break;
}
e->current_count = 1;
e->tv_sec1 = p->ts.tv_sec;
e->tv_timeout = 0;
/** The track is by src/dst or by rule? */
if (td->track != TRACK_RULE)
ThresholdHashAdd(de_ctx, e, p);
else
s->th_entry = e;
}
break;
}
}
/* handle timing out entries */

@ -32,9 +32,19 @@
#define TYPE_BOTH 2
#define TYPE_THRESHOLD 3
#define TYPE_DETECTION 4
#define TYPE_RATE 5
#define TRACK_DST 1
#define TRACK_SRC 2
#define TRACK_RULE 3
/* Get the new action to take */
#define TH_ACTION_ALERT 0x01
#define TH_ACTION_DROP 0x02
#define TH_ACTION_PASS 0x04
#define TH_ACTION_LOG 0x08
#define TH_ACTION_SDROP 0x10
#define TH_ACTION_REJECT 0x20
/**
* \typedef DetectThresholdData
@ -48,17 +58,21 @@ typedef struct DetectThresholdData_ {
uint8_t gid; /**< Signature group id */
uint8_t type; /**< Threshold type : limit , threshold, both, detection_filter */
uint8_t track; /**< Track type: by_src, by_dst */
uint8_t new_action; /**< new_action alert|drop|pass|log|sdrop|reject */
uint32_t timeout; /**< timeout */
} DetectThresholdData;
typedef struct DetectThresholdEntry_ {
uint32_t seconds; /**< Event seconds */
uint32_t sid; /**< Signature id */
uint32_t tv_sec1; /**< Var for time control */
uint32_t tv_timeout; /**< Timeout for new_action (for rate_filter)
its not "seconds", that define the time interval */
uint32_t seconds; /**< Event seconds */
uint32_t sid; /**< Signature id */
uint32_t tv_sec1; /**< Var for time control */
uint32_t current_count; /**< Var for count control */
Address addr; /**< Var used to store dst or src addr */
uint8_t gid; /**< Signature group id */
uint8_t ipv; /**< Packet ip version */
uint8_t track; /**< Track type: by_src, by_src */
Address addr; /**< Var used to store dst or src addr */
uint8_t gid; /**< Signature group id */
uint8_t ipv; /**< Packet ip version */
uint8_t track; /**< Track type: by_src, by_src */
} DetectThresholdEntry;

@ -84,12 +84,13 @@ static fpos_t SeekFn(void *handler, fpos_t offset, int whence) {
switch (whence) {
case SEEK_SET:
if (offset > 0 && (size_t)offset <= mem->size)
if (offset >= 0 && (size_t)offset <= mem->size) {
return mem->pos = offset;
}
break;
case SEEK_CUR:
if (mem->pos + offset <= mem->size)
return mem->pos = offset;
return mem->pos += offset;
break;
case SEEK_END:
/* must be negative */
@ -112,15 +113,22 @@ static int ReadFn(void *handler, char *buf, int size) {
size_t count = 0;
SCFmem *mem = handler;
size_t available = mem->size - mem->pos;
int is_eof = 0;
if (size < 0) return - 1;
if ((size_t)size > available)
if ((size_t)size > available) {
size = available;
} else {
is_eof = 1;
}
while (count < (size_t)size)
buf[count++] = mem->buffer[mem->pos++];
if (is_eof == 1)
return 0;
return count;
}

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save