Tag engine improvements. Output tags only on unified format. Added atomic counter for tagged hosts/sessions

remotes/origin/master-1.0.x
Pablo Rincon 15 years ago committed by Victor Julien
parent 8cdd02877f
commit 868d4614b9

@ -186,11 +186,16 @@ TmEcode AlertUnifiedLog (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq,
{
AlertUnifiedLogThread *aun = (AlertUnifiedLogThread *)data;
AlertUnifiedLogPacketHeader hdr;
PacketAlert pa_tag;
PacketAlert *pa;
int ret;
uint8_t ethh_offset = 0;
uint8_t buf[80000];
uint32_t buflen = 0;
if (p->flags & PKT_HAS_TAG)
PacketAlertAppendTag(p, &pa_tag);
/* the unified1 format only supports IPv4. */
if (p->alerts.cnt == 0 || !PKT_IS_IPV4(p))
return TM_ECODE_OK;
@ -211,8 +216,14 @@ TmEcode AlertUnifiedLog (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq,
uint16_t i = 0;
for (; i < p->alerts.cnt; i++) {
PacketAlert *pa = &p->alerts.alerts[i];
for (; i < p->alerts.cnt + 1; i++) {
if (i < p->alerts.cnt)
pa = &p->alerts.alerts[i];
else
if (p->flags & PKT_HAS_TAG)
pa = &pa_tag;
else
break;
/* fill the hdr structure with the data of the alert */
hdr.sig_gen = pa->gid;

@ -291,6 +291,7 @@ int Unified2IPv6TypeAlert (ThreadVars *t, Packet *p, void *data, PacketQueue *pq
Unified2AlertThread *aun = (Unified2AlertThread *)data;
AlertIPv6Unified2 phdr;
Unified2AlertFileHeader hdr;
PacketAlert pa_tag;
PacketAlert *pa;
uint8_t ethh_offset = 0;
int ret, len;
@ -363,8 +364,18 @@ int Unified2IPv6TypeAlert (ThreadVars *t, Packet *p, void *data, PacketQueue *pq
break;
}
if (p->flags & PKT_HAS_TAG)
PacketAlertAppendTag(p, &pa_tag);
uint16_t i = 0;
for (; i < p->alerts.cnt; i++) {
for (; i < p->alerts.cnt + 1; i++) {
if (i < p->alerts.cnt)
pa = &p->alerts.alerts[i];
else
if (p->flags & PKT_HAS_TAG)
pa = &pa_tag;
else
break;
pa = &p->alerts.alerts[i];
/* fill the header structure with the data of the alert */
@ -425,6 +436,7 @@ int Unified2IPv4TypeAlert (ThreadVars *tv, Packet *p, void *data, PacketQueue *p
AlertIPv4Unified2 phdr;
Unified2AlertFileHeader hdr;
PacketAlert *pa;
PacketAlert pa_tag;
uint8_t ethh_offset = 0;
int ret, len;
char write_buffer[sizeof(Unified2AlertFileHeader) + sizeof(AlertIPv4Unified2)];
@ -484,8 +496,18 @@ int Unified2IPv4TypeAlert (ThreadVars *tv, Packet *p, void *data, PacketQueue *p
break;
}
if (p->flags & PKT_HAS_TAG)
PacketAlertAppendTag(p, &pa_tag);
uint16_t i = 0;
for (; i < p->alerts.cnt; i++) {
for (; i < p->alerts.cnt + 1; i++) {
if (i < p->alerts.cnt)
pa = &p->alerts.alerts[i];
else
if (p->flags & PKT_HAS_TAG)
pa = &pa_tag;
else
break;
pa = &p->alerts.alerts[i];
/* fill the hdr structure with the alert data */
phdr.generator_id = htonl(pa->gid);

@ -170,50 +170,22 @@ int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p)
return 0;
}
int PacketAlertAppendTag(DetectEngineThreadCtx *det_ctx, Packet *p)
/**
* \brief Fill the data of a tagged packet to be logged by unified
*/
int PacketAlertAppendTag(Packet *p, PacketAlert *pa)
{
int i = 0;
if (p->alerts.cnt == PACKET_ALERT_MAX)
return 0;
/* It should be usually the last, so check it before iterating */
if (p->alerts.cnt == 0) {
p->alerts.alerts[p->alerts.cnt].sid = TAG_SIG_ID;
p->alerts.alerts[p->alerts.cnt].gid = TAG_SIG_GEN;
p->alerts.alerts[p->alerts.cnt].num = TAG_SIG_ID;
p->alerts.alerts[p->alerts.cnt].order_id = 1000;
p->alerts.alerts[p->alerts.cnt].action = ACTION_ALERT;
p->alerts.alerts[p->alerts.cnt].rev = 1;
p->alerts.alerts[p->alerts.cnt].prio = 2;
p->alerts.alerts[p->alerts.cnt].msg = NULL;
p->alerts.alerts[p->alerts.cnt].class = 0;
p->alerts.alerts[p->alerts.cnt].class_msg = NULL;
p->alerts.alerts[p->alerts.cnt].references = NULL;
} else {
/* We need to make room for this s->num
(a bit ugly with mamcpy but we are planning changes here)*/
for (i = p->alerts.cnt - 1; i >= 0; i--) {
memcpy(&p->alerts.alerts[i + 1], &p->alerts.alerts[i], sizeof(PacketAlert));
}
i++; /* The right place to store the alert */
p->alerts.alerts[p->alerts.cnt].sid = TAG_SIG_ID;
p->alerts.alerts[p->alerts.cnt].gid = TAG_SIG_GEN;
p->alerts.alerts[p->alerts.cnt].num = TAG_SIG_ID;
p->alerts.alerts[p->alerts.cnt].order_id = 1000;
p->alerts.alerts[p->alerts.cnt].action = ACTION_ALERT;
p->alerts.alerts[p->alerts.cnt].rev = 1;
p->alerts.alerts[p->alerts.cnt].prio = 2;
p->alerts.alerts[p->alerts.cnt].msg = NULL;
p->alerts.alerts[p->alerts.cnt].class = 0;
p->alerts.alerts[p->alerts.cnt].class_msg = NULL;
p->alerts.alerts[p->alerts.cnt].references = NULL;
}
p->alerts.cnt++;
pa->sid = TAG_SIG_ID;
pa->gid = TAG_SIG_GEN;
pa->num = TAG_SIG_ID;
pa->order_id = 1000;
pa->action = ACTION_ALERT;
pa->rev = 1;
pa->prio = 2;
pa->msg = NULL;
pa->class = 0;
pa->class_msg = NULL;
pa->references = NULL;
return 0;
}

@ -29,7 +29,7 @@
void PacketAlertFinalize(DetectEngineCtx *, DetectEngineThreadCtx *, Packet *);
int PacketAlertAppend(DetectEngineThreadCtx *, Signature *, Packet *);
int PacketAlertAppendTag(DetectEngineThreadCtx *, Packet *);
int PacketAlertAppendTag(Packet *, PacketAlert *);
int PacketAlertCheck(Packet *, uint32_t);
int PacketAlertRemove(Packet *, uint16_t);

@ -26,6 +26,7 @@
#include "suricata-common.h"
#include "util-hash.h"
#include "util-atomic.h"
#include "util-time.h"
#include "util-hashlist.h"
#include "detect-engine-tag.h"
@ -33,6 +34,10 @@
static void TagTimeoutRemove(DetectTagHostCtx *tag_ctx, struct timeval *tv);
SC_ATOMIC_DECLARE(unsigned int, num_tags); /**< Atomic counter, to know if we
have tagged hosts/sessions,
to avoid locking */
/* Global Ctx for tagging hosts */
DetectTagHostCtx *tag_ctx = NULL;
@ -114,6 +119,7 @@ void TagInitCtx(void) {
}
TagHashInit(tag_ctx);
SC_ATOMIC_INIT(num_tags);
}
/**
@ -131,6 +137,7 @@ void TagDestroyCtx(void)
tag_ctx->tag_hash_table_ipv6 = NULL;
SCMutexDestroy(&tag_ctx->lock);
SC_ATOMIC_DESTROY(num_tags);
SCFree(tag_ctx);
tag_ctx = NULL;
@ -322,6 +329,11 @@ void TagHandlePacket(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
DetectTagDataEntry *iter = NULL;
DetectTagDataEntryList tdl;
unsigned int current_tags = SC_ATOMIC_GET(num_tags);
/* If there's no tag, get out of here */
if (current_tags == 0)
return;
uint8_t flag_added = 0;
struct timeval ts = { 0, 0 };
TimeGet(&ts);
@ -351,18 +363,19 @@ void TagHandlePacket(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
prev->next = iter->next;
iter = iter->next;
SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1);
continue;
} else {
p->flow->tag_list->header_entry = iter->next;
tde = iter;
iter = iter->next;
SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1);
continue;
}
} else if (flag_added == 0) {
/* It's matching the tag. Add it to be logged and
* update "flag_added" to add the packet once. */
PacketAlertAppendTag(det_ctx, p);
p->flags |= PKT_HAS_TAG;
flag_added++;
}
@ -375,18 +388,19 @@ void TagHandlePacket(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
prev->next = iter->next;
iter = iter->next;
SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1);
continue;
} else {
p->flow->tag_list->header_entry = iter->next;
tde = iter;
iter = iter->next;
SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1);
continue;
}
} else if (flag_added == 0) {
/* It's matching the tag. Add it to be logged and
* update "flag_added" to add the packet once. */
PacketAlertAppendTag(det_ctx, p);
p->flags |= PKT_HAS_TAG;
flag_added++;
}
@ -401,18 +415,19 @@ void TagHandlePacket(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
prev->next = iter->next;
iter = iter->next;
SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1);
continue;
} else {
p->flow->tag_list->header_entry = iter->next;
tde = iter;
iter = iter->next;
SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1);
continue;
}
} else if (flag_added == 0) {
/* It's matching the tag. Add it to be logged and
* update "flag_added" to add the packet once. */
PacketAlertAppendTag(det_ctx, p);
p->flags |= PKT_HAS_TAG;
flag_added++;
}
@ -487,13 +502,13 @@ void TagHandlePacket(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
tde = iter;
iter = iter->next;
SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1);
tde_src->header_entry = NULL;
continue;
}
} else if (flag_added == 0) {
/* It's matching the tag. Add it to be logged and
* update "flag_added" to add the packet once. */
PacketAlertAppendTag(det_ctx, p);
p->flags |= PKT_HAS_TAG;
flag_added++;
}
@ -511,13 +526,13 @@ void TagHandlePacket(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
tde = iter;
iter = iter->next;
SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1);
tde_src->header_entry = NULL;
continue;
}
} else if (flag_added == 0) {
/* It's matching the tag. Add it to be logged and
* update "flag_added" to add the packet once. */
PacketAlertAppendTag(det_ctx, p);
p->flags |= PKT_HAS_TAG;
flag_added++;
}
@ -537,13 +552,13 @@ void TagHandlePacket(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
tde = iter;
iter = iter->next;
SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1);
tde_src->header_entry = NULL;
continue;
}
} else if (flag_added == 0) {
/* It's matching the tag. Add it to be logged and
* update "flag_added" to add the packet once. */
PacketAlertAppendTag(det_ctx, p);
p->flags |= PKT_HAS_TAG;
flag_added++;
}
@ -582,13 +597,13 @@ void TagHandlePacket(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
tde = iter;
iter = iter->next;
SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1);
tde_dst->header_entry = NULL;
continue;
}
} else if (flag_added == 0) {
/* It's matching the tag. Add it to be logged and
* update "flag_added" to add the packet once. */
PacketAlertAppendTag(det_ctx, p);
p->flags |= PKT_HAS_TAG;
flag_added++;
}
@ -606,13 +621,13 @@ void TagHandlePacket(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
tde = iter;
iter = iter->next;
SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1);
tde_dst->header_entry = NULL;
continue;
}
} else if (flag_added == 0) {
/* It's matching the tag. Add it to be logged and
* update "flag_added" to add the packet once. */
PacketAlertAppendTag(det_ctx, p);
p->flags |= PKT_HAS_TAG;
flag_added++;
}
@ -632,13 +647,13 @@ void TagHandlePacket(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
tde = iter;
iter = iter->next;
SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1);
tde_dst->header_entry = NULL;
continue;
}
} else if (flag_added == 0) {
/* It's matching the tag. Add it to be logged and
* update "flag_added" to add the packet once. */
PacketAlertAppendTag(det_ctx, p);
p->flags |= PKT_HAS_TAG;
flag_added++;
}
@ -696,6 +711,7 @@ static void TagTimeoutRemove(DetectTagHostCtx *tag_ctx, struct timeval *tv)
tmp = tmp->next;
SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1);
} else {
tdl->header_entry = tmp->next;
@ -703,6 +719,7 @@ static void TagTimeoutRemove(DetectTagHostCtx *tag_ctx, struct timeval *tv)
tmp = tmp->next;
SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1);
}
}
}
@ -734,6 +751,7 @@ static void TagTimeoutRemove(DetectTagHostCtx *tag_ctx, struct timeval *tv)
tmp = tmp->next;
SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1);
} else {
tdl->header_entry = tmp->next;
@ -741,6 +759,7 @@ static void TagTimeoutRemove(DetectTagHostCtx *tag_ctx, struct timeval *tv)
tmp = tmp->next;
SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1);
}
}
}

