]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
json drop log: move into packet module
authorVictor Julien <victor@inliniac.net>
Thu, 30 Jan 2014 09:15:59 +0000 (10:15 +0100)
committerVictor Julien <victor@inliniac.net>
Thu, 30 Jan 2014 09:51:26 +0000 (10:51 +0100)
Move JSON drop log into a full packet module.

src/output-droplog.c
src/output-droplog.h
src/output-json.c
src/suricata.c
src/tm-threads-common.h

index c437cd91e67abc4de45da69e2bda624659ead94d..cf390bc154e2d1cd01ba3f3d79db09d06f65aca4 100644 (file)
 #include "util-time.h"
 #include "util-buffer.h"
 
+#define MODULE_NAME "JsonDropLog"
+
 #ifdef HAVE_LIBJANSSON
 #include <jansson.h>
 
+typedef struct JsonDropLogThread_ {
+    /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */
+    LogFileCtx* file_ctx;
+    MemBuffer *buffer;
+} JsonDropLogThread;
+
 /**
  * \brief   Log the dropped packets in netfilter format when engine is running
  *          in inline mode
  *
  * \return return TM_EODE_OK on success
  */
-TmEcode OutputDropLogJSON (AlertJsonThread *aft, Packet *p)
+static int DropLogJSON (JsonDropLogThread *aft, const Packet *p)
 {
     uint16_t proto = 0;
     MemBuffer *buffer = (MemBuffer *)aft->buffer;
-    json_t *js = CreateJSONHeader(p, 0);
+    json_t *js = CreateJSONHeader((Packet *)p, 0);//TODO const
     if (unlikely(js == NULL))
         return TM_ECODE_OK;
 
@@ -125,7 +133,7 @@ TmEcode OutputDropLogJSON (AlertJsonThread *aft, Packet *p)
             break;
     }
     json_object_set_new(js, "drop", djs);
-    OutputJSON(js, aft, &aft->drop_cnt);
+    OutputJSONBuffer(js, aft->file_ctx, buffer);
     json_object_del(js, "drop");
     json_object_clear(js);
     json_decref(js);
@@ -133,52 +141,167 @@ TmEcode OutputDropLogJSON (AlertJsonThread *aft, Packet *p)
     return TM_ECODE_OK;
 }
 
+#define OUTPUT_BUFFER_SIZE 65535
+static TmEcode JsonDropLogThreadInit(ThreadVars *t, void *initdata, void **data)
+{
+    JsonDropLogThread *aft = SCMalloc(sizeof(JsonDropLogThread));
+    if (unlikely(aft == NULL))
+        return TM_ECODE_FAILED;
+    memset(aft, 0, sizeof(*aft));
+    if(initdata == NULL)
+    {
+        SCLogDebug("Error getting context for AlertFastLog.  \"initdata\" argument NULL");
+        SCFree(aft);
+        return TM_ECODE_FAILED;
+    }
+
+    aft->buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE);
+    if (aft->buffer == NULL) {
+        SCFree(aft);
+        return TM_ECODE_FAILED;
+    }
+
+    /** Use the Ouptut Context (file pointer and mutex) */
+    aft->file_ctx = ((OutputCtx *)initdata)->data;
+
+    *data = (void *)aft;
+    return TM_ECODE_OK;
+}
+
+static TmEcode JsonDropLogThreadDeinit(ThreadVars *t, void *data)
+{
+    JsonDropLogThread *aft = (JsonDropLogThread *)data;
+    if (aft == NULL) {
+        return TM_ECODE_OK;
+    }
+
+    /* clear memory */
+    memset(aft, 0, sizeof(*aft));
+
+    SCFree(aft);
+    return TM_ECODE_OK;
+}
+
+static void JsonDropLogDeInitCtx(OutputCtx *output_ctx)
+{
+    LogFileCtx *logfile_ctx = (LogFileCtx *)output_ctx->data;
+    LogFileFreeCtx(logfile_ctx);
+    SCFree(output_ctx);
+}
+
+#define DEFAULT_LOG_FILENAME "drop.json"
+static OutputCtx *JsonDropLogInitCtx(ConfNode *conf)
+{
+    LogFileCtx *logfile_ctx = LogFileNewCtx();
+    if (logfile_ctx == NULL) {
+        return NULL;
+    }
+
+    if (SCConfLogOpenGeneric(conf, logfile_ctx, DEFAULT_LOG_FILENAME) < 0) {
+        LogFileFreeCtx(logfile_ctx);
+        return NULL;
+    }
+
+    OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
+    if (unlikely(output_ctx == NULL)) {
+        return NULL;
+    }
+
+    output_ctx->data = logfile_ctx;
+    output_ctx->DeInit = JsonDropLogDeInitCtx;
+    return output_ctx;
+}
+
 /**
  * \brief   Log the dropped packets when engine is running in inline mode
  *
  * \param tv    Pointer the current thread variables
- * \param p     Pointer the packet which is being logged
  * \param data  Pointer to the droplog struct
+ * \param p     Pointer the packet which is being logged
  *
- * \return return TM_EODE_OK on success
+ * \retval 0 on succes
  */
