Store TX id with alerts

When generating an alert and storing it in the packet, store the tx_id
as well. This way the output modules can log the tx_id and access the
proper tx for logging.

Issue #904.
pull/584/merge
Victor Julien 12 years ago
parent 51c2e1eaf6
commit edeeb7ed44

@ -248,6 +248,7 @@ typedef struct PacketAlert_ {
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
@ -258,6 +259,8 @@ typedef struct PacketAlert_ {
#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

@ -175,7 +175,7 @@ int PacketAlertRemove(Packet *p, uint16_t pos)
* \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;
@ -192,6 +192,7 @@ int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, u
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)*/
@ -205,6 +206,7 @@ int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, u
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 */

@ -29,7 +29,7 @@
#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);

@ -1084,9 +1084,9 @@ void IPOnlyMatchPacket(ThreadVars *tv,
}
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);

@ -236,7 +236,7 @@ int DeStateFlowHasInspectableState(Flow *f, uint16_t alproto, uint16_t alversion
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;
@ -310,8 +310,17 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
/* 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);
@ -337,12 +346,27 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
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);
}
}
}
}
@ -373,8 +397,15 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
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;
}
}
@ -405,7 +436,7 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
SCMutexUnlock(&f->de_state_m);
end:
return alert_cnt;
return alert_cnt ? 1:0;
}
void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
@ -621,7 +652,12 @@ 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);
}

@ -170,7 +170,7 @@ int DeStateFlowHasInspectableState(Flow *f, uint16_t alproto, uint16_t alversion
*/
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);

@ -1103,8 +1103,8 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
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();
@ -1305,7 +1305,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
/* 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
@ -1492,11 +1492,16 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
}
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 */
@ -1506,11 +1511,6 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
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
@ -1518,12 +1518,14 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
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);

Loading…
Cancel
Save