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