diff --git a/src/detect-engine-alert.c b/src/detect-engine-alert.c index 8ec66f6f8f..039727ae2f 100644 --- a/src/detect-engine-alert.c +++ b/src/detect-engine-alert.c @@ -1,7 +1,26 @@ +/* Copyright (C) 2007-2010 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + #include "detect-engine-alert.h" #include "suricata-common.h" #include "detect.h" #include "decode.h" +#include "flow.h" +#include "flow-private.h" /** * \brief Check if a certain sid alerted, this is used in the test functions @@ -108,3 +127,68 @@ int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p) return 0; } +/** + * \brief Check the threshold of the sigs that match, set actions, break on pass action + * This function iterate the packet alerts array, removing those that didn't match + * the threshold, and those that match after a signature with the action "pass". + * The array is sorted by action priority/order + * \param de_ctx detection engine context + * \param det_ctx detection engine thread context + * \param p pointer to the packet + * \retval 1 if at least one signature match on this packet, 0 if not + */ +int PacketAlertReal(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p) { + int i = 0; + Signature *s = NULL; + 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 (s->flags & SIG_FLAG_IPONLY) { + if ((p->flowflags & FLOW_PKT_TOSERVER && !(p->flowflags & FLOW_PKT_TOSERVER_IPONLY_SET)) || + (p->flowflags & FLOW_PKT_TOCLIENT && !(p->flowflags & FLOW_PKT_TOCLIENT_IPONLY_SET))) { + SCLogDebug("testing against \"ip-only\" signatures"); + + /* save in the flow that we scanned this direction... locking is + * done in the FlowSetIPOnlyFlag function. */ + if (p->flow != NULL) { + FlowSetIPOnlyFlag(p->flow, p->flowflags & FLOW_PKT_TOSERVER ? 1 : 0); + } + + /* Update flow flags for iponly */ + if (p->flow != NULL) { + if (s->action & ACTION_DROP) + p->flow->flags |= FLOW_ACTION_DROP; + if (s->action & ACTION_REJECT) + p->flow->flags |= FLOW_ACTION_DROP; + if (s->action & ACTION_REJECT_DST) + p->flow->flags |= FLOW_ACTION_DROP; + if (s->action & ACTION_REJECT_BOTH) + p->flow->flags |= FLOW_ACTION_DROP; + if (s->action & ACTION_PASS) + p->flow->flags |= FLOW_ACTION_PASS; + } + } + } + + /* set verdict on packet */ + p->action |= p->alerts.alerts[i].action; + 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 */ + p->alerts.cnt = i; + 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) */ + } + +} + diff --git a/src/detect-engine-alert.h b/src/detect-engine-alert.h index 8718e12b88..ca78946da0 100644 --- a/src/detect-engine-alert.h +++ b/src/detect-engine-alert.h @@ -4,6 +4,7 @@ #include "decode.h" #include "detect.h" +int PacketAlertReal(DetectEngineCtx *, DetectEngineThreadCtx *, Packet *); int PacketAlertAppend(DetectEngineThreadCtx *, Signature *, Packet *); int PacketAlertCheck(Packet *, uint32_t); int PacketAlertRemove(Packet *, uint16_t); diff --git a/src/detect-window.h b/src/detect-window.h index 66cec5f3cf..c51bbae388 100644 --- a/src/detect-window.h +++ b/src/detect-window.h @@ -15,12 +15,6 @@ * 02110-1301, USA. */ -/** - * \file - * - * \author Pablo Rincon Crespo - */ - #ifndef __DETECT_WINDOW_H__ #define __DETECT_WINDOW_H__ diff --git a/src/detect.c b/src/detect.c index b63ec7ed53..7b73017fca 100644 --- a/src/detect.c +++ b/src/detect.c @@ -496,7 +496,6 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh void *alstate = NULL; uint8_t flags = 0; uint32_t cnt = 0; - int i = 0; SCEnter(); @@ -803,58 +802,10 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh } } - /* so now let's iterate the alerts and remove the ones after a pass rule - * matched (if any) */ end: - 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 (s->flags & SIG_FLAG_IPONLY) { - if ((p->flowflags & FLOW_PKT_TOSERVER && !(p->flowflags & FLOW_PKT_TOSERVER_IPONLY_SET)) || - (p->flowflags & FLOW_PKT_TOCLIENT && !(p->flowflags & FLOW_PKT_TOCLIENT_IPONLY_SET))) { - SCLogDebug("testing against \"ip-only\" signatures"); - - /* save in the flow that we scanned this direction... locking is - * done in the FlowSetIPOnlyFlag function. */ - if (p->flow != NULL) { - FlowSetIPOnlyFlag(p->flow, p->flowflags & FLOW_PKT_TOSERVER ? 1 : 0); - } - - /* Update flow flags for iponly */ - if (p->flow != NULL) { - if (s->action & ACTION_DROP) - p->flow->flags |= FLOW_ACTION_DROP; - if (s->action & ACTION_REJECT) - p->flow->flags |= FLOW_ACTION_DROP; - if (s->action & ACTION_REJECT_DST) - p->flow->flags |= FLOW_ACTION_DROP; - if (s->action & ACTION_REJECT_BOTH) - p->flow->flags |= FLOW_ACTION_DROP; - if (s->action & ACTION_PASS) - p->flow->flags |= FLOW_ACTION_PASS; - } - } - } - - /* set verdict on packet */ - p->action |= p->alerts.alerts[i].action; - 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 */ - p->alerts.cnt = i; - 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) */ - } + /* so now let's iterate the alerts and remove the ones after a pass rule + * matched (if any). This is done inside PacketAlertReal() */ + PacketAlertReal(de_ctx, det_ctx, p); /* cleanup pkt specific part of the patternmatcher */ PacketPatternCleanup(th_v, det_ctx);