}
}
+/** \brief Get the decoder events from the flow
+ * \param f flow pointer to a LOCKED flow
+ * \param tx_id transaction id
+ * \retval files void pointer to the state
+ * \retval NULL in case we have no state */
+AppLayerDecoderEvents *AppLayerGetEventsFromFlowByTx(Flow *f, uint64_t tx_id) {
+ SCEnter();
+
+ DEBUG_ASSERT_FLOW_LOCKED(f);
+
+ uint16_t alproto = f->alproto;
+ if (alproto == ALPROTO_UNKNOWN)
+ SCReturnPtr(NULL, "AppLayerDecoderEvents");
+
+ if (al_proto_table[alproto].StateGetEvents != NULL) {
+ AppLayerDecoderEvents *ptr = al_proto_table[alproto].StateGetEvents(AppLayerGetProtoStateFromFlow(f), tx_id);
+ SCReturnPtr(ptr, "AppLayerDecoderEvents");
+ } else {
+ SCReturnPtr(NULL, "AppLayerDecoderEvents");
+ }
+}
+
+/** \brief check if we have decoder events */
+int AppLayerFlowHasDecoderEvents(Flow *f, uint8_t flags) {
+ AppLayerDecoderEvents *decoder_events;
+ uint64_t tx_id, max_id;
+
+ DEBUG_ASSERT_FLOW_LOCKED(f);
+
+ if (f->alproto <= ALPROTO_UNKNOWN || f->alproto >= ALPROTO_MAX)
+ return 0;
+
+ if (AppLayerProtoIsTxEventAware(f->alproto)) {
+ tx_id = AppLayerTransactionGetInspectId(f, flags);
+ max_id = AppLayerGetTxCnt(f->alproto, f->alstate);
+
+ for ( ; tx_id < max_id; tx_id++) {
+ decoder_events = AppLayerGetEventsFromFlowByTx(f, tx_id);
+ if (decoder_events && decoder_events->cnt)
+ return 1;
+ }
+ }
+
+ decoder_events = AppLayerGetDecoderEventsForFlow(f);
+ if (decoder_events && decoder_events->cnt)
+ return 1;
+
+ return 0;
+}
+
+/** \brief Return true if alproto uses per TX events
+ * \param alproto proto to check
+ */
+int AppLayerProtoIsTxEventAware(uint16_t alproto) {
+ if (alproto > ALPROTO_UNKNOWN && alproto < ALPROTO_MAX &&
+ al_proto_table[alproto].StateGetEvents != NULL)
+ return 1;
+
+ return 0;
+}
+
/** \brief Alloc a AppLayerParserResultElmt func for the pool */
static void *AlpResultElmtPoolAlloc()
{
StateGetAlstateProgressCompletionStatus;
}
+void AppLayerRegisterGetEventsFunc(uint16_t proto,
+ AppLayerDecoderEvents *(*StateGetEvents)(void *, uint64_t))
+{
+ al_proto_table[proto].StateGetEvents = StateGetEvents;
+}
+
/** \brief Indicate to the app layer parser that a logger is active
* for this protocol.
*/
/** truncate state after a gap/depth event */
void (*Truncate)(void *, uint8_t);
FileContainer *(*StateGetFiles)(void *, uint8_t);
+ AppLayerDecoderEvents *(*StateGetEvents)(void *, uint64_t);
int (*StateGetAlstateProgress)(void *alstate, uint8_t direction);
uint64_t (*StateGetTxCnt)(void *alstate);
void *AppLayerGetProtocolParserLocalStorage(uint16_t);
void AppLayerRegisterGetFilesFunc(uint16_t proto,
FileContainer *(*StateGetFile)(void *, uint8_t));
+void AppLayerRegisterGetEventsFunc(uint16_t proto,
+ AppLayerDecoderEvents *(*StateGetEvents)(void *, uint64_t));
void AppLayerRegisterLogger(uint16_t proto);
uint16_t AppLayerGetProtoByName(const char *);
const char *AppLayerGetProtoString(int proto);
void AppLayerListSupportedProtocols(void);
AppLayerDecoderEvents *AppLayerGetDecoderEventsForFlow(Flow *);
+AppLayerDecoderEvents *AppLayerGetEventsFromFlowByTx(Flow *f, uint64_t tx_id);
+int AppLayerProtoIsTxEventAware(uint16_t alproto);
+int AppLayerFlowHasDecoderEvents(Flow *f, uint8_t flags);
/***** Alproto param retrieval ******/
#endif /* #if 0 */
+/**
+ * \brief Set an app layer decoder event.
+ *
+ * \param sevents Pointer to a DecoderEvents pointer head. If
+ * the head points to a DecoderEvents instance, a
+ * new instance would be created and the pointer head would
+ * would be updated with this new instance
+ * \param event The event to be stored.
+ */
+#define AppLayerDecoderEventsSetEventRaw(sevents, event) \
+ do { \
+ AppLayerDecoderEvents *devents = (sevents); \
+ if (devents == NULL) { \
+ AppLayerDecoderEvents *new_devents = \
+ SCMalloc(sizeof(AppLayerDecoderEvents)); \
+ if (new_devents == NULL) \
+ break; \
+ memset(new_devents, 0, sizeof(AppLayerDecoderEvents)); \
+ (sevents) = devents = new_devents; \
+ } \
+ if (devents->cnt == devents->events_buffer_size) { \
+ devents->events = SCRealloc(devents->events, \
+ (devents->cnt + \
+ DECODER_EVENTS_BUFFER_STEPS) * \
+ sizeof(uint8_t)); \
+ if (devents->events == NULL) { \
+ devents->events_buffer_size = 0; \
+ devents->cnt = 0; \
+ (sevents) = NULL; \
+ break; \
+ } \
+ devents->events_buffer_size += DECODER_EVENTS_BUFFER_STEPS; \
+ } \
+ devents->events[devents->cnt++] = (event); \
+ } while (0)
+
/**
* \brief Set an app layer decoder event.
*
SigMatch *m)
{
SCEnter();
+ AppLayerDecoderEvents *decoder_events = NULL;
int r = 0;
-
+ uint64_t tx_id = 0, max_id;
DetectAppLayerEventData *aled = (DetectAppLayerEventData *)m->ctx;
FLOWLOCK_RDLOCK(f);
- AppLayerDecoderEvents *decoder_events = AppLayerGetDecoderEventsForFlow(f);
- if (decoder_events != NULL &&
- AppLayerDecoderEventsIsEventSet(decoder_events, aled->event_id)) {
- r = 1;
+ /* inspect TX events first if we need to */
+ if (AppLayerProtoIsTxEventAware(f->alproto)) {
+ SCLogDebug("proto is AppLayerProtoIsTxEventAware true");
+
+ tx_id = AppLayerTransactionGetInspectId(f, flags);
+ max_id = AppLayerGetTxCnt(f->alproto, f->alstate);
+
+ for ( ; tx_id < max_id; tx_id++) {
+ decoder_events = AppLayerGetEventsFromFlowByTx(f, tx_id);
+ if (decoder_events != NULL &&
+ AppLayerDecoderEventsIsEventSet(decoder_events, aled->event_id)) {
+ r = 1;
+ break;
+ }
+ }
+ }
+
+ if (r == 0) {
+ decoder_events = AppLayerGetDecoderEventsForFlow(f);
+ if (decoder_events != NULL &&
+ AppLayerDecoderEventsIsEventSet(decoder_events, aled->event_id)) {
+ r = 1;
+ }
}
FLOWLOCK_UNLOCK(f);
SigMatch *sm = NULL;
uint16_t alversion = 0;
int reset_de_state = 0;
- AppLayerDecoderEvents *app_decoder_events = NULL;
- int app_decoder_events_cnt = 0;
int alerts = 0;
int i;
+ int app_decoder_events = 0;
SCEnter();
SCLogDebug("packet doesn't have established flag set (proto %d)", p->proto);
}
- app_decoder_events = AppLayerGetDecoderEventsForFlow(p->flow);
- if (app_decoder_events != NULL)
- app_decoder_events_cnt = app_decoder_events->cnt;
+ app_decoder_events = AppLayerFlowHasDecoderEvents(p->flow, flags);
}
FLOWLOCK_UNLOCK(p->flow);
/* create our prefilter mask */
SignatureMask mask = 0;
- PacketCreateMask(p, &mask, alproto, alstate, smsg, app_decoder_events_cnt);
+ PacketCreateMask(p, &mask, alproto, alstate, smsg, app_decoder_events);
/* run the mpm for each type */
PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM);
*/
static void
PacketCreateMask(Packet *p, SignatureMask *mask, uint16_t alproto, void *alstate, StreamMsg *smsg,
- int app_decoder_events_cnt)
+ int app_decoder_events)
{
if (!(p->flags & PKT_NOPAYLOAD_INSPECTION) && (p->payload_len > 0 || smsg != NULL)) {
SCLogDebug("packet has payload");
(*mask) |= SIG_MASK_REQUIRE_NO_PAYLOAD;
}
- if (p->events.cnt > 0 || app_decoder_events_cnt > 0) {
+ if (p->events.cnt > 0 || app_decoder_events != 0) {
SCLogDebug("packet/flow has events set");
(*mask) |= SIG_MASK_REQUIRE_ENGINE_EVENT;
}