/* Copyright (C) 2007-2020 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 Victor Julien * \author Anoop Saldanha */ #ifndef __APP_LAYER_PARSER_H__ #define __APP_LAYER_PARSER_H__ #include "app-layer-events.h" #include "util-file.h" #include "rust.h" #include "util-config.h" /* Flags for AppLayerParserState. */ // flag available BIT_U16(0) #define APP_LAYER_PARSER_NO_INSPECTION BIT_U16(1) #define APP_LAYER_PARSER_NO_REASSEMBLY BIT_U16(2) #define APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD BIT_U16(3) #define APP_LAYER_PARSER_BYPASS_READY BIT_U16(4) #define APP_LAYER_PARSER_EOF_TS BIT_U16(5) #define APP_LAYER_PARSER_EOF_TC BIT_U16(6) #define APP_LAYER_PARSER_TRUNC_TS BIT_U16(7) #define APP_LAYER_PARSER_TRUNC_TC BIT_U16(8) #define APP_LAYER_PARSER_SFRAME_TS BIT_U16(9) #define APP_LAYER_PARSER_SFRAME_TC BIT_U16(10) /* Flags for AppLayerParserProtoCtx. */ #define APP_LAYER_PARSER_OPT_ACCEPT_GAPS BIT_U32(0) #define APP_LAYER_PARSER_INT_STREAM_DEPTH_SET BIT_U32(0) /* applies to DetectFlags uint64_t field */ /** reserved for future use */ #define APP_LAYER_TX_RESERVED1_FLAG BIT_U64(48) #define APP_LAYER_TX_RESERVED2_FLAG BIT_U64(49) #define APP_LAYER_TX_RESERVED3_FLAG BIT_U64(50) #define APP_LAYER_TX_RESERVED4_FLAG BIT_U64(51) #define APP_LAYER_TX_RESERVED5_FLAG BIT_U64(52) #define APP_LAYER_TX_RESERVED6_FLAG BIT_U64(53) #define APP_LAYER_TX_RESERVED7_FLAG BIT_U64(54) #define APP_LAYER_TX_RESERVED8_FLAG BIT_U64(55) #define APP_LAYER_TX_RESERVED9_FLAG BIT_U64(56) #define APP_LAYER_TX_RESERVED10_FLAG BIT_U64(57) #define APP_LAYER_TX_RESERVED11_FLAG BIT_U64(58) #define APP_LAYER_TX_RESERVED12_FLAG BIT_U64(59) #define APP_LAYER_TX_RESERVED13_FLAG BIT_U64(60) #define APP_LAYER_TX_RESERVED14_FLAG BIT_U64(61) #define APP_LAYER_TX_RESERVED_FLAGS \ (APP_LAYER_TX_RESERVED1_FLAG | APP_LAYER_TX_RESERVED2_FLAG | APP_LAYER_TX_RESERVED3_FLAG | \ APP_LAYER_TX_RESERVED4_FLAG | APP_LAYER_TX_RESERVED5_FLAG | \ APP_LAYER_TX_RESERVED6_FLAG | APP_LAYER_TX_RESERVED7_FLAG | \ APP_LAYER_TX_RESERVED8_FLAG | APP_LAYER_TX_RESERVED9_FLAG | \ APP_LAYER_TX_RESERVED10_FLAG | APP_LAYER_TX_RESERVED11_FLAG | \ APP_LAYER_TX_RESERVED12_FLAG | APP_LAYER_TX_RESERVED13_FLAG | \ APP_LAYER_TX_RESERVED14_FLAG) /** should inspection be skipped in that direction */ #define APP_LAYER_TX_SKIP_INSPECT_FLAG BIT_U64(62) /** is tx fully inspected? */ #define APP_LAYER_TX_INSPECTED_FLAG BIT_U64(63) /** other 63 bits are for tracking which prefilter engine is already * completely inspected */ #define APP_LAYER_TX_PREFILTER_MASK ~(APP_LAYER_TX_INSPECTED_FLAG | APP_LAYER_TX_RESERVED_FLAGS) /** parser has successfully processed in the input, and has consumed * all of it. */ #define APP_LAYER_OK (AppLayerResult) { 0, 0, 0 } /** parser has hit an unrecoverable error. Returning this to the API * leads to no further calls to the parser. */ #define APP_LAYER_ERROR (AppLayerResult) { -1, 0, 0 } /** parser needs more data. Through 'c' it will indicate how many * of the input bytes it has consumed. Through 'n' it will indicate * how many more bytes it needs before getting called again. * \note consumed (c) should never be more than the input len * needed (n) + consumed (c) should be more than the input len */ #define APP_LAYER_INCOMPLETE(c,n) (AppLayerResult) { 1, (c), (n) } int AppLayerParserProtoIsRegistered(uint8_t ipproto, AppProto alproto); /***** transaction handling *****/ int AppLayerParserSetup(void); void AppLayerParserPostStreamSetup(void); int AppLayerParserDeSetup(void); typedef struct AppLayerParserThreadCtx_ AppLayerParserThreadCtx; /** * \brief Gets a new app layer protocol's parser thread context. * * \retval Non-NULL pointer on success. * NULL pointer on failure. */ AppLayerParserThreadCtx *AppLayerParserThreadCtxAlloc(void); /** * \brief Destroys the app layer parser thread context obtained * using AppLayerParserThreadCtxAlloc(). * * \param tctx Pointer to the thread context to be destroyed. */ void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx); /** * \brief Given a protocol name, checks if the parser is enabled in * the conf file. * * \param alproto_name Name of the app layer protocol. * * \retval 1 If enabled. * \retval 0 If disabled. */ int AppLayerParserConfParserEnabled(const char *ipproto, const char *alproto_name); /** \brief Prototype for parsing functions */ typedef AppLayerResult (*AppLayerParserFPtr)(Flow *f, void *protocol_state, AppLayerParserState *pstate, StreamSlice stream_slice, void *local_storage); typedef struct AppLayerGetTxIterState { union { void *ptr; uint64_t u64; } un; } AppLayerGetTxIterState; /** \brief tx iterator prototype */ typedef AppLayerGetTxIterTuple (*AppLayerGetTxIteratorFunc) (const uint8_t ipproto, const AppProto alproto, void *alstate, uint64_t min_tx_id, uint64_t max_tx_id, AppLayerGetTxIterState *state); /***** Parser related registration *****/ typedef int (*AppLayerParserGetFrameIdByNameFn)(const char *frame_name); typedef const char *(*AppLayerParserGetFrameNameByIdFn)(const uint8_t id); /** * \brief Register app layer parser for the protocol. * * \retval 0 On success. * \retval -1 On failure. */ int AppLayerParserRegisterParser(uint8_t ipproto, AppProto alproto, uint8_t direction, AppLayerParserFPtr Parser); void AppLayerParserRegisterParserAcceptableDataDirection(uint8_t ipproto, AppProto alproto, uint8_t direction); void AppLayerParserRegisterOptionFlags(uint8_t ipproto, AppProto alproto, uint32_t flags); void AppLayerParserRegisterStateFuncs(uint8_t ipproto, AppProto alproto, void *(*StateAlloc)(void *, AppProto), void (*StateFree)(void *)); void AppLayerParserRegisterLocalStorageFunc(uint8_t ipproto, AppProto proto, void *(*LocalStorageAlloc)(void), void (*LocalStorageFree)(void *)); // void AppLayerParserRegisterGetEventsFunc(uint8_t ipproto, AppProto proto, // AppLayerDecoderEvents *(*StateGetEvents)(void *) __attribute__((nonnull))); void AppLayerParserRegisterGetTxFilesFunc(uint8_t ipproto, AppProto alproto, AppLayerGetFileState (*GetTxFiles)(void *, void *, uint8_t)); void AppLayerParserRegisterLogger(uint8_t ipproto, AppProto alproto); void AppLayerParserRegisterLoggerBits(uint8_t ipproto, AppProto alproto, LoggerId bits); void AppLayerParserRegisterTruncateFunc(uint8_t ipproto, AppProto alproto, void (*Truncate)(void *, uint8_t)); void AppLayerParserRegisterGetStateProgressFunc(uint8_t ipproto, AppProto alproto, int (*StateGetStateProgress)(void *alstate, uint8_t direction)); void AppLayerParserRegisterTxFreeFunc(uint8_t ipproto, AppProto alproto, void (*StateTransactionFree)(void *, uint64_t)); void AppLayerParserRegisterGetTxCnt(uint8_t ipproto, AppProto alproto, uint64_t (*StateGetTxCnt)(void *alstate)); void AppLayerParserRegisterGetTx(uint8_t ipproto, AppProto alproto, void *(StateGetTx)(void *alstate, uint64_t tx_id)); void AppLayerParserRegisterGetTxIterator(uint8_t ipproto, AppProto alproto, AppLayerGetTxIteratorFunc Func); void AppLayerParserRegisterStateProgressCompletionStatus( AppProto alproto, const int ts, const int tc); void AppLayerParserRegisterGetEventInfo(uint8_t ipproto, AppProto alproto, int (*StateGetEventInfo)(const char *event_name, int *event_id, AppLayerEventType *event_type)); void AppLayerParserRegisterGetEventInfoById(uint8_t ipproto, AppProto alproto, int (*StateGetEventInfoById)(int event_id, const char **event_name, AppLayerEventType *event_type)); void AppLayerParserRegisterGetFrameFuncs(uint8_t ipproto, AppProto alproto, AppLayerParserGetFrameIdByNameFn GetFrameIdByName, AppLayerParserGetFrameNameByIdFn GetFrameNameById); void AppLayerParserRegisterSetStreamDepthFlag(uint8_t ipproto, AppProto alproto, void (*SetStreamDepthFlag)(void *tx, uint8_t flags)); void AppLayerParserRegisterTxDataFunc(uint8_t ipproto, AppProto alproto, AppLayerTxData *(*GetTxData)(void *tx)); void AppLayerParserRegisterApplyTxConfigFunc(uint8_t ipproto, AppProto alproto, bool (*ApplyTxConfig)(void *state, void *tx, int mode, AppLayerTxConfig)); void AppLayerParserRegisterStateDataFunc( uint8_t ipproto, AppProto alproto, AppLayerStateData *(*GetStateData)(void *state)); /***** Get and transaction functions *****/ uint32_t AppLayerParserGetOptionFlags(uint8_t protomap, AppProto alproto); AppLayerGetTxIteratorFunc AppLayerGetTxIterator(const uint8_t ipproto, const AppProto alproto); void *AppLayerParserGetProtocolParserLocalStorage(uint8_t ipproto, AppProto alproto); void AppLayerParserDestroyProtocolParserLocalStorage(uint8_t ipproto, AppProto alproto, void *local_data); uint64_t AppLayerParserGetTransactionLogId(AppLayerParserState *pstate); void AppLayerParserSetTransactionLogId(AppLayerParserState *pstate, uint64_t tx_id); uint64_t AppLayerParserGetTransactionInspectId(AppLayerParserState *pstate, uint8_t direction); void AppLayerParserSetTransactionInspectId(const Flow *f, AppLayerParserState *pstate, void *alstate, const uint8_t flags, bool tag_txs_as_inspected); AppLayerDecoderEvents *AppLayerParserGetDecoderEvents(AppLayerParserState *pstate); void AppLayerParserSetDecoderEvents(AppLayerParserState *pstate, AppLayerDecoderEvents *devents); AppLayerDecoderEvents *AppLayerParserGetEventsByTx(uint8_t ipproto, AppProto alproto, void *tx); AppLayerGetFileState AppLayerParserGetTxFiles( const Flow *f, void *state, void *tx, const uint8_t direction); int AppLayerParserGetStateProgress(uint8_t ipproto, AppProto alproto, void *alstate, uint8_t direction); uint64_t AppLayerParserGetTxCnt(const Flow *, void *alstate); void *AppLayerParserGetTx(uint8_t ipproto, AppProto alproto, void *alstate, uint64_t tx_id); int AppLayerParserGetStateProgressCompletionStatus(AppProto alproto, uint8_t direction); int AppLayerParserGetEventInfo(uint8_t ipproto, AppProto alproto, const char *event_name, int *event_id, AppLayerEventType *event_type); int AppLayerParserGetEventInfoById(uint8_t ipproto, AppProto alproto, int event_id, const char **event_name, AppLayerEventType *event_type); uint64_t AppLayerParserGetTransactionActive(const Flow *f, AppLayerParserState *pstate, uint8_t direction); uint8_t AppLayerParserGetFirstDataDir(uint8_t ipproto, AppProto alproto); int AppLayerParserSupportsFiles(uint8_t ipproto, AppProto alproto); AppLayerTxData *AppLayerParserGetTxData(uint8_t ipproto, AppProto alproto, void *tx); uint64_t AppLayerParserGetTxDetectFlags(AppLayerTxData *txd, const uint8_t dir); AppLayerStateData *AppLayerParserGetStateData(uint8_t ipproto, AppProto alproto, void *state); void AppLayerParserApplyTxConfig(uint8_t ipproto, AppProto alproto, void *state, void *tx, enum ConfigAction mode, AppLayerTxConfig); static inline bool AppLayerParserIsFileTx(const AppLayerTxData *txd) { if (txd->file_tx != 0) { return true; } return false; } static inline bool AppLayerParserIsFileTxInDir(const AppLayerTxData *txd, const uint8_t direction) { if ((txd->file_tx & direction) != 0) { return true; } return false; } /** \brief check if tx (possibly) has files in this tx for the direction */ static inline bool AppLayerParserHasFilesInDir(const AppLayerTxData *txd, const uint8_t direction) { return (txd->files_opened && AppLayerParserIsFileTxInDir(txd, direction)); } /***** General *****/ int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len); void AppLayerParserSetEOF(AppLayerParserState *pstate); bool AppLayerParserHasDecoderEvents(AppLayerParserState *pstate); int AppLayerParserProtocolHasLogger(uint8_t ipproto, AppProto alproto); LoggerId AppLayerParserProtocolGetLoggerBits(uint8_t ipproto, AppProto alproto); void AppLayerParserTriggerRawStreamReassembly(Flow *f, int direction); void AppLayerParserSetStreamDepth(uint8_t ipproto, AppProto alproto, uint32_t stream_depth); uint32_t AppLayerParserGetStreamDepth(const Flow *f); void AppLayerParserSetStreamDepthFlag(uint8_t ipproto, AppProto alproto, void *state, uint64_t tx_id, uint8_t flags); int AppLayerParserIsEnabled(AppProto alproto); int AppLayerParserGetFrameIdByName(uint8_t ipproto, AppProto alproto, const char *name); const char *AppLayerParserGetFrameNameById(uint8_t ipproto, AppProto alproto, const uint8_t id); /***** Cleanup *****/ void AppLayerParserStateProtoCleanup( uint8_t protomap, AppProto alproto, void *alstate, AppLayerParserState *pstate); void AppLayerParserStateCleanup(const Flow *f, void *alstate, AppLayerParserState *pstate); void AppLayerParserRegisterProtocolParsers(void); void AppLayerParserStateSetFlag(AppLayerParserState *pstate, uint16_t flag); uint16_t AppLayerParserStateIssetFlag(AppLayerParserState *pstate, uint16_t flag); AppLayerParserState *AppLayerParserStateAlloc(void); void AppLayerParserStateFree(AppLayerParserState *pstate); void AppLayerParserTransactionsCleanup(Flow *f, const uint8_t pkt_dir); #ifdef DEBUG void AppLayerParserStatePrintDetails(AppLayerParserState *pstate); #endif /***** Unittests *****/ #ifdef UNITTESTS void AppLayerParserRegisterProtocolUnittests(uint8_t ipproto, AppProto alproto, void (*RegisterUnittests)(void)); void AppLayerParserRegisterUnittests(void); void AppLayerParserBackupParserTable(void); void AppLayerParserRestoreParserTable(void); void UTHAppLayerParserStateGetIds(void *ptr, uint64_t *i1, uint64_t *i2, uint64_t *log, uint64_t *min); #endif void AppLayerFramesFreeContainer(Flow *f); void FileApplyTxFlags(const AppLayerTxData *txd, const uint8_t direction, File *file); #endif /* __APP_LAYER_PARSER_H__ */