|
|
|
@ -357,6 +357,23 @@ void AlertQueueAppend(DetectEngineThreadCtx *det_ctx, const Signature *s, Packet
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** \internal
|
|
|
|
|
|
|
|
* \brief sort helper for sorting alerts by priority
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* Sorting is done first based on num and then using tx_id, if nums are equal.
|
|
|
|
|
|
|
|
* The Signature::num field is set based on internal priority. Higher priority
|
|
|
|
|
|
|
|
* rules have lower nums.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
static int AlertQueueSortHelper(const void *a, const void *b)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
const PacketAlert *pa0 = a;
|
|
|
|
|
|
|
|
const PacketAlert *pa1 = b;
|
|
|
|
|
|
|
|
if (pa1->num == pa0->num)
|
|
|
|
|
|
|
|
return pa0->tx_id < pa1->tx_id ? 1 : -1;
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
return pa0->num > pa1->num ? 1 : -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* \brief Check the threshold of the sigs that match, set actions, break on pass action
|
|
|
|
* \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
|
|
|
|
* This function iterate the packet alerts array, removing those that didn't match
|
|
|
|
@ -369,13 +386,18 @@ void AlertQueueAppend(DetectEngineThreadCtx *det_ctx, const Signature *s, Packet
|
|
|
|
void PacketAlertFinalize(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
|
|
|
|
void PacketAlertFinalize(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
SCEnter();
|
|
|
|
SCEnter();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* sort the alert queue before thresholding and appending to Packet */
|
|
|
|
|
|
|
|
qsort(det_ctx->alert_queue, det_ctx->alert_queue_size, sizeof(PacketAlert),
|
|
|
|
|
|
|
|
AlertQueueSortHelper);
|
|
|
|
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
uint16_t max_pos = det_ctx->alert_queue_size;
|
|
|
|
|
|
|
|
|
|
|
|
while (i < p->alerts.cnt) {
|
|
|
|
while (i < max_pos) {
|
|
|
|
const Signature *s = de_ctx->sig_array[p->alerts.alerts[i].num];
|
|
|
|
const Signature *s = de_ctx->sig_array[det_ctx->alert_queue[i].num];
|
|
|
|
SCLogDebug("Sig->num: %" PRIu32 " SID %u", p->alerts.alerts[i].num, s->id);
|
|
|
|
uint8_t res = PacketAlertHandle(de_ctx, det_ctx, s, p, &det_ctx->alert_queue[i]);
|
|
|
|
|
|
|
|
|
|
|
|
int res = PacketAlertHandle(de_ctx, det_ctx, s, p, &p->alerts.alerts[i]);
|
|
|
|
|
|
|
|
if (res > 0) {
|
|
|
|
if (res > 0) {
|
|
|
|
/* Now, if we have an alert, we have to check if we want
|
|
|
|
/* Now, if we have an alert, we have to check if we want
|
|
|
|
* to tag this session or src/dst host */
|
|
|
|
* to tag this session or src/dst host */
|
|
|
|
@ -398,36 +420,35 @@ void PacketAlertFinalize(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx
|
|
|
|
* - match is in applayer
|
|
|
|
* - match is in applayer
|
|
|
|
* - match is in stream */
|
|
|
|
* - match is in stream */
|
|
|
|
if (s->action & (ACTION_DROP | ACTION_PASS)) {
|
|
|
|
if (s->action & (ACTION_DROP | ACTION_PASS)) {
|
|
|
|
if ((p->alerts.alerts[i].flags &
|
|
|
|
if ((det_ctx->alert_queue[i].flags &
|
|
|
|
(PACKET_ALERT_FLAG_STATE_MATCH | PACKET_ALERT_FLAG_STREAM_MATCH)) ||
|
|
|
|
(PACKET_ALERT_FLAG_STATE_MATCH | PACKET_ALERT_FLAG_STREAM_MATCH)) ||
|
|
|
|
(s->flags & (SIG_FLAG_IPONLY | SIG_FLAG_PDONLY | SIG_FLAG_APPLAYER))) {
|
|
|
|
(s->flags & (SIG_FLAG_IPONLY | SIG_FLAG_PDONLY | SIG_FLAG_APPLAYER))) {
|
|
|
|
p->alerts.alerts[i].flags |= PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW;
|
|
|
|
det_ctx->alert_queue[i].flags |= PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW;
|
|
|
|
SCLogDebug("packet %" PRIu64 " sid %u action %02x alert_flags %02x (set "
|
|
|
|
SCLogDebug("packet %" PRIu64 " sid %u action %02x alert_flags %02x (set "
|
|
|
|
"PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW)",
|
|
|
|
"PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW)",
|
|
|
|
p->pcap_cnt, s->id, s->action, p->alerts.alerts[i].flags);
|
|
|
|
p->pcap_cnt, s->id, s->action, det_ctx->alert_queue[i].flags);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* set actions on packet */
|
|
|
|
/* set actions on packet */
|
|
|
|
PacketApplySignatureActions(p, p->alerts.alerts[i].s, p->alerts.alerts[i].flags);
|
|
|
|
PacketApplySignatureActions(p, s, det_ctx->alert_queue[i].flags);
|
|
|
|
|
|
|
|
|
|
|
|
if (PacketTestAction(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;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Thresholding removes this alert */
|
|
|
|
/* Thresholding removes this alert */
|
|
|
|
if (res == 0 || res == 2 || (s->flags & SIG_FLAG_NOALERT)) {
|
|
|
|
if (res == 0 || res == 2 || (s->flags & SIG_FLAG_NOALERT)) {
|
|
|
|
PacketAlertRemove(p, i);
|
|
|
|
/* we will not copy this to the AlertQueue */
|
|
|
|
|
|
|
|
} else if (p->alerts.cnt < packet_alert_max) {
|
|
|
|
|
|
|
|
p->alerts.alerts[p->alerts.cnt] = det_ctx->alert_queue[i];
|
|
|
|
|
|
|
|
SCLogDebug("Appending sid %" PRIu32 " alert to Packet::alerts at pos %u", s->id, i);
|
|
|
|
|
|
|
|
|
|
|
|
if (p->alerts.cnt == 0)
|
|
|
|
if (PacketTestAction(p, ACTION_PASS)) {
|
|
|
|
|
|
|
|
/* Ok, reset the alert cnt to end in the previous of pass
|
|
|
|
|
|
|
|
* so we ignore the rest with less prio */
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
p->alerts.cnt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* At this point, we should have all the new alerts. Now check the tag
|
|
|
|
/* At this point, we should have all the new alerts. Now check the tag
|
|
|
|
|