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