-TmEcode OutputDropLog (ThreadVars *tv, Packet *p, void *data)
+static int JsonDropLogger(ThreadVars *tv, void *thread_data, const Packet *p)
 {
-    AlertJsonThread *aft = (AlertJsonThread *)data;
+    JsonDropLogThread *td = thread_data;
+    int r = DropLogJSON(td, p);
+    if (r < 0)
+        return -1;
 
-    /* Check if we are in inline mode or not, if not then no need to log */
+    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;
+}
+
+
+/**
+ * \brief Check if we need to drop-log this packet
+ *
+ * \param tv    Pointer the current thread variables
+ * \param p     Pointer the packet which is tested
+ *
+ * \retval bool TRUE or FALSE
+ */
+static int JsonDropLogCondition(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 OutputDropLogJSON(aft, p);
-
-        } else if (PKT_IS_TOCLIENT(p) && !(p->flow->flags & FLOW_TOCLIENT_DROP_LOGGED)) {
-            p->flow->flags |= FLOW_TOCLIENT_DROP_LOGGED;
-            return OutputDropLogJSON(aft, p);
+    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 OutputDropLogJSON(aft, p);
+        FLOWLOCK_UNLOCK(p->flow);
+        return ret;
+    } else if (PACKET_TEST_ACTION(p, ACTION_DROP)) {
+        return TRUE;
     }
 
-    return TM_ECODE_OK;
+    return FALSE;
+}
+
 
+void TmModuleJsonDropLogRegister (void) {
+    tmm_modules[TMM_JSONDROPLOG].name = MODULE_NAME;
+    tmm_modules[TMM_JSONDROPLOG].ThreadInit = JsonDropLogThreadInit;
+    tmm_modules[TMM_JSONDROPLOG].ThreadDeinit = JsonDropLogThreadDeinit;
+    tmm_modules[TMM_JSONDROPLOG].cap_flags = 0;
+
+    OutputRegisterPacketModule(MODULE_NAME, "drop-json-log",
+            JsonDropLogInitCtx, JsonDropLogger, JsonDropLogCondition);
 }
 
-OutputCtx *OutputDropLogInit(ConfNode *conf)
-{
-    OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
-    if (unlikely(output_ctx == NULL)) {
-        return NULL;
-    }
+#else
 
-    return output_ctx;
+static TmEcode OutputJsonThreadInit(ThreadVars *t, void *initdata, void **data)
+{
+    SCLogInfo("Can't init JSON output - JSON support was disabled during build.");
+    return TM_ECODE_FAILED;
 }
 
+void TmModuleJsonDropLogRegister (void)
+{
+    tmm_modules[TMM_JSONDROPLOG].name = MODULE_NAME;
+    tmm_modules[TMM_JSONDROPLOG].ThreadInit = OutputJsonThreadInit;
+}
 
 #endif
index 79e5f38cd7f1b3a62dbcfea7e1abf7894762a94a..12ccf5e5d0346b926b466e132db06e67a6c637e3 100644 (file)
@@ -28,5 +28,6 @@
 
 TmEcode OutputDropLog (ThreadVars *tv, Packet *p, void *data);
 OutputCtx *OutputDropLogInit(ConfNode *);
+void TmModuleJsonDropLogRegister (void);
 
 #endif /* OUTPUT_DROPLOG_H */
index 9a65b89f50ebf25babd63d3f763a0e6170629a4f..71ec1cb2d637871477b94c25b577ad8f4afbce26 100644 (file)
@@ -357,10 +357,6 @@ TmEcode OutputJSON(json_t *js, void *data, uint64_t *count)
 
 TmEcode OutputJson (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
 {
-    if (output_flags & OUTPUT_DROP) {
-        OutputDropLog(tv, p, data);
-    }
-
     if (output_flags & OUTPUT_FILES) {
         OutputFileLog(tv, p, data);
     }
@@ -535,11 +531,6 @@ OutputCtx *OutputJsonInitCtx(ConfNode *conf)
              * registration capability
              */
             TAILQ_FOREACH(output, &outputs->head, next) {
-                if (strcmp(output->val, "drop") == 0) {
-                    SCLogDebug("Enabling drop output");
-                    output_flags |= OUTPUT_DROP;
-                    continue;
-                }
                 if (strcmp(output->val, "files") == 0) {
                     SCLogDebug("Enabling files output");
                     ConfNode *child = ConfNodeLookupChild(output, "files");
index 6f905d8ba8f6eafa1de4e5edfcbff431cf5b22a1..3a3576fb03ce6233aaa895f5e8b36042c73368e9 100644 (file)
@@ -81,6 +81,7 @@
 #include "output-json-alert.h"
 
 #include "log-droplog.h"
+#include "output-droplog.h"
 #include "log-httplog.h"
 #include "output-httplog.h"
 #include "log-dnslog.h"
@@ -796,6 +797,7 @@ void RegisterAllModules()
     TmModuleAlertPcapInfoRegister();
     /* drop log */
     TmModuleLogDropLogRegister();
+    TmModuleJsonDropLogRegister();
     /* json log */
     TmModuleOutputJsonRegister();
     /* http log */
index a349f85cf6c0b69108eb5f4d3c763e7c79b207d7..e03d70f7ac94894a7b0cac1c839142db2b352283 100644 (file)
@@ -85,6 +85,7 @@ typedef enum {
     TMM_FILELOGGER,
     TMM_FILEDATALOGGER,
     TMM_JSONALERTLOG,
+    TMM_JSONDROPLOG,
     TMM_JSONHTTPLOG,
     TMM_JSONDNSLOG,
     TMM_SIZE,