No longer pass StreamMsg to output for alert logging, instead use the same callback code as is used for state alerts.

remotes/origin/master
Victor Julien 14 years ago
parent 88a21456e3
commit ea0d172693

@ -276,19 +276,17 @@ TmEcode AlertDebugLogger(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq,
fprintf(aft->file_ctx->fp, "ALERT REV [%02d]: %" PRIu32 "\n", i, pa->s->rev);
fprintf(aft->file_ctx->fp, "ALERT CLASS [%02d]: %s\n", i, pa->s->class_msg ? pa->s->class_msg : "<none>");
fprintf(aft->file_ctx->fp, "ALERT PRIO [%02d]: %" PRIu32 "\n", i, pa->s->prio);
fprintf(aft->file_ctx->fp, "ALERT FOUND IN [%02d]: %s\n", i, pa->alert_msg ? "STREAM" : "OTHER");
if (pa->alert_msg != NULL) {
fprintf(aft->file_ctx->fp, "ALERT STREAM LEN[%02d]:%"PRIu16"\n", i, ((StreamMsg *)pa->alert_msg)->data.data_len);
fprintf(aft->file_ctx->fp, "ALERT STREAM [%02d]:\n", i);
PrintRawDataFp(aft->file_ctx->fp, ((StreamMsg *)pa->alert_msg)->data.data,
((StreamMsg *)pa->alert_msg)->data.data_len);
} else if (p->payload_len > 0) {
fprintf(aft->file_ctx->fp, "ALERT FOUND IN [%02d]: %s\n", i,
pa->flags & PACKET_ALERT_FLAG_STREAM_MATCH ? "STREAM" :
(pa->flags & PACKET_ALERT_FLAG_STATE_MATCH ? "STATE" : "PACKET"));
if (p->payload_len > 0) {
fprintf(aft->file_ctx->fp, "PAYLOAD LEN: %" PRIu32 "\n", p->payload_len);
fprintf(aft->file_ctx->fp, "PAYLOAD:\n");
PrintRawDataFp(aft->file_ctx->fp, p->payload, p->payload_len);
}
if (pa->flags & PACKET_ALERT_FLAG_STATE_MATCH) {
/* This is an app layer alert */
if (pa->flags & PACKET_ALERT_FLAG_STATE_MATCH ||
pa->flags & PACKET_ALERT_FLAG_STREAM_MATCH) {
/* This is an app layer or stream alert */
int ret;
uint8_t flag;
if ((! PKT_IS_TCP(p)) || p->flow == NULL ||

@ -106,8 +106,8 @@ TmEcode AlertPcapInfo (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, P
PacketAlert *pa = &p->alerts.alerts[i];
fprintf(aft->file_ctx->fp, "%" PRIu64 ":%" PRIu32 ":%" PRIu32 ":%d:%d:%d:%d:0:0:%s\n",
p->pcap_cnt, pa->s->gid, pa->s->id,
pa->s->rev, pa->alert_msg ? 1 : 0,
p->pcap_cnt, pa->s->gid, pa->s->id, pa->s->rev,
pa->flags & (PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_STREAM_MATCH) ? 1 : 0,
p->flowflags & FLOW_PKT_TOSERVER ? 1 : 0,
p->flowflags & FLOW_PKT_TOCLIENT ? 1 : 0,
pa->s->msg);

@ -171,7 +171,7 @@ TmEcode Unified2AlertThreadInit(ThreadVars *, void *, void **);
TmEcode Unified2AlertThreadDeinit(ThreadVars *, void *);
int Unified2IPv4TypeAlert(ThreadVars *, Packet *, void *, PacketQueue *);
int Unified2IPv6TypeAlert(ThreadVars *, Packet *, void *, PacketQueue *);
int Unified2PacketTypeAlert(Unified2AlertThread *, Packet *, void *, uint32_t, int);
int Unified2PacketTypeAlert(Unified2AlertThread *, Packet *, uint32_t, int);
void Unified2RegisterTests();
int Unified2AlertOpenFileCtx(LogFileCtx *, const char *);
static void Unified2AlertDeInitCtx(OutputCtx *);
@ -334,205 +334,6 @@ static int Unified2ForgeFakeIPv6Header(FakeIPv6Hdr *fakehdr, Packet *p, int pkt_
return 1;
}
/**
* \brief Log the stream chunk that we alerted on. We construct a
* fake ipv4 and tcp header to make sure the packet length
* is correct.
*
* No need to lock here, since it's already locked
*
* \param aun thread local data
* \param p Packet
* \param stream pointer to the stream msg to log
*
* \retval 0 on succces
* \retval -1 on failure
*
* \todo We can consolidate the first 3 memcpy's into a single copy if
* we create a struct containing the 3 separate structures we copy
* into the buffer now.
* \todo We could even have union of the headers with the write buffers
*/
static int Unified2StreamTypeAlertIPv4 (Unified2AlertThread *aun,
Packet *p, void *stream,
uint32_t event_id)
{
struct {
IPV4Hdr ip4h;
TCPHdr tcph;
} fakehdr;
EthernetHdr ethhdr = { {0,0,0,0,0,0}, {0,0,0,0,0,0}, htons(ETHERNET_TYPE_IP) };
int eth_offset = 0;
Unified2Packet phdr;
Unified2AlertFileHeader hdr;
int ret;
uint32_t pkt_len;
aun->length += (sizeof(Unified2AlertFileHeader) + UNIFIED2_PACKET_SIZE);
memset(&fakehdr, 0x00, sizeof(fakehdr));
memset(aun->data + aun->offset, 0x00, aun->datalen - aun->offset);
memset(&hdr, 0, sizeof(Unified2AlertFileHeader));
memset(&phdr, 0, sizeof(Unified2Packet));
StreamMsg *stream_msg = (StreamMsg *)stream;
pkt_len = sizeof(fakehdr) + stream_msg->data.data_len;
if (pkt_len > USHRT_MAX) {
SCLogError(SC_ERR_INVALID_VALUE, "fake pkt is too big for IP data: "
"%"PRIu32" vs %"PRIu16, pkt_len, USHRT_MAX);
return -1;
}
fakehdr.ip4h.ip_verhl = p->ip4h->ip_verhl;
fakehdr.ip4h.ip_proto = p->ip4h->ip_proto;
fakehdr.ip4h.s_ip_src.s_addr = p->ip4h->s_ip_src.s_addr;
fakehdr.ip4h.s_ip_dst.s_addr = p->ip4h->s_ip_dst.s_addr;
fakehdr.ip4h.ip_len = htons((uint16_t)pkt_len);
fakehdr.tcph.th_sport = p->tcph->th_sport;
fakehdr.tcph.th_dport = p->tcph->th_dport;
fakehdr.tcph.th_offx2 = 0x50; /* just the TCP header, no options */
if (p->datalink == DLT_EN10MB) {
eth_offset = 14;
phdr.linktype = htonl(DLT_EN10MB);
} else {
phdr.linktype = htonl(DLT_RAW);
}
aun->length += (int)pkt_len + eth_offset;
if (aun->length > aun->datalen) {
SCLogError(SC_ERR_INVALID_VALUE, "len is too big for thread data: %d vs %d",
aun->length, aun->datalen);
return -1;
}
hdr.type = htonl(UNIFIED2_PACKET_TYPE);
hdr.length = htonl(UNIFIED2_PACKET_SIZE + pkt_len + eth_offset);
phdr.sensor_id = 0;
phdr.event_id = event_id;
phdr.event_second = phdr.packet_second = htonl(p->ts.tv_sec);
phdr.packet_microsecond = htonl(p->ts.tv_usec);
phdr.packet_length = htonl(pkt_len + eth_offset);
memcpy(aun->data + aun->offset, &hdr, sizeof(Unified2AlertFileHeader));
memcpy(aun->data + aun->offset + sizeof(Unified2AlertFileHeader),
&phdr, UNIFIED2_PACKET_SIZE);
if (p->datalink == DLT_EN10MB) {
memcpy(aun->data + aun->offset + sizeof(Unified2AlertFileHeader) + UNIFIED2_PACKET_SIZE,
&ethhdr, eth_offset);
}
memcpy(aun->data + aun->offset + sizeof(Unified2AlertFileHeader) + UNIFIED2_PACKET_SIZE + eth_offset,
&fakehdr, sizeof(fakehdr));
memcpy(aun->data + aun->offset + sizeof(Unified2AlertFileHeader) + UNIFIED2_PACKET_SIZE + sizeof(fakehdr) + eth_offset,
stream_msg->data.data, stream_msg->data.data_len);
ret = Unified2Write(aun);
if (ret != 1) {
return -1;
}
return 1;
}
/**
* \brief Log the stream chunk that we alerted on. We construct a
* fake ipv6 and tcp header to make sure the packet length
* is correct.
*
* We create a ETHERNET header here because baryard2 doesn't seem
* to like IPv6 packets on DLT_RAW.
*
* No need to lock here, since it's already locked
*
* \param aun thread local data
* \param p Packet
* \param stream pointer to the stream msg to log
*
* \retval 0 on succces
* \retval -1 on failure
*
* \todo We can consolidate the first 3 memcpy's into a single copy if
* we create a struct containing the 3 separate structures we copy
* into the buffer now.
* \todo We could even have union of the headers with the write buffers
*/
static int Unified2StreamTypeAlertIPv6 (Unified2AlertThread *aun,
Packet *p, void *stream,
uint32_t event_id)
{
struct fakehdr_ {
EthernetHdr ethh;
IPV6Hdr ip6h;
TCPHdr tcph;
} __attribute__((__packed__));
struct fakehdr_ fakehdr;
Unified2Packet phdr;
Unified2AlertFileHeader hdr;
int ret;
aun->length += (sizeof(Unified2AlertFileHeader) + UNIFIED2_PACKET_SIZE);
memset(&fakehdr, 0x00, sizeof(fakehdr));
memset(aun->data + aun->offset, 0x00, aun->datalen - aun->offset);
memset(&hdr, 0, sizeof(Unified2AlertFileHeader));
memset(&phdr, 0, sizeof(Unified2Packet));
StreamMsg *stream_msg = (StreamMsg *)stream;
fakehdr.ethh.eth_type = htons(ETHERNET_TYPE_IPV6);
if (p->ethh != NULL) {
memcpy(&fakehdr.ethh.eth_src, p->ethh->eth_src, 6);
memcpy(&fakehdr.ethh.eth_dst, p->ethh->eth_dst, 6);
}
fakehdr.ip6h.s_ip6_vfc = p->ip6h->s_ip6_vfc;
fakehdr.ip6h.s_ip6_nxt = IPPROTO_TCP;
fakehdr.ip6h.s_ip6_plen = htons(sizeof(TCPHdr) + stream_msg->data.data_len);
memcpy(&fakehdr.ip6h.s_ip6_addrs, p->ip6h->s_ip6_addrs, 32);
fakehdr.tcph.th_sport = p->tcph->th_sport;
fakehdr.tcph.th_dport = p->tcph->th_dport;
fakehdr.tcph.th_offx2 = 0x50; /* just the TCP header, no options */
aun->length += (sizeof(fakehdr) + stream_msg->data.data_len);
if (aun->length > aun->datalen) {
SCLogError(SC_ERR_INVALID_VALUE, "len is too big for thread data: %d vs %d",
aun->length, aun->datalen);
return -1;
}
hdr.type = htonl(UNIFIED2_PACKET_TYPE);
hdr.length = htonl(UNIFIED2_PACKET_SIZE + (sizeof(fakehdr) + stream_msg->data.data_len));
phdr.sensor_id = 0;
phdr.linktype = htonl(DLT_EN10MB);
phdr.event_id = event_id;
phdr.event_second = phdr.packet_second = htonl(p->ts.tv_sec);
phdr.packet_microsecond = htonl(p->ts.tv_usec);
phdr.packet_length = htonl(sizeof(fakehdr) + stream_msg->data.data_len);
memcpy(aun->data + aun->offset, &hdr, sizeof(Unified2AlertFileHeader));
memcpy(aun->data + aun->offset + sizeof(Unified2AlertFileHeader),
&phdr, UNIFIED2_PACKET_SIZE);
memcpy(aun->data + aun->offset + sizeof(Unified2AlertFileHeader) + UNIFIED2_PACKET_SIZE,
&fakehdr, sizeof(fakehdr));
memcpy(aun->data + aun->offset + sizeof(Unified2AlertFileHeader) + UNIFIED2_PACKET_SIZE + sizeof(fakehdr),
stream_msg->data.data, stream_msg->data.data_len);
ret = Unified2Write(aun);
if (ret != 1) {
return -1;
}
return 1;
}
/**
* \brief Write a faked Packet in unified2 file for each stream segment.
*/
@ -612,18 +413,8 @@ static int Unified2PrintStreamSegmentCallback(Packet *p, void *data, uint8_t *bu
* \retval 0 on succces
* \retval -1 on failure
*/
int Unified2PacketTypeAlert (Unified2AlertThread *aun, Packet *p, void *stream, uint32_t event_id, int state)
int Unified2PacketTypeAlert (Unified2AlertThread *aun, Packet *p, uint32_t event_id, int state)
{
if (PKT_IS_TCP(p) && stream != NULL) {
SCLogDebug("reassembled stream logging");
if (PKT_IS_IPV4(p)) {
return Unified2StreamTypeAlertIPv4(aun, p, stream, event_id);
} else if (PKT_IS_IPV6(p)) {
return Unified2StreamTypeAlertIPv6(aun, p, stream, event_id);
}
}
Unified2AlertFileHeader *hdr = (Unified2AlertFileHeader*)(aun->data + aun->offset);
Unified2Packet *phdr = (Unified2Packet *)(hdr + 1);
int ret = 0;
@ -917,7 +708,7 @@ int Unified2IPv6TypeAlert (ThreadVars *t, Packet *p, void *data, PacketQueue *pq
aun->length = 0;
aun->offset = 0;
ret = Unified2PacketTypeAlert(aun, p, pa->alert_msg, phdr->event_id, pa->flags & PACKET_ALERT_FLAG_STATE_MATCH ? 1 : 0);
ret = Unified2PacketTypeAlert(aun, p, phdr->event_id, pa->flags & (PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_STREAM_MATCH) ? 1 : 0);
if (ret != 1) {
SCLogError(SC_ERR_FWRITE, "Error: fwrite failed: %s", strerror(errno));
aun->file_ctx->alerts += i;
@ -1056,7 +847,7 @@ int Unified2IPv4TypeAlert (ThreadVars *tv, Packet *p, void *data, PacketQueue *p
/* Write the alert (it doesn't lock inside, since we
* already locked here for rotation check)
*/
ret = Unified2PacketTypeAlert(aun, p, pa->alert_msg, event_id, pa->flags & PACKET_ALERT_FLAG_STATE_MATCH ? 1 : 0);
ret = Unified2PacketTypeAlert(aun, p, event_id, pa->flags & (PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_STREAM_MATCH) ? 1 : 0);
if (ret != 1) {
SCLogError(SC_ERR_FWRITE, "Error: PacketTypeAlert writing failed");
aun->file_ctx->alerts += i;

@ -232,32 +232,23 @@ typedef struct PacketAlert_ {
SigIntId order_id; /* Internal num, used for sorting */
uint8_t action; /* Internal num, used for sorting */
uint8_t flags;
/** Pointer to stream message this signature matched on, or
* NULL if the sig didn't match on a smsg */
void *alert_msg;
struct Signature_ *s;
} 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
/** Signature matched (partly) in the state. Used in unified logger to
* know if it needs to log the stream or the packet. */
#define PACKET_ALERT_FLAG_STATE_MATCH 0x02
#define PACKET_ALERT_FLAG_DROP_FLOW 0x01
/** alert was generated based on state */
#define PACKET_ALERT_FLAG_STATE_MATCH 0x02
/** alert was generated based on stream */
#define PACKET_ALERT_FLAG_STREAM_MATCH 0x04
#define PACKET_ALERT_MAX 15
typedef struct PacketAlerts_ {
uint16_t cnt;
PacketAlert alerts[PACKET_ALERT_MAX];
/** pointer to (list of) stream message(s)
* that one or more of the signatures
* matched on */
void *alert_msgs;
} PacketAlerts;
/** number of decoder events we support per packet. Power of 2 minus 1
@ -380,7 +371,6 @@ typedef struct Packet_
IPFWPacketVars ipfw_v;
#endif /* IPFW */
/** libpcap vars: shared by Pcap Live mode and Pcap File mode */
PcapPacketVars pcap_v;
};

@ -147,7 +147,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, void *alert_msg)
int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, uint8_t flags)
{
int i = 0;
@ -164,7 +164,6 @@ int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, u
p->alerts.alerts[p->alerts.cnt].order_id = s->order_id;
p->alerts.alerts[p->alerts.cnt].action = s->action;
p->alerts.alerts[p->alerts.cnt].flags = flags;
p->alerts.alerts[p->alerts.cnt].alert_msg = alert_msg;
p->alerts.alerts[p->alerts.cnt].s = s;
} else {
/* We need to make room for this s->num
@ -179,7 +178,6 @@ int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, u
p->alerts.alerts[i].order_id = s->order_id;
p->alerts.alerts[i].action = s->action;
p->alerts.alerts[i].flags = flags;
p->alerts.alerts[i].alert_msg = alert_msg;
p->alerts.alerts[i].s = s;
}

@ -29,7 +29,7 @@
#include "detect.h"
void PacketAlertFinalize(DetectEngineCtx *, DetectEngineThreadCtx *, Packet *);
int PacketAlertAppend(DetectEngineThreadCtx *, Signature *, Packet *, uint8_t, /* (StreamMsg *) */void *);
int PacketAlertAppend(DetectEngineThreadCtx *, Signature *, Packet *, uint8_t);
int PacketAlertCheck(Packet *, uint32_t);
int PacketAlertRemove(Packet *, uint16_t);
void PacketAlertTagInit(void);

@ -1068,9 +1068,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, NULL);
PacketAlertAppend(det_ctx, s, p, PACKET_ALERT_FLAG_DROP_FLOW);
else
PacketAlertAppend(det_ctx, s, p, 0, NULL);
PacketAlertAppend(det_ctx, s, p, 0);
}
}
}

@ -1478,7 +1478,6 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
PACKET_PROFILING_DETECT_START(p, PROF_DETECT_RULES);
/* inspect the sigs against the packet */
for (idx = 0; idx < det_ctx->match_array_cnt; idx++) {
StreamMsg *alert_msg = NULL;
RULE_PROFILING_START;
s = det_ctx->match_array[idx];
@ -1572,12 +1571,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
if (s->action & ACTION_DROP)
alert_flags |= PACKET_ALERT_FLAG_DROP_FLOW;
/* store ptr to current smsg */
if (alert_msg == NULL) {
alert_msg = smsg_inspect;
p->alerts.alert_msgs = smsg;
}
alert_flags |= PACKET_ALERT_FLAG_STREAM_MATCH;
break;
}
}
@ -1687,7 +1681,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
SigMatchSignaturesRunPostMatch(th_v, de_ctx, det_ctx, p, s);
if (!(s->flags & SIG_FLAG_NOALERT)) {
PacketAlertAppend(det_ctx, s, p, alert_flags, alert_msg);
PacketAlertAppend(det_ctx, s, p, alert_flags);
}
next:
DetectReplaceFree(det_ctx->replist);
@ -1782,10 +1776,7 @@ end:
/* if we had no alerts that involved the smsgs,
* we can get rid of them now. */
if (p->alerts.alert_msgs == NULL) {
/* if we have (a) smsg(s), return to the pool */
StreamMsgReturnListToPool(smsg);
}
StreamMsgReturnListToPool(smsg);
FLOWLOCK_UNLOCK(p->flow);

@ -130,11 +130,6 @@ void TmqhOutputPacketpool(ThreadVars *t, Packet *p)
SCEnter();
SCLogDebug("Packet %p, p->root %p, alloced %s", p, p->root, p->flags & PKT_ALLOC ? "true" : "false");
/* final alerts cleanup... return smsgs to pool if needed */
if (p->alerts.alert_msgs != NULL) {
StreamMsgReturnListToPool(p->alerts.alert_msgs);
p->alerts.alert_msgs = NULL;
}
/** \todo make this a callback
* Release tcp segments. Done here after alerting can use them. */
if (p->flow != NULL && p->proto == IPPROTO_TCP) {

Loading…
Cancel
Save