uint64_t tx_id;
} PacketAlert;
-/** After processing an alert by the thresholding module, if at
- * last it gets triggered, we might want to stick the drop action to
- * the flow on IPS mode */
-#define PACKET_ALERT_FLAG_DROP_FLOW 0x01
+/* flag to indicate the rule action (drop/pass) needs to be applied to the flow */
+#define PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW 0x1
/** alert was generated based on state */
#define PACKET_ALERT_FLAG_STATE_MATCH 0x02
/** alert was generated based on stream */
static inline void RuleActionToFlow(const uint8_t action, Flow *f)
{
- if (action & ACTION_DROP)
- f->flags |= FLOW_ACTION_DROP;
-
- if (action & ACTION_REJECT_ANY)
- f->flags |= FLOW_ACTION_DROP;
+ if (action & (ACTION_DROP | ACTION_REJECT_ANY | ACTION_PASS)) {
+ if (f->flags & (FLOW_ACTION_DROP | FLOW_ACTION_PASS)) {
+ /* drop or pass already set. First to set wins. */
+ SCLogDebug("not setting %s flow already set to %s",
+ (action & ACTION_PASS) ? "pass" : "drop",
+ (f->flags & FLOW_ACTION_DROP) ? "drop" : "pass");
+ } else {
+ if (action & (ACTION_DROP | ACTION_REJECT_ANY)) {
+ f->flags |= FLOW_ACTION_DROP;
+ SCLogDebug("setting flow action drop");
+ }
+ if (action & ACTION_PASS) {
+ f->flags |= FLOW_ACTION_PASS;
+ SCLogDebug("setting flow action pass");
+ FlowSetNoPacketInspectionFlag(f);
+ }
+ }
+ }
+}
- if (action & ACTION_PASS) {
- FlowSetNoPacketInspectionFlag(f);
+/** \brief Apply action(s) and Set 'drop' sig info,
+ * if applicable */
+static void PacketApplySignatureActions(Packet *p, const Signature *s, const uint8_t alert_flags)
+{
+ SCLogDebug("packet %" PRIu64 " sid %u action %02x alert_flags %02x", p->pcap_cnt, s->id,
+ s->action, alert_flags);
+ PACKET_UPDATE_ACTION(p, s->action);
+
+ if (s->action & ACTION_DROP) {
+ if (p->alerts.drop.action == 0) {
+ p->alerts.drop.num = s->num;
+ p->alerts.drop.action = s->action;
+ p->alerts.drop.s = (Signature *)s;
+ }
+ if ((p->flow != NULL) && (alert_flags & PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW)) {
+ RuleActionToFlow(s->action, p->flow);
+ }
+ } else if (s->action & ACTION_PASS) {
+ if ((p->flow != NULL) && (alert_flags & PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW)) {
+ RuleActionToFlow(s->action, p->flow);
+ }
}
}
int i = 0;
while (i < p->alerts.cnt) {
- SCLogDebug("Sig->num: %"PRIu32, p->alerts.alerts[i].num);
const Signature *s = de_ctx->sig_array[p->alerts.alerts[i].num];
+ SCLogDebug("Sig->num: %" PRIu32 " SID %u", p->alerts.alerts[i].num, s->id);
int res = PacketAlertHandle(de_ctx, det_ctx, s, p, &p->alerts.alerts[i]);
if (res > 0) {
}
}
- /* IP-only and PD-only matches should apply to the flow */
- if (s->flags & (SIG_FLAG_IPONLY | SIG_FLAG_PDONLY)) {
- if (p->flow != NULL) {
- RuleActionToFlow(s->action, p->flow);
+ /* For DROP and PASS sigs we need to apply the action to the flow if
+ * - sig is IP or PD only
+ * - match is in applayer
+ * - match is in stream */
+ if (s->action & (ACTION_DROP | ACTION_PASS)) {
+ if ((p->alerts.alerts[i].flags &
+ (PACKET_ALERT_FLAG_STATE_MATCH | PACKET_ALERT_FLAG_STREAM_MATCH)) ||
+ (s->flags & (SIG_FLAG_IPONLY | SIG_FLAG_PDONLY | SIG_FLAG_APPLAYER))) {
+ p->alerts.alerts[i].flags |= PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW;
+ SCLogDebug("packet %" PRIu64 " sid %u action %02x alert_flags %02x (set "
+ "PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW)",
+ p->pcap_cnt, s->id, s->action, p->alerts.alerts[i].flags);
}
}
/* set actions on packet */
- DetectSignatureApplyActions(p, p->alerts.alerts[i].s, p->alerts.alerts[i].flags);
+ PacketApplySignatureActions(p, p->alerts.alerts[i].s, p->alerts.alerts[i].flags);
if (PACKET_TEST_ACTION(p, 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;
-
- /* if the signature wants to drop, check if the
- * PACKET_ALERT_FLAG_DROP_FLOW flag is set. */
- } else if ((PACKET_TEST_ACTION(p, ACTION_DROP)) &&
- ((p->alerts.alerts[i].flags & PACKET_ALERT_FLAG_DROP_FLOW) ||
- (s->flags & SIG_FLAG_APPLAYER))
- && p->flow != NULL)
- {
- /* This will apply only on IPS mode (check StreamTcpPacket) */
- p->flow->flags |= FLOW_ACTION_DROP; // XXX API?
}
}
/* Thresholding removes this alert */
- if (res == 0 || res == 2) {
+ if (res == 0 || res == 2 || (s->flags & SIG_FLAG_NOALERT)) {
PacketAlertRemove(p, i);
if (p->alerts.cnt == 0)
}
}
}
- if (!(s->flags & SIG_FLAG_NOALERT)) {
- if (s->action & ACTION_DROP)
- PacketAlertAppend(det_ctx, s, p, 0, PACKET_ALERT_FLAG_DROP_FLOW);
- else
- PacketAlertAppend(det_ctx, s, p, 0, 0);
- } else {
- /* apply actions for noalert/rule suppressed as well */
- DetectSignatureApplyActions(p, s, 0);
- }
+ PacketAlertAppend(det_ctx, s, p, 0, 0);
}
}
}
pmatch = DetectEngineInspectStreamPayload(de_ctx, det_ctx, s, p->flow, p);
if (pmatch) {
det_ctx->flags |= DETECT_ENGINE_THREAD_CTX_STREAM_CONTENT_MATCH;
- /* Tell the engine that this reassembled stream can drop the
- * rest of the pkts with no further inspection */
- if (s->action & ACTION_DROP)
- *alert_flags |= PACKET_ALERT_FLAG_DROP_FLOW;
-
*alert_flags |= PACKET_ALERT_FLAG_STREAM_MATCH;
}
}
/* save in the flow that we scanned this direction... */
FlowSetIPOnlyFlag(pflow, p->flowflags & FLOW_PKT_TOSERVER ? 1 : 0);
-
- } else if (((p->flowflags & FLOW_PKT_TOSERVER) &&
- (pflow->flags & FLOW_TOSERVER_IPONLY_SET)) ||
- ((p->flowflags & FLOW_PKT_TOCLIENT) &&
- (pflow->flags & FLOW_TOCLIENT_IPONLY_SET)))
- {
- /* If we have a drop from IP only module,
- * we will drop the rest of the flow packets
- * This will apply only to inline/IPS */
- if (pflow->flags & FLOW_ACTION_DROP) {
- PACKET_DROP(p);
- }
+ }
+ /* If we have a drop from IP only module,
+ * we will drop the rest of the flow packets
+ * This will apply only to inline/IPS */
+ if (pflow->flags & FLOW_ACTION_DROP) {
+ PACKET_DROP(p);
}
} else { /* p->flags & PKT_HAS_FLOW */
/* no flow */
#endif
DetectRunPostMatch(tv, det_ctx, p, s);
- if (!(sflags & SIG_FLAG_NOALERT)) {
- PacketAlertAppend(det_ctx, s, p, 0, alert_flags);
- } else {
- /* apply actions even if not alerting */
- DetectSignatureApplyActions(p, s, alert_flags);
- }
+ PacketAlertAppend(det_ctx, s, p, 0, alert_flags);
next:
DetectVarProcessList(det_ctx, pflow, p);
DetectReplaceFree(det_ctx);
/* match */
DetectRunPostMatch(tv, det_ctx, p, s);
- uint8_t alert_flags = (PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_TX);
- if (s->action & ACTION_DROP)
- alert_flags |= PACKET_ALERT_FLAG_DROP_FLOW;
-
+ const uint8_t alert_flags = (PACKET_ALERT_FLAG_STATE_MATCH | PACKET_ALERT_FLAG_TX);
SCLogDebug("%p/%"PRIu64" sig %u (%u) matched", tx.tx_ptr, tx.tx_id, s->id, s->num);
- if (!(s->flags & SIG_FLAG_NOALERT)) {
- PacketAlertAppend(det_ctx, s, p, tx.tx_id, alert_flags);
- } else {
- DetectSignatureApplyActions(p, s, alert_flags);
- }
+ PacketAlertAppend(det_ctx, s, p, tx.tx_id, alert_flags);
}
DetectVarProcessList(det_ctx, p->flow, p);
RULE_PROFILING_END(det_ctx, s, r, p);
}
}
-/** \brief Apply action(s) and Set 'drop' sig info,
- * if applicable */
-void DetectSignatureApplyActions(Packet *p,
- const Signature *s, const uint8_t alert_flags)
-{
- PACKET_UPDATE_ACTION(p, s->action);
-
- if (s->action & ACTION_DROP) {
- if (p->alerts.drop.action == 0) {
- p->alerts.drop.num = s->num;
- p->alerts.drop.action = s->action;
- p->alerts.drop.s = (Signature *)s;
- }
- } else if (s->action & ACTION_PASS) {
- /* if an stream/app-layer match we enforce the pass for the flow */
- if ((p->flow != NULL) &&
- (alert_flags & (PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_STREAM_MATCH)))
- {
- FlowSetNoPacketInspectionFlag(p->flow);
- }
-
- }
-}
-
static DetectEngineThreadCtx *GetTenantById(HashTable *h, uint32_t id)
{
/* technically we need to pass a DetectEngineThreadCtx struct with the
int DetectRegisterThreadCtxFuncs(DetectEngineCtx *, const char *name, void *(*InitFunc)(void *), void *data, void (*FreeFunc)(void *), int);
void *DetectThreadCtxGetKeywordThreadCtx(DetectEngineThreadCtx *, int);
-void DetectSignatureApplyActions(Packet *p, const Signature *s, const uint8_t);
-
void RuleMatchCandidateTxArrayInit(DetectEngineThreadCtx *det_ctx, uint32_t size);
void RuleMatchCandidateTxArrayFree(DetectEngineThreadCtx *det_ctx);
/** Indicate that the flow did trigger an expectation creation */
#define FLOW_HAS_EXPECTATION BIT_U32(27)
+/** All packets in this flow should be passed */
+#define FLOW_ACTION_PASS BIT_U32(28)
+
/* File flags */
/** no magic on files in this flow */