From: Victor Julien Date: Mon, 21 May 2012 11:54:45 +0000 (+0200) Subject: No longer pass StreamMsg to output for alert logging, instead use the same callback... X-Git-Tag: suricata-1.3beta2~39 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ea0d172693da41c606f19f3aad33c88fef744a04;p=thirdparty%2Fsuricata.git No longer pass StreamMsg to output for alert logging, instead use the same callback code as is used for state alerts. --- diff --git a/src/alert-debuglog.c b/src/alert-debuglog.c index b79f88e882..c273c446b1 100644 --- a/src/alert-debuglog.c +++ b/src/alert-debuglog.c @@ -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 : ""); 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 || diff --git a/src/alert-pcapinfo.c b/src/alert-pcapinfo.c index 8c1e97a1f9..8e5700338e 100644 --- a/src/alert-pcapinfo.c +++ b/src/alert-pcapinfo.c @@ -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); diff --git a/src/alert-unified2-alert.c b/src/alert-unified2-alert.c index 7850a4b0fe..b23dde5a41 100644 --- a/src/alert-unified2-alert.c +++ b/src/alert-unified2-alert.c @@ -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, - ðhdr, 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; diff --git a/src/decode.h b/src/decode.h index 274c1391e3..553a254341 100644 --- a/src/decode.h +++ b/src/decode.h @@ -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; }; diff --git a/src/detect-engine-alert.c b/src/detect-engine-alert.c index 88be52abc2..0b2f78f426 100644 --- a/src/detect-engine-alert.c +++ b/src/detect-engine-alert.c @@ -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; } diff --git a/src/detect-engine-alert.h b/src/detect-engine-alert.h index bd296d6876..8bff764dd4 100644 --- a/src/detect-engine-alert.h +++ b/src/detect-engine-alert.h @@ -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); diff --git a/src/detect-engine-iponly.c b/src/detect-engine-iponly.c index 7b9af5acca..2f637cb189 100644 --- a/src/detect-engine-iponly.c +++ b/src/detect-engine-iponly.c @@ -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); } } } diff --git a/src/detect.c b/src/detect.c index 4228536795..3c109f7b52 100644 --- a/src/detect.c +++ b/src/detect.c @@ -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); diff --git a/src/tmqh-packetpool.c b/src/tmqh-packetpool.c index 3a9702e374..01422d3957 100644 --- a/src/tmqh-packetpool.c +++ b/src/tmqh-packetpool.c @@ -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) {