app layer: add support for per TX decoder events

pull/412/merge
Victor Julien 12 years ago
parent 72e35efbc6
commit 9dc04d9fab

@ -99,6 +99,67 @@ FileContainer *AppLayerGetFilesFromFlow(Flow *f, uint8_t direction) {
}
}
/** \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()
{
@ -735,6 +796,12 @@ void AppLayerRegisterGetAlstateProgressCompletionStatus(uint16_t alproto,
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.
*/

@ -58,6 +58,7 @@ typedef struct AppLayerProto_ {
/** 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);
@ -258,6 +259,8 @@ void AppLayerRegisterLocalStorageFunc(uint16_t proto,
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);
@ -332,6 +335,9 @@ void AppLayerPrintProbingParsers(AppLayerProbingParser *);
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 ******/

@ -310,6 +310,42 @@ static inline int AppLayerDecoderEventsIsEventSet(int module_id,
#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.
*

@ -73,16 +73,36 @@ int DetectAppLayerEventMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
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);

@ -1258,10 +1258,9 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
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();
@ -1346,9 +1345,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
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);
@ -1447,7 +1444,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
/* 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);
@ -2184,7 +2181,7 @@ deonly:
*/
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");
@ -2194,7 +2191,7 @@ PacketCreateMask(Packet *p, SignatureMask *mask, uint16_t alproto, void *alstate
(*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;
}

Loading…
Cancel
Save