Changing threshold logic

remotes/origin/master-1.0.x
Pablo Rincon 16 years ago committed by Victor Julien
parent 8bcdf29ab7
commit e18e2ec998

@ -40,6 +40,7 @@ host.c host.h \
reputation.c reputation.h \
detect.c detect.h \
detect-engine-sigorder.c detect-engine-sigorder.h \
detect-engine-alert.c detect-engine-alert.h \
detect-engine.c detect-engine.h \
detect-rpc.c detect-rpc.h \
detect-isdataat.c detect-isdataat.h \

@ -0,0 +1,108 @@
#include "detect-engine-alert.h"
#include "suricata-common.h"
#include "detect.h"
#include "decode.h"
/**
* \brief Check if a certain sid alerted, this is used in the test functions
*
* \param p Packet on which we want to check if the signature alerted or not
* \param sid Signature id of the signature that thas to be checked for a match
*
* \retval match A value > 0 on a match; 0 on no match
*/
int PacketAlertCheck(Packet *p, uint32_t sid)
{
uint16_t i = 0;
int match = 0;
for (i = 0; i < p->alerts.cnt; i++) {
if (p->alerts.alerts[i].sid == sid)
match++;
}
return match;
}
/**
* \brief Remove alert from the p->alerts.alerts array at pos
* \param p Pointer to the Packet
* \param pos Position in the array
* \retval 0 if the number of alerts is less than pos
* 1 if all goes well
*/
int PacketAlertRemove(Packet *p, uint16_t pos)
{
uint16_t i = 0;
int match = 0;
if (pos >= p->alerts.cnt)
return 0;
for (i = pos; i <= p->alerts.cnt - 1; i++) {
memcpy(&p->alerts.alerts[i], &p->alerts.alerts[i + 1], sizeof(PacketAlert));
}
// Update it, since we removed 1
p->alerts.cnt--;
return match;
}
int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p)
{
int i = 0;
if (p->alerts.cnt == PACKET_ALERT_MAX)
return 0;
SCLogDebug("sid %"PRIu32"", s->id);
/* It should be usually the last, so check it before iterating */
if (p->alerts.cnt == 0 || (p->alerts.cnt > 0 &&
p->alerts.alerts[p->alerts.cnt - 1].num < s->num)) {
/* We just add it */
if (s->gid > 1)
p->alerts.alerts[p->alerts.cnt].gid = s->gid;
else
p->alerts.alerts[p->alerts.cnt].gid = 1;
p->alerts.alerts[p->alerts.cnt].num= s->num;
p->alerts.alerts[p->alerts.cnt].action = s->action;
p->alerts.alerts[p->alerts.cnt].sid = s->id;
p->alerts.alerts[p->alerts.cnt].rev = s->rev;
p->alerts.alerts[p->alerts.cnt].prio = s->prio;
p->alerts.alerts[p->alerts.cnt].msg = s->msg;
p->alerts.alerts[p->alerts.cnt].class_msg = s->class_msg;
p->alerts.alerts[p->alerts.cnt].references = s->references;
} else {
/* We need to make room for this s->num
(a bit ugly with mamcpy but we are planning changes here)*/
for (i = p->alerts.cnt - 1; i >= 0 && p->alerts.alerts[i].num > s->num; i--) {
memcpy(&p->alerts.alerts[i + 1], &p->alerts.alerts[i], sizeof(PacketAlert));
}
i++; /* The right place to store the alert */
if (s->gid > 1)
p->alerts.alerts[i].gid = s->gid;
else
p->alerts.alerts[i].gid = 1;
p->alerts.alerts[i].num= s->num;
p->alerts.alerts[i].action = s->action;
p->alerts.alerts[i].sid = s->id;
p->alerts.alerts[i].rev = s->rev;
p->alerts.alerts[i].prio = s->prio;
p->alerts.alerts[i].msg = s->msg;
p->alerts.alerts[i].class_msg = s->class_msg;
p->alerts.alerts[i].references = s->references;
}
/* Update the count */
p->alerts.cnt++;
SCPerfCounterIncr(det_ctx->counter_alerts, det_ctx->tv->sc_perf_pca);
return 0;
}

@ -0,0 +1,11 @@
#ifndef __DETECT_ENGINE_ALERT_H__
#define __DETECT_ENGINE_ALERT_H__
#include "suricata-common.h"
#include "decode.h"
#include "detect.h"
int PacketAlertAppend(DetectEngineThreadCtx *, Signature *, Packet *);
int PacketAlertCheck(Packet *, uint32_t);
int PacketAlertRemove(Packet *, uint16_t);
#endif /* __DETECT_ENGINE_ALERT_H__ */

