]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
add "united" drop JSON log
authorTom DeCanio <decanio.tom@gmail.com>
Thu, 14 Nov 2013 03:33:00 +0000 (19:33 -0800)
committerVictor Julien <victor@inliniac.net>
Wed, 29 Jan 2014 10:07:51 +0000 (11:07 +0100)
src/Makefile.am
src/output-droplog.c [new file with mode: 0644]
src/output-droplog.h [new file with mode: 0644]
src/output-json.c
src/output-json.h

index 49d526929fd1874ab4248d82982990c8d5ceaae6..816991cce7e0de652e10ce5e0bd2e0d1c206f048 100644 (file)
@@ -219,6 +219,7 @@ output-filedata.c output-filedata.h \
 output-packet.c output-packet.h \
 output-tx.c output-tx.h \
 output-dnslog.c output-dnslog.h \
+output-droplog.c output-droplog.h \
 output-file.c output-file.h \
 output-httplog.c output-httplog.h \
 output-json.c output-json.h \
diff --git a/src/output-droplog.c b/src/output-droplog.c
new file mode 100644 (file)
index 0000000..7ed3b95
--- /dev/null
@@ -0,0 +1,191 @@
+/* Copyright (C) 2007-2013 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 Tom DeCanio <td@npulsetech.com>
+ *
+ * JSON Drop log module to log the dropped packet information
+ *
+ */
+
+#include "suricata-common.h"
+#include "debug.h"
+#include "detect.h"
+#include "flow.h"
+#include "conf.h"
+
+#include "threads.h"
+#include "tm-threads.h"
+#include "threadvars.h"
+#include "util-debug.h"
+
+#include "decode-ipv4.h"
+#include "detect.h"
+#include "detect-parse.h"
+#include "detect-engine.h"
+#include "detect-engine-mpm.h"
+#include "detect-reference.h"
+
+#include "output.h"
+#include "output-json.h"
+
+#include "util-unittest.h"
+#include "util-unittest-helper.h"
+#include "util-classification-config.h"
+#include "util-privs.h"
+#include "util-print.h"
+#include "util-proto-name.h"
+#include "util-logopenfile.h"
+#include "util-time.h"
+#include "util-buffer.h"
+
+#ifdef HAVE_LIBJANSSON
+#include <jansson.h>
+
+/**
+ * \brief   Log the dropped packets in netfilter format 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 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 OutputDropLogJSON (AlertJsonThread *aft, Packet *p, PacketQueue *pq,
+                      PacketQueue *postpq)
+{
+    uint16_t proto = 0;
+    MemBuffer *buffer = (MemBuffer *)aft->buffer;
+    json_t *js = CreateJSONHeader(p, 0);
+    if (unlikely(js == NULL))
+        return TM_ECODE_OK;
+
+    json_t *djs = json_object();
+    if (unlikely(djs == NULL)) {
+        json_decref(js);
+        return TM_ECODE_OK;
+    }
+
+    /* reset */
+    MemBufferReset(buffer);
+
+    if (PKT_IS_IPV4(p)) {
+        json_object_set_new(djs, "len", json_integer(IPV4_GET_IPLEN(p)));
+        json_object_set_new(djs, "tos", json_integer(IPV4_GET_IPTOS(p)));
+        json_object_set_new(djs, "ttl", json_integer(IPV4_GET_IPTTL(p)));
+        json_object_set_new(djs, "ipid", json_integer(IPV4_GET_IPID(p)));
+        proto = IPV4_GET_IPPROTO(p);
+    } else if (PKT_IS_IPV6(p)) {
+        json_object_set_new(djs, "len", json_integer(IPV6_GET_PLEN(p)));
+        json_object_set_new(djs, "tc", json_integer(IPV6_GET_CLASS(p)));
+        json_object_set_new(djs, "hoplimit", json_integer(IPV6_GET_HLIM(p)));
+        json_object_set_new(djs, "flowlbl", json_integer(IPV6_GET_FLOW(p)));
+        proto = IPV6_GET_L4PROTO(p);
+    }
+    switch (proto) {
+        case IPPROTO_TCP:
+            json_object_set_new(djs, "tcpseq", json_integer(TCP_GET_SEQ(p)));
+            json_object_set_new(djs, "tcpack", json_integer(TCP_GET_ACK(p)));
+            json_object_set_new(djs, "tcpwin", json_integer(TCP_GET_WINDOW(p)));
+            json_object_set_new(djs, "syn", TCP_ISSET_FLAG_SYN(p) ? json_true() : json_false());
+            json_object_set_new(djs, "ack", TCP_ISSET_FLAG_ACK(p) ? json_true() : json_false());
+            json_object_set_new(djs, "psh", TCP_ISSET_FLAG_PUSH(p) ? json_true() : json_false());
+            json_object_set_new(djs, "rst", TCP_ISSET_FLAG_RST(p) ? json_true() : json_false());
+            json_object_set_new(djs, "urg", TCP_ISSET_FLAG_URG(p) ? json_true() : json_false());
+            json_object_set_new(djs, "fin", TCP_ISSET_FLAG_FIN(p) ? json_true() : json_false());
+            json_object_set_new(djs, "tcpres", json_integer(TCP_GET_RAW_X2(p->tcph)));
+            json_object_set_new(djs, "tcpurgp", json_integer(TCP_GET_URG_POINTER(p)));
+            break;
+        case IPPROTO_UDP:
+            json_object_set_new(djs, "udplen", json_integer(UDP_GET_LEN(p)));
+            break;
+        case IPPROTO_ICMP:
+            if (PKT_IS_ICMPV4(p)) {
+                json_object_set_new(djs, "icmp_id", json_integer(ICMPV4_GET_ID(p)));
+                json_object_set_new(djs, "icmp_seq", json_integer(ICMPV4_GET_SEQ(p)));
+            } else if(PKT_IS_ICMPV6(p)) {
+                json_object_set_new(djs, "icmp_id", json_integer(ICMPV6_GET_ID(p)));
+                json_object_set_new(djs, "icmp_seq", json_integer(ICMPV6_GET_SEQ(p)));
+            }
+            break;
+    }
+    json_object_set_new(js, "drop", djs);
+    OutputJSON(js, aft, &aft->drop_cnt);
+    json_object_del(js, "drop");
+    json_object_clear(js);
+    json_decref(js);
+
+    return TM_ECODE_OK;
+}
+
+/**
+ * \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 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 OutputDropLog (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq,
+                      PacketQueue *postpq)
+{
+    AlertJsonThread *aft = (AlertJsonThread *)data;
+
+    /* Check if we are in inline mode or not, if not then no need to log */
+    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;
+    }
+
+    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, pq, NULL);
+
+        } else if (PKT_IS_TOCLIENT(p) && !(p->flow->flags & FLOW_TOCLIENT_DROP_LOGGED)) {
+            p->flow->flags |= FLOW_TOCLIENT_DROP_LOGGED;
+            return OutputDropLogJSON(aft, p, pq, NULL);
+        }
+    } else {
+        return OutputDropLogJSON(aft, p, pq, postpq);
+    }
+
+    return TM_ECODE_OK;
+
+}
+
+OutputCtx *OutputDropLogInit(ConfNode *conf)
+{
+    OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
+    if (unlikely(output_ctx == NULL)) {
+        return NULL;
+    }
+
+    return output_ctx;
+}
+
+
+#endif
diff --git a/src/output-droplog.h b/src/output-droplog.h
new file mode 100644 (file)
index 0000000..1510351
--- /dev/null
@@ -0,0 +1,32 @@
+/* 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 Tom DeCanio <td@npulsetech.com>
+ *
+ */
+
+
+#ifndef OUTPUT_DROPLOG_H
+#define        OUTPUT_DROPLOG_H
+
+TmEcode OutputDropLog (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq);
+OutputCtx *OutputDropLogInit(ConfNode *);
+
+#endif /* OUTPUT_DROPLOG_H */
index ad2c7524ebc23dbf41cf62bb478f46335fb1ef4c..98ea77d527aac3d3a7dfd846f7742eda8c58d31c 100644 (file)
@@ -49,6 +49,7 @@
 
 #include "output.h"
 #include "output-dnslog.h"
