]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
eve: top level metadata object
authorJason Ish <ish@unx.ca>
Mon, 11 Dec 2017 16:16:47 +0000 (10:16 -0600)
committerVictor Julien <victor@inliniac.net>
Tue, 30 Jan 2018 13:43:51 +0000 (14:43 +0100)
Contains:
- flowbits (as array)
- flowints (map)
- flowvars (map)
- pktvars (map)

src/output-json.c

index 4d2fe5e572316f46f20c00f7947497c27dc8ee85..26bd123e99899df75b08894ccca4327e084b56d5 100644 (file)
@@ -154,6 +154,111 @@ static void JsonAddPacketvars(const Packet *p, json_t *js_vars)
     }
 }
 
+/**
+ * \brief "New" Add flow variables to a json object.
+ *
+ * Adds "flowvars" (map), "flowints" (map) and "flowbits" (array) to
+ * the json object provided as js_root.
+ *
+ * This is the "new" method for doing this as flowbits is an array of
+ * strings instead of a map of boolean values.
+ */
+static void JsonAddFlowVars(const Flow *f, json_t *js_root)
+{
+    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 && fv->key == NULL) {
+                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_STR && fv->key != NULL) {
+                if (js_flowvars == NULL) {
+                    js_flowvars = json_object();
+                    if (js_flowvars == NULL)
+                        break;
+                }
+
+                uint8_t keybuf[fv->keylen + 1];
+                uint32_t offset = 0;
+                PrintStringsToBuffer(keybuf, &offset,
+                        sizeof(keybuf),
+                        fv->key, fv->keylen);
+
+                uint32_t len = fv->data.fv_str.value_len;
+                uint8_t printable_buf[len + 1];
+                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, (const char *)keybuf,
+                        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_array();
+                    if (js_flowbits == NULL)
+                        break;
+                }
+                json_array_append(js_flowbits, json_string(varname));
+            }
+        }
+        gv = gv->next;
+    }
+    if (js_flowbits) {
+        json_object_set_new(js_root, "flowbits", js_flowbits);
+    }
+    if (js_flowints) {
+        json_object_set_new(js_root, "flowints", js_flowints);
+    }
+    if (js_flowvars) {
+        json_object_set_new(js_root, "flowvars", js_flowvars);
+    }
+}
+
 static void JsonAddFlowvars(const Flow *f, json_t *js_vars)
 {
     if (f == NULL || f->flowvar == NULL) {
@@ -263,6 +368,26 @@ void JsonAddVars(const Packet *p, const Flow *f, json_t *js)
     }
 }
 
+/**
+ * \brief Add top-level metadata to the eve json object.
+ */
+static void JsonAddMetadata(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, "metadata", js_vars);
+        }
+    }
+}
+
 /** \brief jsonify tcp flags field
  *  Only add 'true' fields in an attempt to keep things reasonably compact.
  */
@@ -396,6 +521,7 @@ json_t *CreateJSONHeader(const Packet *p, int direction_sensitive,
                          const char *event_type)
 {
     char timebuf[64];
+    const Flow *f = (const Flow *)p->flow;
 
     json_t *js = json_object();
     if (unlikely(js == NULL))
@@ -406,7 +532,7 @@ json_t *CreateJSONHeader(const Packet *p, int direction_sensitive,
     /* time & tx */
     json_object_set_new(js, "timestamp", json_string(timebuf));
 
-    CreateJSONFlowId(js, (const Flow *)p->flow);
+    CreateJSONFlowId(js, f);
 
     /* sensor id */
     if (sensor_id >= 0)
@@ -453,6 +579,9 @@ json_t *CreateJSONHeader(const Packet *p, int direction_sensitive,
     /* 5-tuple */
     JsonFiveTuple(p, direction_sensitive, js);
 
+    /* Metadata. */
+    JsonAddMetadata(p, f, js);
+
     /* icmp */
     switch (p->proto) {
         case IPPROTO_ICMP: