uint8_t action; /* Internal num, used for sorting */
uint8_t flags;
struct Signature_ *s;
+ uint64_t tx_id;
} PacketAlert;
/** After processing an alert by the thresholding module, if at
#define PACKET_ALERT_FLAG_STATE_MATCH 0x02
/** alert was generated based on stream */
#define PACKET_ALERT_FLAG_STREAM_MATCH 0x04
+/** alert is in a tx, tx_id set */
+#define PACKET_ALERT_FLAG_TX 0x08
#define PACKET_ALERT_MAX 15
* \param flags alert flags
* \param alert_msg ptr to StreamMsg object that the signature matched on
*/
-int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, uint8_t flags)
+int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, uint64_t tx_id, uint8_t flags)
{
int i = 0;
p->alerts.alerts[p->alerts.cnt].action = s->action;
p->alerts.alerts[p->alerts.cnt].flags = flags;
p->alerts.alerts[p->alerts.cnt].s = s;
+ p->alerts.alerts[p->alerts.cnt].tx_id = tx_id;
} else {
/* We need to make room for this s->num
(a bit ugly with memcpy but we are planning changes here)*/
p->alerts.alerts[i].action = s->action;
p->alerts.alerts[i].flags = flags;
p->alerts.alerts[i].s = s;
+ p->alerts.alerts[i].tx_id = tx_id;
}
/* Update the count */
#include "detect.h"
void PacketAlertFinalize(DetectEngineCtx *, DetectEngineThreadCtx *, Packet *);
-int PacketAlertAppend(DetectEngineThreadCtx *, Signature *, Packet *, uint8_t);
+int PacketAlertAppend(DetectEngineThreadCtx *, Signature *, Packet *, uint64_t tx_id, uint8_t);
int PacketAlertCheck(Packet *, uint32_t);
int PacketAlertRemove(Packet *, uint16_t);
void PacketAlertTagInit(void);
}
if (!(s->flags & SIG_FLAG_NOALERT)) {
if (s->action & ACTION_DROP)
- PacketAlertAppend(det_ctx, s, p, PACKET_ALERT_FLAG_DROP_FLOW);
+ PacketAlertAppend(det_ctx, s, p, 0, PACKET_ALERT_FLAG_DROP_FLOW);
else
- PacketAlertAppend(det_ctx, s, p, 0);
+ PacketAlertAppend(det_ctx, s, p, 0, 0);
} else {
/* apply actions for noalert/rule suppressed as well */
PACKET_UPDATE_ACTION(p, s->action);
int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
- Signature *s, Flow *f, uint8_t flags,
+ Signature *s, Packet *p, Flow *f, uint8_t flags,
void *alstate, uint16_t alproto, uint16_t alversion)
{
DetectEngineAppInspectionEngine *engine = NULL;
/* all the engines seem to be exhausted at this point. If we
* didn't have a match in one of the engines we would have
* broken off and engine wouldn't be NULL. Hence the alert. */
- if (engine == NULL && total_matches > 0)
- alert_cnt++;
+ if (engine == NULL && total_matches > 0) {
+
+ if (!(s->flags & SIG_FLAG_NOALERT)) {
+ PacketAlertAppend(det_ctx, s, p, tx_id,
+ PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_TX);
+ } else {
+ PACKET_UPDATE_ACTION(p, s->action);
+ }
+
+ alert_cnt = 1;
+ }
if (tx_id == (total_txs - 1)) {
void *tx = AppLayerGetTx(alproto, alstate, tx_id);
if (smb_state->dcerpc_present &&
DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f,
flags, &smb_state->dcerpc) == 1) {
- alert_cnt++;
+ if (!(s->flags & SIG_FLAG_NOALERT)) {
+ PacketAlertAppend(det_ctx, s, p, 0,
+ PACKET_ALERT_FLAG_STATE_MATCH);
+ } else {
+ PACKET_UPDATE_ACTION(p, s->action);
+ }
+
+ alert_cnt = 1;
}
} else {
if (DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f,
flags, alstate) == 1) {
- alert_cnt++;
+ alert_cnt = 1;
+
+ if (!(s->flags & SIG_FLAG_NOALERT)) {
+ PacketAlertAppend(det_ctx, s, p, 0,
+ PACKET_ALERT_FLAG_STATE_MATCH);
+ } else {
+ PACKET_UPDATE_ACTION(p, s->action);
+ }
+
}
}
}
if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) {
store_de_state = 1;
if (sm == NULL || inspect_flags & DE_STATE_FLAG_SIG_CANT_MATCH) {
- if (match == 1)
+ if (match == 1) {
+ if (!(s->flags & SIG_FLAG_NOALERT)) {
+ PacketAlertAppend(det_ctx, s, p, 0,
+ PACKET_ALERT_FLAG_STATE_MATCH);
+ } else {
+ PACKET_UPDATE_ACTION(p, s->action);
+ }
alert_cnt = 1;
+ }
inspect_flags |= DE_STATE_FLAG_FULL_INSPECT;
}
}
SCMutexUnlock(&f->de_state_m);
end:
- return alert_cnt;
+ return alert_cnt ? 1:0;
}
void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
SigMatchSignaturesRunPostMatch(tv, de_ctx, det_ctx, p, s);
if (!(s->flags & SIG_FLAG_NOALERT)) {
- PacketAlertAppend(det_ctx, s, p, 0);
+ if (alproto_supports_txs)
+ PacketAlertAppend(det_ctx, s, p, inspect_tx_id,
+ PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_TX);
+ else
+ PacketAlertAppend(det_ctx, s, p, 0,
+ PACKET_ALERT_FLAG_STATE_MATCH);
} else {
PACKET_UPDATE_ACTION(p, s->action);
}
*/
int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
- Signature *s, Flow *f, uint8_t flags,
+ Signature *s, Packet *p, Flow *f, uint8_t flags,
void *alstate, uint16_t alproto,
uint16_t alversion);
SigMatch *sm = NULL;
uint16_t alversion = 0;
int reset_de_state = 0;
+ int state_alert = 0;
int alerts = 0;
- int i;
int app_decoder_events = 0;
SCEnter();
/* inspect the sigs against the packet */
for (idx = 0; idx < det_ctx->match_array_cnt; idx++) {
RULE_PROFILING_START;
- alerts = 0;
+ state_alert = 0;
#ifdef PROFILING
smatch = 0;
#endif
}
SCLogDebug("stateful app layer match inspection starting");
+
+ /* if DeStateDetectStartDetection matches, it's a full
+ * signature match. It will then call PacketAlertAppend
+ * itself, so we can skip it below. This is done so it
+ * can store the tx_id with the alert */
PACKET_PROFILING_DETECT_START(p, PROF_DETECT_STATEFUL);
- alerts = DeStateDetectStartDetection(th_v, de_ctx, det_ctx, s,
- p->flow, flags, alstate, alproto, alversion);
+ state_alert = DeStateDetectStartDetection(th_v, de_ctx, det_ctx, s,
+ p, p->flow, flags, alstate, alproto, alversion);
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_STATEFUL);
- if (alerts == 0)
+ if (state_alert == 0)
goto next;
/* match */
alert_flags |= PACKET_ALERT_FLAG_STATE_MATCH;
}
- /* If we have reached this stage and we don't have any alerts, it
- * indicates that we didn't have a stateful sig, hence we set alerts
- * to 1. But if we have an alert set, then the sig is definitely a
- * stateful sig and we need to retain the no of alerts */
- alerts = (alerts == 0) ? 1 : alerts;
#ifdef PROFILING
smatch = 1;
#endif
SigMatchSignaturesRunPostMatch(th_v, de_ctx, det_ctx, p, s);
if (!(s->flags & SIG_FLAG_NOALERT)) {
- for (i = 0; i < alerts; i++)
- PacketAlertAppend(det_ctx, s, p, alert_flags);
+ /* stateful sigs call PacketAlertAppend from DeStateDetectStartDetection */
+ if (!state_alert)
+ PacketAlertAppend(det_ctx, s, p, 0, alert_flags);
} else {
/* apply actions even if not alerting */
PACKET_UPDATE_ACTION(p, s->action);
}
+ alerts++;
next:
DetectFlowvarProcessList(det_ctx, p->flow);
DetectReplaceFree(det_ctx->replist);