From 35aa6c1e6674e3438686b0da57c9de90d6661d30 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Fri, 6 Dec 2013 12:33:51 +0100 Subject: [PATCH] Convert log-drop to packet logger api. --- src/log-droplog.c | 177 ++++++++++++++++++++++++---------------------- 1 file changed, 93 insertions(+), 84 deletions(-) diff --git a/src/log-droplog.c b/src/log-droplog.c index ba5540f997..086608318b 100644 --- a/src/log-droplog.c +++ b/src/log-droplog.c @@ -19,9 +19,10 @@ * \file * * \author Gurvinder Singh + * \author Victor Julien * - * Drop log module to log the dropped packet information - * + * Drop log module to log the dropped packet information in a format + * compatible to Linux' Netfilter. */ #include "suricata-common.h" @@ -58,31 +59,6 @@ #define MODULE_NAME "LogDropLog" -TmEcode LogDropLog (ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); -TmEcode LogDropLogNetFilter(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); -TmEcode LogDropLogIPv6(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); -TmEcode LogDropLogDecoderEvent(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); -TmEcode LogDropLogThreadInit(ThreadVars *, void *, void **); -TmEcode LogDropLogThreadDeinit(ThreadVars *, void *); -OutputCtx *LogDropLogInitCtx(ConfNode *); -static void LogDropLogDeInitCtx(OutputCtx *); -void LogDropLogRegisterTests(void); -void LogDropLogExitPrintStats(ThreadVars *, void *); - -/** \brief function to register the drop log module */ -void TmModuleLogDropLogRegister (void) { - - tmm_modules[TMM_LOGDROPLOG].name = MODULE_NAME; - tmm_modules[TMM_LOGDROPLOG].ThreadInit = LogDropLogThreadInit; - tmm_modules[TMM_LOGDROPLOG].Func = LogDropLog; - tmm_modules[TMM_LOGDROPLOG].ThreadExitPrintStats = LogDropLogExitPrintStats; - tmm_modules[TMM_LOGDROPLOG].ThreadDeinit = LogDropLogThreadDeinit; - tmm_modules[TMM_LOGDROPLOG].RegisterTests = LogDropLogRegisterTests; - tmm_modules[TMM_LOGDROPLOG].cap_flags = 0; - - OutputRegisterModule(MODULE_NAME, "drop", LogDropLogInitCtx); -} - typedef struct LogDropLogThread_ { /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ LogFileCtx* file_ctx; @@ -97,7 +73,7 @@ typedef struct LogDropLogThread_ { * * \return TM_ECODE_OK on success */ -TmEcode LogDropLogThreadInit(ThreadVars *t, void *initdata, void **data) +static TmEcode LogDropLogThreadInit(ThreadVars *t, void *initdata, void **data) { if(initdata == NULL) { SCLogDebug("Error getting context for LogDropLog. \"initdata\" argument NULL"); @@ -123,7 +99,7 @@ TmEcode LogDropLogThreadInit(ThreadVars *t, void *initdata, void **data) * * \return TM_ECODE_OK on success */ -TmEcode LogDropLogThreadDeinit(ThreadVars *t, void *data) +static TmEcode LogDropLogThreadDeinit(ThreadVars *t, void *data) { LogDropLogThread *dlt = (LogDropLogThread *)data; if (dlt == NULL) { @@ -137,13 +113,28 @@ TmEcode LogDropLogThreadDeinit(ThreadVars *t, void *data) return TM_ECODE_OK; } +/** + * \brief Destroy the LogFileCtx and cleared "drop" output module + * + * \param output_ctx pointer the output context to be cleared + */ +static void LogDropLogDeInitCtx(OutputCtx *output_ctx) +{ + if (output_ctx != NULL) { + LogFileCtx *logfile_ctx = (LogFileCtx *)output_ctx->data; + if (logfile_ctx != NULL) { + LogFileFreeCtx(logfile_ctx); + } + SCFree(output_ctx); + } +} /** * \brief Create a new LogFileCtx for "drop" output style. * \param conf The configuration node for this output. * \return A LogFileCtx pointer on success, NULL on failure. */ -OutputCtx *LogDropLogInitCtx(ConfNode *conf) +static OutputCtx *LogDropLogInitCtx(ConfNode *conf) { LogFileCtx *logfile_ctx = LogFileNewCtx(); if (logfile_ctx == NULL) { @@ -167,22 +158,6 @@ OutputCtx *LogDropLogInitCtx(ConfNode *conf) return output_ctx; } -/** - * \brief Destroy the LogFileCtx and cleared "drop" output module - * - * \param output_ctx pointer the output context to be cleared - */ -static void LogDropLogDeInitCtx(OutputCtx *output_ctx) -{ - if (output_ctx != NULL) { - LogFileCtx *logfile_ctx = (LogFileCtx *)output_ctx->data; - if (logfile_ctx != NULL) { - LogFileFreeCtx(logfile_ctx); - } - SCFree(output_ctx); - } -} - /** * \brief Log the dropped packets in netfilter format when engine is running * in inline mode @@ -190,22 +165,15 @@ static void LogDropLogDeInitCtx(OutputCtx *output_ctx) * \param tv Pointer the current thread variables * \param p Pointer the packet which is being logged * \param data Pointer to the droplog struct - * \param pq Pointer the packet queue - * \param postpq Pointer the packet queue where this packet will be sent * * \return return TM_EODE_OK on success */ -TmEcode LogDropLogNetFilter (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, - PacketQueue *postpq) +static int LogDropLogNetFilter (ThreadVars *tv, const Packet *p, void *data) { LogDropLogThread *dlt = (LogDropLogThread *)data; uint16_t proto = 0; char timebuf[64]; - if (!(PACKET_TEST_ACTION(p, ACTION_DROP)) || PKT_IS_PSEUDOPKT(p)) { - return TM_ECODE_OK; - } - CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); SCMutexLock(&dlt->file_ctx->fp_mutex); @@ -284,44 +252,71 @@ TmEcode LogDropLogNetFilter (ThreadVars *tv, Packet *p, void *data, PacketQueue } /** - * \brief Log the dropped packets when engine is running in inline mode + * \brief Check if we need to drop-log this packet * * \param tv Pointer the current thread variables - * \param p Pointer the packet which is being logged - * \param data Pointer to the droplog struct - * \param pq Pointer the packet queue - * \param postpq Pointer the packet queue where this packet will be sent + * \param p Pointer the packet which is tested * - * \return return TM_EODE_OK on success + * \retval bool TRUE or FALSE */ -TmEcode LogDropLog (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, - PacketQueue *postpq) -{ - /* Check if we are in inline mode or not, if not then no need to log */ +static int LogDropCondition(ThreadVars *tv, const Packet *p) { extern uint8_t engine_mode; if (!IS_ENGINE_MODE_IPS(engine_mode)) { SCLogDebug("engine is not running in inline mode, so returning"); - return TM_ECODE_OK; + return FALSE; + } + if (PKT_IS_PSEUDOPKT(p)) { + SCLogDebug("drop log doesn't log pseudo packets"); + return FALSE; } - if ((p->flow != NULL) && (p->flow->flags & FLOW_ACTION_DROP)) { - if (PKT_IS_TOSERVER(p) && !(p->flow->flags & FLOW_TOSERVER_DROP_LOGGED)) { - p->flow->flags |= FLOW_TOSERVER_DROP_LOGGED; - return LogDropLogNetFilter(tv, p, data, pq, NULL); - - } else if (PKT_IS_TOCLIENT(p) && !(p->flow->flags & FLOW_TOCLIENT_DROP_LOGGED)) { - p->flow->flags |= FLOW_TOCLIENT_DROP_LOGGED; - return LogDropLogNetFilter(tv, p, data, pq, NULL); + if (p->flow != NULL) { + int ret = FALSE; + FLOWLOCK_RDLOCK(p->flow); + if (p->flow->flags & FLOW_ACTION_DROP) { + if (PKT_IS_TOSERVER(p) && !(p->flow->flags & FLOW_TOSERVER_DROP_LOGGED)) + ret = TRUE; + else if (PKT_IS_TOCLIENT(p) && !(p->flow->flags & FLOW_TOCLIENT_DROP_LOGGED)) + ret = TRUE; } - } else { - return LogDropLogNetFilter(tv, p, data, pq, postpq); + FLOWLOCK_UNLOCK(p->flow); + return ret; + } else if (PACKET_TEST_ACTION(p, ACTION_DROP)) { + return TRUE; } - return TM_ECODE_OK; + return FALSE; +} +/** + * \brief Log the dropped packets when engine is running in inline mode + * + * \param tv Pointer the current thread variables + * \param data Pointer to the droplog struct + * \param p Pointer the packet which is being logged + * + * \retval 0 on succes + */ +static int LogDropLogger(ThreadVars *tv, void *thread_data, const Packet *p) { + + int r = LogDropLogNetFilter(tv, p, thread_data); + if (r < 0) + return -1; + + if (p->flow) { + FLOWLOCK_RDLOCK(p->flow); + if (p->flow->flags & FLOW_ACTION_DROP) { + if (PKT_IS_TOSERVER(p) && !(p->flow->flags & FLOW_TOSERVER_DROP_LOGGED)) + p->flow->flags |= FLOW_TOSERVER_DROP_LOGGED; + else if (PKT_IS_TOCLIENT(p) && !(p->flow->flags & FLOW_TOCLIENT_DROP_LOGGED)) + p->flow->flags |= FLOW_TOCLIENT_DROP_LOGGED; + } + FLOWLOCK_UNLOCK(p->flow); + } + return 0; } -void LogDropLogExitPrintStats(ThreadVars *tv, void *data) { +static void LogDropLogExitPrintStats(ThreadVars *tv, void *data) { LogDropLogThread *dlt = (LogDropLogThread *)data; if (dlt == NULL) { return; @@ -387,7 +382,8 @@ int LogDropLogTest01() else result = 0; - LogDropLog(NULL, p, &dlt, NULL, NULL); + if (LogDropCondition(NULL, p) == TRUE) + LogDropLogger(NULL, &dlt, p); if (dlt.drop_cnt == 0) { printf("Packet should be logged but its not\n"); @@ -455,7 +451,8 @@ int LogDropLogTest02() else result = 0; - LogDropLog(NULL, p, &dlt, NULL, NULL); + if (LogDropCondition(NULL, p) == TRUE) + LogDropLogger(NULL, &dlt, p); if (dlt.drop_cnt != 0) { printf("Packet shouldn't be logged but it is\n"); @@ -470,17 +467,29 @@ int LogDropLogTest02() UTHFreePackets(&p, 1); return result; } -#endif /** * \brief This function registers unit tests for AlertFastLog API. */ -void LogDropLogRegisterTests(void) +static void LogDropLogRegisterTests(void) { - -#ifdef UNITTESTS UtRegisterTest("LogDropLogTest01", LogDropLogTest01, 1); UtRegisterTest("LogDropLogTest02", LogDropLogTest02, 1); -#endif /* UNITTESTS */ +} +#endif + +/** \brief function to register the drop log module */ +void TmModuleLogDropLogRegister (void) { + + tmm_modules[TMM_LOGDROPLOG].name = MODULE_NAME; + tmm_modules[TMM_LOGDROPLOG].ThreadInit = LogDropLogThreadInit; + tmm_modules[TMM_LOGDROPLOG].ThreadExitPrintStats = LogDropLogExitPrintStats; + tmm_modules[TMM_LOGDROPLOG].ThreadDeinit = LogDropLogThreadDeinit; +#ifdef UNITTESTS + tmm_modules[TMM_LOGDROPLOG].RegisterTests = LogDropLogRegisterTests; +#endif + tmm_modules[TMM_LOGDROPLOG].cap_flags = 0; + OutputRegisterPacketModule(MODULE_NAME, "drop", LogDropLogInitCtx, + LogDropLogger, LogDropCondition); }