@ -47,6 +47,10 @@
#include "util-unittest.h"
#include "util-unittest-helper.h"
#include "util-debug.h"
#include "threads.h"
extern SCSpinlock num_tags_sc_lock__;
extern unsigned int num_tags_sc_atomic__;
extern DetectTagHostCtx *tag_ctx;
@ -191,6 +195,8 @@ int DetectTagMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Si
SCLogDebug("Tagging Host with sid %"PRIu32":%"PRIu32"", s->id, s->gid);
if (TagHashAddTag(tag_ctx, tde, p) == 1)
SCFree(tde);
else
SC_ATOMIC_ADD(num_tags, 1);
} else {
SCLogError(SC_ERR_INVALID_VALUE, "Error on direction of a tag keyword (not src nor dst)");
@ -201,6 +207,8 @@ int DetectTagMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Si
/* If it already exists it will be updated */
if (DetectTagFlowAdd(p, tde) == 1)
SCFree(tde);
else
SC_ATOMIC_ADD(num_tags, 1);
} else {
SCLogDebug("No flow to append the session tag");
}
@ -891,10 +899,17 @@ void DetectTagRegisterTests(void) {
UtRegisterTest("DetectTagTestParse04", DetectTagTestParse04, 1);
UtRegisterTest("DetectTagTestParse05", DetectTagTestParse05, 1);
#if 0
As we have changed the way of handling tags, now we do not get an alert
of a tagged packet, but the unified plugins write the tags. Now we reach
the flag of p->flags & PACKET_HAS_TAG, but we do not know which signature
triggered the tag, so this unittests needs to be updated, at least to
check the packets one by one for the TAG flag
UtRegisterTest("DetectTagTestPacket01", DetectTagTestPacket01, 1);
UtRegisterTest("DetectTagTestPacket02", DetectTagTestPacket02, 1);
UtRegisterTest("DetectTagTestPacket03", DetectTagTestPacket03, 1);
UtRegisterTest("DetectTagTestPacket04", DetectTagTestPacket04, 1);
#endif
#endif /* UNITTESTS */
}

Loading…
Cancel
Save