suricata
output-json.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2018 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Tom DeCanio <td@npulsetech.com>
22  *
23  * Logs detection and monitoring events in JSON format.
24  *
25  */
26 
27 #include "suricata-common.h"
28 #include "debug.h"
29 #include "detect.h"
30 #include "flow.h"
31 #include "conf.h"
32 
33 #include "threads.h"
34 #include "tm-threads.h"
35 #include "threadvars.h"
36 #include "util-debug.h"
37 
38 #include "util-unittest.h"
39 #include "util-unittest-helper.h"
40 
41 #include "detect-parse.h"
42 #include "detect-engine.h"
43 #include "detect-engine-mpm.h"
44 #include "detect-reference.h"
45 #include "app-layer-parser.h"
47 #include "util-syslog.h"
48 
49 #include "output.h"
50 #include "output-json.h"
51 
52 #include "util-byte.h"
53 #include "util-privs.h"
54 #include "util-print.h"
55 #include "util-proto-name.h"
56 #include "util-optimize.h"
57 #include "util-buffer.h"
58 #include "util-logopenfile.h"
59 #include "util-log-redis.h"
60 #include "util-device.h"
61 #include "util-validate.h"
62 #include "util-crypt.h"
63 
64 #include "flow-var.h"
65 #include "flow-bit.h"
66 
67 #include "source-pcap-file.h"
68 
69 #define DEFAULT_LOG_FILENAME "eve.json"
70 #define DEFAULT_ALERT_SYSLOG_FACILITY_STR "local0"
71 #define DEFAULT_ALERT_SYSLOG_FACILITY LOG_LOCAL0
72 #define DEFAULT_ALERT_SYSLOG_LEVEL LOG_INFO
73 #define MODULE_NAME "OutputJSON"
74 
75 #define MAX_JSON_SIZE 2048
76 
77 static void OutputJsonDeInitCtx(OutputCtx *);
78 static void CreateJSONCommunityFlowId(json_t *js, const Flow *f, const uint16_t seed);
79 
80 static const char *TRAFFIC_ID_PREFIX = "traffic/id/";
81 static const char *TRAFFIC_LABEL_PREFIX = "traffic/label/";
82 static size_t traffic_id_prefix_len = 0;
83 static size_t traffic_label_prefix_len = 0;
84 
85 void OutputJsonRegister (void)
86 {
88 
89  traffic_id_prefix_len = strlen(TRAFFIC_ID_PREFIX);
90  traffic_label_prefix_len = strlen(TRAFFIC_LABEL_PREFIX);
91 }
92 
93 json_t *SCJsonBool(int val)
94 {
95  return (val ? json_true() : json_false());
96 }
97 
98 /**
99  * Wrap json_decref. This is mainly to expose this function to Rust as its
100  * defined in the Jansson header file as an inline function.
101  */
102 void SCJsonDecref(json_t *json)
103 {
104  json_decref(json);
105 }
106 
107 json_t *SCJsonString(const char *val)
108 {
109  if (val == NULL){
110  return NULL;
111  }
112  json_t * retval = json_string(val);
113  char retbuf[MAX_JSON_SIZE] = {0};
114  if (retval == NULL) {
115  uint32_t u = 0;
116  uint32_t offset = 0;
117  for (u = 0; u < strlen(val); u++) {
118  if (isprint(val[u])) {
119  PrintBufferData(retbuf, &offset, MAX_JSON_SIZE-1, "%c",
120  val[u]);
121  } else {
122  PrintBufferData(retbuf, &offset, MAX_JSON_SIZE-1,
123  "\\x%02X", val[u]);
124  }
125  }
126  retbuf[offset] = '\0';
127  retval = json_string(retbuf);
128  }
129  return retval;
130 }
131 
132 /* Default Sensor ID value */
133 static int64_t sensor_id = -1; /* -1 = not defined */
134 
135 /**
136  * \brief Create a JSON string from a character sequence
137  *
138  * \param Pointer to character sequence
139  * \param Number of characters to use from the sequence
140  * \retval JSON object for the character sequence
141  */
142 json_t *JsonAddStringN(const char *string, size_t size)
143 {
144  char tmpbuf[size + 1];
145 
146  memcpy(tmpbuf, string, size);
147  tmpbuf[size] = '\0';
148 
149  return SCJsonString(tmpbuf);
150 }
151 static void JsonAddPacketvars(const Packet *p, json_t *js_vars)
152 {
153  if (p == NULL || p->pktvar == NULL) {
154  return;
155  }
156  json_t *js_pktvars = NULL;
157  PktVar *pv = p->pktvar;
158  while (pv != NULL) {
159  if (pv->key || pv->id > 0) {
160  if (js_pktvars == NULL) {
161  js_pktvars = json_array();
162  if (js_pktvars == NULL)
163  break;
164  }
165  json_t *js_pair = json_object();
166  if (js_pair == NULL) {
167  break;
168  }
169 
170  if (pv->key != NULL) {
171  uint32_t offset = 0;
172  uint8_t keybuf[pv->key_len + 1];
173  PrintStringsToBuffer(keybuf, &offset,
174  sizeof(keybuf),
175  pv->key, pv->key_len);
176  uint32_t len = pv->value_len;
177  uint8_t printable_buf[len + 1];
178  offset = 0;
179  PrintStringsToBuffer(printable_buf, &offset,
180  sizeof(printable_buf),
181  pv->value, pv->value_len);
182  json_object_set_new(js_pair, (char *)keybuf,
183  json_string((char *)printable_buf));
184  } else {
185  const char *varname = VarNameStoreLookupById(pv->id, VAR_TYPE_PKT_VAR);
186  uint32_t len = pv->value_len;
187  uint8_t printable_buf[len + 1];
188  uint32_t offset = 0;
189  PrintStringsToBuffer(printable_buf, &offset,
190  sizeof(printable_buf),
191  pv->value, pv->value_len);
192 
193  json_object_set_new(js_pair, varname,
194  json_string((char *)printable_buf));
195  }
196  json_array_append_new(js_pktvars, js_pair);
197  }
198  pv = pv->next;
199  }
200  if (js_pktvars) {
201  json_object_set_new(js_vars, "pktvars", js_pktvars);
202  }
203 }
204 
205 /**
206  * \brief Check if string s has prefix prefix.
207  *
208  * \retval true if string has prefix
209  * \retval false if string does not have prefix
210  *
211  * TODO: Move to file with other string handling functions.
212  */
213 static bool SCStringHasPrefix(const char *s, const char *prefix)
214 {
215  if (strncmp(s, prefix, strlen(prefix)) == 0) {
216  return true;
217  }
218  return false;
219 }
220 
221 /**
222  * \brief Add flow variables to a json object.
223  *
224  * Adds "flowvars" (map), "flowints" (map) and "flowbits" (array) to
225  * the json object provided as js_root.
226  */
227 static void JsonAddFlowVars(const Flow *f, json_t *js_root, json_t **js_traffic)
228 {
229  if (f == NULL || f->flowvar == NULL) {
230  return;
231  }
232  json_t *js_flowvars = NULL;
233  json_t *js_traffic_id = NULL;
234  json_t *js_traffic_label = NULL;
235  json_t *js_flowints = NULL;
236  json_t *js_flowbits = NULL;
237  GenericVar *gv = f->flowvar;
238  while (gv != NULL) {
239  if (gv->type == DETECT_FLOWVAR || gv->type == DETECT_FLOWINT) {
240  FlowVar *fv = (FlowVar *)gv;
241  if (fv->datatype == FLOWVAR_TYPE_STR && fv->key == NULL) {
242  const char *varname = VarNameStoreLookupById(fv->idx,
244  if (varname) {
245  if (js_flowvars == NULL) {
246  js_flowvars = json_array();
247  if (js_flowvars == NULL)
248  break;
249  }
250 
251  uint32_t len = fv->data.fv_str.value_len;
252  uint8_t printable_buf[len + 1];
253  uint32_t offset = 0;
254  PrintStringsToBuffer(printable_buf, &offset,
255  sizeof(printable_buf),
256  fv->data.fv_str.value, fv->data.fv_str.value_len);
257 
258  json_t *js_flowvar = json_object();
259  if (unlikely(js_flowvar == NULL)) {
260  break;
261  }
262  json_object_set_new(js_flowvar, varname,
263  json_string((char *)printable_buf));
264  json_array_append_new(js_flowvars, js_flowvar);
265  }
266  } else if (fv->datatype == FLOWVAR_TYPE_STR && fv->key != NULL) {
267  if (js_flowvars == NULL) {
268  js_flowvars = json_array();
269  if (js_flowvars == NULL)
270  break;
271  }
272 
273  uint8_t keybuf[fv->keylen + 1];
274  uint32_t offset = 0;
275  PrintStringsToBuffer(keybuf, &offset,
276  sizeof(keybuf),
277  fv->key, fv->keylen);
278 
279  uint32_t len = fv->data.fv_str.value_len;
280  uint8_t printable_buf[len + 1];
281  offset = 0;
282  PrintStringsToBuffer(printable_buf, &offset,
283  sizeof(printable_buf),
284  fv->data.fv_str.value, fv->data.fv_str.value_len);
285 
286  json_t *js_flowvar = json_object();
287  if (unlikely(js_flowvar == NULL)) {
288  break;
289  }
290  json_object_set_new(js_flowvar, (const char *)keybuf,
291  json_string((char *)printable_buf));
292  json_array_append_new(js_flowvars, js_flowvar);
293  } else if (fv->datatype == FLOWVAR_TYPE_INT) {
294  const char *varname = VarNameStoreLookupById(fv->idx,
296  if (varname) {
297  if (js_flowints == NULL) {
298  js_flowints = json_object();
299  if (js_flowints == NULL)
300  break;
301  }
302 
303  json_object_set_new(js_flowints, varname,
304  json_integer(fv->data.fv_int.value));
305  }
306 
307  }
308  } else if (gv->type == DETECT_FLOWBITS) {
309  FlowBit *fb = (FlowBit *)gv;
310  const char *varname = VarNameStoreLookupById(fb->idx,
312  if (varname) {
313  if (SCStringHasPrefix(varname, TRAFFIC_ID_PREFIX)) {
314  if (js_traffic_id == NULL) {
315  js_traffic_id = json_array();
316  if (unlikely(js_traffic_id == NULL)) {
317  break;
318  }
319  }
320  json_array_append_new(js_traffic_id,
321  json_string(&varname[traffic_id_prefix_len]));
322  } else if (SCStringHasPrefix(varname, TRAFFIC_LABEL_PREFIX)) {
323  if (js_traffic_label == NULL) {
324  js_traffic_label = json_array();
325  if (unlikely(js_traffic_label == NULL)) {
326  break;
327  }
328  }
329  json_array_append_new(js_traffic_label,
330  json_string(&varname[traffic_label_prefix_len]));
331  } else {
332  if (js_flowbits == NULL) {
333  js_flowbits = json_array();
334  if (unlikely(js_flowbits == NULL))
335  break;
336  }
337  json_array_append_new(js_flowbits, json_string(varname));
338  }
339  }
340  }
341  gv = gv->next;
342  }
343  if (js_flowbits) {
344  json_object_set_new(js_root, "flowbits", js_flowbits);
345  }
346  if (js_flowints) {
347  json_object_set_new(js_root, "flowints", js_flowints);
348  }
349  if (js_flowvars) {
350  json_object_set_new(js_root, "flowvars", js_flowvars);
351  }
352 
353  if (js_traffic_id != NULL || js_traffic_label != NULL) {
354  *js_traffic = json_object();
355  if (likely(*js_traffic != NULL)) {
356  if (js_traffic_id != NULL) {
357  json_object_set_new(*js_traffic, "id", js_traffic_id);
358  }
359  if (js_traffic_label != NULL) {
360  json_object_set_new(*js_traffic, "label", js_traffic_label);
361  }
362  }
363  }
364 }
365 
366 /**
367  * \brief Add top-level metadata to the eve json object.
368  */
369 static void JsonAddMetadata(const Packet *p, const Flow *f, json_t *js)
370 {
371  if ((p && p->pktvar) || (f && f->flowvar)) {
372  json_t *js_vars = json_object();
373  json_t *js_traffic = NULL;
374  if (js_vars) {
375  if (f && f->flowvar) {
376  JsonAddFlowVars(f, js_vars, &js_traffic);
377  if (js_traffic != NULL) {
378  json_object_set_new(js, "traffic", js_traffic);
379  }
380  }
381  if (p && p->pktvar) {
382  JsonAddPacketvars(p, js_vars);
383  }
384 
385  json_object_set_new(js, "metadata", js_vars);
386  }
387  }
388 }
389 
391  const Packet *p, const Flow *f, json_t *js)
392 {
393  if (cfg->include_metadata) {
394  JsonAddMetadata(p, f, js);
395  }
396  if (cfg->include_community_id && f != NULL) {
397  CreateJSONCommunityFlowId(js, f, cfg->community_id_seed);
398  }
399 }
400 
401 /**
402  * \brief Jsonify a packet
403  *
404  * \param p Packet
405  * \param js JSON object
406  * \param max_length If non-zero, restricts the number of packet data bytes handled.
407  */
408 void JsonPacket(const Packet *p, json_t *js, unsigned long max_length)
409 {
410  unsigned long max_len = max_length == 0 ? GET_PKT_LEN(p) : max_length;
411  unsigned long len = 2 * max_len;
412  uint8_t encoded_packet[len];
413  if (Base64Encode((unsigned char*) GET_PKT_DATA(p), max_len, encoded_packet, &len) == SC_BASE64_OK) {
414  json_object_set_new(js, "packet", json_string((char *)encoded_packet));
415  }
416 
417  /* Create packet info. */
418  json_t *packetinfo_js = json_object();
419  if (unlikely(packetinfo_js == NULL)) {
420  return;
421  }
422  json_object_set_new(packetinfo_js, "linktype", json_integer(p->datalink));
423  json_object_set_new(js, "packet_info", packetinfo_js);
424 }
425 /** \brief jsonify tcp flags field
426  * Only add 'true' fields in an attempt to keep things reasonably compact.
427  */
428 void JsonTcpFlags(uint8_t flags, json_t *js)
429 {
430  if (flags & TH_SYN)
431  json_object_set_new(js, "syn", json_true());
432  if (flags & TH_FIN)
433  json_object_set_new(js, "fin", json_true());
434  if (flags & TH_RST)
435  json_object_set_new(js, "rst", json_true());
436  if (flags & TH_PUSH)
437  json_object_set_new(js, "psh", json_true());
438  if (flags & TH_ACK)
439  json_object_set_new(js, "ack", json_true());
440  if (flags & TH_URG)
441  json_object_set_new(js, "urg", json_true());
442  if (flags & TH_ECN)
443  json_object_set_new(js, "ecn", json_true());
444  if (flags & TH_CWR)
445  json_object_set_new(js, "cwr", json_true());
446 }
447 
448 /**
449  * \brief Add five tuple from packet to JSON object
450  *
451  * \param p Packet
452  * \param dir log direction (packet or flow)
453  * \param js JSON object
454  */
455 void JsonFiveTuple(const Packet *p, enum OutputJsonLogDirection dir, json_t *js)
456 {
457  char srcip[46] = {0}, dstip[46] = {0};
458  Port sp, dp;
459  char proto[16];
460 
461  switch (dir) {
462  case LOG_DIR_PACKET:
463  if (PKT_IS_IPV4(p)) {
464  PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p),
465  srcip, sizeof(srcip));
466  PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p),
467  dstip, sizeof(dstip));
468  } else if (PKT_IS_IPV6(p)) {
469  PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p),
470  srcip, sizeof(srcip));
471  PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p),
472  dstip, sizeof(dstip));
473  } else {
474  /* Not an IP packet so don't do anything */
475  return;
476  }
477  sp = p->sp;
478  dp = p->dp;
479  break;
480  case LOG_DIR_FLOW:
482  if ((PKT_IS_TOSERVER(p))) {
483  if (PKT_IS_IPV4(p)) {
484  PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p),
485  srcip, sizeof(srcip));
486  PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p),
487  dstip, sizeof(dstip));
488  } else if (PKT_IS_IPV6(p)) {
489  PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p),
490  srcip, sizeof(srcip));
491  PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p),
492  dstip, sizeof(dstip));
493  }
494  sp = p->sp;
495  dp = p->dp;
496  } else {
497  if (PKT_IS_IPV4(p)) {
498  PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p),
499  srcip, sizeof(srcip));
500  PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p),
501  dstip, sizeof(dstip));
502  } else if (PKT_IS_IPV6(p)) {
503  PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p),
504  srcip, sizeof(srcip));
505  PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p),
506  dstip, sizeof(dstip));
507  }
508  sp = p->dp;
509  dp = p->sp;
510  }
511  break;
513  if ((PKT_IS_TOCLIENT(p))) {
514  if (PKT_IS_IPV4(p)) {
515  PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p),
516  srcip, sizeof(srcip));
517  PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p),
518  dstip, sizeof(dstip));
519  } else if (PKT_IS_IPV6(p)) {
520  PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p),
521  srcip, sizeof(srcip));
522  PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p),
523  dstip, sizeof(dstip));
524  }
525  sp = p->sp;
526  dp = p->dp;
527  } else {
528  if (PKT_IS_IPV4(p)) {
529  PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p),
530  srcip, sizeof(srcip));
531  PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p),
532  dstip, sizeof(dstip));
533  } else if (PKT_IS_IPV6(p)) {
534  PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p),
535  srcip, sizeof(srcip));
536  PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p),
537  dstip, sizeof(dstip));
538  }
539  sp = p->dp;
540  dp = p->sp;
541  }
542  break;
543  default:
545  return;
546  }
547 
548  if (SCProtoNameValid(IP_GET_IPPROTO(p)) == TRUE) {
549  strlcpy(proto, known_proto[IP_GET_IPPROTO(p)], sizeof(proto));
550  } else {
551  snprintf(proto, sizeof(proto), "%03" PRIu32, IP_GET_IPPROTO(p));
552  }
553 
554  json_object_set_new(js, "src_ip", json_string(srcip));
555 
556  switch(p->proto) {
557  case IPPROTO_ICMP:
558  break;
559  case IPPROTO_UDP:
560  case IPPROTO_TCP:
561  case IPPROTO_SCTP:
562  json_object_set_new(js, "src_port", json_integer(sp));
563  break;
564  }
565 
566  json_object_set_new(js, "dest_ip", json_string(dstip));
567 
568  switch(p->proto) {
569  case IPPROTO_ICMP:
570  break;
571  case IPPROTO_UDP:
572  case IPPROTO_TCP:
573  case IPPROTO_SCTP:
574  json_object_set_new(js, "dest_port", json_integer(dp));
575  break;
576  }
577 
578  json_object_set_new(js, "proto", json_string(proto));
579 }
580 
581 static void CreateJSONCommunityFlowIdv4(json_t *js, const Flow *f,
582  const uint16_t seed)
583 {
584  struct {
585  uint16_t seed;
586  uint32_t src;
587  uint32_t dst;
588  uint8_t proto;
589  uint8_t pad0;
590  uint16_t sp;
591  uint16_t dp;
592  } __attribute__((__packed__)) ipv4;
593 
594  uint32_t src = f->src.addr_data32[0];
595  uint32_t dst = f->dst.addr_data32[0];
596  uint16_t sp = f->sp;
597  if (f->proto == IPPROTO_ICMP)
598  sp = f->icmp_s.type;
599  sp = htons(sp);
600  uint16_t dp = f->dp;
601  if (f->proto == IPPROTO_ICMP)
602  dp = f->icmp_d.type;
603  dp = htons(dp);
604 
605  ipv4.seed = htons(seed);
606  if (ntohl(src) < ntohl(dst) || (src == dst && sp < dp)) {
607  ipv4.src = src;
608  ipv4.dst = dst;
609  ipv4.sp = sp;
610  ipv4.dp = dp;
611  } else {
612  ipv4.src = dst;
613  ipv4.dst = src;
614  ipv4.sp = dp;
615  ipv4.dp = sp;
616  }
617  ipv4.proto = f->proto;
618  ipv4.pad0 = 0;
619 
620  uint8_t hash[20];
621  if (ComputeSHA1((const uint8_t *)&ipv4, sizeof(ipv4), hash, sizeof(hash)) == 1) {
622  unsigned char base64buf[64] = "1:";
623  unsigned long out_len = sizeof(base64buf) - 2;
624  if (Base64Encode(hash, sizeof(hash), base64buf+2, &out_len) == SC_BASE64_OK) {
625  json_object_set_new(js, "community_id", json_string((const char *)base64buf));
626  }
627  }
628 }
629 
630 static inline bool FlowHashRawAddressIPv6LtU32(const uint32_t *a, const uint32_t *b)
631 {
632  for (int i = 0; i < 4; i++) {
633  if (a[i] < b[i])
634  return true;
635  if (a[i] > b[i])
636  break;
637  }
638 
639  return false;
640 }
641 
642 static void CreateJSONCommunityFlowIdv6(json_t *js, const Flow *f,
643  const uint16_t seed)
644 {
645  struct {
646  uint16_t seed;
647  uint32_t src[4];
648  uint32_t dst[4];
649  uint8_t proto;
650  uint8_t pad0;
651  uint16_t sp;
652  uint16_t dp;
653  } __attribute__((__packed__)) ipv6;
654 
655  uint16_t sp = f->sp;
656  if (f->proto == IPPROTO_ICMPV6)
657  sp = f->icmp_s.type;
658  sp = htons(sp);
659  uint16_t dp = f->dp;
660  if (f->proto == IPPROTO_ICMPV6)
661  dp = f->icmp_d.type;
662  dp = htons(dp);
663 
664  ipv6.seed = htons(seed);
665  if (FlowHashRawAddressIPv6LtU32(f->src.addr_data32, f->dst.addr_data32) ||
666  ((memcmp(&f->src, &f->dst, sizeof(f->src)) == 0) && sp < dp))
667  {
668  memcpy(&ipv6.src, &f->src.addr_data32, 16);
669  memcpy(&ipv6.dst, &f->dst.addr_data32, 16);
670  ipv6.sp = sp;
671  ipv6.dp = dp;
672  } else {
673  memcpy(&ipv6.src, &f->dst.addr_data32, 16);
674  memcpy(&ipv6.dst, &f->src.addr_data32, 16);
675  ipv6.sp = dp;
676  ipv6.dp = sp;
677  }
678  ipv6.proto = f->proto;
679  ipv6.pad0 = 0;
680 
681  uint8_t hash[20];
682  if (ComputeSHA1((const uint8_t *)&ipv6, sizeof(ipv6), hash, sizeof(hash)) == 1) {
683  unsigned char base64buf[64] = "1:";
684  unsigned long out_len = sizeof(base64buf) - 2;
685  if (Base64Encode(hash, sizeof(hash), base64buf+2, &out_len) == SC_BASE64_OK) {
686  json_object_set_new(js, "community_id", json_string((const char *)base64buf));
687  }
688  }
689 }
690 
691 static void CreateJSONCommunityFlowId(json_t *js, const Flow *f, const uint16_t seed)
692 {
693  if (f->flags & FLOW_IPV4)
694  return CreateJSONCommunityFlowIdv4(js, f, seed);
695  else if (f->flags & FLOW_IPV6)
696  return CreateJSONCommunityFlowIdv6(js, f, seed);
697 }
698 
699 void CreateJSONFlowId(json_t *js, const Flow *f)
700 {
701  if (f == NULL)
702  return;
703  int64_t flow_id = FlowGetId(f);
704  json_object_set_new(js, "flow_id", json_integer(flow_id));
705  if (f->parent_id) {
706  json_object_set_new(js, "parent_id", json_integer(f->parent_id));
707  }
708 }
709 
710 json_t *CreateJSONHeader(const Packet *p, enum OutputJsonLogDirection dir,
711  const char *event_type)
712 {
713  char timebuf[64];
714  const Flow *f = (const Flow *)p->flow;
715 
716  json_t *js = json_object();
717  if (unlikely(js == NULL))
718  return NULL;
719 
720  CreateIsoTimeString(&p->ts, timebuf, sizeof(timebuf));
721 
722  /* time & tx */
723  json_object_set_new(js, "timestamp", json_string(timebuf));
724 
725  CreateJSONFlowId(js, f);
726 
727  /* sensor id */
728  if (sensor_id >= 0)
729  json_object_set_new(js, "sensor_id", json_integer(sensor_id));
730 
731  /* input interface */
732  if (p->livedev) {
733  json_object_set_new(js, "in_iface", json_string(p->livedev->dev));
734  }
735 
736  /* pcap_cnt */
737  if (p->pcap_cnt != 0) {
738  json_object_set_new(js, "pcap_cnt", json_integer(p->pcap_cnt));
739  }
740 
741  if (event_type) {
742  json_object_set_new(js, "event_type", json_string(event_type));
743  }
744 
745  /* vlan */
746  if (p->vlan_idx > 0) {
747  json_t *js_vlan = json_array();
748  if (js_vlan) {
749  json_array_append_new(js_vlan, json_integer(p->vlan_id[0]));
750  if (p->vlan_idx > 1) {
751  json_array_append_new(js_vlan, json_integer(p->vlan_id[1]));
752  }
753  json_object_set_new(js, "vlan", js_vlan);
754  }
755  }
756 
757  /* 5-tuple */
758  JsonFiveTuple(p, dir, js);
759 
760  /* icmp */
761  switch (p->proto) {
762  case IPPROTO_ICMP:
763  if (p->icmpv4h) {
764  json_object_set_new(js, "icmp_type",
765  json_integer(p->icmpv4h->type));
766  json_object_set_new(js, "icmp_code",
767  json_integer(p->icmpv4h->code));
768  }
769  break;
770  case IPPROTO_ICMPV6:
771  if (p->icmpv6h) {
772  json_object_set_new(js, "icmp_type",
773  json_integer(p->icmpv6h->type));
774  json_object_set_new(js, "icmp_code",
775  json_integer(p->icmpv6h->code));
776  }
777  break;
778  }
779 
780  return js;
781 }
782 
784  const char *event_type, uint64_t tx_id)
785 {
786  json_t *js = CreateJSONHeader(p, dir, event_type);
787  if (unlikely(js == NULL))
788  return NULL;
789 
790  /* tx id for correlation with other events */
791  json_object_set_new(js, "tx_id", json_integer(tx_id));
792 
793  return js;
794 }
795 
796 int OutputJSONMemBufferCallback(const char *str, size_t size, void *data)
797 {
798  OutputJSONMemBufferWrapper *wrapper = data;
799  MemBuffer **memb = wrapper->buffer;
800 
801  if (MEMBUFFER_OFFSET(*memb) + size >= MEMBUFFER_SIZE(*memb)) {
802  MemBufferExpand(memb, wrapper->expand_by);
803  }
804 
805  MemBufferWriteRaw((*memb), str, size);
806  return 0;
807 }
808 
809 int OutputJSONBuffer(json_t *js, LogFileCtx *file_ctx, MemBuffer **buffer)
810 {
811  if (file_ctx->sensor_name) {
812  json_object_set_new(js, "host",
813  json_string(file_ctx->sensor_name));
814  }
815 
816  if (file_ctx->is_pcap_offline) {
817  json_object_set_new(js, "pcap_filename", json_string(PcapFileGetFilename()));
818  }
819 
820  if (file_ctx->prefix) {
821  MemBufferWriteRaw((*buffer), file_ctx->prefix, file_ctx->prefix_len);
822  }
823 
824  OutputJSONMemBufferWrapper wrapper = {
825  .buffer = buffer,
826  .expand_by = JSON_OUTPUT_BUFFER_SIZE
827  };
828 
829  int r = json_dump_callback(js, OutputJSONMemBufferCallback, &wrapper,
830  file_ctx->json_flags);
831  if (r != 0)
832  return TM_ECODE_OK;
833 
834  LogFileWrite(file_ctx, *buffer);
835  return 0;
836 }
837 
838 /**
839  * \brief Create a new LogFileCtx for "fast" output style.
840  * \param conf The configuration node for this output.
841  * \return A LogFileCtx pointer on success, NULL on failure.
842  */
844 {
845  OutputInitResult result = { NULL, false };
846 
847  OutputJsonCtx *json_ctx = SCCalloc(1, sizeof(OutputJsonCtx));
848  if (unlikely(json_ctx == NULL)) {
849  SCLogDebug("could not create new OutputJsonCtx");
850  return result;
851  }
852 
853  /* First lookup a sensor-name value in this outputs configuration
854  * node (deprecated). If that fails, lookup the global one. */
855  const char *sensor_name = ConfNodeLookupChildValue(conf, "sensor-name");
856  if (sensor_name != NULL) {
858  "Found deprecated eve-log setting \"sensor-name\". "
859  "Please set sensor-name globally.");
860  }
861  else {
862  (void)ConfGet("sensor-name", &sensor_name);
863  }
864 
865  json_ctx->file_ctx = LogFileNewCtx();
866  if (unlikely(json_ctx->file_ctx == NULL)) {
867  SCLogDebug("AlertJsonInitCtx: Could not create new LogFileCtx");
868  SCFree(json_ctx);
869  return result;
870  }
871 
872  if (sensor_name) {
873  json_ctx->file_ctx->sensor_name = SCStrdup(sensor_name);
874  if (json_ctx->file_ctx->sensor_name == NULL) {
875  LogFileFreeCtx(json_ctx->file_ctx);
876  SCFree(json_ctx);
877  return result;
878  }
879  } else {
880  json_ctx->file_ctx->sensor_name = NULL;
881  }
882 
883  OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
884  if (unlikely(output_ctx == NULL)) {
885  LogFileFreeCtx(json_ctx->file_ctx);
886  SCFree(json_ctx);
887  return result;
888  }
889 
890  output_ctx->data = json_ctx;
891  output_ctx->DeInit = OutputJsonDeInitCtx;
892 
893  if (conf) {
894  const char *output_s = ConfNodeLookupChildValue(conf, "filetype");
895 
896  // Backwards compatibility
897  if (output_s == NULL) {
898  output_s = ConfNodeLookupChildValue(conf, "type");
899  }
900 
901  if (output_s != NULL) {
902  if (strcmp(output_s, "file") == 0 ||
903  strcmp(output_s, "regular") == 0) {
904  json_ctx->json_out = LOGFILE_TYPE_FILE;
905  } else if (strcmp(output_s, "syslog") == 0) {
906  json_ctx->json_out = LOGFILE_TYPE_SYSLOG;
907  } else if (strcmp(output_s, "unix_dgram") == 0) {
908  json_ctx->json_out = LOGFILE_TYPE_UNIX_DGRAM;
909  } else if (strcmp(output_s, "unix_stream") == 0) {
911  } else if (strcmp(output_s, "redis") == 0) {
912 #ifdef HAVE_LIBHIREDIS
913  SCLogRedisInit();
914  json_ctx->json_out = LOGFILE_TYPE_REDIS;
915 #else
917  "redis JSON output option is not compiled");
918  exit(EXIT_FAILURE);
919 #endif
920  } else {
922  "Invalid JSON output option: %s", output_s);
923  exit(EXIT_FAILURE);
924  }
925  }
926 
927  const char *prefix = ConfNodeLookupChildValue(conf, "prefix");
928  if (prefix != NULL)
929  {
930  SCLogInfo("Using prefix '%s' for JSON messages", prefix);
931  json_ctx->file_ctx->prefix = SCStrdup(prefix);
932  if (json_ctx->file_ctx->prefix == NULL)
933  {
935  "Failed to allocate memory for eve-log.prefix setting.");
936  exit(EXIT_FAILURE);
937  }
938  json_ctx->file_ctx->prefix_len = strlen(prefix);
939  }
940 
941  if (json_ctx->json_out == LOGFILE_TYPE_FILE ||
942  json_ctx->json_out == LOGFILE_TYPE_UNIX_DGRAM ||
943  json_ctx->json_out == LOGFILE_TYPE_UNIX_STREAM)
944  {
945  if (SCConfLogOpenGeneric(conf, json_ctx->file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) {
946  LogFileFreeCtx(json_ctx->file_ctx);
947  SCFree(json_ctx);
948  SCFree(output_ctx);
949  return result;
950  }
952  }
953 #ifndef OS_WIN32
954  else if (json_ctx->json_out == LOGFILE_TYPE_SYSLOG) {
955  const char *facility_s = ConfNodeLookupChildValue(conf, "facility");
956  if (facility_s == NULL) {
958  }
959 
960  int facility = SCMapEnumNameToValue(facility_s, SCSyslogGetFacilityMap());
961  if (facility == -1) {
962  SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid syslog facility: \"%s\","
963  " now using \"%s\" as syslog facility", facility_s,
966  }
967 
968  const char *level_s = ConfNodeLookupChildValue(conf, "level");
969  if (level_s != NULL) {
970  int level = SCMapEnumNameToValue(level_s, SCSyslogGetLogLevelMap());
971  if (level != -1) {
972  json_ctx->file_ctx->syslog_setup.alert_syslog_level = level;
973  }
974  }
975 
976  const char *ident = ConfNodeLookupChildValue(conf, "identity");
977  /* if null we just pass that to openlog, which will then
978  * figure it out by itself. */
979 
980  openlog(ident, LOG_PID|LOG_NDELAY, facility);
981  }
982 #endif
983 #ifdef HAVE_LIBHIREDIS
984  else if (json_ctx->json_out == LOGFILE_TYPE_REDIS) {
985  ConfNode *redis_node = ConfNodeLookupChild(conf, "redis");
986  if (!json_ctx->file_ctx->sensor_name) {
987  char hostname[1024];
988  gethostname(hostname, 1023);
989  json_ctx->file_ctx->sensor_name = SCStrdup(hostname);
990  }
991  if (json_ctx->file_ctx->sensor_name == NULL) {
992  LogFileFreeCtx(json_ctx->file_ctx);
993  SCFree(json_ctx);
994  SCFree(output_ctx);
995  return result;
996  }
997 
998  if (SCConfLogOpenRedis(redis_node, json_ctx->file_ctx) < 0) {
999  LogFileFreeCtx(json_ctx->file_ctx);
1000  SCFree(json_ctx);
1001  SCFree(output_ctx);
1002  return result;
1003  }
1004  }
1005 #endif
1006 
1007  const char *sensor_id_s = ConfNodeLookupChildValue(conf, "sensor-id");
1008  if (sensor_id_s != NULL) {
1009  if (ByteExtractStringUint64((uint64_t *)&sensor_id, 10, 0, sensor_id_s) == -1) {
1011  "Failed to initialize JSON output, "
1012  "invalid sensor-id: %s", sensor_id_s);
1013  exit(EXIT_FAILURE);
1014  }
1015  }
1016 
1017  /* Check if top-level metadata should be logged. */
1018  const ConfNode *metadata = ConfNodeLookupChild(conf, "metadata");
1019  if (metadata && metadata->val && ConfValIsFalse(metadata->val)) {
1020  SCLogConfig("Disabling eve metadata logging.");
1021  json_ctx->cfg.include_metadata = false;
1022  } else {
1023  json_ctx->cfg.include_metadata = true;
1024  }
1025 
1026  /* See if we want to enable the community id */
1027  const ConfNode *community_id = ConfNodeLookupChild(conf, "community-id");
1028  if (community_id && community_id->val && ConfValIsTrue(community_id->val)) {
1029  SCLogConfig("Enabling eve community_id logging.");
1030  json_ctx->cfg.include_community_id = true;
1031  } else {
1032  json_ctx->cfg.include_community_id = false;
1033  }
1034  const char *cid_seed = ConfNodeLookupChildValue(conf, "community-id-seed");
1035  if (cid_seed != NULL) {
1037  10, 0, cid_seed) == -1)
1038  {
1040  "Failed to initialize JSON output, "
1041  "invalid community-id-seed: %s", cid_seed);
1042  exit(EXIT_FAILURE);
1043  }
1044  }
1045 
1046  /* Do we have a global eve xff configuration? */
1047  const ConfNode *xff = ConfNodeLookupChild(conf, "xff");
1048  if (xff != NULL) {
1049  json_ctx->xff_cfg = SCCalloc(1, sizeof(HttpXFFCfg));
1050  if (likely(json_ctx->xff_cfg != NULL)) {
1051  HttpXFFGetCfg(conf, json_ctx->xff_cfg);
1052  }
1053  }
1054 
1055  const char *pcapfile_s = ConfNodeLookupChildValue(conf, "pcap-file");
1056  if (pcapfile_s != NULL && ConfValIsTrue(pcapfile_s)) {
1057  json_ctx->file_ctx->is_pcap_offline =
1059  }
1060 
1061  json_ctx->file_ctx->type = json_ctx->json_out;
1062  }
1063 
1064 
1065  SCLogDebug("returning output_ctx %p", output_ctx);
1066 
1067  result.ctx = output_ctx;
1068  result.ok = true;
1069  return result;
1070 }
1071 
1072 static void OutputJsonDeInitCtx(OutputCtx *output_ctx)
1073 {
1074  OutputJsonCtx *json_ctx = (OutputJsonCtx *)output_ctx->data;
1075  LogFileCtx *logfile_ctx = json_ctx->file_ctx;
1076  if (logfile_ctx->dropped) {
1078  "%"PRIu64" events were dropped due to slow or "
1079  "disconnected socket", logfile_ctx->dropped);
1080  }
1081  if (json_ctx->xff_cfg != NULL) {
1082  SCFree(json_ctx->xff_cfg);
1083  }
1084  LogFileFreeCtx(logfile_ctx);
1085  SCFree(json_ctx);
1086  SCFree(output_ctx);
1087 }
void OutputJsonRegister(void)
Definition: output-json.c:85
#define GET_IPV4_SRC_ADDR_PTR(p)
Definition: decode.h:214
void JsonFiveTuple(const Packet *p, enum OutputJsonLogDirection dir, json_t *js)
Add five tuple from packet to JSON object.
Definition: output-json.c:455
#define JSON_OUTPUT_BUFFER_SIZE
Definition: output-json.h:44
char * known_proto[256]
uint16_t flags
json_t * CreateJSONHeader(const Packet *p, enum OutputJsonLogDirection dir, const char *event_type)
Definition: output-json.c:710
uint8_t type
Definition: util-var.h:49
#define FLOWVAR_TYPE_STR
Definition: flow-var.h:33
uint8_t SCProtoNameValid(uint16_t proto)
Function to check if the received protocol number is valid and do we have corresponding name entry fo...
#define SCLogDebug(...)
Definition: util-debug.h:335
#define MemBufferWriteRaw(dst, raw_buffer, raw_buffer_len)
Write a raw buffer to the MemBuffer dst.
Definition: util-buffer.h:133
int OutputJSONBuffer(json_t *js, LogFileCtx *file_ctx, MemBuffer **buffer)
Definition: output-json.c:809
uint32_t idx
Definition: flow-var.h:52
#define FLOW_IPV6
Definition: flow.h:96
uint16_t value_len
Definition: flow-var.h:39
struct Flow_ * flow
Definition: decode.h:445
struct PktVar_ * next
Definition: decode.h:312
#define MEMBUFFER_SIZE(mem_buffer)
Get the MemBuffers current size.
Definition: util-buffer.h:60
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
uint32_t event_type
uint8_t proto
Definition: flow.h:344
int ComputeSHA1(const uint8_t *inbuf, size_t inbuf_len, uint8_t *outbuf, size_t outbuf_size)
calculate SHA1 hash
Definition: util-crypt.c:230
#define PKT_IS_TOCLIENT(p)
Definition: decode.h:258
Port sp
Definition: flow.h:331
void HttpXFFGetCfg(ConfNode *conf, HttpXFFCfg *result)
Function to return XFF configuration from a configuration node.
#define unlikely(expr)
Definition: util-optimize.h:35
#define GET_IPV4_DST_ADDR_PTR(p)
Definition: decode.h:215
SyslogSetup syslog_setup
Port sp
Definition: decode.h:415
uint8_t * key
Definition: flow-var.h:60
Port dp
Definition: decode.h:423
ICMPV4Hdr * icmpv4h
Definition: decode.h:528
#define TH_RST
Definition: decode-tcp.h:37
uint8_t code
json_t * CreateJSONHeaderWithTxId(const Packet *p, enum OutputJsonLogDirection dir, const char *event_type, uint64_t tx_id)
Definition: output-json.c:783
#define TH_FIN
Definition: decode-tcp.h:35
uint64_t offset
int LogFileWrite(LogFileCtx *file_ctx, MemBuffer *buffer)
#define PKT_IS_IPV6(p)
Definition: decode.h:252
SCEnumCharMap * SCSyslogGetFacilityMap(void)
returns the syslog facility enum map
Definition: util-syslog.c:57
uint16_t src
struct Flow_::@121::@125 icmp_s
void(* DeInit)(struct OutputCtx_ *)
Definition: tm-modules.h:84
uint64_t pcap_cnt
Definition: decode.h:561
int SCMapEnumNameToValue(const char *enum_name, SCEnumCharMap *table)
Maps a string name to an enum value from the supplied table. Please specify the last element of any m...
Definition: util-enum.c:41
uint16_t key_len
Definition: decode.h:315
void JsonAddCommonOptions(const OutputJsonCommonSettings *cfg, const Packet *p, const Flow *f, json_t *js)
Definition: output-json.c:390
char * val
Definition: conf.h:34
ConfNode * ConfNodeLookupChild(const ConfNode *node, const char *name)
Lookup a child configuration node by name.
Definition: conf.c:815
#define TRUE
#define PKT_IS_IPV4(p)
Definition: decode.h:251
int ConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:331
enum @34 __attribute__
DNP3 application header.
HttpXFFCfg * xff_cfg
Definition: output-json.h:82
uint16_t vlan_id[2]
Definition: decode.h:435
FlowVarTypeStr fv_str
Definition: flow-var.h:57
FlowAddress dst
Definition: flow.h:329
char * dev
Definition: util-device.h:41
int ByteExtractStringUint16(uint16_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:264
uint8_t datatype
Definition: flow-var.h:50
json_t * SCJsonBool(int val)
Definition: output-json.c:93
int ByteExtractStringUint64(uint64_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:239
struct GenericVar_ * next
Definition: util-var.h:52
#define MODULE_NAME
Definition: output-json.c:73
PktVar * pktvar
Definition: decode.h:490
#define str(s)
uint16_t dst
#define SCCalloc(nm, a)
Definition: util-mem.h:253
#define openlog(__ident, __option, __facility)
Definition: win32-syslog.h:76
const char * ConfNodeLookupChildValue(const ConfNode *node, const char *name)
Lookup the value of a child configuration node by name.
Definition: conf.c:843
void JsonTcpFlags(uint8_t flags, json_t *js)
jsonify tcp flags field Only add &#39;true&#39; fields in an attempt to keep things reasonably compact...
Definition: output-json.c:428
void OutputRegisterFileRotationFlag(int *flag)
Register a flag for file rotation notification.
Definition: output.c:871
#define DEFAULT_LOG_FILENAME
Definition: output-json.c:69
void CreateIsoTimeString(const struct timeval *ts, char *str, size_t size)
Definition: util-time.c:187
ICMPV6Hdr * icmpv6h
Definition: decode.h:530
OutputInitResult OutputJsonInitCtx(ConfNode *conf)
Create a new LogFileCtx for "fast" output style.
Definition: output-json.c:843
uint16_t value_len
Definition: decode.h:316
int datalink
Definition: decode.h:574
uint8_t proto
Definition: decode.h:430
#define GET_IPV6_DST_ADDR(p)
Definition: decode.h:220
enum LogFileType type
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
OutputJsonCommonSettings cfg
Definition: output-json.h:81
LogFileCtx * file_ctx
Definition: output-json.h:79
#define PrintBufferData(buf, buf_offset_ptr, buf_size,...)
Definition: util-print.h:29
uint32_t idx
Definition: flow-bit.h:33
uint32_t value
Definition: flow-var.h:44
#define TH_URG
Definition: decode-tcp.h:40
#define TH_ACK
Definition: decode-tcp.h:39
union FlowVar_::@117 data
int ConfValIsFalse(const char *val)
Check if a value is false.
Definition: conf.c:591
LogFileCtx * LogFileNewCtx(void)
LogFileNewCtx() Get a new LogFileCtx.
#define PKT_IS_TOSERVER(p)
Definition: decode.h:257
json_t * SCJsonString(const char *val)
Definition: output-json.c:107
#define TH_PUSH
Definition: decode-tcp.h:38
void SCJsonDecref(json_t *json)
Definition: output-json.c:102
#define TH_ECN
Definition: decode-tcp.h:42
int SCConfLogOpenGeneric(ConfNode *conf, LogFileCtx *log_ctx, const char *default_filename, int rotate)
open a generic output "log file", which may be a regular file or a socket
const char * PrintInet(int af, const void *src, char *dst, socklen_t size)
Definition: util-print.c:267
char * sensor_name
void PrintStringsToBuffer(uint8_t *dst_buf, uint32_t *dst_buf_offset_ptr, uint32_t dst_buf_size, const uint8_t *src_buf, const uint32_t src_buf_len)
Definition: util-print.c:224
uint8_t proto
uint16_t Port
Definition: decode.h:235
GenericVar * flowvar
Definition: flow.h:448
struct Flow_::@123::@126 icmp_d
#define SCLogWarning(err_code,...)
Macro used to log WARNING messages.
Definition: util-debug.h:281
int ConfValIsTrue(const char *val)
Check if a value is true.
Definition: conf.c:566
FlowVarTypeInt fv_int
Definition: flow-var.h:58
uint8_t vlan_idx
Definition: decode.h:436
int OutputJSONMemBufferCallback(const char *str, size_t size, void *data)
Definition: output-json.c:796
uint8_t * value
Definition: flow-var.h:38
uint32_t id
Definition: decode.h:311
Definition: conf.h:32
OutputCtx * ctx
Definition: output.h:42
#define GET_IPV6_SRC_ADDR(p)
Definition: decode.h:219
json_t * JsonAddStringN(const char *string, size_t size)
Create a JSON string from a character sequence.
Definition: output-json.c:142
int LogFileFreeCtx(LogFileCtx *lf_ctx)
LogFileFreeCtx() Destroy a LogFileCtx (Close the file and free memory)
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:254
#define TH_SYN
Definition: decode-tcp.h:36
#define DEFAULT_ALERT_SYSLOG_FACILITY_STR
Definition: output-json.c:70
#define SCFree(a)
Definition: util-mem.h:322
uint8_t * key
Definition: decode.h:317
Port dp
Definition: flow.h:338
uint8_t * value
Definition: decode.h:318
uint16_t tx_id
SCEnumCharMap * SCSyslogGetLogLevelMap(void)
returns the syslog facility enum map
Definition: util-syslog.c:75
uint8_t type
#define MEMBUFFER_OFFSET(mem_buffer)
Get the MemBuffers current offset.
Definition: util-buffer.h:55
#define MAX_JSON_SIZE
Definition: output-json.c:75
const char * VarNameStoreLookupById(const uint32_t id, const enum VarTypes type)
const char * PcapFileGetFilename(void)
void * data
Definition: tm-modules.h:81
int64_t parent_id
Definition: flow.h:389
int RunmodeGetCurrent(void)
Definition: suricata.c:275
#define IP_GET_IPPROTO(p)
Definition: decode.h:263
#define DEFAULT_ALERT_SYSLOG_FACILITY
Definition: output-json.c:71
#define GET_PKT_DATA(p)
Definition: decode.h:225
int Base64Encode(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen)
Definition: util-crypt.c:272
void JsonPacket(const Packet *p, json_t *js, unsigned long max_length)
Jsonify a packet.
Definition: output-json.c:408
#define SCStrdup(a)
Definition: util-mem.h:268
FlowAddress src
Definition: flow.h:329
uint16_t keylen
Definition: flow-var.h:51
struct LiveDevice_ * livedev
Definition: decode.h:553
uint8_t len
struct timeval ts
Definition: decode.h:451
#define GET_PKT_LEN(p)
Definition: decode.h:224
#define FLOWVAR_TYPE_INT
Definition: flow-var.h:34
void CreateJSONFlowId(json_t *js, const Flow *f)
Definition: output-json.c:699
struct SCLogConfig_ SCLogConfig
Holds the config state used by the logging api.
#define likely(expr)
Definition: util-optimize.h:32
uint8_t pad0
#define TH_CWR
Definition: decode-tcp.h:44
int MemBufferExpand(MemBuffer **buffer, uint32_t expand_by)
expand membuffer by size of &#39;expand_by&#39;
Definition: util-buffer.c:60
OutputJsonLogDirection
Definition: output-json.h:36
Flow data structure.
Definition: flow.h:325
#define FLOW_IPV4
Definition: flow.h:94
uint32_t flags
Definition: flow.h:379
enum LogFileType json_out
Definition: output-json.h:80
#define DEBUG_VALIDATE_BUG_ON(exp)
void OutputRegisterModule(const char *, const char *, OutputInitFunc)