diff --git a/src/alert-debuglog.c b/src/alert-debuglog.c index 9f802fd5cd..7367c4b758 100644 --- a/src/alert-debuglog.c +++ b/src/alert-debuglog.c @@ -30,6 +30,7 @@ #include "detect.h" #include "flow.h" #include "conf.h" +#include "stream.h" #include "threads.h" #include "threadvars.h" @@ -181,18 +182,6 @@ TmEcode AlertDebugLogIPv4(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq if (p->pcap_cnt > 0) { fprintf(aft->file_ctx->fp, "PCAP PKT NUM: %"PRIu64"\n", p->pcap_cnt); } - fprintf(aft->file_ctx->fp, "ALERT CNT: %" PRIu32 "\n", p->alerts.cnt); - - for (i = 0; i < p->alerts.cnt; i++) { - PacketAlert *pa = &p->alerts.alerts[i]; - - fprintf(aft->file_ctx->fp, "ALERT MSG [%02d]: %s\n", i, pa->msg); - fprintf(aft->file_ctx->fp, "ALERT GID [%02d]: %" PRIu32 "\n", i, pa->gid); - fprintf(aft->file_ctx->fp, "ALERT SID [%02d]: %" PRIu32 "\n", i, pa->sid); - fprintf(aft->file_ctx->fp, "ALERT REV [%02d]: %" PRIu32 "\n", i, pa->rev); - fprintf(aft->file_ctx->fp, "ALERT CLASS [%02d]: %s\n", i, pa->class_msg); - fprintf(aft->file_ctx->fp, "ALERT PRIO [%02d]: %" PRIu32 "\n", i, pa->prio); - } char srcip[16], dstip[16]; inet_ntop(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); @@ -223,17 +212,17 @@ TmEcode AlertDebugLogIPv4(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq fprintf(aft->file_ctx->fp, "FLOW PKTS TOSRC: %"PRIu32"\n",p->flow->tosrcpktcnt); fprintf(aft->file_ctx->fp, "FLOW Total Bytes: %"PRIu64"\n",p->flow->bytecnt); fprintf(aft->file_ctx->fp, "FLOW IPONLY SET: TOSERVER: %s, TOCLIENT: %s\n", - p->flow->flags & FLOW_TOSERVER_IPONLY_SET ? "TRUE" : "FALSE", - p->flow->flags & FLOW_TOCLIENT_IPONLY_SET ? "TRUE" : "FALSE"); + p->flow->flags & FLOW_TOSERVER_IPONLY_SET ? "TRUE" : "FALSE", + p->flow->flags & FLOW_TOCLIENT_IPONLY_SET ? "TRUE" : "FALSE"); fprintf(aft->file_ctx->fp, "FLOW ACTION: DROP: %s, PASS %s\n", - p->flow->flags & FLOW_ACTION_DROP ? "TRUE" : "FALSE", - p->flow->flags & FLOW_ACTION_PASS ? "TRUE" : "FALSE"); + p->flow->flags & FLOW_ACTION_DROP ? "TRUE" : "FALSE", + p->flow->flags & FLOW_ACTION_PASS ? "TRUE" : "FALSE"); fprintf(aft->file_ctx->fp, "FLOW NOINSPECTION: PACKET: %s, PAYLOAD: %s, APP_LAYER: %s\n", - p->flow->flags & FLOW_NOPACKET_INSPECTION ? "TRUE" : "FALSE", - p->flow->flags & FLOW_NOPAYLOAD_INSPECTION ? "TRUE" : "FALSE", - p->flow->alflags & FLOW_AL_NO_APPLAYER_INSPECTION ? "TRUE" : "FALSE"); + p->flow->flags & FLOW_NOPACKET_INSPECTION ? "TRUE" : "FALSE", + p->flow->flags & FLOW_NOPAYLOAD_INSPECTION ? "TRUE" : "FALSE", + p->flow->alflags & FLOW_AL_NO_APPLAYER_INSPECTION ? "TRUE" : "FALSE"); fprintf(aft->file_ctx->fp, "FLOW APP_LAYER: DETECTED: %s, PROTO %"PRIu16"\n", - p->flow->alflags & FLOW_AL_PROTO_DETECT_DONE ? "TRUE" : "FALSE", p->flow->alproto); + p->flow->alflags & FLOW_AL_PROTO_DETECT_DONE ? "TRUE" : "FALSE", p->flow->alproto); AlertDebugLogFlowVars(aft, p); AlertDebugLogFlowBits(aft, p); SCMutexUnlock(&p->flow->m); @@ -244,12 +233,36 @@ TmEcode AlertDebugLogIPv4(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq /* any stuff */ /* Sig details? */ - aft->file_ctx->alerts += p->alerts.cnt; - fprintf(aft->file_ctx->fp, "PACKET LEN: %" PRIu32 "\n", GET_PKT_LEN(p)); fprintf(aft->file_ctx->fp, "PACKET:\n"); PrintRawDataFp(aft->file_ctx->fp, GET_PKT_DATA(p), GET_PKT_LEN(p)); + fprintf(aft->file_ctx->fp, "ALERT CNT: %" PRIu32 "\n", p->alerts.cnt); + + for (i = 0; i < p->alerts.cnt; i++) { + PacketAlert *pa = &p->alerts.alerts[i]; + + fprintf(aft->file_ctx->fp, "ALERT MSG [%02d]: %s\n", i, pa->msg); + fprintf(aft->file_ctx->fp, "ALERT GID [%02d]: %" PRIu32 "\n", i, pa->gid); + fprintf(aft->file_ctx->fp, "ALERT SID [%02d]: %" PRIu32 "\n", i, pa->sid); + fprintf(aft->file_ctx->fp, "ALERT REV [%02d]: %" PRIu32 "\n", i, pa->rev); + fprintf(aft->file_ctx->fp, "ALERT CLASS [%02d]: %s\n", i, pa->class_msg ? pa->class_msg : ""); + fprintf(aft->file_ctx->fp, "ALERT PRIO [%02d]: %" PRIu32 "\n", i, pa->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, "PAYLOAD LEN: %" PRIu32 "\n", p->payload_len); + fprintf(aft->file_ctx->fp, "PAYLOAD:\n"); + PrintRawDataFp(aft->file_ctx->fp, p->payload, p->payload_len); + } + } + + aft->file_ctx->alerts += p->alerts.cnt; + fflush(aft->file_ctx->fp); SCMutexUnlock(&aft->file_ctx->fp_mutex); diff --git a/src/decode.h b/src/decode.h index 2104365d8d..84ff6bd9d4 100644 --- a/src/decode.h +++ b/src/decode.h @@ -226,6 +226,10 @@ typedef struct PacketAlert_ { char *class_msg; DetectReference *references; uint8_t flags; + + /** Pointer to smsg this signature matched on, or + * NULL if the sig didn't match on a smsg */ + void *alert_msg; } PacketAlert; /* After processing an alert by the thresholding module, if at @@ -238,6 +242,11 @@ typedef struct PacketAlert_ { 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 diff --git a/src/detect-engine-alert.c b/src/detect-engine-alert.c index 7379f5cf5a..d0a1329dbc 100644 --- a/src/detect-engine-alert.c +++ b/src/detect-engine-alert.c @@ -35,7 +35,7 @@ * \param p Packet structure * */ -int PacketAlertHandle(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, +static int PacketAlertHandle(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, uint16_t pos) { SCEnter(); @@ -110,7 +110,15 @@ int PacketAlertRemove(Packet *p, uint16_t pos) return match; } -int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, uint8_t flags) +/** \brief append a signature match to a packet + * + * \param det_ctx thread detection engine ctx + * \param s the signature that matched + * \param p packet + * \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 i = 0; @@ -139,6 +147,7 @@ int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, u p->alerts.alerts[p->alerts.cnt].class_msg = s->class_msg; p->alerts.alerts[p->alerts.cnt].references = s->references; p->alerts.alerts[p->alerts.cnt].flags = flags; + p->alerts.alerts[p->alerts.cnt].alert_msg = alert_msg; } else { /* We need to make room for this s->num (a bit ugly with mamcpy but we are planning changes here)*/ @@ -164,6 +173,7 @@ int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, u p->alerts.alerts[i].class_msg = s->class_msg; p->alerts.alerts[i].references = s->references; p->alerts.alerts[i].flags = flags; + p->alerts.alerts[i].alert_msg = alert_msg; } /* Update the count */ diff --git a/src/detect-engine-alert.h b/src/detect-engine-alert.h index eb3d4c71c1..a1b80894dc 100644 --- a/src/detect-engine-alert.h +++ b/src/detect-engine-alert.h @@ -28,7 +28,7 @@ #include "detect.h" void PacketAlertFinalize(DetectEngineCtx *, DetectEngineThreadCtx *, Packet *); -int PacketAlertAppend(DetectEngineThreadCtx *, Signature *, Packet *, uint8_t); +int PacketAlertAppend(DetectEngineThreadCtx *, Signature *, Packet *, uint8_t, /* (StreamMsg *) */void *); int PacketAlertAppendTag(Packet *, PacketAlert *); int PacketAlertCheck(Packet *, uint32_t); int PacketAlertRemove(Packet *, uint16_t); diff --git a/src/detect-engine-iponly.c b/src/detect-engine-iponly.c index acd4a8c8ec..8fad7159e2 100644 --- a/src/detect-engine-iponly.c +++ b/src/detect-engine-iponly.c @@ -1004,9 +1004,9 @@ void IPOnlyMatchPacket(DetectEngineCtx *de_ctx, if ( !(s->flags & SIG_FLAG_NOALERT)) { if (s->action & ACTION_DROP) - PacketAlertAppend(det_ctx, s, p, PACKET_ALERT_FLAG_DROP_FLOW); + PacketAlertAppend(det_ctx, s, p, PACKET_ALERT_FLAG_DROP_FLOW, NULL); else - PacketAlertAppend(det_ctx, s, p, 0); + PacketAlertAppend(det_ctx, s, p, 0, NULL); } } } diff --git a/src/detect-engine-threshold.h b/src/detect-engine-threshold.h index 777993918e..679f8b95be 100644 --- a/src/detect-engine-threshold.h +++ b/src/detect-engine-threshold.h @@ -29,8 +29,6 @@ #define THRESHOLD_HASH_SIZE 0xffff -int PacketAlertHandle(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *, - Signature *sig, Packet *p, uint16_t); DetectThresholdData *SigGetThresholdType(Signature *, Packet *); int PacketAlertThreshold(DetectEngineCtx *, DetectEngineThreadCtx *, DetectThresholdData *, Packet *, Signature *); diff --git a/src/detect.c b/src/detect.c index 7f1afbf3e9..0d24096502 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1244,6 +1244,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh /* inspect the sigs against the packet */ for (idx = 0; idx < det_ctx->match_array_cnt; idx++) { + StreamMsg *alert_msg = NULL; PROFILING_START; s = det_ctx->match_array[idx]; @@ -1345,6 +1346,13 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh * rest of the pkts with no further inspection */ 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; + } + break; } } @@ -1378,6 +1386,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh if (DetectEngineInspectPacketPayload(de_ctx, det_ctx, s, p->flow, flags, alstate, p) != 1) { goto next; } + } else { if (DetectEngineInspectPacketPayload(de_ctx, det_ctx, s, p->flow, flags, alstate, p) != 1) goto next; @@ -1425,7 +1434,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh fmatch = 1; if (!(s->flags & SIG_FLAG_NOALERT)) { - PacketAlertAppend(det_ctx, s, p, alert_flags); + PacketAlertAppend(det_ctx, s, p, alert_flags, NULL); } } else { if (s->flags & SIG_FLAG_RECURSIVE) { @@ -1445,7 +1454,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh if (!(s->flags & SIG_FLAG_NOALERT)) { /* only add once */ if (rmatch == 0) { - PacketAlertAppend(det_ctx, s, p, alert_flags); + PacketAlertAppend(det_ctx, s, p, alert_flags, alert_msg); } } rmatch = fmatch = 1; @@ -1478,7 +1487,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh if (sm == NULL) { fmatch = 1; if (!(s->flags & SIG_FLAG_NOALERT)) { - PacketAlertAppend(det_ctx, s, p, alert_flags); + PacketAlertAppend(det_ctx, s, p, alert_flags, alert_msg); } } } else { @@ -1546,16 +1555,13 @@ end: } } - /* if we have (a) smsg(s), return to the pool */ - while (smsg != NULL) { - StreamMsg *smsg_next = smsg->next; - SCLogDebug("returning smsg %p to pool", smsg); - smsg->next = NULL; - smsg->prev = NULL; - smsg->flow = NULL; - StreamMsgReturnToPool(smsg); - smsg = smsg_next; + /* 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); } + SCMutexUnlock(&p->flow->m); FlowDecrUsecnt(p->flow); diff --git a/src/stream.c b/src/stream.c index c0967cef39..4aff699076 100644 --- a/src/stream.c +++ b/src/stream.c @@ -223,3 +223,17 @@ uint16_t StreamMsgQueueGetMinChunkLen(uint8_t dir) { } } +/** \brief Return a list of smsgs to the pool */ +void StreamMsgReturnListToPool(void *list) { + /* if we have (a) smsg(s), return to the pool */ + StreamMsg *smsg = (StreamMsg *)list; + while (smsg != NULL) { + StreamMsg *smsg_next = smsg->next; + SCLogDebug("returning smsg %p to pool", smsg); + smsg->next = NULL; + smsg->prev = NULL; + smsg->flow = NULL; + StreamMsgReturnToPool(smsg); + smsg = smsg_next; + } +} diff --git a/src/stream.h b/src/stream.h index 0ca2bab1a8..3e9e177a50 100644 --- a/src/stream.h +++ b/src/stream.h @@ -87,5 +87,7 @@ void StreamMsgQueueSetMinChunkLen(uint8_t dir, uint16_t len); uint16_t StreamMsgQueueGetMinInitChunkLen(uint8_t); uint16_t StreamMsgQueueGetMinChunkLen(uint8_t); +void StreamMsgReturnListToPool(void *); + #endif /* __STREAM_H__ */ diff --git a/src/tmqh-packetpool.c b/src/tmqh-packetpool.c index efb6b3c475..a90356bc05 100644 --- a/src/tmqh-packetpool.c +++ b/src/tmqh-packetpool.c @@ -37,6 +37,8 @@ #include "threadvars.h" #include "flow.h" +#include "stream.h" + #include "tm-queuehandlers.h" #include "pkt-var.h" @@ -127,6 +129,12 @@ void TmqhOutputPacketpool(ThreadVars *t, Packet *p) char proot = 0; + /* 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; + } + if (IS_TUNNEL_PKT(p)) { SCLogDebug("Packet %p is a tunnel packet: %s", p,p->root ? "upper layer" : "tunnel root");