You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
suricata/src/app-layer-parser.h

331 lines
15 KiB
C

/* 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 <victor@inliniac.net>
* \author Anoop Saldanha <anoopsaldanha@gmail.com>
*/
#ifndef SURICATA_APP_LAYER_PARSER_H
#define SURICATA_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 *****/
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);
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);
bool 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);
/***** 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 /* SURICATA_APP_LAYER_PARSER_H */