]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
eve: log pktvars/flowvars/bits/ints
authorVictor Julien <victor@inliniac.net>
Fri, 21 Oct 2016 10:55:32 +0000 (12:55 +0200)
committerVictor Julien <victor@inliniac.net>
Thu, 16 Feb 2017 09:35:44 +0000 (10:35 +0100)
Optionally logs 'vars' into alerts

src/output-json-alert.c
src/output-json.c
src/output-json.h
suricata.yaml.in

index c589f1213b57bb4af4ce7b911b44a3fa8f224e45..258eeee9ffddea566f3d8543d13988f2c0edcb17 100644 (file)
@@ -81,6 +81,7 @@
 #define LOG_JSON_SMTP           0x040
 #define LOG_JSON_TAGGED_PACKETS 0x080
 #define LOG_JSON_DNP3           0x100
+#define LOG_JSON_VARS           0x200
 
 #define JSON_STREAM_BUFFER_SIZE 4096
 
@@ -319,6 +320,10 @@ static int AlertJson(ThreadVars *tv, JsonAlertLogThread *aft, const Packet *p)
             }
         }
 
+        if (json_output_ctx->flags & LOG_JSON_VARS) {
+            JsonAddVars(p, p->flow, js);
+        }
+
         /* payload */
         if (json_output_ctx->flags & (LOG_JSON_PAYLOAD | LOG_JSON_PAYLOAD_BASE64)) {
             int stream = (p->proto == IPPROTO_TCP) ?
@@ -637,7 +642,13 @@ static void XffSetup(AlertJsonOutputCtx *json_output_ctx, ConfNode *conf)
         const char *smtp = ConfNodeLookupChildValue(conf, "smtp");
         const char *tagged_packets = ConfNodeLookupChildValue(conf, "tagged-packets");
         const char *dnp3 = ConfNodeLookupChildValue(conf, "dnp3");
+        const char *vars = ConfNodeLookupChildValue(conf, "vars");
 
+        if (vars != NULL) {
+            if (ConfValIsTrue(vars)) {
+                json_output_ctx->flags |= LOG_JSON_VARS;
+            }
+        }
         if (ssh != NULL) {
             if (ConfValIsTrue(ssh)) {
                 json_output_ctx->flags |= LOG_JSON_SSH;
index ccf43b692359d40066f7883b2a273d8eec44fe9f..7aa7a23aa7abdde875a6005fa6090b381d4efdbd 100644 (file)
@@ -58,6 +58,8 @@
 #include "util-logopenfile.h"
 #include "util-device.h"
 
+#include "flow-var.h"
+#include "flow-bit.h"
 
 #ifndef HAVE_LIBJANSSON
 
@@ -92,6 +94,125 @@ void OutputJsonRegister (void)
 /* Default Sensor ID value */
 static int64_t sensor_id = -1; /* -1 = not defined */
 
+static void JsonAddPacketvars(const Packet *p, json_t *js_vars)
+{
+    if (p == NULL || p->pktvar == NULL) {
+        return;
+    }
+    json_t *js_pktvars = NULL;
+    PktVar *pv = p->pktvar;
+    while (pv != NULL) {
+        const char *varname = VarNameStoreLookupById(pv->id, VAR_TYPE_PKT_VAR);
+        if (varname) {
+            if (js_pktvars == NULL) {
+                js_pktvars = json_object();
+                if (js_pktvars == NULL)
+                    break;
+            }
+
+            uint32_t len = pv->value_len;
+            uint8_t printable_buf[len + 1];
+            uint32_t offset = 0;
+            PrintStringsToBuffer(printable_buf, &offset,
+                    sizeof(printable_buf),
+                    pv->value, pv->value_len);
+
+            json_object_set_new(js_pktvars, varname,
+                    json_string((char *)printable_buf));
+        }
+        pv = pv->next;
+    }
+    if (js_pktvars) {
+        json_object_set_new(js_vars, "pktvars", js_pktvars);
+    }
+}
+
+static void JsonAddFlowvars(const Flow *f, json_t *js_vars)
+{
+    if (f == NULL || f->flowvar == NULL) {
+        return;
+    }
+    json_t *js_flowvars = NULL;
+    json_t *js_flowints = NULL;
+    json_t *js_flowbits = NULL;
+    GenericVar *gv = f->flowvar;
+    while (gv != NULL) {
+        if (gv->type == DETECT_FLOWVAR || gv->type == DETECT_FLOWINT) {
+            FlowVar *fv = (FlowVar *)gv;
+            if (fv->datatype == FLOWVAR_TYPE_STR) {
+                const char *varname = VarNameStoreLookupById(fv->idx, VAR_TYPE_FLOW_VAR);
+                if (varname) {
+                    if (js_flowvars == NULL) {
+                        js_flowvars = json_object();
+                        if (js_flowvars == NULL)
+                            break;
+                    }
+
+                    uint32_t len = fv->data.fv_str.value_len;
+                    uint8_t printable_buf[len + 1];
+                    uint32_t offset = 0;
+                    PrintStringsToBuffer(printable_buf, &offset,
+                            sizeof(printable_buf),
+                            fv->data.fv_str.value, fv->data.fv_str.value_len);
+
+                    json_object_set_new(js_flowvars, varname,
+                            json_string((char *)printable_buf));
+                }
+            } else if (fv->datatype == FLOWVAR_TYPE_INT) {
+                const char *varname = VarNameStoreLookupById(fv->idx, VAR_TYPE_FLOW_INT);
+                if (varname) {
+                    if (js_flowints == NULL) {
+                        js_flowints = json_object();
+                        if (js_flowints == NULL)
+                            break;
+                    }
+
+                    json_object_set_new(js_flowints, varname, json_integer(fv->data.fv_int.value));
+                }
+
+            }
+        } else if (gv->type == DETECT_FLOWBITS) {
+            FlowBit *fb = (FlowBit *)gv;
+            const char *varname = VarNameStoreLookupById(fb->idx, VAR_TYPE_FLOW_BIT);
+            if (varname) {
+                if (js_flowbits == NULL) {
+                    js_flowbits = json_object();
+                    if (js_flowbits == NULL)
+                        break;
+                }
+                json_object_set_new(js_flowbits, varname, json_boolean(1));
+            }
+        }
+        gv = gv->next;
+    }
+    if (js_flowbits) {
+        json_object_set_new(js_vars, "flowbits", js_flowbits);
+    }
+    if (js_flowints) {
+        json_object_set_new(js_vars, "flowints", js_flowints);
+    }
+    if (js_flowvars) {
+        json_object_set_new(js_vars, "flowvars", js_flowvars);
+    }
+}
+
+void JsonAddVars(const Packet *p, const Flow *f, json_t *js)
+{
+    if ((p && p->pktvar) || (f && f->flowvar)) {
+        json_t *js_vars = json_object();
+        if (js_vars) {
+            if (f && f->flowvar) {
+                JsonAddFlowvars(f, js_vars);
+            }
+            if (p && p->pktvar) {
+                JsonAddPacketvars(p, js_vars);
+            }
+
+            json_object_set_new(js, "vars", js_vars);
+        }
+    }
+}
+
 /** \brief jsonify tcp flags field
  *  Only add 'true' fields in an attempt to keep things reasonably compact.
  */
index bb7d94de9ee56c221f9ae273712a4382251427fc..c654549219407c0cb3372f6d7cce97097fac1bf0 100644 (file)
@@ -39,6 +39,7 @@ typedef struct OutputJSONMemBufferWrapper_ {
 
 int OutputJSONMemBufferCallback(const char *str, size_t size, void *data);
 
+void JsonAddVars(const Packet *p, const Flow *f, json_t *js);
 void CreateJSONFlowId(json_t *js, const Flow *f);
 void JsonTcpFlags(uint8_t flags, json_t *js);
 json_t *CreateJSONHeader(const Packet *p, int direction_sensative, const char *event_type);
index eef8799486cbcbc08cab570cb863f56375b78a07..17090cb9363cbe9f3f919f03e308b5126a6fc8b7 100644 (file)
@@ -168,6 +168,7 @@ outputs:
             ssh: yes                 # enable dumping of ssh fields
             smtp: yes                # enable dumping of smtp fields
             dnp3: yes                # enable dumping of DNP3 fields
+            vars: yes                # enable dumping of flowbits and other vars
 
             # Enable the logging of tagged packets for rules using the
             # "tag" keyword.