@ -977,7 +977,7 @@ void IPOnlyMatchPacket(DetectEngineCtx *de_ctx,
p->flow->flags |= FLOW_ACTION_PASS;
}
p->action |= ACTION_PASS;
PacketAlertHandle(de_ctx, det_ctx, s, p);
PacketAlertAppend(det_ctx, s, p);
}
}
}

@ -60,10 +60,11 @@
* \param p Packet structure
*
*/
void PacketAlertHandle(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
Signature *s, Packet *p)
int PacketAlertHandle(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
Signature *s, Packet *p, uint16_t pos)
{
SCEnter();
int ret = 0;
/* retrieve the sig match data */
DetectThresholdData *td = SigGetThresholdType(s,p);
@ -72,12 +73,18 @@ void PacketAlertHandle(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
/* if have none just alert, otherwise handle thresholding */
if (td == NULL) {
PacketAlertAppend(det_ctx, s, p);
} else {
PacketAlertThreshold(de_ctx, det_ctx, td, p, s);
//PacketAlertAppend(det_ctx, s, p);
/* Already inserted so get out */
ret = 1;
} else {
ret = PacketAlertThreshold(de_ctx, det_ctx, td, p, s);
if (ret == 0) {
/* It doesn't match threshold, remove it */
PacketAlertRemove(p, pos);
}
}
SCReturn;
SCReturnInt(ret);
}
/**
@ -243,23 +250,24 @@ void ThresholdHashAdd(DetectEngineCtx *de_ctx, DetectThresholdEntry *tsh_ptr, Pa
* \param s Signature structure
*
*/
void PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
int PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
DetectThresholdData *td, Packet *p, Signature *s)
{
SCEnter();
int ret = 0;
struct timeval ts;
DetectThresholdEntry *lookup_tsh = NULL;
DetectThresholdEntry *ste = NULL;
if (td == NULL)
SCReturn;
SCReturnInt(ret);
/* setup the Entry we use to search our hash with */
ste = SCMalloc(sizeof(DetectThresholdEntry));
if (ste == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "SCMalloc failed: %s", strerror(errno));
SCReturn;
SCReturnInt(ret);
}
memset(ste, 0x00, sizeof(ste));
@ -297,20 +305,20 @@ void PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ct
if (lookup_tsh != NULL) {
if ((ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) {
if (lookup_tsh->current_count < td->count) {
PacketAlertAppend(det_ctx, s, p);
ret = 1;
}
lookup_tsh->current_count++;
} else {
lookup_tsh->tv_sec1 = ts.tv_sec;
lookup_tsh->current_count = 1;
PacketAlertAppend(det_ctx, s, p);
ret = 1;
}
} else {
ste->tv_sec1 = ts.tv_sec;
ste->current_count = 1;
PacketAlertAppend(det_ctx, s, p);
ret = 1;
ThresholdHashAdd(de_ctx, ste, p);
ste = NULL;
@ -327,7 +335,7 @@ void PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ct
lookup_tsh->current_count++;
if (lookup_tsh->current_count >= td->count) {
PacketAlertAppend(det_ctx, s, p);
ret = 1;
lookup_tsh->current_count = 0;
}
} else {
@ -339,7 +347,7 @@ void PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ct
ste->tv_sec1 = ts.tv_sec;
if (td->count == 1) {
PacketAlertAppend(det_ctx, s, p);
ret = 1;
ste->current_count = 0;
} else {
ThresholdHashAdd(de_ctx,ste,p);
@ -357,7 +365,7 @@ void PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ct
if ((ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) {
lookup_tsh->current_count++;
if (lookup_tsh->current_count == td->count) {
PacketAlertAppend(det_ctx, s, p);
ret = 1;
}
} else {
lookup_tsh->tv_sec1 = ts.tv_sec;
@ -368,7 +376,7 @@ void PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ct
ste->tv_sec1 = ts.tv_sec;
if (td->count == 1) {
PacketAlertAppend(det_ctx, s, p);
ret = 1;
ste->current_count = 0;
} else {
ThresholdHashAdd(de_ctx,ste,p);
@ -387,7 +395,7 @@ void PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ct
if ((ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) {
lookup_tsh->current_count++;
if (lookup_tsh->current_count >= td->count) {
PacketAlertAppend(det_ctx, s, p);
ret = 1;
}
} else {
lookup_tsh->tv_sec1 = ts.tv_sec;
@ -398,7 +406,7 @@ void PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ct
ste->tv_sec1 = ts.tv_sec;
if (td->count == 1) {
PacketAlertAppend(det_ctx, s, p);
ret = 1;
}
ThresholdHashAdd(de_ctx, ste, p);
ste = NULL;
@ -412,7 +420,7 @@ void PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ct
SCFree(ste);
ThresholdTimeoutRemove(de_ctx);
SCReturn;
SCReturnInt(ret);
}
void ThresholdFreeFunc(void *data)

@ -29,10 +29,10 @@
#define THRESHOLD_HASH_SIZE 0xffff
void PacketAlertHandle(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *,
Signature *sig, Packet *p);
int PacketAlertHandle(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *,
Signature *sig, Packet *p, uint16_t);
DetectThresholdData *SigGetThresholdType(Signature *, Packet *);
void PacketAlertThreshold(DetectEngineCtx *, DetectEngineThreadCtx *,
int PacketAlertThreshold(DetectEngineCtx *, DetectEngineThreadCtx *,
DetectThresholdData *, Packet *, Signature *);
void ThresholdFreeFunc(void *data);
char ThresholdCompareFunc(void *data1, uint16_t len1, void *data2,uint16_t len2);

@ -33,6 +33,7 @@
#include "detect-parse.h"
#include "detect-engine.h"
#include "detect-engine-alert.h"
#include "detect-engine-siggroup.h"
#include "detect-engine-address.h"
#include "detect-engine-proto.h"
@ -139,6 +140,7 @@
#include "util-cuda.h"
#include "util-privs.h"
SigMatch *SigMatchAlloc(void);
void DetectExitPrintStats(ThreadVars *tv, void *data);
@ -404,85 +406,6 @@ int SigLoadSignatures (DetectEngineCtx *de_ctx, char *sig_file)
SCReturnInt(0);
}
/**
* \brief Check if a certain sid alerted, this is used in the test functions
*
* \param p Packet on which we want to check if the signature alerted or not
* \param sid Signature id of the signature that thas to be checked for a match
*
* \retval match A value > 0 on a match; 0 on no match
*/
int PacketAlertCheck(Packet *p, uint32_t sid)
{
uint16_t i = 0;
int match = 0;
for (i = 0; i < p->alerts.cnt; i++) {
if (p->alerts.alerts[i].sid == sid)
match++;
}
return match;
}
int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p)
{
int i = 0;
if (p->alerts.cnt == PACKET_ALERT_MAX)
return 0;
SCLogDebug("sid %"PRIu32"", s->id);
/* It should be usually the last, so check it before iterating */
if (p->alerts.cnt == 0 || (p->alerts.cnt > 0 &&
p->alerts.alerts[p->alerts.cnt - 1].num < s->num)) {
/* We just add it */
if (s->gid > 1)
p->alerts.alerts[p->alerts.cnt].gid = s->gid;
else
p->alerts.alerts[p->alerts.cnt].gid = 1;
p->alerts.alerts[p->alerts.cnt].num= s->num;
p->alerts.alerts[p->alerts.cnt].action = s->action;
p->alerts.alerts[p->alerts.cnt].sid = s->id;
p->alerts.alerts[p->alerts.cnt].rev = s->rev;
p->alerts.alerts[p->alerts.cnt].prio = s->prio;
p->alerts.alerts[p->alerts.cnt].msg = s->msg;
p->alerts.alerts[p->alerts.cnt].class_msg = s->class_msg;
p->alerts.alerts[p->alerts.cnt].references = s->references;
} else {
/* We need to make room for this s->num
(a bit ugly with mamcpy but we are planning changes here)*/
for (i = p->alerts.cnt - 1; i >= 0 && p->alerts.alerts[i].num > s->num; i--) {
memcpy(&p->alerts.alerts[i + 1], &p->alerts.alerts[i], sizeof(PacketAlert));
}
i++; /* The right place to store the alert */
if (s->gid > 1)
p->alerts.alerts[i].gid = s->gid;
else
p->alerts.alerts[i].gid = 1;
p->alerts.alerts[i].num= s->num;
p->alerts.alerts[i].action = s->action;
p->alerts.alerts[i].sid = s->id;
p->alerts.alerts[i].rev = s->rev;
p->alerts.alerts[i].prio = s->prio;
p->alerts.alerts[i].msg = s->msg;
p->alerts.alerts[i].class_msg = s->class_msg;
p->alerts.alerts[i].references = s->references;
}
/* Update the count */
p->alerts.cnt++;
SCPerfCounterIncr(det_ctx->counter_alerts, det_ctx->tv->sc_perf_pca);
return 0;
}
SigGroupHead *SigMatchSignaturesGetSgh(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p) {
SCEnter();
@ -552,7 +475,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
void *alstate = NULL;
uint8_t flags = 0;
uint32_t cnt = 0;
uint16_t i = 0;
int i = 0;
SCEnter();
@ -759,7 +682,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
if (!(s->flags & SIG_FLAG_NOALERT)) {
/* set verdict on packet */
p->action |= s->action;
PacketAlertHandle(de_ctx, det_ctx, s, p);
PacketAlertAppend(det_ctx, s, p);
}
} else {
/* reset offset */
@ -798,7 +721,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
/* set verdict on packet */
p->action |= s->action;
PacketAlertHandle(de_ctx, det_ctx, s, p);
PacketAlertAppend(det_ctx, s, p);
}
}
rmatch = fmatch = 1;
@ -845,7 +768,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
/* set verdict on packet */
p->action |= s->action;
PacketAlertHandle(de_ctx, det_ctx, s, p);
PacketAlertAppend(det_ctx, s, p);
}
}
} else {
@ -863,9 +786,14 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
* matched (if any) */
end:
SCLogDebug("(p->action & ation pass)) = %"PRIu8, (p->action & ACTION_PASS));
if (p->action & ACTION_PASS) {
for (; i < p->alerts.cnt; i++) {
SCLogDebug("Sig->num: %"PRIu16, p->alerts.alerts[i].num);
for (i = 0; i < p->alerts.cnt; i++) {
SCLogDebug("Sig->num: %"PRIu16, p->alerts.alerts[i].num);
s = de_ctx->sig_array[p->alerts.alerts[i].num];
int res = PacketAlertHandle(de_ctx, det_ctx, s, p, i);
/* Thresholding might remove one alert */
if (res == 0) {
i--;
} else {
if (p->alerts.alerts[i].action & ACTION_PASS) {
/* Ok, reset the alert cnt to end in the previous of pass
* so we ignore the rest with less prio */
@ -873,6 +801,9 @@ end:
break;
}
}
/* Because we removed the alert from the array, we should
* have compacted the array and decreased cnt by one, so
* process again the same position (with different alert now) */
}
/* cleanup pkt specific part of the patternmatcher */

@ -690,17 +690,11 @@ int SigGroupBuild(DetectEngineCtx *);
int SigGroupCleanup();
void SigAddressPrepareBidirectionals (DetectEngineCtx *);
int PacketAlertAppend(DetectEngineThreadCtx *, Signature *s, Packet *);
int SigLoadSignatures (DetectEngineCtx *, char *);
void SigTableSetup(void);
int PacketAlertCheck(Packet *p, uint32_t sid);
int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx, Packet *p);
int PacketAlertCheck(Packet *p, uint32_t sid);
int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx, Packet *p);
int SignatureIsIPOnly(DetectEngineCtx *de_ctx, Signature *s);
#endif /* __DETECT_H__ */

@ -121,13 +121,6 @@
#include <assert.h>
#define BUG_ON(x) assert(!(x))
#include <htp/htp.h>
#include "threads.h"
#include "util-debug.h"
#include "util-error.h"
#include "util-mem.h"
/** type for the internal signature id. Since it's used in the matching engine
* extensively keeping this as small as possible reduces the overall memory
* footprint of the engine. Set to uint32_t if the engine needs to support
@ -135,6 +128,14 @@
#define SigIntId uint16_t
//#define SigIntId uint32_t
#include <htp/htp.h>
#include "threads.h"
#include "util-debug.h"
#include "util-error.h"
#include "util-mem.h"
#include "detect-engine-alert.h"
size_t strlcat(char *, const char *src, size_t siz);
size_t strlcpy(char *dst, const char *src, size_t siz);

@ -23,6 +23,7 @@
#ifndef __UTIL_MPM_H__
#define __UTIL_MPM_H__
#include "suricata-common.h"
#define MPM_ENDMATCH_SINGLE 0x01 /**< A single match is sufficient. No
depth, offset, etc settings. */

Loading…
Cancel
Save