+#include "output-droplog.h"
 #include "output-httplog.h"
 #include "output-tlslog.h"
 #include "output-file.h"
@@ -164,9 +165,10 @@ static enum json_output json_out = ALERT_FILE;
 
 #define OUTPUT_ALERTS (1<<0)
 #define OUTPUT_DNS    (1<<1)
-#define OUTPUT_FILES  (1<<2)
-#define OUTPUT_HTTP   (1<<3)
-#define OUTPUT_TLS    (1<<4)
+#define OUTPUT_DROP   (1<<2)
+#define OUTPUT_FILES  (1<<3)
+#define OUTPUT_HTTP   (1<<4)
+#define OUTPUT_TLS    (1<<5)
 
 static uint32_t outputFlags = 0;
 
@@ -536,6 +538,10 @@ TmEcode AlertJson (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, Packe
         OutputDnsLog(tv, p, data, pq, postpq);
     }
 
+    if (outputFlags & OUTPUT_DROP) {
+        OutputDropLog(tv, p, data, pq, postpq);
+    }
+
     if (outputFlags & OUTPUT_FILES) {
         OutputFileLog(tv, p, data, pq, postpq);
     }
@@ -724,6 +730,11 @@ OutputCtx *AlertJsonInitCtx(ConfNode *conf)
                     outputFlags |= OUTPUT_DNS;
                     continue;
                 }
+                if (strcmp(output->val, "drop") == 0) {
+                    SCLogDebug("Enabling drop output");
+                    outputFlags |= OUTPUT_DROP;
+                    continue;
+                }
                 if (strcmp(output->val, "files") == 0) {
                     SCLogDebug("Enabling files output");
                     ConfNode *child = ConfNodeLookupChild(output, "files");
index f914a141f4db565ff5d0def13edc0f2b0c57d9d0..53fc352c6abb1b35c429cb6b0777843f16a8e5cf 100644 (file)
@@ -41,8 +41,9 @@ OutputCtx *AlertJsonInitCtx(ConfNode *);
  */
 typedef struct OutputJsonCtx_ {
     LogFileCtx *file_ctx;
-    OutputCtx *http_ctx;
+    OutputCtx *drop_ctx;
     OutputCtx *files_ctx;
+    OutputCtx *http_ctx;
     OutputCtx *tls_ctx;
 } OutputJsonCtx;
 
@@ -54,11 +55,13 @@ typedef struct AlertJsonThread_ {
 
     uint64_t alert_cnt;
     uint64_t dns_cnt;
+    uint64_t drop_cnt;
     uint64_t files_cnt;
     uint64_t http_cnt;
     uint64_t tls_cnt;
-    OutputCtx *http_ctx;
+    OutputCtx *drop_ctx;
     OutputCtx *files_ctx;
+    OutputCtx *http_ctx;
     OutputCtx *tls_ctx;
 } AlertJsonThread;