From eea5ab4a7aab02dc7f451ab09f737e063712258c Mon Sep 17 00:00:00 2001 From: Anoop Saldanha Date: Fri, 6 Jan 2012 11:28:33 +0530 Subject: [PATCH] Support for app layer decoder events added + app_layer_event keyword added --- src/Makefile.am | 4 +- src/app-layer-parser.c | 20 +++ src/app-layer-parser.h | 6 + src/decode-events.c | 130 +++++++++++++++ src/decode-events.h | 163 ++++++++++++++++++- src/detect-app-layer-event.c | 297 +++++++++++++++++++++++++++++++++++ src/detect-app-layer-event.h | 34 ++++ src/detect-engine-state.c | 2 +- src/detect.c | 2 + src/detect.h | 1 + 10 files changed, 656 insertions(+), 3 deletions(-) create mode 100644 src/decode-events.c create mode 100644 src/detect-app-layer-event.c create mode 100644 src/detect-app-layer-event.h diff --git a/src/Makefile.am b/src/Makefile.am index 7fa106ef25..640cb5fa55 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ noinst_HEADERS = action-globals.h \ app-layer-nbss.h app-layer-dcerpc-common.h \ - debug.h decode-events.h \ + debug.h \ flow-private.h queue.h source-nfq-prototypes.h \ suricata-common.h threadvars.h util-binsearch.h \ util-atomic.h util-validate.h @@ -161,6 +161,8 @@ detect-http-stat-code.c detect-http-stat-code.h \ detect-ssl-version.c detect-ssl-version.h \ detect-ssl-state.c detect-ssl-state.h \ detect-byte-extract.c detect-byte-extract.h \ +detect-app-layer-event.c detect-app-layer-event.h \ +decode-events.c decode-events.h \ detect-replace.c detect-replace.h \ util-magic.c util-magic.h \ util-misc.c util-misc.h \ diff --git a/src/app-layer-parser.c b/src/app-layer-parser.c index c9813db73c..85f8c1d4fc 100644 --- a/src/app-layer-parser.c +++ b/src/app-layer-parser.c @@ -56,6 +56,7 @@ #include "util-spm.h" #include "util-debug.h" +#include "decode-events.h" #include "util-unittest-helper.h" static AppLayerProto al_proto_table[ALPROTO_MAX]; /**< Application layer protocol @@ -676,6 +677,8 @@ void AppLayerParserStateStoreFree(AppLayerParserStateStore *s) SCFree(s->to_server.store); if (s->to_client.store != NULL) SCFree(s->to_client.store); + if (s->decoder_events != NULL) + AppLayerDecoderEventsFreeEvents(s->decoder_events); SCFree(s); } @@ -1203,6 +1206,23 @@ int AppLayerTransactionUpdateInspectId(Flow *f, char direction) SCReturnInt(r); } +AppLayerDecoderEvents *AppLayerGetDecoderEventsForFlow(Flow *f) +{ + /* Get the parser state (if any) */ + AppLayerParserStateStore *parser_state_store = NULL; + + if (f == NULL || f->alparser == NULL) { + return NULL; + } + + parser_state_store = (AppLayerParserStateStore *)f->alparser; + if (parser_state_store != NULL) { + return parser_state_store->decoder_events; + } + + return NULL; +} + void RegisterAppLayerParsers(void) { /** \todo move to general init function */ diff --git a/src/app-layer-parser.h b/src/app-layer-parser.h index 9bbed02962..362f7f1392 100644 --- a/src/app-layer-parser.h +++ b/src/app-layer-parser.h @@ -24,6 +24,8 @@ #ifndef __APP_LAYER_PARSER_H__ #define __APP_LAYER_PARSER_H__ +#include "decode-events.h" + #include "util-file.h" /** Mapping between local parser id's (e.g. HTTP_FIELD_REQUEST_URI) and @@ -124,6 +126,9 @@ typedef struct AppLayerParserStateStore_ { uint16_t version; /**< state version, incremented for each update, * can wrap around */ + + /* Used to store decoder events */ + AppLayerDecoderEvents *decoder_events; } AppLayerParserStateStore; typedef struct AppLayerParserTableElement_ { @@ -284,5 +289,6 @@ void AppLayerPrintProbingParsers(AppLayerProbingParser *); uint16_t AppLayerGetStateVersion(Flow *f); FileContainer *AppLayerGetFilesFromFlow(Flow *, uint8_t); +AppLayerDecoderEvents *AppLayerGetDecoderEventsForFlow(Flow *); #endif /* __APP_LAYER_PARSER_H__ */ diff --git a/src/decode-events.c b/src/decode-events.c new file mode 100644 index 0000000000..ac1b972999 --- /dev/null +++ b/src/decode-events.c @@ -0,0 +1,130 @@ +/* Copyright (C) 2007-2011 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \file + * + * \author Anoop Saldanha + */ + +#include "suricata-common.h" +#include "app-layer-parser.h" +#include "decode-events.h" +#include "flow.h" + +AppLayerDecoderEventsModule *decoder_events_module = NULL; + +void AppLayerDecoderEventsModuleRegister(uint16_t alproto, SCEnumCharMap *table) +{ + AppLayerDecoderEventsModule *dvm = decoder_events_module; + + if (table == NULL) { + SCLogError(SC_ERR_INVALID_ARGUMENT, "argument \"table\" NULL"); + return; + } + + while (dvm != NULL) { + if (dvm->alproto == alproto) { + SCLogInfo("Decoder event module for alproto - %"PRIu16" already " + "registered", alproto); + return; + } + dvm = dvm->next; + } + + AppLayerDecoderEventsModule *new_dev = + SCMalloc(sizeof(AppLayerDecoderEventsModule)); + if (new_dev == NULL) + return; + + new_dev->alproto = alproto; + new_dev->table = table; + new_dev->next = NULL; + + if (decoder_events_module != NULL) + new_dev->next = decoder_events_module; + decoder_events_module = new_dev; + + return; +} + +uint16_t AppLayerDecoderEventsModuleGetAlproto(const char *alproto) +{ + return AppLayerGetProtoByName(alproto); +} + +int AppLayerDecoderEventsModuleGetEventId(uint16_t alproto, + const char *event_name) +{ + AppLayerDecoderEventsModule *dvm = decoder_events_module; + + while (dvm != NULL) { + if (dvm->alproto != alproto) + dvm = dvm->next; + break; + } + if (dvm == NULL) { + SCLogError(SC_ERR_FATAL, "decoder event module not found for " + "alproto - %"PRIu16, alproto); + return -1; + } + + int event_id = SCMapEnumNameToValue(event_name, dvm->table); + if (event_id == -1) { + SCLogError(SC_ERR_INVALID_ENUM_MAP, "event \"%s\" not present in " + "module enum map table.", event_name); + /* yes this is fatal */ + return -1; + } + + return event_id; +} + +void AppLayerDecoderEventsModuleDeRegister(void) +{ + AppLayerDecoderEventsModule *dvm = decoder_events_module; + AppLayerDecoderEventsModule *prev_dvm; + + while (dvm != NULL) { + prev_dvm = dvm; + dvm = dvm->next; + SCFree(prev_dvm); + } + + decoder_events_module = NULL; +} + +/************************************Unittests*********************************/ + +AppLayerDecoderEventsModule *decoder_events_module_backup = NULL; + +void AppLayerDecoderEventsModuleCreateBackup(void) +{ + decoder_events_module_backup = decoder_events_module; + decoder_events_module = NULL; + + return; +} + +void AppLayerDecoderEventsModuleRestoreBackup(void) +{ + AppLayerDecoderEventsModuleDeRegister(); + decoder_events_module = decoder_events_module_backup; + decoder_events_module_backup = NULL; + + return; +} diff --git a/src/decode-events.h b/src/decode-events.h index b820bb0b65..ac2fcd0e6e 100644 --- a/src/decode-events.h +++ b/src/decode-events.h @@ -19,6 +19,7 @@ * \file * * \author Victor Julien + * \author Anoop Saldanha */ #ifndef __DECODE_EVENTS_H__ @@ -192,5 +193,165 @@ enum { DECODE_EVENT_MAX, }; -#endif /* __DECODE_EVENTS_H__ */ +#define DECODER_EVENTS_BUFFER_STEPS 5 + +/** + * \brief Data structure to store app layer decoder events. + */ +typedef struct AppLayerDecoderEvents_ { + /* array of events */ + uint8_t *events; + /* number of events in the above buffer */ + uint8_t cnt; + /* current event buffer size */ + uint8_t events_buffer_size; +} AppLayerDecoderEvents; + +/** + * \brief Store decoder event module + */ +typedef struct AppLayerDecoderEventsModule_ { + /* the alproto module for which we are storing the event table */ + uint16_t alproto; + /* the event table map */ + SCEnumCharMap *table; + + struct AppLayerDecoderEventsModule_ *next; +} AppLayerDecoderEventsModule; + +#if 0 + +#define AppLayerDecoderEventsSetEvent(module_id, devents_head, event) \ + do { \ + DecoderEvents devents = *devents_head; \ + while (devents != NULL && devents->module_id != module_id) { \ + devents = devents->next; \ + } \ + if (devents == NULL) { \ + DecoderEvents new_devents = SCMalloc(sizeof(DecoderEvents));\ + if (new_devents == NULL) \ + return; \ + memset(new_devents, 0, sizeof(DecoderEvents)); \ + devents_head = new_devents; \ + } \ + if ((devents)->cnt == 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; \ + break; \ + } \ + devents->events_buffer_size += DECODER_EVENTS_BUFFER_STEPS; \ + } \ + devents->events[devents->cnt++] = event; \ + } while (0) + +static inline int AppLayerDecoderEventsIsEventSet(int module_id, + DecoderEvents *devents, + uint8_t event) +{ + while (devents != NULL && devents->module_id != module_id) { + devents = devents->next; + } + + if (devents == NULL) + return 0; + + int i; + int cnt = devents->cnt; + for (i = 0; i < cnt; i++) { + if (devents->events[i] == event) + return 1; + } + + return 0; +} +#define DecoderEventsFreeEvents(devents) \ + do { \ + while ((devents) != NULL) { \ + if ((devents)->events != NULL) \ + SCFree((devents)->events); \ + (devents) = (devents)->next; \ + } \ + } while (0) + + +#endif /* #if 0 */ + +/** + * \brief Set an app layer decoder event. + * + * \param devents_head 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 AppLayerDecoderEventsSetEvent(f, event) \ + do { \ + AppLayerParserStateStore *parser_state_store = \ + (AppLayerParserStateStore *)(f)->alparser; \ + AppLayerDecoderEvents *devents = \ + parser_state_store->decoder_events; \ + if (devents == NULL) { \ + AppLayerDecoderEvents *new_devents = \ + SCMalloc(sizeof(AppLayerDecoderEvents)); \ + if (new_devents == NULL) \ + break; \ + memset(new_devents, 0, sizeof(AppLayerDecoderEvents)); \ + parser_state_store->decoder_events = new_devents; \ + 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; \ + break; \ + } \ + devents->events_buffer_size += DECODER_EVENTS_BUFFER_STEPS; \ + } \ + devents->events[devents->cnt++] = event; \ + } while (0) + +static inline int AppLayerDecoderEventsIsEventSet(AppLayerDecoderEvents *devents, + uint8_t event) +{ + if (devents == NULL) + return 0; + + int i; + int cnt = devents->cnt; + for (i = 0; i < cnt; i++) { + if (devents->events[i] == event) + return 1; + } + + return 0; +} + +#define AppLayerDecoderEventsFreeEvents(devents) \ + do { \ + if ((devents) != NULL) { \ + if ((devents)->events != NULL) \ + SCFree((devents)->events); \ + } \ + } while (0) + +void AppLayerDecoderEventsModuleRegister(uint16_t, SCEnumCharMap *); +uint16_t AppLayerDecoderEventsModuleGetAlproto(const char *); +int AppLayerDecoderEventsModuleGetEventId(uint16_t, const char *); +void AppLayerDecodeEventsModuleDeRegister(void); + +/***** Unittest helper functions *****/ +void AppLayerDecoderEventsModuleCreateBackup(void); +void AppLayerDecoderEventsModuleRestoreBackup(void); + +#endif /* __DECODE_EVENTS_H__ */ diff --git a/src/detect-app-layer-event.c b/src/detect-app-layer-event.c new file mode 100644 index 0000000000..c4709165bb --- /dev/null +++ b/src/detect-app-layer-event.c @@ -0,0 +1,297 @@ +/* Copyright (C) 2007-2011 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \file + * + * \author Anoop Saldanha + */ + +#include "suricata-common.h" +#include "threads.h" +#include "decode.h" + +#include "app-layer-protos.h" +#include "app-layer-parser.h" +#include "app-layer-smtp.h" +#include "detect.h" +#include "detect-parse.h" +#include "detect-engine.h" +#include "detect-engine-state.h" +#include "detect-app-layer-event.h" + +#include "flow.h" +#include "flow-var.h" +#include "flow-util.h" + +#include "decode-events.h" +#include "util-byte.h" +#include "util-debug.h" +#include "util-unittest.h" +#include "util-unittest-helper.h" + + +int DetectAppLayerEventMatch(ThreadVars *, DetectEngineThreadCtx *, Flow *, + uint8_t, void *, Signature *, SigMatch *); +int DetectAppLayerEventSetup(DetectEngineCtx *, Signature *, char *); +void DetectAppLayerEventRegisterTests(void); +void DetectAppLayerEventFree(void *); + +/** + * \brief Registers the keyword handlers for the "app_layer_event" keyword. + */ +void DetectAppLayerEventRegister(void) +{ + sigmatch_table[DETECT_AL_APP_LAYER_EVENT].name = "app_layer_event"; + sigmatch_table[DETECT_AL_APP_LAYER_EVENT].Match = NULL; + sigmatch_table[DETECT_AL_APP_LAYER_EVENT].AppLayerMatch = + DetectAppLayerEventMatch; + sigmatch_table[DETECT_AL_APP_LAYER_EVENT].Setup = DetectAppLayerEventSetup; + sigmatch_table[DETECT_AL_APP_LAYER_EVENT].Free = DetectAppLayerEventFree; + sigmatch_table[DETECT_AL_APP_LAYER_EVENT].RegisterTests = + DetectAppLayerEventRegisterTests; + + return; +} + +int DetectAppLayerEventMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, + Flow *f, uint8_t flags, void *state, Signature *s, + SigMatch *m) +{ + DetectAppLayerEventData *aled = (DetectAppLayerEventData *)m->ctx; + + AppLayerDecoderEvents *decoder_events = AppLayerGetDecoderEventsForFlow(f); + if (decoder_events == NULL) + return 0; + + if (AppLayerDecoderEventsIsEventSet(decoder_events, aled->event_id)) { + return 1; + } + + return 0; +} + +static DetectAppLayerEventData *DetectAppLayerEventParse(const char *arg) +{ + /* period index */ + const char *p_idx; + + if (arg == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "app_layer_event keyword supplied " + "with no arguments. This keyword needs an argument."); + return NULL; + } + + while (*arg != '\0' && isspace(*arg)) { + arg++; + } + + p_idx = strchr(arg, '.'); + if (p_idx == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "app_layer_event keyword supplied " + "with an argument which is not in the right format. The " + "right format is \".\""); + return NULL; + } + + char buffer[50]; + strncpy(buffer, arg, p_idx - arg); + buffer[p_idx - arg] = '\0'; + + //int module_id = DecoderEventModuleGetModuleId(buffer); + //uint16_t alproto = AppLayerGetProtoByName(buffer); + uint16_t alproto = AppLayerDecoderEventsModuleGetAlproto(buffer); + if (alproto == ALPROTO_UNKNOWN) + return NULL; + int event_id = AppLayerDecoderEventsModuleGetEventId(alproto, p_idx + 1); + if (event_id == -1) + return NULL; + + DetectAppLayerEventData *aled = SCMalloc(sizeof(DetectAppLayerEventData)); + if (aled == NULL) + return NULL; + aled->alproto = alproto; + aled->event_id = event_id; + + return aled; +} + +int DetectAppLayerEventSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) +{ + DetectAppLayerEventData *data = NULL; + SigMatch *sm = NULL; + + data = DetectAppLayerEventParse(arg); + if (data == NULL) + goto error; + + sm = SigMatchAlloc(); + if (sm == NULL) + goto error; + + sm->type = DETECT_AL_APP_LAYER_EVENT; + sm->ctx = (void *)data; + + if (s->alproto != ALPROTO_UNKNOWN) { + if (s->alproto != ((DetectAppLayerEventData *)sm->ctx)->alproto) { + SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains " + "conflicting keywords needing different alprotos"); + goto error; + } + } else { + s->alproto = ((DetectAppLayerEventData *)sm->ctx)->alproto; + } + + SigMatchAppendAppLayer(s, sm); + s->flags |= SIG_FLAG_APPLAYER; + + return 0; + + error: + return -1; +} + +void DetectAppLayerEventFree(void *ptr) +{ + SCFree(ptr); + + return; +} + +/**********************************Unittests***********************************/ + +#ifdef UNITTESTS /* UNITTESTS */ + +#define APP_LAYER_EVENT_TEST_MAP_EVENT1 0 +#define APP_LAYER_EVENT_TEST_MAP_EVENT2 1 +#define APP_LAYER_EVENT_TEST_MAP_EVENT3 2 +#define APP_LAYER_EVENT_TEST_MAP_EVENT4 3 +#define APP_LAYER_EVENT_TEST_MAP_EVENT5 4 +#define APP_LAYER_EVENT_TEST_MAP_EVENT6 5 + +SCEnumCharMap app_layer_event_test_map[ ] = { + { "event1", APP_LAYER_EVENT_TEST_MAP_EVENT1 }, + { "event2", APP_LAYER_EVENT_TEST_MAP_EVENT2 }, + { "event3", APP_LAYER_EVENT_TEST_MAP_EVENT3 }, + { "event4", APP_LAYER_EVENT_TEST_MAP_EVENT4 }, + { "event5", APP_LAYER_EVENT_TEST_MAP_EVENT5 }, + { "event6", APP_LAYER_EVENT_TEST_MAP_EVENT6 }, +}; + +int DetectAppLayerEventTest01(void) +{ + AppLayerDecoderEventsModuleCreateBackup(); + AppLayerDecoderEventsModuleRegister(ALPROTO_SMTP, app_layer_event_test_map); + + int result = 0; + + DetectAppLayerEventData *aled = DetectAppLayerEventParse("smtp.event1"); + if (aled == NULL) + goto end; + if (aled->alproto != ALPROTO_SMTP || + aled->event_id != APP_LAYER_EVENT_TEST_MAP_EVENT1) { + printf("test failure. Holding wrong state\n"); + goto end; + } + + result = 1; + + end: + AppLayerDecoderEventsModuleRestoreBackup(); + if (aled != NULL) + DetectAppLayerEventFree(aled); + return result; +} + +int DetectAppLayerEventTest02(void) +{ + AppLayerDecoderEventsModuleCreateBackup(); + AppLayerDecoderEventsModuleRegister(ALPROTO_SMTP, app_layer_event_test_map); + AppLayerDecoderEventsModuleRegister(ALPROTO_HTTP, app_layer_event_test_map); + AppLayerDecoderEventsModuleRegister(ALPROTO_SMB, app_layer_event_test_map); + AppLayerDecoderEventsModuleRegister(ALPROTO_FTP, app_layer_event_test_map); + + int result = 0; + + DetectAppLayerEventData *aled = DetectAppLayerEventParse("smtp.event1"); + if (aled == NULL) + goto end; + if (aled->alproto != ALPROTO_SMTP || + aled->event_id != APP_LAYER_EVENT_TEST_MAP_EVENT1) { + printf("test failure. Holding wrong state\n"); + goto end; + } + + aled = DetectAppLayerEventParse("smtp.event4"); + if (aled == NULL) + goto end; + if (aled->alproto != ALPROTO_SMTP || + aled->event_id != APP_LAYER_EVENT_TEST_MAP_EVENT4) { + printf("test failure. Holding wrong state\n"); + goto end; + } + + aled = DetectAppLayerEventParse("http.event2"); + if (aled == NULL) + goto end; + if (aled->alproto != ALPROTO_HTTP || + aled->event_id != APP_LAYER_EVENT_TEST_MAP_EVENT2) { + printf("test failure. Holding wrong state\n"); + goto end; + } + + aled = DetectAppLayerEventParse("smb.event3"); + if (aled == NULL) + goto end; + if (aled->alproto != ALPROTO_SMB || + aled->event_id != APP_LAYER_EVENT_TEST_MAP_EVENT3) { + printf("test failure. Holding wrong state\n"); + goto end; + } + + aled = DetectAppLayerEventParse("ftp.event5"); + if (aled == NULL) + goto end; + if (aled->alproto != ALPROTO_FTP || + aled->event_id != APP_LAYER_EVENT_TEST_MAP_EVENT5) { + printf("test failure. Holding wrong state\n"); + goto end; + } + + result = 1; + + end: + AppLayerDecoderEventsModuleRestoreBackup(); + if (aled != NULL) + DetectAppLayerEventFree(aled); + return result; +} + +#endif /* UNITTESTS */ + +/** + * \brief This function registers unit tests for "app_layer_event" keyword. + */ +void DetectAppLayerEventRegisterTests(void) +{ +#ifdef UNITTESTS /* UNITTESTS */ + UtRegisterTest("DetectAppLayerEventTest01", DetectAppLayerEventTest01, 1); + UtRegisterTest("DetectAppLayerEventTest02", DetectAppLayerEventTest02, 1); +#endif /* UNITTESTS */ + + return; +} diff --git a/src/detect-app-layer-event.h b/src/detect-app-layer-event.h new file mode 100644 index 0000000000..a5ce95a2cf --- /dev/null +++ b/src/detect-app-layer-event.h @@ -0,0 +1,34 @@ +/* Copyright (C) 2007-2010 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \file + * + * \author Anoop Saldanha + */ + +#ifndef __DETECT_APP_LAYER_EVENT_H__ +#define __DETECT_APP_LAYER_EVENT_H__ + +typedef struct DetectAppLayerEventData_ { + uint16_t alproto; + int event_id; +} DetectAppLayerEventData; + +void DetectAppLayerEventRegister(void); + +#endif /* __DETECT_APP_LAYER_EVENT_H__ */ diff --git a/src/detect-engine-state.c b/src/detect-engine-state.c index 0a85928547..721dc64715 100644 --- a/src/detect-engine-state.c +++ b/src/detect-engine-state.c @@ -598,7 +598,7 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, if (sigmatch_table[sm->type].AppLayerMatch != NULL && (alproto == s->alproto || - alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) ) + alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2)) { if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) { SMBState *smb_state = (SMBState *)alstate; diff --git a/src/detect.c b/src/detect.c index ebd3cedbc7..1682e08f31 100644 --- a/src/detect.c +++ b/src/detect.c @@ -132,6 +132,7 @@ #include "detect-file-data.h" #include "detect-replace.h" #include "detect-tos.h" +#include "detect-app-layer-event.h" #include "util-rule-vars.h" @@ -4395,6 +4396,7 @@ void SigTableSetup(void) { DetectFileextRegister(); DetectFilestoreRegister(); DetectFilemagicRegister(); + DetectAppLayerEventRegister(); uint8_t i = 0; for (i = 0; i < DETECT_TBLSIZE; i++) { diff --git a/src/detect.h b/src/detect.h index ed8152d78d..b964b129a1 100644 --- a/src/detect.h +++ b/src/detect.h @@ -998,6 +998,7 @@ enum { DETECT_AL_SSL_STATE, DETECT_BYTE_EXTRACT, DETECT_FILE_DATA, + DETECT_AL_APP_LAYER_EVENT, DETECT_DCE_IFACE, DETECT_DCE_OPNUM,