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