suricata
output-json-alert.c
Go to the documentation of this file.
1/* Copyright (C) 2013-2024 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 alerts in JSON format.
24 *
25 */
26
27#include "suricata-common.h"
28#include "packet.h"
29#include "detect.h"
30#include "flow.h"
31#include "conf.h"
32
33#include "stream.h"
34#include "threadvars.h"
35#include "util-debug.h"
36#include "stream-tcp.h"
37
38#include "util-logopenfile.h"
39#include "util-misc.h"
40#include "util-time.h"
41
42#include "detect-engine.h"
43#include "detect-metadata.h"
44#include "app-layer-parser.h"
45#include "app-layer-htp-xff.h"
46#include "app-layer-ftp.h"
47#include "app-layer-frames.h"
48#include "log-pcap.h"
49
50#include "output.h"
51#include "output-json.h"
52#include "output-json-alert.h"
53#include "output-json-http.h"
54#include "rust.h"
55#include "output-json-smtp.h"
57#include "output-json-nfs.h"
58#include "output-json-smb.h"
59#include "output-json-flow.h"
60#include "output-json-ike.h"
61#include "output-json-frame.h"
62
63#include "util-print.h"
64#include "util-optimize.h"
65#include "util-buffer.h"
67#include "util-validate.h"
68
69#include "action-globals.h"
70
71#define MODULE_NAME "JsonAlertLog"
72
73#define LOG_JSON_PAYLOAD BIT_U16(0)
74#define LOG_JSON_PACKET BIT_U16(1)
75#define LOG_JSON_PAYLOAD_BASE64 BIT_U16(2)
76#define LOG_JSON_TAGGED_PACKETS BIT_U16(3)
77#define LOG_JSON_APP_LAYER BIT_U16(4)
78#define LOG_JSON_FLOW BIT_U16(5)
79#define LOG_JSON_HTTP_BODY BIT_U16(6)
80#define LOG_JSON_HTTP_BODY_BASE64 BIT_U16(7)
81#define LOG_JSON_RULE_METADATA BIT_U16(8)
82#define LOG_JSON_RULE BIT_U16(9)
83#define LOG_JSON_VERDICT BIT_U16(10)
84#define LOG_JSON_WEBSOCKET_PAYLOAD BIT_U16(11)
85#define LOG_JSON_WEBSOCKET_PAYLOAD_BASE64 BIT_U16(12)
86#define LOG_JSON_PAYLOAD_LENGTH BIT_U16(13)
87#define LOG_JSON_REFERENCE BIT_U16(14)
88
89#define METADATA_DEFAULTS ( LOG_JSON_FLOW | \
90 LOG_JSON_APP_LAYER | \
91 LOG_JSON_RULE_METADATA)
92
93#define JSON_BODY_LOGGING \
94 (LOG_JSON_HTTP_BODY | LOG_JSON_HTTP_BODY_BASE64 | LOG_JSON_WEBSOCKET_PAYLOAD | \
95 LOG_JSON_WEBSOCKET_PAYLOAD_BASE64)
96
97#define JSON_STREAM_BUFFER_SIZE 4096
98
107
113
114static void AlertJsonSourceTarget(
115 const Packet *p, const PacketAlert *pa, SCJsonBuilder *js, JsonAddrInfo *addr)
116{
117 SCJbOpenObject(js, "source");
118 if (pa->s->flags & SIG_FLAG_DEST_IS_TARGET) {
119 SCJbSetString(js, "ip", addr->src_ip);
120 switch (p->proto) {
121 case IPPROTO_ICMP:
122 case IPPROTO_ICMPV6:
123 break;
124 case IPPROTO_UDP:
125 case IPPROTO_TCP:
126 case IPPROTO_SCTP:
127 SCJbSetUint(js, "port", addr->sp);
128 break;
129 }
130 } else if (pa->s->flags & SIG_FLAG_SRC_IS_TARGET) {
131 SCJbSetString(js, "ip", addr->dst_ip);
132 switch (p->proto) {
133 case IPPROTO_ICMP:
134 case IPPROTO_ICMPV6:
135 break;
136 case IPPROTO_UDP:
137 case IPPROTO_TCP:
138 case IPPROTO_SCTP:
139 SCJbSetUint(js, "port", addr->dp);
140 break;
141 }
142 }
143 SCJbClose(js);
144
145 SCJbOpenObject(js, "target");
146 if (pa->s->flags & SIG_FLAG_DEST_IS_TARGET) {
147 SCJbSetString(js, "ip", addr->dst_ip);
148 switch (p->proto) {
149 case IPPROTO_ICMP:
150 case IPPROTO_ICMPV6:
151 break;
152 case IPPROTO_UDP:
153 case IPPROTO_TCP:
154 case IPPROTO_SCTP:
155 SCJbSetUint(js, "port", addr->dp);
156 break;
157 }
158 } else if (pa->s->flags & SIG_FLAG_SRC_IS_TARGET) {
159 SCJbSetString(js, "ip", addr->src_ip);
160 switch (p->proto) {
161 case IPPROTO_ICMP:
162 case IPPROTO_ICMPV6:
163 break;
164 case IPPROTO_UDP:
165 case IPPROTO_TCP:
166 case IPPROTO_SCTP:
167 SCJbSetUint(js, "port", addr->sp);
168 break;
169 }
170 }
171 SCJbClose(js);
172}
173
174static void AlertJsonReference(const PacketAlert *pa, SCJsonBuilder *jb)
175{
176 if (!pa->s->references) {
177 return;
178 }
179
180 const DetectReference *kv = pa->s->references;
181 SCJbOpenArray(jb, "references");
182 while (kv) {
183 /* Note that the key and reference sizes have been bound
184 * checked during parsing
185 */
186 const size_t size_needed = kv->key_len + kv->reference_len + 1;
187 char kv_store[size_needed];
188 snprintf(kv_store, size_needed, "%s%s", kv->key, kv->reference);
189 SCJbAppendString(jb, kv_store);
190 kv = kv->next;
191 }
192 SCJbClose(jb);
193}
194
195static void AlertJsonMetadata(const PacketAlert *pa, SCJsonBuilder *js)
196{
197 if (pa->s->metadata && pa->s->metadata->json_str) {
198 SCJbSetFormatted(js, pa->s->metadata->json_str);
199 }
200}
201
202void AlertJsonHeader(const Packet *p, const PacketAlert *pa, SCJsonBuilder *js, uint16_t flags,
203 JsonAddrInfo *addr, char *xff_buffer)
204{
205 const char *action = "allowed";
206 /* use packet action if rate_filter modified the action */
209 action = "blocked";
210 }
211 } else {
212 if (pa->action & ACTION_REJECT_ANY) {
213 action = "blocked";
214 } else if ((pa->action & ACTION_DROP) && EngineModeIsIPS()) {
215 action = "blocked";
216 }
217 }
218
219 /* Add tx_id to root element for correlation with other events. */
220 /* json_object_del(js, "tx_id"); */
221 if (pa->flags & PACKET_ALERT_FLAG_TX) {
222 SCJbSetUint(js, "tx_id", pa->tx_id);
223 }
225 SCJbSetBool(js, "tx_guessed", true);
226 }
227
228 SCJbOpenObject(js, "alert");
229
230 SCJbSetString(js, "action", action);
231 SCJbSetUint(js, "gid", pa->s->gid);
232 SCJbSetUint(js, "signature_id", pa->s->id);
233 SCJbSetUint(js, "rev", pa->s->rev);
234 /* TODO: SCJsonBuilder should handle unprintable characters like
235 * SCJsonString. */
236 SCJbSetString(js, "signature", pa->s->msg ? pa->s->msg : "");
237 SCJbSetString(js, "category", pa->s->class_msg ? pa->s->class_msg : "");
238 SCJbSetUint(js, "severity", pa->s->prio);
239
240 if (p->tenant_id > 0) {
241 SCJbSetUint(js, "tenant_id", p->tenant_id);
242 }
243
244 if (addr && pa->s->flags & SIG_FLAG_HAS_TARGET) {
245 AlertJsonSourceTarget(p, pa, js, addr);
246 }
247
248 if ((flags & LOG_JSON_REFERENCE)) {
249 AlertJsonReference(pa, js);
250 }
251
253 AlertJsonMetadata(pa, js);
254 }
255
256 if (pa->json_info != NULL) {
257 SCJbOpenObject(js, "context");
258 const struct PacketContextData *json_info = pa->json_info;
259 while (json_info) {
260 SCLogDebug("JSON string '{%s}'", json_info->json_string);
261 /* The string is valid json as it is validated by JANSSON
262 during parsing and included later via a format string */
263 SCJbSetFormatted(js, json_info->json_string);
264 json_info = json_info->next;
265 }
266 SCJbClose(js);
267 }
268 if (flags & LOG_JSON_RULE) {
269 SCJbSetString(js, "rule", pa->s->sig_str);
270 }
271 if (xff_buffer && xff_buffer[0]) {
272 SCJbSetString(js, "xff", xff_buffer);
273 }
274
275 SCJbClose(js);
276}
277
278static void AlertJsonTunnel(const Packet *p, SCJsonBuilder *js)
279{
280 if (p->root == NULL) {
281 return;
282 }
283
284 SCJbOpenObject(js, "tunnel");
285
286 enum PktSrcEnum pkt_src;
287 uint64_t pcap_cnt;
289 JsonAddrInfoInit(p->root, 0, &addr);
290 pcap_cnt = p->root->pcap_cnt;
291 pkt_src = p->root->pkt_src;
292
293 SCJbSetString(js, "src_ip", addr.src_ip);
294 SCJbSetUint(js, "src_port", addr.sp);
295 SCJbSetString(js, "dest_ip", addr.dst_ip);
296 SCJbSetUint(js, "dest_port", addr.dp);
297 SCJbSetString(js, "proto", addr.proto);
298
299 SCJbSetUint(js, "depth", p->recursion_level);
300 if (pcap_cnt != 0) {
301 SCJbSetUint(js, "pcap_cnt", pcap_cnt);
302 }
303 SCJbSetString(js, "pkt_src", PktSrcToString(pkt_src));
304 SCJbClose(js);
305}
306
307static void AlertAddPayload(AlertJsonOutputCtx *json_output_ctx, SCJsonBuilder *js, const Packet *p)
308{
309 if (json_output_ctx->flags & LOG_JSON_PAYLOAD_BASE64) {
310 SCJbSetBase64(js, "payload", p->payload, p->payload_len);
311 }
312 if (json_output_ctx->flags & LOG_JSON_PAYLOAD_LENGTH) {
313 SCJbSetUint(js, "payload_length", p->payload_len);
314 }
315
316 if (json_output_ctx->flags & LOG_JSON_PAYLOAD) {
317 uint8_t printable_buf[p->payload_len + 1];
318 uint32_t offset = 0;
319 PrintStringsToBuffer(printable_buf, &offset,
320 p->payload_len + 1,
321 p->payload, p->payload_len);
322 printable_buf[p->payload_len] = '\0';
323 SCJbSetString(js, "payload_printable", (char *)printable_buf);
324 }
325}
326
327static void AlertAddAppLayer(
328 const Packet *p, SCJsonBuilder *jb, const uint64_t tx_id, const uint16_t option_flags)
329{
330 const AppProto proto = FlowGetAppProtocol(p->flow);
332 SCJsonBuilderMark mark = { 0, 0, 0 };
333 if (al && al->LogTx) {
334 void *state = FlowGetAppState(p->flow);
335 if (state) {
336 void *tx = AppLayerParserGetTx(p->flow->proto, proto, state, tx_id);
337 if (tx) {
338 const int ts =
339 AppLayerParserGetStateProgress(p->flow->proto, proto, tx, STREAM_TOSERVER);
340 const int tc =
341 AppLayerParserGetStateProgress(p->flow->proto, proto, tx, STREAM_TOCLIENT);
342 SCJbSetString(jb, "ts_progress",
343 AppLayerParserGetStateNameById(p->flow->proto, proto, ts, STREAM_TOSERVER));
344 SCJbSetString(jb, "tc_progress",
345 AppLayerParserGetStateNameById(p->flow->proto, proto, tc, STREAM_TOCLIENT));
346 SCJbGetMark(jb, &mark);
347 switch (proto) {
348 // first check some protocols need special options for alerts logging
350 if (option_flags &
352 bool pp = (option_flags & LOG_JSON_WEBSOCKET_PAYLOAD) != 0;
353 bool pb64 = (option_flags & LOG_JSON_WEBSOCKET_PAYLOAD_BASE64) != 0;
354 if (!SCWebSocketLogDetails(tx, jb, pp, pb64)) {
355 SCJbRestoreMark(jb, &mark);
356 }
357 // nothing more to log or do
358 return;
359 }
360 }
361 if (!al->LogTx(tx, jb)) {
362 SCJbRestoreMark(jb, &mark);
363 }
364 }
365 }
366 return;
367 }
368 void *state = FlowGetAppState(p->flow);
369 if (state) {
370 void *tx = AppLayerParserGetTx(p->flow->proto, proto, state, tx_id);
371 if (tx) {
372 const int ts =
373 AppLayerParserGetStateProgress(p->flow->proto, proto, tx, STREAM_TOSERVER);
374 const int tc =
375 AppLayerParserGetStateProgress(p->flow->proto, proto, tx, STREAM_TOCLIENT);
376 SCJbSetString(jb, "ts_progress",
377 AppLayerParserGetStateNameById(p->flow->proto, proto, ts, STREAM_TOSERVER));
378 SCJbSetString(jb, "tc_progress",
379 AppLayerParserGetStateNameById(p->flow->proto, proto, tc, STREAM_TOCLIENT));
380 }
381 }
382 switch (proto) {
383 case ALPROTO_HTTP1:
384 // TODO: Could result in an empty http object being logged.
385 SCJbOpenObject(jb, "http");
386 if (EveHttpAddMetadata(p->flow, tx_id, jb)) {
387 if (option_flags & LOG_JSON_HTTP_BODY) {
388 EveHttpLogJSONBodyPrintable(jb, p->flow, tx_id);
389 }
390 if (option_flags & LOG_JSON_HTTP_BODY_BASE64) {
391 EveHttpLogJSONBodyBase64(jb, p->flow, tx_id);
392 }
393 }
394 SCJbClose(jb);
395 break;
396 case ALPROTO_SMTP:
397 SCJbGetMark(jb, &mark);
398 SCJbOpenObject(jb, "smtp");
399 if (EveSMTPAddMetadata(p->flow, tx_id, jb)) {
400 SCJbClose(jb);
401 } else {
402 SCJbRestoreMark(jb, &mark);
403 }
404 SCJbGetMark(jb, &mark);
405 SCJbOpenObject(jb, "email");
406 if (EveEmailAddMetadata(p->flow, tx_id, jb)) {
407 SCJbClose(jb);
408 } else {
409 SCJbRestoreMark(jb, &mark);
410 }
411 break;
412 case ALPROTO_NFS:
413 /* rpc */
414 SCJbGetMark(jb, &mark);
415 SCJbOpenObject(jb, "rpc");
416 if (EveNFSAddMetadataRPC(p->flow, tx_id, jb)) {
417 SCJbClose(jb);
418 } else {
419 SCJbRestoreMark(jb, &mark);
420 }
421 /* nfs */
422 SCJbGetMark(jb, &mark);
423 SCJbOpenObject(jb, "nfs");
424 if (EveNFSAddMetadata(p->flow, tx_id, jb)) {
425 SCJbClose(jb);
426 } else {
427 SCJbRestoreMark(jb, &mark);
428 }
429 break;
430 case ALPROTO_SMB:
431 SCJbGetMark(jb, &mark);
432 SCJbOpenObject(jb, "smb");
433 if (EveSMBAddMetadata(p->flow, tx_id, jb)) {
434 SCJbClose(jb);
435 } else {
436 SCJbRestoreMark(jb, &mark);
437 }
438 break;
439 case ALPROTO_IKE:
440 SCJbGetMark(jb, &mark);
441 if (!EveIKEAddMetadata(p->flow, tx_id, jb)) {
442 SCJbRestoreMark(jb, &mark);
443 }
444 break;
445 case ALPROTO_DCERPC: {
446 if (state) {
447 void *tx = AppLayerParserGetTx(p->flow->proto, proto, state, tx_id);
448 if (tx) {
449 SCJbGetMark(jb, &mark);
450 SCJbOpenObject(jb, "dcerpc");
451 if (p->proto == IPPROTO_TCP) {
452 if (!SCDcerpcLogJsonRecordTcp(state, tx, jb)) {
453 SCJbRestoreMark(jb, &mark);
454 }
455 } else {
456 if (!SCDcerpcLogJsonRecordUdp(state, tx, jb)) {
457 SCJbRestoreMark(jb, &mark);
458 }
459 }
460 SCJbClose(jb);
461 }
462 }
463 break;
464 }
465 default:
466 break;
467 }
468}
469
470static void AlertAddFiles(const Packet *p, SCJsonBuilder *jb, const uint64_t tx_id)
471{
472 const uint8_t direction =
473 (p->flowflags & FLOW_PKT_TOSERVER) ? STREAM_TOSERVER : STREAM_TOCLIENT;
474 FileContainer *ffc = NULL;
475 if (p->flow->alstate != NULL) {
476 void *tx = AppLayerParserGetTx(p->flow->proto, p->flow->alproto, p->flow->alstate, tx_id);
477 if (tx) {
478 AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, tx, direction);
479 ffc = files.fc;
480 }
481 }
482 if (ffc != NULL) {
483 File *file = ffc->head;
484 bool isopen = false;
485 while (file) {
486 if (!isopen) {
487 isopen = true;
488 SCJbOpenArray(jb, "files");
489 }
490 SCJbStartObject(jb);
491 EveFileInfo(jb, file, tx_id, file->flags);
492 SCJbClose(jb);
493 file = file->next;
494 }
495 if (isopen) {
496 SCJbClose(jb);
497 }
498 }
499}
500
501static void AlertAddFrame(
502 const Packet *p, const int64_t frame_id, SCJsonBuilder *jb, MemBuffer *buffer)
503{
504 if (p->flow == NULL || (p->proto == IPPROTO_TCP && p->flow->protoctx == NULL))
505 return;
506
507 FramesContainer *frames_container = AppLayerFramesGetContainer(p->flow);
508 if (frames_container == NULL)
509 return;
510
511 Frames *frames = NULL;
512 TcpStream *stream = NULL;
513 if (p->proto == IPPROTO_TCP) {
514 TcpSession *ssn = p->flow->protoctx;
515 if (PKT_IS_TOSERVER(p)) {
516 stream = &ssn->client;
517 frames = &frames_container->toserver;
518 } else {
519 stream = &ssn->server;
520 frames = &frames_container->toclient;
521 }
522 Frame *frame = FrameGetById(frames, frame_id);
523 if (frame != NULL) {
524 FrameJsonLogOneFrame(IPPROTO_TCP, frame, p->flow, stream, p, jb, buffer);
525 }
526 } else if (p->proto == IPPROTO_UDP) {
527 if (PKT_IS_TOSERVER(p)) {
528 frames = &frames_container->toserver;
529 } else {
530 frames = &frames_container->toclient;
531 }
532 Frame *frame = FrameGetById(frames, frame_id);
533 if (frame != NULL) {
534 FrameJsonLogOneFrame(IPPROTO_UDP, frame, p->flow, NULL, p, jb, buffer);
535 }
536 }
537}
538
539/**
540 * \brief Build verdict object
541 *
542 * \param p Pointer to Packet current being logged
543 *
544 */
545void EveAddVerdict(SCJsonBuilder *jb, const Packet *p)
546{
547 SCJbOpenObject(jb, "verdict");
548
549 /* add verdict info */
551 // check rule to define type of reject packet sent
552 if (EngineModeIsIPS()) {
553 JB_SET_STRING(jb, "action", "drop");
554 } else {
555 JB_SET_STRING(jb, "action", "alert");
556 }
558 JB_SET_STRING(jb, "reject-target", "to_client");
559 } else if (PacketCheckAction(p, ACTION_REJECT_DST)) {
560 JB_SET_STRING(jb, "reject-target", "to_server");
561 } else if (PacketCheckAction(p, ACTION_REJECT_BOTH)) {
562 JB_SET_STRING(jb, "reject-target", "both");
563 }
564 SCJbOpenArray(jb, "reject");
565 switch (p->proto) {
566 case IPPROTO_UDP:
567 case IPPROTO_ICMP:
568 case IPPROTO_ICMPV6:
569 SCJbAppendString(jb, "icmp-prohib");
570 break;
571 case IPPROTO_TCP:
572 SCJbAppendString(jb, "tcp-reset");
573 break;
574 }
575 SCJbClose(jb);
576
577 } else if (PacketCheckAction(p, ACTION_DROP) && EngineModeIsIPS()) {
578 JB_SET_STRING(jb, "action", "drop");
579 } else if (PacketCheckAction(p, ACTION_ACCEPT)) {
580 JB_SET_STRING(jb, "action", "accept");
581 } else if (p->alerts.alerts[p->alerts.cnt].action & ACTION_PASS) {
582 JB_SET_STRING(jb, "action", "pass");
583 } else {
584 // TODO make sure we don't have a situation where this wouldn't work
585 JB_SET_STRING(jb, "action", "alert");
586 }
587
588 /* Close verdict */
589 SCJbClose(jb);
590}
591
596
597static int AlertJsonStreamDataCallback(
598 void *cb_data, const uint8_t *input, const uint32_t input_len, const uint64_t input_offset)
599{
600 struct AlertJsonStreamDataCallbackData *cbd = cb_data;
601 if (input_offset > cbd->last_re) {
603 cbd->payload, "[%" PRIu64 " bytes missing]", input_offset - cbd->last_re);
604 }
605
606 int done = 0;
607 uint32_t written = MemBufferWriteRaw(cbd->payload, input, input_len);
608 if (written < input_len)
609 done = 1;
610 cbd->last_re = input_offset + input_len;
611 return done;
612}
613
614/** \internal
615 * \brief try to log stream data into payload/payload_printable
616 * \retval true stream data logged
617 * \retval false stream data not logged
618 */
619static bool AlertJsonStreamData(const AlertJsonOutputCtx *json_output_ctx, JsonAlertLogThread *aft,
620 Flow *f, const Packet *p, SCJsonBuilder *jb)
621{
622 TcpSession *ssn = f->protoctx;
623 TcpStream *stream = (PKT_IS_TOSERVER(p)) ? &ssn->client : &ssn->server;
624
625 MemBufferReset(aft->payload_buffer);
627 .last_re = STREAM_BASE_OFFSET(stream) };
628 uint64_t unused = 0;
629 StreamReassembleLog(ssn, stream, AlertJsonStreamDataCallback, &cbd, STREAM_BASE_OFFSET(stream),
630 &unused, false);
631 if (cbd.payload->offset) {
632 if (json_output_ctx->flags & LOG_JSON_PAYLOAD_BASE64) {
633 SCJbSetBase64(jb, "payload", cbd.payload->buffer, cbd.payload->offset);
634 }
635 if (json_output_ctx->flags & LOG_JSON_PAYLOAD_LENGTH) {
636 SCJbSetUint(jb, "payload_length", cbd.payload->offset);
637 }
638
639 if (json_output_ctx->flags & LOG_JSON_PAYLOAD) {
640 uint8_t printable_buf[cbd.payload->offset + 1];
641 uint32_t offset = 0;
642 PrintStringsToBuffer(printable_buf, &offset, cbd.payload->offset + 1,
643 cbd.payload->buffer, cbd.payload->offset);
644 SCJbSetString(jb, "payload_printable", (char *)printable_buf);
645 }
646 return true;
647 }
648 return false;
649}
650
651static int AlertJson(ThreadVars *tv, JsonAlertLogThread *aft, const Packet *p)
652{
653 AlertJsonOutputCtx *json_output_ctx = aft->json_output_ctx;
654
655 if (p->alerts.cnt == 0 && !(p->flags & PKT_HAS_TAG))
656 return TM_ECODE_OK;
657
658 for (int i = 0; i < p->alerts.cnt; i++) {
659 const PacketAlert *pa = &p->alerts.alerts[i];
660 if (unlikely(pa->s == NULL)) {
661 continue;
662 }
663
664 /* First initialize the address info (5-tuple). */
667
668 /* Check for XFF, overwriting address info if needed. */
669 HttpXFFCfg *xff_cfg = json_output_ctx->xff_cfg != NULL ? json_output_ctx->xff_cfg
670 : json_output_ctx->parent_xff_cfg;
671 int have_xff_ip = 0;
672 char xff_buffer[XFF_MAXLEN];
673 xff_buffer[0] = 0;
674 if ((xff_cfg != NULL) && !(xff_cfg->flags & XFF_DISABLED) && p->flow != NULL) {
675 if (FlowGetAppProtocol(p->flow) == ALPROTO_HTTP1) {
676 if (pa->flags & PACKET_ALERT_FLAG_TX) {
677 have_xff_ip = HttpXFFGetIPFromTx(p->flow, pa->tx_id, xff_cfg,
678 xff_buffer, XFF_MAXLEN);
679 } else {
680 have_xff_ip = HttpXFFGetIP(p->flow, xff_cfg, xff_buffer,
681 XFF_MAXLEN);
682 }
683 }
684
685 if (have_xff_ip && xff_cfg->flags & XFF_OVERWRITE) {
686 if (p->flowflags & FLOW_PKT_TOCLIENT) {
687 strlcpy(addr.dst_ip, xff_buffer, JSON_ADDR_LEN);
688 } else {
689 strlcpy(addr.src_ip, xff_buffer, JSON_ADDR_LEN);
690 }
691 /* Clear have_xff_ip so the xff field does not get
692 * logged below. */
693 have_xff_ip = false;
694 }
695 if (have_xff_ip && !(xff_cfg->flags & XFF_EXTRADATA)) {
696 // reset xff_buffer so as not to log it
697 xff_buffer[0] = 0;
698 }
699 }
700
701 SCJsonBuilder *jb =
702 CreateEveHeader(p, LOG_DIR_PACKET, "alert", &addr, json_output_ctx->eve_ctx);
703 if (unlikely(jb == NULL))
704 return TM_ECODE_OK;
705
706
707 /* alert */
708 AlertJsonHeader(p, pa, jb, json_output_ctx->flags, &addr, xff_buffer);
709
710 if (PacketIsTunnel(p)) {
711 AlertJsonTunnel(p, jb);
712 }
713
714 if (p->flow != NULL) {
715 if (pa->flags & PACKET_ALERT_FLAG_TX) {
716 if (json_output_ctx->flags & LOG_JSON_APP_LAYER) {
717 AlertAddAppLayer(p, jb, pa->tx_id, json_output_ctx->flags);
718 }
719 /* including fileinfo data is configured by the metadata setting */
720 if (json_output_ctx->flags & LOG_JSON_RULE_METADATA) {
721 AlertAddFiles(p, jb, pa->tx_id);
722 }
723 }
724
725 EveAddAppProto(p->flow, jb);
726
727 if (p->flowflags & FLOW_PKT_TOSERVER) {
728 SCJbSetString(jb, "direction", "to_server");
729 } else {
730 SCJbSetString(jb, "direction", "to_client");
731 }
732
733 if (json_output_ctx->flags & LOG_JSON_FLOW) {
734 SCJbOpenObject(jb, "flow");
735 EveAddFlow(p->flow, jb);
736 if (p->flowflags & FLOW_PKT_TOCLIENT) {
737 SCJbSetString(jb, "src_ip", addr.dst_ip);
738 SCJbSetString(jb, "dest_ip", addr.src_ip);
739 if (addr.sp > 0) {
740 SCJbSetUint(jb, "src_port", addr.dp);
741 SCJbSetUint(jb, "dest_port", addr.sp);
742 }
743 } else {
744 SCJbSetString(jb, "src_ip", addr.src_ip);
745 SCJbSetString(jb, "dest_ip", addr.dst_ip);
746 if (addr.sp > 0) {
747 SCJbSetUint(jb, "src_port", addr.sp);
748 SCJbSetUint(jb, "dest_port", addr.dp);
749 }
750 }
751 SCJbClose(jb);
752 }
753 }
754
755 /* payload */
756 if (json_output_ctx->flags &
758 int stream = (p->proto == IPPROTO_TCP) ?
760 1 : 0) : 0;
761 // should be impossible, as stream implies flow
762 DEBUG_VALIDATE_BUG_ON(stream && p->flow == NULL);
763
764 /* Is this a stream? If so, pack part of it into the payload field */
765 if (stream && p->flow != NULL) {
766 const bool stream_data_logged =
767 AlertJsonStreamData(json_output_ctx, aft, p->flow, p, jb);
768 if (!stream_data_logged && p->payload_len) {
769 /* Fallback on packet payload */
770 AlertAddPayload(json_output_ctx, jb, p);
771 }
772 } else {
773 /* This is a single packet and not a stream */
774 AlertAddPayload(json_output_ctx, jb, p);
775 }
776
777 SCJbSetUint(jb, "stream", stream);
778 }
779
780 if (pa->flags & PACKET_ALERT_FLAG_FRAME) {
781 AlertAddFrame(p, pa->frame_id, jb, aft->payload_buffer);
782 }
783
784 /* base64-encoded full packet */
785 if (json_output_ctx->flags & LOG_JSON_PACKET) {
786 EvePacket(p, jb, 0);
787 }
788
790 if (pcap_filename != NULL) {
791 SCJbSetString(jb, "capture_file", pcap_filename);
792 }
793
794 if (json_output_ctx->flags & LOG_JSON_VERDICT) {
795 EveAddVerdict(jb, p);
796 }
797
798 OutputJsonBuilderBuffer(tv, p, p->flow, jb, aft->ctx);
799 SCJbFree(jb);
800 }
801
802 if ((p->flags & PKT_HAS_TAG) && (json_output_ctx->flags &
804 SCJsonBuilder *packetjs =
805 CreateEveHeader(p, LOG_DIR_PACKET, "packet", NULL, json_output_ctx->eve_ctx);
806 if (unlikely(packetjs != NULL)) {
807 EvePacket(p, packetjs, 0);
808 OutputJsonBuilderBuffer(tv, p, p->flow, packetjs, aft->ctx);
809 SCJbFree(packetjs);
810 }
811 }
812
813 return TM_ECODE_OK;
814}
815
816static int AlertJsonDecoderEvent(ThreadVars *tv, JsonAlertLogThread *aft, const Packet *p)
817{
818 AlertJsonOutputCtx *json_output_ctx = aft->json_output_ctx;
819
820 if (p->alerts.cnt == 0)
821 return TM_ECODE_OK;
822
823 for (int i = 0; i < p->alerts.cnt; i++) {
824 const PacketAlert *pa = &p->alerts.alerts[i];
825 if (unlikely(pa->s == NULL)) {
826 continue;
827 }
828
829 SCJsonBuilder *jb =
830 CreateEveHeader(p, LOG_DIR_PACKET, "alert", NULL, json_output_ctx->eve_ctx);
831 if (unlikely(jb == NULL))
832 return TM_ECODE_OK;
833
834 AlertJsonHeader(p, pa, jb, json_output_ctx->flags, NULL, NULL);
835
836 if (PacketIsTunnel(p)) {
837 AlertJsonTunnel(p, jb);
838 }
839
840 /* base64-encoded full packet */
841 if (json_output_ctx->flags & LOG_JSON_PACKET) {
842 EvePacket(p, jb, 0);
843 }
844
846 if (pcap_filename != NULL) {
847 SCJbSetString(jb, "capture_file", pcap_filename);
848 }
849
850 if (json_output_ctx->flags & LOG_JSON_VERDICT) {
851 EveAddVerdict(jb, p);
852 }
853
854 OutputJsonBuilderBuffer(tv, p, p->flow, jb, aft->ctx);
855 SCJbFree(jb);
856 }
857
858 return TM_ECODE_OK;
859}
860
861static int JsonAlertFlush(ThreadVars *tv, void *thread_data, const Packet *p)
862{
863 JsonAlertLogThread *aft = thread_data;
864 SCLogDebug("%s flushing %s", tv->name, ((LogFileCtx *)(aft->ctx->file_ctx))->filename);
865 OutputJsonFlush(aft->ctx);
866 return 0;
867}
868
869static int JsonAlertLogger(ThreadVars *tv, void *thread_data, const Packet *p)
870{
871 JsonAlertLogThread *aft = thread_data;
872
873 if (PacketIsIPv4(p) || PacketIsIPv6(p)) {
874 return AlertJson(tv, aft, p);
875 } else if (p->alerts.cnt > 0) {
876 return AlertJsonDecoderEvent(tv, aft, p);
877 }
878 return 0;
879}
880
881static bool JsonAlertLogCondition(ThreadVars *tv, void *thread_data, const Packet *p)
882{
883 return (p->alerts.cnt || (p->flags & PKT_HAS_TAG));
884}
885
886static TmEcode JsonAlertLogThreadInit(ThreadVars *t, const void *initdata, void **data)
887{
889 if (unlikely(aft == NULL))
890 return TM_ECODE_FAILED;
891
892 if (initdata == NULL)
893 {
894 SCLogDebug("Error getting context for EveLogAlert. \"initdata\" argument NULL");
895 goto error_exit;
896 }
897
898 /** Use the Output Context (file pointer and mutex) */
899 AlertJsonOutputCtx *json_output_ctx = ((OutputCtx *)initdata)->data;
900
902 if (aft->payload_buffer == NULL) {
903 goto error_exit;
904 }
905 aft->ctx = CreateEveThreadCtx(t, json_output_ctx->eve_ctx);
906 if (!aft->ctx) {
907 goto error_exit;
908 }
909
910 aft->json_output_ctx = json_output_ctx;
911
912 *data = (void *)aft;
913 return TM_ECODE_OK;
914
915error_exit:
916 if (aft->payload_buffer != NULL) {
918 }
919 SCFree(aft);
920 return TM_ECODE_FAILED;
921}
922
923static TmEcode JsonAlertLogThreadDeinit(ThreadVars *t, void *data)
924{
926 if (aft == NULL) {
927 return TM_ECODE_OK;
928 }
929
931 FreeEveThreadCtx(aft->ctx);
932
933 /* clear memory */
934 memset(aft, 0, sizeof(JsonAlertLogThread));
935
936 SCFree(aft);
937 return TM_ECODE_OK;
938}
939
940static void JsonAlertLogDeInitCtxSub(OutputCtx *output_ctx)
941{
942 SCLogDebug("cleaning up sub output_ctx %p", output_ctx);
943
944 AlertJsonOutputCtx *json_output_ctx = (AlertJsonOutputCtx *) output_ctx->data;
945
946 if (json_output_ctx != NULL) {
947 HttpXFFCfg *xff_cfg = json_output_ctx->xff_cfg;
948 if (xff_cfg != NULL) {
949 SCFree(xff_cfg);
950 }
951 SCFree(json_output_ctx);
952 }
953 SCFree(output_ctx);
954}
955
956static void SetFlag(const SCConfNode *conf, const char *name, uint16_t flag, uint16_t *out_flags)
957{
958 DEBUG_VALIDATE_BUG_ON(conf == NULL);
959 const char *setting = SCConfNodeLookupChildValue(conf, name);
960 if (setting != NULL) {
961 if (SCConfValIsTrue(setting)) {
962 *out_flags |= flag;
963 } else {
964 *out_flags &= ~flag;
965 }
966 }
967}
968
969static void JsonAlertLogSetupMetadata(AlertJsonOutputCtx *json_output_ctx, SCConfNode *conf)
970{
971 static bool warn_no_meta = false;
972 uint32_t payload_buffer_size = JSON_STREAM_BUFFER_SIZE;
973 uint16_t flags = METADATA_DEFAULTS;
974
975 if (conf != NULL) {
976 /* Check for metadata to enable/disable. */
977 SCConfNode *metadata = SCConfNodeLookupChild(conf, "metadata");
978 if (metadata != NULL) {
979 if (metadata->val != NULL && SCConfValIsFalse(metadata->val)) {
980 flags &= ~METADATA_DEFAULTS;
981 } else if (SCConfNodeHasChildren(metadata)) {
982 SCConfNode *rule_metadata = SCConfNodeLookupChild(metadata, "rule");
983 if (rule_metadata) {
984 SetFlag(rule_metadata, "raw", LOG_JSON_RULE, &flags);
985 SetFlag(rule_metadata, "metadata", LOG_JSON_RULE_METADATA,
986 &flags);
987 SetFlag(rule_metadata, "reference", LOG_JSON_REFERENCE, &flags);
988 }
989 SetFlag(metadata, "flow", LOG_JSON_FLOW, &flags);
990 SetFlag(metadata, "app-layer", LOG_JSON_APP_LAYER, &flags);
991 }
992 }
993
994 /* Non-metadata toggles. */
995 SetFlag(conf, "payload", LOG_JSON_PAYLOAD_BASE64, &flags);
996 SetFlag(conf, "packet", LOG_JSON_PACKET, &flags);
997 SetFlag(conf, "tagged-packets", LOG_JSON_TAGGED_PACKETS, &flags);
998 SetFlag(conf, "payload-printable", LOG_JSON_PAYLOAD, &flags);
999 SetFlag(conf, "http-body-printable", LOG_JSON_HTTP_BODY, &flags);
1000 SetFlag(conf, "http-body", LOG_JSON_HTTP_BODY_BASE64, &flags);
1001 SetFlag(conf, "websocket-payload-printable", LOG_JSON_WEBSOCKET_PAYLOAD, &flags);
1002 SetFlag(conf, "websocket-payload", LOG_JSON_WEBSOCKET_PAYLOAD_BASE64, &flags);
1003 SetFlag(conf, "verdict", LOG_JSON_VERDICT, &flags);
1004 SetFlag(conf, "payload-length", LOG_JSON_PAYLOAD_LENGTH, &flags);
1005
1006 /* Check for obsolete flags and warn that they have no effect. */
1007 static const char *deprecated_flags[] = { "http", "tls", "ssh", "smtp", "dnp3", "app-layer",
1008 "flow", NULL };
1009 for (int i = 0; deprecated_flags[i] != NULL; i++) {
1010 if (SCConfNodeLookupChildValue(conf, deprecated_flags[i]) != NULL) {
1011 SCLogWarning("Found deprecated eve-log.alert flag \"%s\", this flag has no effect",
1012 deprecated_flags[i]);
1013 }
1014 }
1015
1016 const char *payload_buffer_value = SCConfNodeLookupChildValue(conf, "payload-buffer-size");
1017
1018 if (payload_buffer_value != NULL) {
1019 uint32_t value;
1020 if (ParseSizeStringU32(payload_buffer_value, &value) < 0) {
1021 SCLogError("Error parsing "
1022 "payload-buffer-size - %s. Killing engine",
1023 payload_buffer_value);
1024 exit(EXIT_FAILURE);
1025 } else if (value == 0) {
1026 // you should not ask for payload if you want 0 of it
1027 SCLogError("Error payload-buffer-size should not be 0");
1028 exit(EXIT_FAILURE);
1029 } else {
1030 payload_buffer_size = value;
1031 }
1032 }
1033
1034 if (!warn_no_meta && flags & JSON_BODY_LOGGING) {
1035 if (((flags & LOG_JSON_APP_LAYER) == 0)) {
1036 SCLogWarning("HTTP body logging has been configured, however, "
1037 "metadata logging has not been enabled. HTTP body logging will be "
1038 "disabled.");
1039 flags &= ~JSON_BODY_LOGGING;
1040 warn_no_meta = true;
1041 }
1042 }
1043 }
1044
1047 }
1048
1049 json_output_ctx->payload_buffer_size = payload_buffer_size;
1050 json_output_ctx->flags |= flags;
1051}
1052
1053static HttpXFFCfg *JsonAlertLogGetXffCfg(SCConfNode *conf)
1054{
1055 HttpXFFCfg *xff_cfg = NULL;
1056 if (conf != NULL && SCConfNodeLookupChild(conf, "xff") != NULL) {
1057 xff_cfg = SCCalloc(1, sizeof(HttpXFFCfg));
1058 if (likely(xff_cfg != NULL)) {
1059 HttpXFFGetCfg(conf, xff_cfg);
1060 }
1061 }
1062 return xff_cfg;
1063}
1064
1065/**
1066 * \brief Create a new LogFileCtx for "fast" output style.
1067 * \param conf The configuration node for this output.
1068 * \return A LogFileCtx pointer on success, NULL on failure.
1069 */
1070static OutputInitResult JsonAlertLogInitCtxSub(SCConfNode *conf, OutputCtx *parent_ctx)
1071{
1072 OutputInitResult result = { NULL, false };
1073 OutputJsonCtx *ajt = parent_ctx->data;
1074 AlertJsonOutputCtx *json_output_ctx = NULL;
1075
1076 OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
1077 if (unlikely(output_ctx == NULL))
1078 return result;
1079
1080 json_output_ctx = SCCalloc(1, sizeof(AlertJsonOutputCtx));
1081 if (unlikely(json_output_ctx == NULL)) {
1082 goto error;
1083 }
1084
1085 json_output_ctx->file_ctx = ajt->file_ctx;
1086 json_output_ctx->eve_ctx = ajt;
1087
1088 JsonAlertLogSetupMetadata(json_output_ctx, conf);
1089 json_output_ctx->xff_cfg = JsonAlertLogGetXffCfg(conf);
1090 if (json_output_ctx->xff_cfg == NULL) {
1091 json_output_ctx->parent_xff_cfg = ajt->xff_cfg;
1092 }
1093
1094 output_ctx->data = json_output_ctx;
1095 output_ctx->DeInit = JsonAlertLogDeInitCtxSub;
1096
1097 result.ctx = output_ctx;
1098 result.ok = true;
1099 return result;
1100
1101error:
1102 if (json_output_ctx != NULL) {
1103 SCFree(json_output_ctx);
1104 }
1105 if (output_ctx != NULL) {
1106 SCFree(output_ctx);
1107 }
1108
1109 return result;
1110}
1111
1113{
1114 OutputPacketLoggerFunctions output_logger_functions = {
1115 .LogFunc = JsonAlertLogger,
1116 .FlushFunc = JsonAlertFlush,
1117 .ConditionFunc = JsonAlertLogCondition,
1118 .ThreadInitFunc = JsonAlertLogThreadInit,
1119 .ThreadDeinitFunc = JsonAlertLogThreadDeinit,
1120 .ThreadExitPrintStatsFunc = NULL,
1121 };
1122
1123 OutputRegisterPacketSubModule(LOGGER_JSON_ALERT, "eve-log", MODULE_NAME, "eve-log.alert",
1124 JsonAlertLogInitCtxSub, &output_logger_functions);
1125}
#define ACTION_DROP_REJECT
#define ACTION_REJECT
#define ACTION_PASS
#define ACTION_ACCEPT
#define ACTION_REJECT_ANY
#define ACTION_REJECT_BOTH
#define ACTION_REJECT_DST
#define ACTION_DROP
Frame * FrameGetById(Frames *frames, const int64_t id)
FramesContainer * AppLayerFramesGetContainer(Flow *f)
int HttpXFFGetIPFromTx(const Flow *f, uint64_t tx_id, HttpXFFCfg *xff_cfg, char *dstbuf, int dstbuflen)
Function to return XFF IP if any in the selected transaction. The caller needs to lock the flow.
int HttpXFFGetIP(const Flow *f, HttpXFFCfg *xff_cfg, char *dstbuf, int dstbuflen)
Function to return XFF IP if any. The caller needs to lock the flow.
void HttpXFFGetCfg(SCConfNode *conf, HttpXFFCfg *result)
Function to return XFF configuration from a configuration node.
#define XFF_MAXLEN
#define XFF_EXTRADATA
#define XFF_OVERWRITE
#define XFF_DISABLED
AppLayerGetFileState AppLayerParserGetTxFiles(const Flow *f, void *tx, const uint8_t direction)
void * AppLayerParserGetTx(uint8_t ipproto, AppProto alproto, void *alstate, uint64_t tx_id)
const char * AppLayerParserGetStateNameById(uint8_t ipproto, AppProto alproto, const int id, const uint8_t direction)
int AppLayerParserGetStateProgress(uint8_t ipproto, AppProto alproto, void *alstate, uint8_t flags)
get the progress value for a tx/protocol
struct AppLayerGetFileState AppLayerGetFileState
uint16_t AppProto
@ ALPROTO_NFS
@ ALPROTO_DCERPC
@ ALPROTO_SMTP
@ ALPROTO_WEBSOCKET
@ ALPROTO_SMB
@ ALPROTO_IKE
@ ALPROTO_HTTP1
SCConfNode * SCConfNodeLookupChild(const SCConfNode *node, const char *name)
Lookup a child configuration node by name.
Definition conf.c:796
bool SCConfNodeHasChildren(const SCConfNode *node)
Check if a node has any children.
Definition conf.c:777
int SCConfValIsTrue(const char *val)
Check if a value is true.
Definition conf.c:551
const char * SCConfNodeLookupChildValue(const SCConfNode *node, const char *name)
Lookup the value of a child configuration node by name.
Definition conf.c:824
int SCConfValIsFalse(const char *val)
Check if a value is false.
Definition conf.c:576
uint8_t flags
Definition decode-gre.h:0
uint8_t proto
#define PKT_HAS_TAG
Definition decode.h:1258
#define PKT_IS_TOSERVER(p)
Definition decode.h:238
PktSrcEnum
Definition decode.h:51
#define IPPROTO_SCTP
Definition decode.h:1228
void DetectEngineSetParseMetadata(void)
#define SIG_FLAG_SRC_IS_TARGET
Definition detect.h:283
#define SIG_FLAG_HAS_TARGET
Definition detect.h:287
#define SIG_FLAG_DEST_IS_TARGET
Definition detect.h:285
#define FLOW_PKT_TOSERVER
Definition flow.h:233
#define FLOW_PKT_TOCLIENT
Definition flow.h:234
ThreadVars * tv
#define PACKET_ALERT_FLAG_TX_GUESSED
Definition decode.h:278
#define PACKET_ALERT_FLAG_TX
Definition decode.h:272
#define PACKET_ALERT_FLAG_RATE_FILTER_MODIFIED
Definition decode.h:274
#define PACKET_ALERT_FLAG_STREAM_MATCH
Definition decode.h:270
#define PACKET_ALERT_FLAG_STATE_MATCH
Definition decode.h:268
#define PACKET_ALERT_FLAG_FRAME
Definition decode.h:276
const char * PktSrcToString(enum PktSrcEnum pkt_src)
Definition decode.c:855
char * PcapLogGetFilename(void)
Definition log-pcap.c:1826
@ LOG_DIR_PACKET
EveJsonSimpleAppLayerLogger * SCEveJsonSimpleGetLogger(AppProto alproto)
Definition output.c:931
#define LOG_JSON_PAYLOAD
#define MODULE_NAME
#define LOG_JSON_WEBSOCKET_PAYLOAD_BASE64
#define JSON_BODY_LOGGING
#define LOG_JSON_RULE
struct AlertJsonOutputCtx_ AlertJsonOutputCtx
#define LOG_JSON_TAGGED_PACKETS
#define LOG_JSON_RULE_METADATA
#define LOG_JSON_WEBSOCKET_PAYLOAD
#define LOG_JSON_APP_LAYER
#define LOG_JSON_REFERENCE
#define LOG_JSON_HTTP_BODY
void EveAddVerdict(SCJsonBuilder *jb, const Packet *p)
Build verdict object.
#define JSON_STREAM_BUFFER_SIZE
void AlertJsonHeader(const Packet *p, const PacketAlert *pa, SCJsonBuilder *js, uint16_t flags, JsonAddrInfo *addr, char *xff_buffer)
#define LOG_JSON_FLOW
#define LOG_JSON_PACKET
#define LOG_JSON_HTTP_BODY_BASE64
struct JsonAlertLogThread_ JsonAlertLogThread
#define METADATA_DEFAULTS
#define LOG_JSON_PAYLOAD_LENGTH
#define LOG_JSON_VERDICT
void JsonAlertLogRegister(void)
#define LOG_JSON_PAYLOAD_BASE64
OutputJsonThreadCtx * CreateEveThreadCtx(ThreadVars *t, OutputJsonCtx *ctx)
void FreeEveThreadCtx(OutputJsonThreadCtx *ctx)
bool EveEmailAddMetadata(const Flow *f, uint64_t tx_id, SCJsonBuilder *js)
void EveAddAppProto(Flow *f, SCJsonBuilder *js)
void EveAddFlow(Flow *f, SCJsonBuilder *js)
void FrameJsonLogOneFrame(const uint8_t ipproto, const Frame *frame, Flow *f, const TcpStream *stream, const Packet *p, SCJsonBuilder *jb, MemBuffer *buffer)
log a single frame
void EveHttpLogJSONBodyPrintable(SCJsonBuilder *js, Flow *f, uint64_t tx_id)
bool EveHttpAddMetadata(const Flow *f, uint64_t tx_id, SCJsonBuilder *js)
void EveHttpLogJSONBodyBase64(SCJsonBuilder *js, Flow *f, uint64_t tx_id)
bool EveIKEAddMetadata(const Flow *f, uint64_t tx_id, SCJsonBuilder *js)
bool EveNFSAddMetadataRPC(const Flow *f, uint64_t tx_id, SCJsonBuilder *jb)
bool EveNFSAddMetadata(const Flow *f, uint64_t tx_id, SCJsonBuilder *jb)
bool EveSMBAddMetadata(const Flow *f, uint64_t tx_id, SCJsonBuilder *jb)
bool EveSMTPAddMetadata(const Flow *f, uint64_t tx_id, SCJsonBuilder *js)
void OutputJsonFlush(OutputJsonThreadCtx *ctx)
SCJsonBuilder * CreateEveHeader(const Packet *p, enum SCOutputJsonLogDirection dir, const char *event_type, JsonAddrInfo *addr, OutputJsonCtx *eve_ctx)
void EveFileInfo(SCJsonBuilder *jb, const File *ff, const uint64_t tx_id, const uint16_t flags)
void JsonAddrInfoInit(const Packet *p, enum SCOutputJsonLogDirection dir, JsonAddrInfo *addr)
void EvePacket(const Packet *p, SCJsonBuilder *js, uint32_t max_length)
Jsonify a packet.
const JsonAddrInfo json_addr_info_zero
Definition output-json.c:81
void OutputJsonBuilderBuffer(ThreadVars *tv, const Packet *p, Flow *f, SCJsonBuilder *js, OutputJsonThreadCtx *ctx)
#define JSON_ADDR_LEN
Definition output-json.h:37
void OutputRegisterPacketSubModule(LoggerId id, const char *parent_name, const char *name, const char *conf_name, OutputInitSubFunc InitFunc, OutputPacketLoggerFunctions *output_logger_functions)
Register a packet output sub-module.
Definition output.c:234
bool PacketCheckAction(const Packet *p, const uint8_t a)
Definition packet.c:49
#define JB_SET_STRING(jb, key, val)
Definition rust.h:26
uint64_t ts
char pcap_filename[PATH_MAX]
#define STREAM_BASE_OFFSET(stream)
int StreamReassembleLog(const TcpSession *ssn, const TcpStream *stream, StreamReassembleRawFunc Callback, void *cb_data, const uint64_t progress_in, uint64_t *progress_out, const bool eof)
OutputJsonCtx * eve_ctx
Signature reference list.
struct DetectReference_ * next
EveJsonSimpleTxLogFunc LogTx
uint16_t flags
Definition util-file.h:80
struct File_ * next
Definition util-file.h:92
Flow data structure.
Definition flow.h:356
uint8_t proto
Definition flow.h:378
AppProto alproto
application level protocol
Definition flow.h:450
void * alstate
Definition flow.h:479
void * protoctx
Definition flow.h:441
char proto[JSON_PROTO_LEN]
Definition output-json.h:46
char src_ip[JSON_ADDR_LEN]
Definition output-json.h:42
char dst_ip[JSON_ADDR_LEN]
Definition output-json.h:43
AlertJsonOutputCtx * json_output_ctx
OutputJsonThreadCtx * ctx
uint8_t buffer[]
Definition util-buffer.h:30
uint32_t offset
Definition util-buffer.h:29
void * data
Definition tm-modules.h:91
void(* DeInit)(struct OutputCtx_ *)
Definition tm-modules.h:94
OutputCtx * ctx
Definition output.h:47
HttpXFFCfg * xff_cfg
Definition output-json.h:79
LogFileCtx * file_ctx
Definition output-json.h:76
LogFileCtx * file_ctx
Definition output-json.h:85
int64_t frame_id
Definition decode.h:254
const struct Signature_ * s
Definition decode.h:252
uint8_t flags
Definition decode.h:251
uint64_t tx_id
Definition decode.h:253
struct PacketContextData * json_info
Definition decode.h:255
uint8_t action
Definition decode.h:250
uint16_t cnt
Definition decode.h:287
PacketAlert * alerts
Definition decode.h:290
struct PacketContextData * next
Definition decode.h:243
char * json_string
Definition decode.h:242
uint32_t tenant_id
Definition decode.h:665
uint8_t flowflags
Definition decode.h:532
uint64_t pcap_cnt
Definition decode.h:626
uint8_t pkt_src
Definition decode.h:611
uint8_t recursion_level
Definition decode.h:526
PacketAlerts alerts
Definition decode.h:620
struct Flow_ * flow
Definition decode.h:546
uint8_t * payload
Definition decode.h:605
struct Packet_ * root
Definition decode.h:653
uint16_t payload_len
Definition decode.h:606
uint32_t flags
Definition decode.h:544
uint8_t proto
Definition decode.h:523
char * val
Definition conf.h:39
uint32_t flags
Definition detect.h:669
DetectReference * references
Definition detect.h:741
DetectMetadataHead * metadata
Definition detect.h:743
uint32_t rev
Definition detect.h:715
int prio
Definition detect.h:716
char * sig_str
Definition detect.h:745
char * class_msg
Definition detect.h:739
uint32_t id
Definition detect.h:713
char * msg
Definition detect.h:736
uint32_t gid
Definition detect.h:714
Per thread variable structure.
Definition threadvars.h:58
char name[16]
Definition threadvars.h:65
@ LOGGER_JSON_ALERT
size_t strlcpy(char *dst, const char *src, size_t siz)
int EngineModeIsIPS(void)
Definition suricata.c:242
@ TM_ECODE_FAILED
@ TM_ECODE_OK
const char * name
void MemBufferWriteString(MemBuffer *dst, const char *fmt,...)
MemBuffer * MemBufferCreateNew(uint32_t size)
Definition util-buffer.c:32
uint32_t MemBufferWriteRaw(MemBuffer *dst, const uint8_t *raw, const uint32_t raw_len)
Write a raw buffer to the MemBuffer dst.
void MemBufferFree(MemBuffer *buffer)
Definition util-buffer.c:86
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition util-debug.h:255
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
#define SCFree(p)
Definition util-mem.h:61
#define SCCalloc(nm, sz)
Definition util-mem.h:53
int ParseSizeStringU32(const char *size, uint32_t *res)
Definition util-misc.c:173
#define likely(expr)
#define unlikely(expr)
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:195
uint64_t offset
#define DEBUG_VALIDATE_BUG_ON(exp)