suricata
output-json.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2023 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 "detect.h"
29 #include "flow.h"
30 #include "conf.h"
31 
32 #include "threads.h"
33 #include "tm-threads.h"
34 #include "threadvars.h"
35 #include "util-debug.h"
36 #include "util-time.h"
37 #include "util-var-name.h"
38 #include "util-macset.h"
39 
40 #include "util-unittest.h"
41 #include "util-unittest-helper.h"
42 
43 #include "detect-parse.h"
44 #include "detect-engine.h"
45 #include "detect-engine-mpm.h"
46 #include "detect-reference.h"
47 #include "app-layer-parser.h"
49 #include "util-syslog.h"
50 
51 /* Internal output plugins */
52 #include "output-eve-syslog.h"
53 #include "output-eve-null.h"
54 
55 #include "output.h"
56 #include "output-json.h"
57 
58 #include "util-byte.h"
59 #include "util-privs.h"
60 #include "util-print.h"
61 #include "util-proto-name.h"
62 #include "util-optimize.h"
63 #include "util-buffer.h"
64 #include "util-logopenfile.h"
65 #include "util-log-redis.h"
66 #include "util-device.h"
67 #include "util-validate.h"
68 
69 #include "flow-var.h"
70 #include "flow-bit.h"
71 #include "flow-storage.h"
72 
74 
75 #define DEFAULT_LOG_FILENAME "eve.json"
76 #define MODULE_NAME "OutputJSON"
77 
78 #define MAX_JSON_SIZE 2048
79 
80 static void OutputJsonDeInitCtx(OutputCtx *);
81 static void CreateEveCommunityFlowId(JsonBuilder *js, const Flow *f, const uint16_t seed);
82 static int CreateJSONEther(JsonBuilder *parent, const Packet *p, const Flow *f);
83 
84 static const char *TRAFFIC_ID_PREFIX = "traffic/id/";
85 static const char *TRAFFIC_LABEL_PREFIX = "traffic/label/";
86 static size_t traffic_id_prefix_len = 0;
87 static size_t traffic_label_prefix_len = 0;
88 
90 
91 void OutputJsonRegister (void)
92 {
94 
95  traffic_id_prefix_len = strlen(TRAFFIC_ID_PREFIX);
96  traffic_label_prefix_len = strlen(TRAFFIC_LABEL_PREFIX);
97 
98  // Register output file types that use the new eve filetype registration
99  // API.
102 }
103 
104 json_t *SCJsonString(const char *val)
105 {
106  if (val == NULL){
107  return NULL;
108  }
109  json_t * retval = json_string(val);
110  char retbuf[MAX_JSON_SIZE] = {0};
111  if (retval == NULL) {
112  uint32_t u = 0;
113  uint32_t offset = 0;
114  for (u = 0; u < strlen(val); u++) {
115  if (isprint(val[u])) {
116  PrintBufferData(retbuf, &offset, MAX_JSON_SIZE-1, "%c",
117  val[u]);
118  } else {
120  "\\x%02X", val[u]);
121  }
122  }
123  retbuf[offset] = '\0';
124  retval = json_string(retbuf);
125  }
126  return retval;
127 }
128 
129 /* Default Sensor ID value */
130 static int64_t sensor_id = -1; /* -1 = not defined */
131 
132 void EveFileInfo(JsonBuilder *jb, const File *ff, const uint64_t tx_id, const uint16_t flags)
133 {
134  jb_set_string_from_bytes(jb, "filename", ff->name, ff->name_len);
135 
136  if (ff->sid_cnt > 0) {
137  jb_open_array(jb, "sid");
138  for (uint32_t i = 0; ff->sid != NULL && i < ff->sid_cnt; i++) {
139  jb_append_uint(jb, ff->sid[i]);
140  }
141  jb_close(jb);
142  }
143 
144 #ifdef HAVE_MAGIC
145  if (ff->magic)
146  jb_set_string(jb, "magic", (char *)ff->magic);
147 #endif
148  jb_set_bool(jb, "gaps", ff->flags & FILE_HAS_GAPS);
149  switch (ff->state) {
150  case FILE_STATE_CLOSED:
151  JB_SET_STRING(jb, "state", "CLOSED");
152  if (ff->flags & FILE_MD5) {
153  jb_set_hex(jb, "md5", (uint8_t *)ff->md5, (uint32_t)sizeof(ff->md5));
154  }
155  if (ff->flags & FILE_SHA1) {
156  jb_set_hex(jb, "sha1", (uint8_t *)ff->sha1, (uint32_t)sizeof(ff->sha1));
157  }
158  break;
160  JB_SET_STRING(jb, "state", "TRUNCATED");
161  break;
162  case FILE_STATE_ERROR:
163  JB_SET_STRING(jb, "state", "ERROR");
164  break;
165  default:
166  JB_SET_STRING(jb, "state", "UNKNOWN");
167  break;
168  }
169 
170  if (ff->flags & FILE_SHA256) {
171  jb_set_hex(jb, "sha256", (uint8_t *)ff->sha256, (uint32_t)sizeof(ff->sha256));
172  }
173 
174  if (flags & FILE_STORED) {
175  JB_SET_TRUE(jb, "stored");
176  jb_set_uint(jb, "file_id", ff->file_store_id);
177  } else {
178  JB_SET_FALSE(jb, "stored");
179  if (flags & FILE_STORE) {
180  JB_SET_TRUE(jb, "storing");
181  }
182  }
183 
184  jb_set_uint(jb, "size", FileTrackedSize(ff));
185  if (ff->end > 0) {
186  jb_set_uint(jb, "start", ff->start);
187  jb_set_uint(jb, "end", ff->end);
188  }
189  jb_set_uint(jb, "tx_id", tx_id);
190 }
191 
192 static void EveAddPacketVars(const Packet *p, JsonBuilder *js_vars)
193 {
194  if (p == NULL || p->pktvar == NULL) {
195  return;
196  }
197  PktVar *pv = p->pktvar;
198  bool open = false;
199  while (pv != NULL) {
200  if (pv->key || pv->id > 0) {
201  if (!open) {
202  jb_open_array(js_vars, "pktvars");
203  open = true;
204  }
205  jb_start_object(js_vars);
206 
207  if (pv->key != NULL) {
208  uint32_t offset = 0;
209  uint8_t keybuf[pv->key_len + 1];
210  PrintStringsToBuffer(keybuf, &offset,
211  sizeof(keybuf),
212  pv->key, pv->key_len);
213  uint32_t len = pv->value_len;
214  uint8_t printable_buf[len + 1];
215  offset = 0;
216  PrintStringsToBuffer(printable_buf, &offset,
217  sizeof(printable_buf),
218  pv->value, pv->value_len);
219  jb_set_string(js_vars, (char *)keybuf, (char *)printable_buf);
220  } else {
221  const char *varname = VarNameStoreLookupById(pv->id, VAR_TYPE_PKT_VAR);
222  uint32_t len = pv->value_len;
223  uint8_t printable_buf[len + 1];
224  uint32_t offset = 0;
225  PrintStringsToBuffer(printable_buf, &offset,
226  sizeof(printable_buf),
227  pv->value, pv->value_len);
228  jb_set_string(js_vars, varname, (char *)printable_buf);
229  }
230  jb_close(js_vars);
231  }
232  pv = pv->next;
233  }
234  if (open) {
235  jb_close(js_vars);
236  }
237 }
238 
239 /**
240  * \brief Check if string s has prefix prefix.
241  *
242  * \retval true if string has prefix
243  * \retval false if string does not have prefix
244  *
245  * TODO: Move to file with other string handling functions.
246  */
247 static bool SCStringHasPrefix(const char *s, const char *prefix)
248 {
249  if (strncmp(s, prefix, strlen(prefix)) == 0) {
250  return true;
251  }
252  return false;
253 }
254 
255 static void EveAddFlowVars(const Flow *f, JsonBuilder *js_root, JsonBuilder **js_traffic)
256 {
257  if (f == NULL || f->flowvar == NULL) {
258  return;
259  }
260  JsonBuilder *js_flowvars = NULL;
261  JsonBuilder *js_traffic_id = NULL;
262  JsonBuilder *js_traffic_label = NULL;
263  JsonBuilder *js_flowints = NULL;
264  JsonBuilder *js_flowbits = NULL;
265  GenericVar *gv = f->flowvar;
266  while (gv != NULL) {
267  if (gv->type == DETECT_FLOWVAR || gv->type == DETECT_FLOWINT) {
268  FlowVar *fv = (FlowVar *)gv;
269  if (fv->datatype == FLOWVAR_TYPE_STR && fv->key == NULL) {
270  const char *varname = VarNameStoreLookupById(fv->idx,
272  if (varname) {
273  if (js_flowvars == NULL) {
274  js_flowvars = jb_new_array();
275  if (js_flowvars == NULL)
276  break;
277  }
278 
279  uint32_t len = fv->data.fv_str.value_len;
280  uint8_t printable_buf[len + 1];
281  uint32_t 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  jb_start_object(js_flowvars);
287  jb_set_string(js_flowvars, varname, (char *)printable_buf);
288  jb_close(js_flowvars);
289  }
290  } else if (fv->datatype == FLOWVAR_TYPE_STR && fv->key != NULL) {
291  if (js_flowvars == NULL) {
292  js_flowvars = jb_new_array();
293  if (js_flowvars == NULL)
294  break;
295  }
296 
297  uint8_t keybuf[fv->keylen + 1];
298  uint32_t offset = 0;
299  PrintStringsToBuffer(keybuf, &offset,
300  sizeof(keybuf),
301  fv->key, fv->keylen);
302 
303  uint32_t len = fv->data.fv_str.value_len;
304  uint8_t printable_buf[len + 1];
305  offset = 0;
306  PrintStringsToBuffer(printable_buf, &offset,
307  sizeof(printable_buf),
308  fv->data.fv_str.value, fv->data.fv_str.value_len);
309 
310  jb_start_object(js_flowvars);
311  jb_set_string(js_flowvars, (const char *)keybuf, (char *)printable_buf);
312  jb_close(js_flowvars);
313  } else if (fv->datatype == FLOWVAR_TYPE_INT) {
314  const char *varname = VarNameStoreLookupById(fv->idx,
316  if (varname) {
317  if (js_flowints == NULL) {
318  js_flowints = jb_new_object();
319  if (js_flowints == NULL)
320  break;
321  }
322  jb_set_uint(js_flowints, varname, fv->data.fv_int.value);
323  }
324 
325  }
326  } else if (gv->type == DETECT_FLOWBITS) {
327  FlowBit *fb = (FlowBit *)gv;
328  const char *varname = VarNameStoreLookupById(fb->idx,
330  if (varname) {
331  if (SCStringHasPrefix(varname, TRAFFIC_ID_PREFIX)) {
332  if (js_traffic_id == NULL) {
333  js_traffic_id = jb_new_array();
334  if (unlikely(js_traffic_id == NULL)) {
335  break;
336  }
337  }
338  jb_append_string(js_traffic_id, &varname[traffic_id_prefix_len]);
339  } else if (SCStringHasPrefix(varname, TRAFFIC_LABEL_PREFIX)) {
340  if (js_traffic_label == NULL) {
341  js_traffic_label = jb_new_array();
342  if (unlikely(js_traffic_label == NULL)) {
343  break;
344  }
345  }
346  jb_append_string(js_traffic_label, &varname[traffic_label_prefix_len]);
347  } else {
348  if (js_flowbits == NULL) {
349  js_flowbits = jb_new_array();
350  if (unlikely(js_flowbits == NULL))
351  break;
352  }
353  jb_append_string(js_flowbits, varname);
354  }
355  }
356  }
357  gv = gv->next;
358  }
359  if (js_flowbits) {
360  jb_close(js_flowbits);
361  jb_set_object(js_root, "flowbits", js_flowbits);
362  jb_free(js_flowbits);
363  }
364  if (js_flowints) {
365  jb_close(js_flowints);
366  jb_set_object(js_root, "flowints", js_flowints);
367  jb_free(js_flowints);
368  }
369  if (js_flowvars) {
370  jb_close(js_flowvars);
371  jb_set_object(js_root, "flowvars", js_flowvars);
372  jb_free(js_flowvars);
373  }
374 
375  if (js_traffic_id != NULL || js_traffic_label != NULL) {
376  *js_traffic = jb_new_object();
377  if (likely(*js_traffic != NULL)) {
378  if (js_traffic_id != NULL) {
379  jb_close(js_traffic_id);
380  jb_set_object(*js_traffic, "id", js_traffic_id);
381  jb_free(js_traffic_id);
382  }
383  if (js_traffic_label != NULL) {
384  jb_close(js_traffic_label);
385  jb_set_object(*js_traffic, "label", js_traffic_label);
386  jb_free(js_traffic_label);
387  }
388  jb_close(*js_traffic);
389  }
390  }
391 }
392 
393 void EveAddMetadata(const Packet *p, const Flow *f, JsonBuilder *js)
394 {
395  if ((p && p->pktvar) || (f && f->flowvar)) {
396  JsonBuilder *js_vars = jb_new_object();
397  if (js_vars) {
398  if (f && f->flowvar) {
399  JsonBuilder *js_traffic = NULL;
400  EveAddFlowVars(f, js_vars, &js_traffic);
401  if (js_traffic != NULL) {
402  jb_set_object(js, "traffic", js_traffic);
403  jb_free(js_traffic);
404  }
405  }
406  if (p && p->pktvar) {
407  EveAddPacketVars(p, js_vars);
408  }
409  jb_close(js_vars);
410  jb_set_object(js, "metadata", js_vars);
411  jb_free(js_vars);
412  }
413  }
414 }
415 
417  const Packet *p, const Flow *f, JsonBuilder *js)
418 {
419  if (cfg->include_metadata) {
420  EveAddMetadata(p, f, js);
421  }
422  if (cfg->include_ethernet) {
423  CreateJSONEther(js, p, f);
424  }
425  if (cfg->include_community_id && f != NULL) {
426  CreateEveCommunityFlowId(js, f, cfg->community_id_seed);
427  }
428  if (f != NULL && f->tenant_id > 0) {
429  jb_set_uint(js, "tenant_id", f->tenant_id);
430  }
431 }
432 
433 /**
434  * \brief Jsonify a packet
435  *
436  * \param p Packet
437  * \param js JSON object
438  * \param max_length If non-zero, restricts the number of packet data bytes handled.
439  */
440 void EvePacket(const Packet *p, JsonBuilder *js, unsigned long max_length)
441 {
442  unsigned long max_len = max_length == 0 ? GET_PKT_LEN(p) : max_length;
443  jb_set_base64(js, "packet", GET_PKT_DATA(p), max_len);
444 
445  if (!jb_open_object(js, "packet_info")) {
446  return;
447  }
448  if (!jb_set_uint(js, "linktype", p->datalink)) {
449  return;
450  }
451  jb_close(js);
452 }
453 
454 /** \brief jsonify tcp flags field
455  * Only add 'true' fields in an attempt to keep things reasonably compact.
456  */
457 void EveTcpFlags(const uint8_t flags, JsonBuilder *js)
458 {
459  if (flags & TH_SYN)
460  JB_SET_TRUE(js, "syn");
461  if (flags & TH_FIN)
462  JB_SET_TRUE(js, "fin");
463  if (flags & TH_RST)
464  JB_SET_TRUE(js, "rst");
465  if (flags & TH_PUSH)
466  JB_SET_TRUE(js, "psh");
467  if (flags & TH_ACK)
468  JB_SET_TRUE(js, "ack");
469  if (flags & TH_URG)
470  JB_SET_TRUE(js, "urg");
471  if (flags & TH_ECN)
472  JB_SET_TRUE(js, "ecn");
473  if (flags & TH_CWR)
474  JB_SET_TRUE(js, "cwr");
475 }
476 
478 {
479  char srcip[46] = {0}, dstip[46] = {0};
480  Port sp, dp;
481 
482  switch (dir) {
483  case LOG_DIR_PACKET:
484  if (PKT_IS_IPV4(p)) {
485  PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p),
486  srcip, sizeof(srcip));
487  PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p),
488  dstip, sizeof(dstip));
489  } else if (PKT_IS_IPV6(p)) {
490  PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p),
491  srcip, sizeof(srcip));
492  PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p),
493  dstip, sizeof(dstip));
494  } else {
495  /* Not an IP packet so don't do anything */
496  return;
497  }
498  sp = p->sp;
499  dp = p->dp;
500  break;
501  case LOG_DIR_FLOW:
503  if ((PKT_IS_TOSERVER(p))) {
504  if (PKT_IS_IPV4(p)) {
505  PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p),
506  srcip, sizeof(srcip));
507  PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p),
508  dstip, sizeof(dstip));
509  } else if (PKT_IS_IPV6(p)) {
510  PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p),
511  srcip, sizeof(srcip));
512  PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p),
513  dstip, sizeof(dstip));
514  }
515  sp = p->sp;
516  dp = p->dp;
517  } else {
518  if (PKT_IS_IPV4(p)) {
519  PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p),
520  srcip, sizeof(srcip));
521  PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p),
522  dstip, sizeof(dstip));
523  } else if (PKT_IS_IPV6(p)) {
524  PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p),
525  srcip, sizeof(srcip));
526  PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p),
527  dstip, sizeof(dstip));
528  }
529  sp = p->dp;
530  dp = p->sp;
531  }
532  break;
534  if ((PKT_IS_TOCLIENT(p))) {
535  if (PKT_IS_IPV4(p)) {
536  PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p),
537  srcip, sizeof(srcip));
538  PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p),
539  dstip, sizeof(dstip));
540  } else if (PKT_IS_IPV6(p)) {
541  PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p),
542  srcip, sizeof(srcip));
543  PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p),
544  dstip, sizeof(dstip));
545  }
546  sp = p->sp;
547  dp = p->dp;
548  } else {
549  if (PKT_IS_IPV4(p)) {
550  PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p),
551  srcip, sizeof(srcip));
552  PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p),
553  dstip, sizeof(dstip));
554  } else if (PKT_IS_IPV6(p)) {
555  PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p),
556  srcip, sizeof(srcip));
557  PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p),
558  dstip, sizeof(dstip));
559  }
560  sp = p->dp;
561  dp = p->sp;
562  }
563  break;
564  default:
566  return;
567  }
568 
569  strlcpy(addr->src_ip, srcip, JSON_ADDR_LEN);
570  strlcpy(addr->dst_ip, dstip, JSON_ADDR_LEN);
571 
572  switch (p->proto) {
573  case IPPROTO_UDP:
574  case IPPROTO_TCP:
575  case IPPROTO_SCTP:
576  addr->sp = sp;
577  addr->dp = dp;
578  break;
579  default:
580  break;
581  }
582 
584  strlcpy(addr->proto, known_proto[IP_GET_IPPROTO(p)], sizeof(addr->proto));
585  } else {
586  snprintf(addr->proto, sizeof(addr->proto), "%" PRIu32, IP_GET_IPPROTO(p));
587  }
588 }
589 
590 #define COMMUNITY_ID_BUF_SIZE 64
591 
592 static bool CalculateCommunityFlowIdv4(const Flow *f,
593  const uint16_t seed, unsigned char *base64buf)
594 {
595  struct {
596  uint16_t seed;
597  uint32_t src;
598  uint32_t dst;
599  uint8_t proto;
600  uint8_t pad0;
601  uint16_t sp;
602  uint16_t dp;
603  } __attribute__((__packed__)) ipv4;
604 
605  uint32_t src = f->src.addr_data32[0];
606  uint32_t dst = f->dst.addr_data32[0];
607  uint16_t sp = f->sp;
608  if (f->proto == IPPROTO_ICMP)
609  sp = f->icmp_s.type;
610  sp = htons(sp);
611  uint16_t dp = f->dp;
612  if (f->proto == IPPROTO_ICMP)
613  dp = f->icmp_d.type;
614  dp = htons(dp);
615 
616  ipv4.seed = htons(seed);
617  if (ntohl(src) < ntohl(dst) || (src == dst && sp < dp)) {
618  ipv4.src = src;
619  ipv4.dst = dst;
620  ipv4.sp = sp;
621  ipv4.dp = dp;
622  } else {
623  ipv4.src = dst;
624  ipv4.dst = src;
625  ipv4.sp = dp;
626  ipv4.dp = sp;
627  }
628  ipv4.proto = f->proto;
629  ipv4.pad0 = 0;
630 
631  uint8_t hash[20];
632  if (SCSha1HashBuffer((const uint8_t *)&ipv4, sizeof(ipv4), hash, sizeof(hash)) == 1) {
633  strlcpy((char *)base64buf, "1:", COMMUNITY_ID_BUF_SIZE);
634  unsigned long out_len = COMMUNITY_ID_BUF_SIZE - 2;
635  if (Base64Encode(hash, sizeof(hash), base64buf+2, &out_len) == SC_BASE64_OK) {
636  return true;
637  }
638  }
639  return false;
640 }
641 
642 static bool CalculateCommunityFlowIdv6(const Flow *f,
643  const uint16_t seed, unsigned char *base64buf)
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  int cmp_r = memcmp(&f->src, &f->dst, sizeof(f->src));
666  if ((cmp_r < 0) || (cmp_r == 0 && sp < dp)) {
667  memcpy(&ipv6.src, &f->src.addr_data32, 16);
668  memcpy(&ipv6.dst, &f->dst.addr_data32, 16);
669  ipv6.sp = sp;
670  ipv6.dp = dp;
671  } else {
672  memcpy(&ipv6.src, &f->dst.addr_data32, 16);
673  memcpy(&ipv6.dst, &f->src.addr_data32, 16);
674  ipv6.sp = dp;
675  ipv6.dp = sp;
676  }
677  ipv6.proto = f->proto;
678  ipv6.pad0 = 0;
679 
680  uint8_t hash[20];
681  if (SCSha1HashBuffer((const uint8_t *)&ipv6, sizeof(ipv6), hash, sizeof(hash)) == 1) {
682  strlcpy((char *)base64buf, "1:", COMMUNITY_ID_BUF_SIZE);
683  unsigned long out_len = COMMUNITY_ID_BUF_SIZE - 2;
684  if (Base64Encode(hash, sizeof(hash), base64buf+2, &out_len) == SC_BASE64_OK) {
685  return true;
686  }
687  }
688  return false;
689 }
690 
691 static void CreateEveCommunityFlowId(JsonBuilder *js, const Flow *f, const uint16_t seed)
692 {
693  unsigned char buf[COMMUNITY_ID_BUF_SIZE];
694  if (f->flags & FLOW_IPV4) {
695  if (CalculateCommunityFlowIdv4(f, seed, buf)) {
696  jb_set_string(js, "community_id", (const char *)buf);
697  }
698  } else if (f->flags & FLOW_IPV6) {
699  if (CalculateCommunityFlowIdv6(f, seed, buf)) {
700  jb_set_string(js, "community_id", (const char *)buf);
701  }
702  }
703 }
704 
705 void CreateEveFlowId(JsonBuilder *js, const Flow *f)
706 {
707  if (f == NULL) {
708  return;
709  }
710  int64_t flow_id = FlowGetId(f);
711  jb_set_uint(js, "flow_id", flow_id);
712  if (f->parent_id) {
713  jb_set_uint(js, "parent_id", f->parent_id);
714  }
715 }
716 
717 static inline void JSONFormatAndAddMACAddr(
718  JsonBuilder *js, const char *key, const uint8_t *val, bool is_array)
719 {
720  char eth_addr[19];
721  (void) snprintf(eth_addr, 19, "%02x:%02x:%02x:%02x:%02x:%02x",
722  val[0], val[1], val[2], val[3], val[4], val[5]);
723  if (is_array) {
724  jb_append_string(js, eth_addr);
725  } else {
726  jb_set_string(js, key, eth_addr);
727  }
728 }
729 
730 /* only required to traverse the MAC address set */
731 typedef struct JSONMACAddrInfo {
732  JsonBuilder *src, *dst;
734 
735 static int MacSetIterateToJSON(uint8_t *val, MacSetSide side, void *data)
736 {
737  JSONMACAddrInfo *info = (JSONMACAddrInfo*) data;
738  if (side == MAC_SET_DST) {
739  JSONFormatAndAddMACAddr(info->dst, NULL, val, true);
740  } else {
741  JSONFormatAndAddMACAddr(info->src, NULL, val, true);
742  }
743  return 0;
744 }
745 
746 static int CreateJSONEther(JsonBuilder *js, const Packet *p, const Flow *f)
747 {
748  if (p != NULL) {
749  /* this is a packet context, so we need to add scalar fields */
750  if (p->ethh != NULL) {
751  jb_open_object(js, "ether");
752  uint8_t *src = p->ethh->eth_src;
753  uint8_t *dst = p->ethh->eth_dst;
754  JSONFormatAndAddMACAddr(js, "src_mac", src, false);
755  JSONFormatAndAddMACAddr(js, "dest_mac", dst, false);
756  jb_close(js);
757  }
758  } else if (f != NULL) {
759  /* we are creating an ether object in a flow context, so we need to
760  append to arrays */
762  if (ms != NULL && MacSetSize(ms) > 0) {
763  jb_open_object(js, "ether");
764  JSONMACAddrInfo info;
765  info.dst = jb_new_array();
766  info.src = jb_new_array();
767  int ret = MacSetForEach(ms, MacSetIterateToJSON, &info);
768  if (unlikely(ret != 0)) {
769  /* should not happen, JSONFlowAppendMACAddrs is sane */
770  jb_free(info.dst);
771  jb_free(info.src);
772  jb_close(js);
773  return ret;
774  }
775  jb_close(info.dst);
776  jb_close(info.src);
777  jb_set_object(js, "dest_macs", info.dst);
778  jb_set_object(js, "src_macs", info.src);
779  jb_free(info.dst);
780  jb_free(info.src);
781  jb_close(js);
782  }
783  }
784  return 0;
785 }
786 
787 JsonBuilder *CreateEveHeader(const Packet *p, enum OutputJsonLogDirection dir,
788  const char *event_type, JsonAddrInfo *addr, OutputJsonCtx *eve_ctx)
789 {
790  char timebuf[64];
791  const Flow *f = (const Flow *)p->flow;
792 
793  JsonBuilder *js = jb_new_object();
794  if (unlikely(js == NULL)) {
795  return NULL;
796  }
797 
798  CreateIsoTimeString(p->ts, timebuf, sizeof(timebuf));
799 
800  jb_set_string(js, "timestamp", timebuf);
801 
802  CreateEveFlowId(js, f);
803 
804  /* sensor id */
805  if (sensor_id >= 0) {
806  jb_set_uint(js, "sensor_id", sensor_id);
807  }
808 
809  /* input interface */
810  if (p->livedev) {
811  jb_set_string(js, "in_iface", p->livedev->dev);
812  }
813 
814  /* pcap_cnt */
815  if (p->pcap_cnt != 0) {
816  jb_set_uint(js, "pcap_cnt", p->pcap_cnt);
817  }
818 
819  if (event_type) {
820  jb_set_string(js, "event_type", event_type);
821  }
822 
823  /* vlan */
824  if (p->vlan_idx > 0) {
825  jb_open_array(js, "vlan");
826  jb_append_uint(js, p->vlan_id[0]);
827  if (p->vlan_idx > 1) {
828  jb_append_uint(js, p->vlan_id[1]);
829  }
830  if (p->vlan_idx > 2) {
831  jb_append_uint(js, p->vlan_id[2]);
832  }
833  jb_close(js);
834  }
835 
836  /* 5-tuple */
837  JsonAddrInfo addr_info = json_addr_info_zero;
838  if (addr == NULL) {
839  JsonAddrInfoInit(p, dir, &addr_info);
840  addr = &addr_info;
841  }
842  jb_set_string(js, "src_ip", addr->src_ip);
843  jb_set_uint(js, "src_port", addr->sp);
844  jb_set_string(js, "dest_ip", addr->dst_ip);
845  jb_set_uint(js, "dest_port", addr->dp);
846  jb_set_string(js, "proto", addr->proto);
847 
848  /* icmp */
849  switch (p->proto) {
850  case IPPROTO_ICMP:
851  if (p->icmpv4h) {
852  jb_set_uint(js, "icmp_type", p->icmpv4h->type);
853  jb_set_uint(js, "icmp_code", p->icmpv4h->code);
854  }
855  break;
856  case IPPROTO_ICMPV6:
857  if (p->icmpv6h) {
858  jb_set_uint(js, "icmp_type", p->icmpv6h->type);
859  jb_set_uint(js, "icmp_code", p->icmpv6h->code);
860  }
861  break;
862  }
863 
864  jb_set_string(js, "pkt_src", PktSrcToString(p->pkt_src));
865 
866  if (eve_ctx != NULL) {
867  EveAddCommonOptions(&eve_ctx->cfg, p, f, js);
868  }
869 
870  return js;
871 }
872 
873 JsonBuilder *CreateEveHeaderWithTxId(const Packet *p, enum OutputJsonLogDirection dir,
874  const char *event_type, JsonAddrInfo *addr, uint64_t tx_id, OutputJsonCtx *eve_ctx)
875 {
876  JsonBuilder *js = CreateEveHeader(p, dir, event_type, addr, eve_ctx);
877  if (unlikely(js == NULL))
878  return NULL;
879 
880  /* tx id for correlation with other events */
881  jb_set_uint(js, "tx_id", tx_id);
882 
883  return js;
884 }
885 
886 int OutputJSONMemBufferCallback(const char *str, size_t size, void *data)
887 {
888  OutputJSONMemBufferWrapper *wrapper = data;
889  MemBuffer **memb = wrapper->buffer;
890 
891  if (MEMBUFFER_OFFSET(*memb) + size >= MEMBUFFER_SIZE(*memb)) {
892  MemBufferExpand(memb, wrapper->expand_by);
893  }
894 
895  MemBufferWriteRaw((*memb), (const uint8_t *)str, size);
896  return 0;
897 }
898 
899 int OutputJSONBuffer(json_t *js, LogFileCtx *file_ctx, MemBuffer **buffer)
900 {
901  if (file_ctx->sensor_name) {
902  json_object_set_new(js, "host",
903  json_string(file_ctx->sensor_name));
904  }
905 
906  if (file_ctx->is_pcap_offline) {
907  json_object_set_new(js, "pcap_filename", json_string(PcapFileGetFilename()));
908  }
909 
910  if (file_ctx->prefix) {
911  MemBufferWriteRaw((*buffer), (const uint8_t *)file_ctx->prefix, file_ctx->prefix_len);
912  }
913 
914  OutputJSONMemBufferWrapper wrapper = {
915  .buffer = buffer,
916  .expand_by = JSON_OUTPUT_BUFFER_SIZE
917  };
918 
919  int r = json_dump_callback(js, OutputJSONMemBufferCallback, &wrapper,
920  file_ctx->json_flags);
921  if (r != 0)
922  return TM_ECODE_OK;
923 
924  LogFileWrite(file_ctx, *buffer);
925  return 0;
926 }
927 
929 {
930  LogFileCtx *file_ctx = ctx->file_ctx;
931  MemBuffer **buffer = &ctx->buffer;
932  if (file_ctx->sensor_name) {
933  jb_set_string(js, "host", file_ctx->sensor_name);
934  }
935 
936  if (file_ctx->is_pcap_offline) {
937  jb_set_string(js, "pcap_filename", PcapFileGetFilename());
938  }
939 
940  jb_close(js);
941 
942  MemBufferReset(*buffer);
943 
944  if (file_ctx->prefix) {
945  MemBufferWriteRaw((*buffer), (const uint8_t *)file_ctx->prefix, file_ctx->prefix_len);
946  }
947 
948  size_t jslen = jb_len(js);
949  if (MEMBUFFER_OFFSET(*buffer) + jslen >= MEMBUFFER_SIZE(*buffer)) {
950  MemBufferExpand(buffer, jslen);
951  }
952 
953  MemBufferWriteRaw((*buffer), jb_ptr(js), jslen);
954  LogFileWrite(file_ctx, *buffer);
955 
956  return 0;
957 }
958 
959 static inline enum LogFileType FileTypeFromConf(const char *typestr)
960 {
961  enum LogFileType log_filetype = LOGFILE_TYPE_NOTSET;
962 
963  if (typestr == NULL) {
964  log_filetype = LOGFILE_TYPE_FILE;
965  } else if (strcmp(typestr, "file") == 0 || strcmp(typestr, "regular") == 0) {
966  log_filetype = LOGFILE_TYPE_FILE;
967  } else if (strcmp(typestr, "unix_dgram") == 0) {
968  log_filetype = LOGFILE_TYPE_UNIX_DGRAM;
969  } else if (strcmp(typestr, "unix_stream") == 0) {
970  log_filetype = LOGFILE_TYPE_UNIX_STREAM;
971  } else if (strcmp(typestr, "redis") == 0) {
972 #ifdef HAVE_LIBHIREDIS
973  log_filetype = LOGFILE_TYPE_REDIS;
974 #else
975  FatalError("redis JSON output option is not compiled");
976 #endif
977  }
978  SCLogDebug("type %s, file type value %d", typestr, log_filetype);
979  return log_filetype;
980 }
981 
982 static int LogFileTypePrepare(
983  OutputJsonCtx *json_ctx, enum LogFileType log_filetype, ConfNode *conf)
984 {
985 
986  if (log_filetype == LOGFILE_TYPE_FILE || log_filetype == LOGFILE_TYPE_UNIX_DGRAM ||
987  log_filetype == LOGFILE_TYPE_UNIX_STREAM) {
988  if (SCConfLogOpenGeneric(conf, json_ctx->file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) {
989  return -1;
990  }
992  }
993 #ifdef HAVE_LIBHIREDIS
994  else if (log_filetype == LOGFILE_TYPE_REDIS) {
995  SCLogRedisInit();
996  ConfNode *redis_node = ConfNodeLookupChild(conf, "redis");
997  if (!json_ctx->file_ctx->sensor_name) {
998  char hostname[1024];
999  gethostname(hostname, 1023);
1000  json_ctx->file_ctx->sensor_name = SCStrdup(hostname);
1001  }
1002  if (json_ctx->file_ctx->sensor_name == NULL) {
1003  return -1;
1004  }
1005 
1006  if (SCConfLogOpenRedis(redis_node, json_ctx->file_ctx) < 0) {
1007  return -1;
1008  }
1009  }
1010 #endif
1011  else if (log_filetype == LOGFILE_TYPE_FILETYPE) {
1012  if (json_ctx->file_ctx->threaded) {
1013  /* Prepare for threaded log output. */
1014  if (!SCLogOpenThreadedFile(NULL, NULL, json_ctx->file_ctx)) {
1015  return -1;
1016  }
1017  }
1018  if (json_ctx->filetype->Init(conf, json_ctx->file_ctx->threaded,
1019  &json_ctx->file_ctx->filetype.init_data) < 0) {
1020  return -1;
1021  }
1022  if (json_ctx->filetype->ThreadInit(json_ctx->file_ctx->filetype.init_data, 0,
1023  &json_ctx->file_ctx->filetype.thread_data) < 0) {
1024  return -1;
1025  }
1026  json_ctx->file_ctx->filetype.filetype = json_ctx->filetype;
1027  }
1028 
1029  return 0;
1030 }
1031 
1032 /**
1033  * \brief Create a new LogFileCtx for "fast" output style.
1034  * \param conf The configuration node for this output.
1035  * \return A LogFileCtx pointer on success, NULL on failure.
1036  */
1038 {
1039  OutputInitResult result = { NULL, false };
1040  OutputCtx *output_ctx = NULL;
1041 
1042  OutputJsonCtx *json_ctx = SCCalloc(1, sizeof(OutputJsonCtx));
1043  if (unlikely(json_ctx == NULL)) {
1044  SCLogDebug("could not create new OutputJsonCtx");
1045  return result;
1046  }
1047 
1048  /* First lookup a sensor-name value in this outputs configuration
1049  * node (deprecated). If that fails, lookup the global one. */
1050  const char *sensor_name = ConfNodeLookupChildValue(conf, "sensor-name");
1051  if (sensor_name != NULL) {
1052  SCLogWarning("Found deprecated eve-log setting \"sensor-name\". "
1053  "Please set sensor-name globally.");
1054  }
1055  else {
1056  (void)ConfGet("sensor-name", &sensor_name);
1057  }
1058 
1059  json_ctx->file_ctx = LogFileNewCtx();
1060  if (unlikely(json_ctx->file_ctx == NULL)) {
1061  SCLogDebug("AlertJsonInitCtx: Could not create new LogFileCtx");
1062  goto error_exit;
1063  }
1064 
1065  if (sensor_name) {
1066  json_ctx->file_ctx->sensor_name = SCStrdup(sensor_name);
1067  if (json_ctx->file_ctx->sensor_name == NULL) {
1068  goto error_exit;
1069  }
1070  } else {
1071  json_ctx->file_ctx->sensor_name = NULL;
1072  }
1073 
1074  output_ctx = SCCalloc(1, sizeof(OutputCtx));
1075  if (unlikely(output_ctx == NULL)) {
1076  goto error_exit;
1077  }
1078 
1079  output_ctx->data = json_ctx;
1080  output_ctx->DeInit = OutputJsonDeInitCtx;
1081 
1082  if (conf) {
1083  const char *output_s = ConfNodeLookupChildValue(conf, "filetype");
1084  // Backwards compatibility
1085  if (output_s == NULL) {
1086  output_s = ConfNodeLookupChildValue(conf, "type");
1087  }
1088 
1089  enum LogFileType log_filetype = FileTypeFromConf(output_s);
1090  if (log_filetype == LOGFILE_TYPE_NOTSET) {
1091  SCEveFileType *filetype = SCEveFindFileType(output_s);
1092  if (filetype != NULL) {
1093  log_filetype = LOGFILE_TYPE_FILETYPE;
1094  json_ctx->filetype = filetype;
1095  } else
1096  FatalError("Invalid JSON output option: %s", output_s);
1097  }
1098 
1099  const char *prefix = ConfNodeLookupChildValue(conf, "prefix");
1100  if (prefix != NULL)
1101  {
1102  SCLogInfo("Using prefix '%s' for JSON messages", prefix);
1103  json_ctx->file_ctx->prefix = SCStrdup(prefix);
1104  if (json_ctx->file_ctx->prefix == NULL)
1105  {
1106  FatalError("Failed to allocate memory for eve-log.prefix setting.");
1107  }
1108  json_ctx->file_ctx->prefix_len = strlen(prefix);
1109  }
1110 
1111  /* Threaded file output */
1112  const ConfNode *threaded = ConfNodeLookupChild(conf, "threaded");
1113  if (threaded && threaded->val && ConfValIsTrue(threaded->val)) {
1114  SCLogConfig("Threaded EVE logging configured");
1115  json_ctx->file_ctx->threaded = true;
1116  } else {
1117  json_ctx->file_ctx->threaded = false;
1118  }
1119  if (LogFileTypePrepare(json_ctx, log_filetype, conf) < 0) {
1120  goto error_exit;
1121  }
1122 
1123  const char *sensor_id_s = ConfNodeLookupChildValue(conf, "sensor-id");
1124  if (sensor_id_s != NULL) {
1125  if (StringParseUint64((uint64_t *)&sensor_id, 10, 0, sensor_id_s) < 0) {
1126  FatalError("Failed to initialize JSON output, "
1127  "invalid sensor-id: %s",
1128  sensor_id_s);
1129  }
1130  }
1131 
1132  /* Check if top-level metadata should be logged. */
1133  const ConfNode *metadata = ConfNodeLookupChild(conf, "metadata");
1134  if (metadata && metadata->val && ConfValIsFalse(metadata->val)) {
1135  SCLogConfig("Disabling eve metadata logging.");
1136  json_ctx->cfg.include_metadata = false;
1137  } else {
1138  json_ctx->cfg.include_metadata = true;
1139  }
1140 
1141  /* Check if ethernet information should be logged. */
1142  const ConfNode *ethernet = ConfNodeLookupChild(conf, "ethernet");
1143  if (ethernet && ethernet->val && ConfValIsTrue(ethernet->val)) {
1144  SCLogConfig("Enabling Ethernet MAC address logging.");
1145  json_ctx->cfg.include_ethernet = true;
1146  } else {
1147  json_ctx->cfg.include_ethernet = false;
1148  }
1149 
1150  /* See if we want to enable the community id */
1151  const ConfNode *community_id = ConfNodeLookupChild(conf, "community-id");
1152  if (community_id && community_id->val && ConfValIsTrue(community_id->val)) {
1153  SCLogConfig("Enabling eve community_id logging.");
1154  json_ctx->cfg.include_community_id = true;
1155  } else {
1156  json_ctx->cfg.include_community_id = false;
1157  }
1158  const char *cid_seed = ConfNodeLookupChildValue(conf, "community-id-seed");
1159  if (cid_seed != NULL) {
1160  if (StringParseUint16(&json_ctx->cfg.community_id_seed,
1161  10, 0, cid_seed) < 0)
1162  {
1163  FatalError("Failed to initialize JSON output, "
1164  "invalid community-id-seed: %s",
1165  cid_seed);
1166  }
1167  }
1168 
1169  /* Do we have a global eve xff configuration? */
1170  const ConfNode *xff = ConfNodeLookupChild(conf, "xff");
1171  if (xff != NULL) {
1172  json_ctx->xff_cfg = SCCalloc(1, sizeof(HttpXFFCfg));
1173  if (likely(json_ctx->xff_cfg != NULL)) {
1174  HttpXFFGetCfg(conf, json_ctx->xff_cfg);
1175  }
1176  }
1177 
1178  const char *pcapfile_s = ConfNodeLookupChildValue(conf, "pcap-file");
1179  if (pcapfile_s != NULL && ConfValIsTrue(pcapfile_s)) {
1180  json_ctx->file_ctx->is_pcap_offline =
1183  }
1184  json_ctx->file_ctx->type = log_filetype;
1185  }
1186 
1187  SCLogDebug("returning output_ctx %p", output_ctx);
1188 
1189  result.ctx = output_ctx;
1190  result.ok = true;
1191  return result;
1192 
1193 error_exit:
1194  if (json_ctx->file_ctx) {
1195  if (json_ctx->file_ctx->prefix) {
1196  SCFree(json_ctx->file_ctx->prefix);
1197  }
1198  LogFileFreeCtx(json_ctx->file_ctx);
1199  }
1200  SCFree(json_ctx);
1201 
1202  if (output_ctx) {
1203  SCFree(output_ctx);
1204  }
1205  return result;
1206 }
1207 
1208 static void OutputJsonDeInitCtx(OutputCtx *output_ctx)
1209 {
1210  OutputJsonCtx *json_ctx = (OutputJsonCtx *)output_ctx->data;
1211  LogFileCtx *logfile_ctx = json_ctx->file_ctx;
1212  if (logfile_ctx->dropped) {
1213  SCLogWarning("%" PRIu64 " events were dropped due to slow or "
1214  "disconnected socket",
1215  logfile_ctx->dropped);
1216  }
1217  if (json_ctx->xff_cfg != NULL) {
1218  SCFree(json_ctx->xff_cfg);
1219  }
1220  LogFileFreeCtx(logfile_ctx);
1221  SCFree(json_ctx);
1222  SCFree(output_ctx);
1223 }
PKT_IS_TOCLIENT
#define PKT_IS_TOCLIENT(p)
Definition: decode.h:253
LogFileCtx_::rotation_flag
int rotation_flag
Definition: util-logopenfile.h:153
util-byte.h
LogFileCtx_::prefix_len
size_t prefix_len
Definition: util-logopenfile.h:132
GenericVar_::type
uint8_t type
Definition: util-var.h:49
tm-threads.h
MacSetSide
MacSetSide
Definition: util-macset.h:28
Packet_::proto
uint8_t proto
Definition: decode.h:459
pad0
uint8_t pad0
Definition: decode-template.h:1
len
uint8_t len
Definition: app-layer-dnp3.h:2
detect-engine.h
LOGFILE_TYPE_REDIS
@ LOGFILE_TYPE_REDIS
Definition: util-logopenfile.h:42
LogFileCtx_::sensor_name
char * sensor_name
Definition: util-logopenfile.h:115
RUNMODE_UNIX_SOCKET
@ RUNMODE_UNIX_SOCKET
Definition: runmodes.h:43
ICMPV6Hdr_::type
uint8_t type
Definition: decode-icmpv6.h:145
OutputJsonCtx_::xff_cfg
HttpXFFCfg * xff_cfg
Definition: output-json.h:83
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
CreateIsoTimeString
void CreateIsoTimeString(const SCTime_t ts, char *str, size_t size)
Definition: util-time.c:209
FlowVar_::keylen
uint16_t keylen
Definition: flow-var.h:51
Flow_::icmp_d
struct Flow_::@119::@125 icmp_d
PKT_IS_IPV6
#define PKT_IS_IPV6(p)
Definition: decode.h:247
ConfNode_::val
char * val
Definition: conf.h:34
OutputJsonCtx_::cfg
OutputJsonCommonSettings cfg
Definition: output-json.h:82
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
FILE_SHA256
#define FILE_SHA256
Definition: util-file.h:52
LogFileNewCtx
LogFileCtx * LogFileNewCtx(void)
LogFileNewCtx() Get a new LogFileCtx.
Definition: util-logopenfile.c:659
MemBufferExpand
int MemBufferExpand(MemBuffer **buffer, uint32_t expand_by)
expand membuffer by size of 'expand_by'
Definition: util-buffer.c:60
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
Packet_::pcap_cnt
uint64_t pcap_cnt
Definition: decode.h:607
FlowVar_::data
union FlowVar_::@112 data
Flow_::proto
uint8_t proto
Definition: flow.h:373
FlowVarTypeStr::value_len
uint16_t value_len
Definition: flow-var.h:39
FLOWVAR_TYPE_STR
#define FLOWVAR_TYPE_STR
Definition: flow-var.h:33
JSON_OUTPUT_BUFFER_SIZE
#define JSON_OUTPUT_BUFFER_SIZE
Definition: output-json.h:61
threads.h
TH_RST
#define TH_RST
Definition: decode-tcp.h:36
util-macset.h
OutputJsonCtx_
Definition: output-json.h:79
LogFileCtx_::json_flags
size_t json_flags
Definition: util-logopenfile.h:150
Packet_::vlan_idx
uint8_t vlan_idx
Definition: decode.h:465
Flow_
Flow data structure.
Definition: flow.h:351
File_::state
FileState state
Definition: util-file.h:82
OutputJsonCommonSettings_
Definition: output-json.h:69
TH_FIN
#define TH_FIN
Definition: decode-tcp.h:34
util-syslog.h
LogFileCtx_
Definition: util-logopenfile.h:76
StringParseUint16
int StringParseUint16(uint16_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:337
PktVar_::next
struct PktVar_ * next
Definition: decode.h:315
FILE_STORE
#define FILE_STORE
Definition: util-file.h:55
File_::file_store_id
uint32_t file_store_id
Definition: util-file.h:85
OutputJsonBuilderBuffer
int OutputJsonBuilderBuffer(JsonBuilder *js, OutputJsonThreadCtx *ctx)
Definition: output-json.c:928
FlowVar_::fv_str
FlowVarTypeStr fv_str
Definition: flow-var.h:57
LOGFILE_TYPE_NOTSET
@ LOGFILE_TYPE_NOTSET
Definition: util-logopenfile.h:45
SCProtoNameValid
bool SCProtoNameValid(uint16_t proto)
Function to check if the received protocol number is valid and do we have corresponding name entry fo...
Definition: util-proto-name.c:454
output-eve-null.h
json_addr_info_zero
const JsonAddrInfo json_addr_info_zero
Definition: output-json.c:89
flow-bit.h
util-var-name.h
util-log-redis.h
COMMUNITY_ID_BUF_SIZE
#define COMMUNITY_ID_BUF_SIZE
Definition: output-json.c:590
OutputJsonCommonSettings_::include_community_id
bool include_community_id
Definition: output-json.h:71
EveFileInfo
void EveFileInfo(JsonBuilder *jb, const File *ff, const uint64_t tx_id, const uint16_t flags)
Definition: output-json.c:132
util-privs.h
OutputJSONMemBufferWrapper_::buffer
MemBuffer ** buffer
Definition: output-json.h:65
known_proto
const char * known_proto[256]
Definition: util-proto-name.c:40
EveAddCommonOptions
void EveAddCommonOptions(const OutputJsonCommonSettings *cfg, const Packet *p, const Flow *f, JsonBuilder *js)
Definition: output-json.c:416
FILE_STATE_TRUNCATED
@ FILE_STATE_TRUNCATED
Definition: util-file.h:73
proto
uint8_t proto
Definition: decode-template.h:0
Flow_::dp
Port dp
Definition: flow.h:367
FLOWVAR_TYPE_INT
#define FLOWVAR_TYPE_INT
Definition: flow-var.h:34
JSONMACAddrInfo
struct JSONMACAddrInfo JSONMACAddrInfo
File_::sha1
uint8_t sha1[SC_SHA1_LEN]
Definition: util-file.h:96
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:97
GET_IPV6_DST_ADDR
#define GET_IPV6_DST_ADDR(p)
Definition: decode.h:216
util-unittest.h
SCJsonString
json_t * SCJsonString(const char *val)
Definition: output-json.c:104
ConfValIsTrue
int ConfValIsTrue(const char *val)
Check if a value is true.
Definition: conf.c:537
util-unittest-helper.h
OutputCtx_::data
void * data
Definition: tm-modules.h:88
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:84
PrintStringsToBuffer
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:199
OutputJsonRegister
void OutputJsonRegister(void)
Definition: output-json.c:91
OutputCtx_
Definition: tm-modules.h:85
SCConfLogOpenGeneric
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
Definition: util-logopenfile.c:452
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
OutputJsonThreadCtx_
Definition: output-json.h:87
detect-reference.h
Packet_::datalink
int datalink
Definition: decode.h:620
File_::name_len
uint16_t name_len
Definition: util-file.h:81
FlowVar_::fv_int
FlowVarTypeInt fv_int
Definition: flow-var.h:58
__attribute__
enum @22 __attribute__
DNP3 application header.
OutputRegisterFileRotationFlag
void OutputRegisterFileRotationFlag(int *flag)
Register a flag for file rotation notification.
Definition: output.c:706
EveAddMetadata
void EveAddMetadata(const Packet *p, const Flow *f, JsonBuilder *js)
Definition: output-json.c:393
ConfGet
int ConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:335
LogFileCtx_::filetype
LogFileTypeCtx filetype
Definition: util-logopenfile.h:94
Flow_::dst
FlowAddress dst
Definition: flow.h:354
JsonAddrInfo_::dp
Port dp
Definition: output-json.h:51
File_::md5
uint8_t md5[SC_MD5_LEN]
Definition: util-file.h:94
LogFileWrite
int LogFileWrite(LogFileCtx *file_ctx, MemBuffer *buffer)
Definition: util-logopenfile.c:925
util-device.h
util-debug.h
JB_SET_STRING
#define JB_SET_STRING(jb, key, val)
Definition: rust.h:26
Packet_::pktvar
PktVar * pktvar
Definition: decode.h:535
GenericVar_::next
struct GenericVar_ * next
Definition: util-var.h:52
GET_IPV4_DST_ADDR_PTR
#define GET_IPV4_DST_ADDR_PTR(p)
Definition: decode.h:211
PKT_IS_TOSERVER
#define PKT_IS_TOSERVER(p)
Definition: decode.h:252
DEFAULT_LOG_FILENAME
#define DEFAULT_LOG_FILENAME
Definition: output-json.c:75
File_::end
uint64_t end
Definition: util-file.h:106
DETECT_FLOWINT
@ DETECT_FLOWINT
Definition: detect-engine-register.h:87
OutputInitResult_::ctx
OutputCtx * ctx
Definition: output.h:47
DETECT_FLOWVAR
@ DETECT_FLOWVAR
Definition: detect-engine-register.h:85
Packet_::ts
SCTime_t ts
Definition: decode.h:485
output-json.h
FlowVar_::idx
uint32_t idx
Definition: flow-var.h:52
JSONMACAddrInfo
Definition: output-json.c:731
PktVar_::value
uint8_t * value
Definition: decode.h:321
OutputRegisterModule
void OutputRegisterModule(const char *, const char *, OutputInitFunc)
CreateEveHeader
JsonBuilder * CreateEveHeader(const Packet *p, enum OutputJsonLogDirection dir, const char *event_type, JsonAddrInfo *addr, OutputJsonCtx *eve_ctx)
Definition: output-json.c:787
util-print.h
FlowVar_::key
uint8_t * key
Definition: flow-var.h:60
GET_PKT_DATA
#define GET_PKT_DATA(p)
Definition: decode.h:221
detect-engine-mpm.h
Packet_::ethh
EthernetHdr * ethh
Definition: decode.h:538
detect.h
PrintInet
const char * PrintInet(int af, const void *src, char *dst, socklen_t size)
Definition: util-print.c:241
Packet_::sp
Port sp
Definition: decode.h:444
FileTrackedSize
uint64_t FileTrackedSize(const File *file)
get the size of the file
Definition: util-file.c:343
EveTcpFlags
void EveTcpFlags(const uint8_t flags, JsonBuilder *js)
jsonify tcp flags field Only add 'true' fields in an attempt to keep things reasonably compact.
Definition: output-json.c:457
PktSrcToString
const char * PktSrcToString(enum PktSrcEnum pkt_src)
Definition: decode.c:820
TH_ACK
#define TH_ACK
Definition: decode-tcp.h:38
util-time.h
JB_SET_TRUE
#define JB_SET_TRUE(jb, key)
Definition: rust.h:27
OutputInitResult_::ok
bool ok
Definition: output.h:48
LiveDevice_::dev
char * dev
Definition: util-device.h:51
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:249
PktVar_::key
uint8_t * key
Definition: decode.h:320
SyslogInitialize
void SyslogInitialize(void)
Definition: output-eve-syslog.c:99
LogFileCtx_::type
enum LogFileType type
Definition: util-logopenfile.h:106
LOGFILE_TYPE_FILE
@ LOGFILE_TYPE_FILE
Definition: util-logopenfile.h:39
app-layer-parser.h
MAC_SET_DST
@ MAC_SET_DST
Definition: util-macset.h:30
ICMPV6Hdr_::code
uint8_t code
Definition: decode-icmpv6.h:146
Flow_::icmp_s
struct Flow_::@117::@123 icmp_s
CreateEveHeaderWithTxId
JsonBuilder * CreateEveHeaderWithTxId(const Packet *p, enum OutputJsonLogDirection dir, const char *event_type, JsonAddrInfo *addr, uint64_t tx_id, OutputJsonCtx *eve_ctx)
Definition: output-json.c:873
ICMPV4Hdr_::type
uint8_t type
Definition: decode-icmpv4.h:166
Packet_::icmpv6h
ICMPV6Hdr * icmpv6h
Definition: decode.h:577
JsonAddrInfo_
Definition: output-json.h:47
source-pcap-file-helper.h
NullLogInitialize
void NullLogInitialize(void)
Definition: output-eve-null.c:66
Packet_
Definition: decode.h:437
OutputJSONMemBufferWrapper_
Definition: output-json.h:64
GET_PKT_LEN
#define GET_PKT_LEN(p)
Definition: decode.h:220
MacSet_
Definition: util-macset.c:45
conf.h
Port
uint16_t Port
Definition: decode.h:230
Packet_::livedev
struct LiveDevice_ * livedev
Definition: decode.h:599
File_::name
uint8_t * name
Definition: util-file.h:88
TH_ECN
#define TH_ECN
Definition: decode-tcp.h:41
OutputJsonThreadCtx_::file_ctx
LogFileCtx * file_ctx
Definition: output-json.h:89
HttpXFFCfg_
Definition: app-layer-htp-xff.h:41
LOGFILE_TYPE_UNIX_DGRAM
@ LOGFILE_TYPE_UNIX_DGRAM
Definition: util-logopenfile.h:40
MacSetGetFlowStorageID
FlowStorageId MacSetGetFlowStorageID(void)
Definition: util-macset.c:114
LOG_DIR_FLOW_TOCLIENT
@ LOG_DIR_FLOW_TOCLIENT
Definition: output-json.h:39
LogFileTypeCtx_::thread_data
void * thread_data
Definition: util-logopenfile.h:72
SCLogOpenThreadedFile
bool SCLogOpenThreadedFile(const char *log_path, const char *append, LogFileCtx *parent_ctx)
Definition: util-logopenfile.c:359
util-proto-name.h
OutputJsonCommonSettings_::include_ethernet
bool include_ethernet
Definition: output-json.h:72
File_::sid
uint32_t * sid
Definition: util-file.h:108
LOGFILE_TYPE_UNIX_STREAM
@ LOGFILE_TYPE_UNIX_STREAM
Definition: util-logopenfile.h:41
MemBuffer_
Definition: util-buffer.h:27
File_::sid_cnt
uint32_t sid_cnt
Definition: util-file.h:109
TH_URG
#define TH_URG
Definition: decode-tcp.h:39
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:224
FlowGetStorageById
void * FlowGetStorageById(const Flow *f, FlowStorageId id)
Definition: flow-storage.c:40
FlowVarTypeInt_::value
uint32_t value
Definition: flow-var.h:44
Flow_::src
FlowAddress src
Definition: flow.h:354
Flow_::flowvar
GenericVar * flowvar
Definition: flow.h:486
OutputJsonCommonSettings_::include_metadata
bool include_metadata
Definition: output-json.h:70
JsonAddrInfo_::proto
char proto[JSON_PROTO_LEN]
Definition: output-json.h:52
ConfNodeLookupChild
ConfNode * ConfNodeLookupChild(const ConfNode *node, const char *name)
Lookup a child configuration node by name.
Definition: conf.c:786
File_::flags
uint16_t flags
Definition: util-file.h:80
OutputJsonInitCtx
OutputInitResult OutputJsonInitCtx(ConfNode *conf)
Create a new LogFileCtx for "fast" output style.
Definition: output-json.c:1037
FILE_STATE_CLOSED
@ FILE_STATE_CLOSED
Definition: util-file.h:71
File_
Definition: util-file.h:79
TH_PUSH
#define TH_PUSH
Definition: decode-tcp.h:37
flow-storage.h
OutputInitResult_
Definition: output.h:46
FlowVarTypeStr::value
uint8_t * value
Definition: flow-var.h:38
Packet_::flow
struct Flow_ * flow
Definition: decode.h:476
OutputJsonThreadCtx_::buffer
MemBuffer * buffer
Definition: output-json.h:90
StringParseUint64
int StringParseUint64(uint64_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:308
LOG_DIR_PACKET
@ LOG_DIR_PACKET
Definition: output-json.h:37
VAR_TYPE_FLOW_BIT
@ VAR_TYPE_FLOW_BIT
Definition: util-var.h:35
GET_IPV4_SRC_ADDR_PTR
#define GET_IPV4_SRC_ADDR_PTR(p)
Definition: decode.h:210
PrintBufferData
#define PrintBufferData(buf, buf_offset_ptr, buf_size,...)
Definition: util-print.h:27
TH_SYN
#define TH_SYN
Definition: decode-tcp.h:35
flags
uint8_t flags
Definition: decode-gre.h:0
JSONMACAddrInfo::src
JsonBuilder * src
Definition: output-json.c:732
suricata-common.h
JsonAddrInfo_::sp
Port sp
Definition: output-json.h:50
FLOW_IPV6
#define FLOW_IPV6
Definition: flow.h:99
OutputCtx_::DeInit
void(* DeInit)(struct OutputCtx_ *)
Definition: tm-modules.h:91
LogFileTypeCtx_::init_data
void * init_data
Definition: util-logopenfile.h:71
VarNameStoreLookupById
const char * VarNameStoreLookupById(const uint32_t id, const enum VarTypes type)
find name for id+type at packet time.
Definition: util-var-name.c:305
OutputJSONMemBufferWrapper_::expand_by
size_t expand_by
Definition: output-json.h:66
MacSetSize
int MacSetSize(const MacSet *ms)
Definition: util-macset.c:233
GenericVar_
Definition: util-var.h:48
JSON_ADDR_LEN
#define JSON_ADDR_LEN
Definition: output-json.h:43
FILE_STORED
#define FILE_STORED
Definition: util-file.h:56
FILE_MD5
#define FILE_MD5
Definition: util-file.h:48
LogFileFreeCtx
int LogFileFreeCtx(LogFileCtx *lf_ctx)
LogFileFreeCtx() Destroy a LogFileCtx (Close the file and free memory)
Definition: util-logopenfile.c:868
output-eve-syslog.h
util-classification-config.h
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
ICMPV4Hdr_::code
uint8_t code
Definition: decode-icmpv4.h:167
FatalError
#define FatalError(...)
Definition: util-debug.h:502
EvePacket
void EvePacket(const Packet *p, JsonBuilder *js, unsigned long max_length)
Jsonify a packet.
Definition: output-json.c:440
Flow_::parent_id
int64_t parent_id
Definition: flow.h:430
OutputJsonLogDirection
OutputJsonLogDirection
Definition: output-json.h:36
FlowBit_::idx
uint32_t idx
Definition: flow-bit.h:33
Packet_::icmpv4h
ICMPV4Hdr * icmpv4h
Definition: decode.h:575
DETECT_FLOWBITS
@ DETECT_FLOWBITS
Definition: detect-engine-register.h:90
File_::sha256
uint8_t sha256[SC_SHA256_LEN]
Definition: util-file.h:98
File_::start
uint64_t start
Definition: util-file.h:105
JB_SET_FALSE
#define JB_SET_FALSE(jb, key)
Definition: rust.h:28
util-optimize.h
RunmodeGetCurrent
int RunmodeGetCurrent(void)
Definition: suricata.c:266
threadvars.h
util-validate.h
LOG_DIR_FLOW
@ LOG_DIR_FLOW
Definition: output-json.h:38
CreateEveFlowId
void CreateEveFlowId(JsonBuilder *js, const Flow *f)
Definition: output-json.c:705
SCLogConfig
struct SCLogConfig_ SCLogConfig
Holds the config state used by the logging api.
JsonAddrInfo_::src_ip
char src_ip[JSON_ADDR_LEN]
Definition: output-json.h:48
FlowBit_
Definition: flow-bit.h:30
str
#define str(s)
Definition: suricata-common.h:291
LOG_DIR_FLOW_TOSERVER
@ LOG_DIR_FLOW_TOSERVER
Definition: output-json.h:40
GET_IPV6_SRC_ADDR
#define GET_IPV6_SRC_ADDR(p)
Definition: decode.h:215
SCFree
#define SCFree(p)
Definition: util-mem.h:61
Packet_::pkt_src
uint8_t pkt_src
Definition: decode.h:592
ConfNode_
Definition: conf.h:32
util-logopenfile.h
MEMBUFFER_SIZE
#define MEMBUFFER_SIZE(mem_buffer)
Get the MemBuffers current size.
Definition: util-buffer.h:61
Flow_::flags
uint32_t flags
Definition: flow.h:421
detect-parse.h
src
uint16_t src
Definition: app-layer-dnp3.h:5
util-buffer.h
IP_GET_IPPROTO
#define IP_GET_IPPROTO(p)
Definition: decode.h:258
TH_CWR
#define TH_CWR
Definition: decode-tcp.h:43
ConfValIsFalse
int ConfValIsFalse(const char *val)
Check if a value is false.
Definition: conf.c:562
VAR_TYPE_FLOW_VAR
@ VAR_TYPE_FLOW_VAR
Definition: util-var.h:37
MacSetForEach
int MacSetForEach(const MacSet *ms, MacSetIteratorFunc IterFunc, void *data)
Definition: util-macset.c:220
LogFileCtx_::prefix
char * prefix
Definition: util-logopenfile.h:131
JsonAddrInfo_::dst_ip
char dst_ip[JSON_ADDR_LEN]
Definition: output-json.h:49
VAR_TYPE_FLOW_INT
@ VAR_TYPE_FLOW_INT
Definition: util-var.h:36
LogFileCtx_::is_pcap_offline
bool is_pcap_offline
Definition: util-logopenfile.h:156
PcapFileGetFilename
const char * PcapFileGetFilename(void)
Definition: source-pcap-file-helper.c:118
PktVar_::value_len
uint16_t value_len
Definition: decode.h:319
MAX_JSON_SIZE
#define MAX_JSON_SIZE
Definition: output-json.c:78
OutputJsonCtx_::file_ctx
LogFileCtx * file_ctx
Definition: output-json.h:80
OutputJSONMemBufferCallback
int OutputJSONMemBufferCallback(const char *str, size_t size, void *data)
Definition: output-json.c:886
OutputJSONBuffer
int OutputJSONBuffer(json_t *js, LogFileCtx *file_ctx, MemBuffer **buffer)
Definition: output-json.c:899
FILE_SHA1
#define FILE_SHA1
Definition: util-file.h:50
LogFileType
LogFileType
Definition: util-logopenfile.h:38
MemBufferWriteRaw
uint32_t MemBufferWriteRaw(MemBuffer *dst, const uint8_t *raw, const uint32_t raw_len)
Write a raw buffer to the MemBuffer dst.
Definition: util-buffer.c:112
SCEveFindFileType
SCEveFileType * SCEveFindFileType(const char *name)
Definition: output-eve.c:43
JsonAddrInfoInit
void JsonAddrInfoInit(const Packet *p, enum OutputJsonLogDirection dir, JsonAddrInfo *addr)
Definition: output-json.c:477
PktVar_
Definition: decode.h:313
HttpXFFGetCfg
void HttpXFFGetCfg(ConfNode *conf, HttpXFFCfg *result)
Function to return XFF configuration from a configuration node.
Definition: app-layer-htp-xff.c:205
Packet_::vlan_id
uint16_t vlan_id[VLAN_MAX_LAYERS]
Definition: decode.h:464
SCEveFileType_::Init
int(* Init)(const ConfNode *conf, const bool threaded, void **init_data)
Function to initialize this filetype.
Definition: output-eve.h:103
likely
#define likely(expr)
Definition: util-optimize.h:32
IPPROTO_SCTP
#define IPPROTO_SCTP
Definition: decode.h:948
SCEveFileType_::ThreadInit
int(* ThreadInit)(const void *init_data, const ThreadId thread_id, void **thread_data)
Initialize thread specific data.
Definition: output-eve.h:124
Flow_::sp
Port sp
Definition: flow.h:356
dst
uint16_t dst
Definition: app-layer-dnp3.h:4
LogFileTypeCtx_::filetype
SCEveFileType * filetype
Definition: util-logopenfile.h:70
OutputJsonCommonSettings_::community_id_seed
uint16_t community_id_seed
Definition: output-json.h:73
flow.h
MEMBUFFER_OFFSET
#define MEMBUFFER_OFFSET(mem_buffer)
Get the MemBuffers current offset.
Definition: util-buffer.h:56
Packet_::dp
Port dp
Definition: decode.h:452
PktVar_::key_len
uint16_t key_len
Definition: decode.h:318
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
JSONMACAddrInfo::dst
JsonBuilder * dst
Definition: output-json.c:732
flow-var.h
FILE_STATE_ERROR
@ FILE_STATE_ERROR
Definition: util-file.h:75
PKT_IS_IPV4
#define PKT_IS_IPV4(p)
Definition: decode.h:246
RUNMODE_PCAP_FILE
@ RUNMODE_PCAP_FILE
Definition: runmodes.h:30
FlowVar_
Definition: flow-var.h:48
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:103
Flow_::tenant_id
uint32_t tenant_id
Definition: flow.h:416
VAR_TYPE_PKT_VAR
@ VAR_TYPE_PKT_VAR
Definition: util-var.h:32
LOGFILE_TYPE_FILETYPE
@ LOGFILE_TYPE_FILETYPE
Definition: util-logopenfile.h:44
FlowVar_::datatype
uint8_t datatype
Definition: flow-var.h:50
FILE_HAS_GAPS
#define FILE_HAS_GAPS
Definition: util-file.h:59
output.h
PktVar_::id
uint32_t id
Definition: decode.h:314
LogFileCtx_::threaded
bool threaded
Definition: util-logopenfile.h:101
MODULE_NAME
#define MODULE_NAME
Definition: output-json.c:76
SCEveFileType_
Structure used to define an EVE output file type plugin.
Definition: output-eve.h:73
OutputJsonCtx_::filetype
SCEveFileType * filetype
Definition: output-json.h:84
ConfNodeLookupChildValue
const char * ConfNodeLookupChildValue(const ConfNode *node, const char *name)
Lookup the value of a child configuration node by name.
Definition: conf.c:814