• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OISF / suricata / 23374838686

21 Mar 2026 07:29AM UTC coverage: 59.341% (-20.0%) from 79.315%
23374838686

Pull #15075

github

web-flow
Merge 90b4e834f into 6587e363a
Pull Request #15075: Stack 8001 v16.4

38 of 70 new or added lines in 10 files covered. (54.29%)

34165 existing lines in 563 files now uncovered.

119621 of 201584 relevant lines covered (59.34%)

650666.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

74.84
/src/output-json-flow.c
1
/* Copyright (C) 2007-2025 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 Victor Julien <victor@inliniac.net>
22
 *
23
 * Implements Flow JSON logging portion of the engine.
24
 */
25

26
#include "suricata-common.h"
27
#include "detect.h"
28
#include "pkt-var.h"
29
#include "conf.h"
30
#include "app-layer-parser.h"
31

32
#include "threads.h"
33
#include "threadvars.h"
34
#include "tm-threads.h"
35

36
#include "util-print.h"
37
#include "util-unittest.h"
38

39
#include "util-debug.h"
40

41
#include "output.h"
42
#include "util-privs.h"
43
#include "util-buffer.h"
44
#include "util-device-private.h"
45
#include "util-proto-name.h"
46
#include "util-logopenfile.h"
47
#include "util-time.h"
48
#include "output-json.h"
49
#include "output-json-flow.h"
50

51
#include "stream-tcp.h"
52
#include "stream-tcp-private.h"
53
#include "flow-storage.h"
54
#include "util-exception-policy.h"
55

56
static SCJsonBuilder *CreateEveHeaderFromFlow(const Flow *f, OutputJsonCommonSettings *cfg)
57
{
9,384✔
58
    char timebuf[64];
9,384✔
59
    char srcip[46] = {0}, dstip[46] = {0};
9,384✔
60
    Port sp, dp;
9,384✔
61

62
    SCJsonBuilder *jb = SCJbNewObject();
9,384✔
63
    if (unlikely(jb == NULL)) {
9,384✔
64
        return NULL;
×
65
    }
×
66

67
    SCTime_t ts = TimeGet();
9,384✔
68

69
    CreateIsoTimeString(ts, timebuf, sizeof(timebuf));
9,384✔
70

71
    if ((f->flags & FLOW_DIR_REVERSED) == 0) {
9,384✔
72
        if (FLOW_IS_IPV4(f)) {
8,020✔
73
            PrintInet(AF_INET, (const void *)&(f->src.addr_data32[0]), srcip, sizeof(srcip));
7,581✔
74
            PrintInet(AF_INET, (const void *)&(f->dst.addr_data32[0]), dstip, sizeof(dstip));
7,581✔
75
        } else if (FLOW_IS_IPV6(f)) {
7,581✔
76
            PrintInetIPv6(
439✔
77
                    (const void *)&(f->src.address), srcip, sizeof(srcip), cfg->compress_ipv6);
439✔
78
            PrintInetIPv6(
439✔
79
                    (const void *)&(f->dst.address), dstip, sizeof(dstip), cfg->compress_ipv6);
439✔
80
        }
439✔
81
        sp = f->sp;
8,020✔
82
        dp = f->dp;
8,020✔
83
    } else {
8,020✔
84
        if (FLOW_IS_IPV4(f)) {
1,364✔
85
            PrintInet(AF_INET, (const void *)&(f->dst.addr_data32[0]), srcip, sizeof(srcip));
1,339✔
86
            PrintInet(AF_INET, (const void *)&(f->src.addr_data32[0]), dstip, sizeof(dstip));
1,339✔
87
        } else if (FLOW_IS_IPV6(f)) {
1,339✔
88
            PrintInetIPv6(
25✔
89
                    (const void *)&(f->dst.address), srcip, sizeof(srcip), cfg->compress_ipv6);
25✔
90
            PrintInetIPv6(
25✔
91
                    (const void *)&(f->src.address), dstip, sizeof(dstip), cfg->compress_ipv6);
25✔
92
        }
25✔
93
        sp = f->dp;
1,364✔
94
        dp = f->sp;
1,364✔
95
    }
1,364✔
96

97
    /* time */
98
    SCJbSetString(jb, "timestamp", timebuf);
9,384✔
99

100
    CreateEveFlowId(jb, (const Flow *)f);
9,384✔
101

102
#if 0 // TODO
103
    /* sensor id */
104
    if (sensor_id >= 0)
105
        json_object_set_new(js, "sensor_id", json_integer(sensor_id));
106
#endif
107

108
    /* input interface */
109
    if (f->livedev) {
9,384✔
UNCOV
110
        SCJbSetString(jb, "in_iface", f->livedev->dev);
×
UNCOV
111
    }
×
112

113
    JB_SET_STRING(jb, "event_type", "flow");
9,384✔
114

115
    /* vlan */
116
    if (f->vlan_idx > 0) {
9,384✔
117
        SCJbOpenArray(jb, "vlan");
186✔
118
        SCJbAppendUint(jb, f->vlan_id[0]);
186✔
119
        if (f->vlan_idx > 1) {
186✔
UNCOV
120
            SCJbAppendUint(jb, f->vlan_id[1]);
×
UNCOV
121
        }
×
122
        if (f->vlan_idx > 2) {
186✔
UNCOV
123
            SCJbAppendUint(jb, f->vlan_id[2]);
×
UNCOV
124
        }
×
125
        SCJbClose(jb);
186✔
126
    }
186✔
127

128
    /* tuple */
129
    SCJbSetString(jb, "src_ip", srcip);
9,384✔
130
    switch(f->proto) {
9,384✔
131
        case IPPROTO_ICMP:
86✔
132
            break;
86✔
133
        case IPPROTO_UDP:
2,099✔
134
        case IPPROTO_TCP:
9,107✔
135
        case IPPROTO_SCTP:
9,107✔
136
            SCJbSetUint(jb, "src_port", sp);
9,107✔
137
            break;
9,107✔
138
    }
9,384✔
139
    SCJbSetString(jb, "dest_ip", dstip);
9,384✔
140
    switch(f->proto) {
9,384✔
141
        case IPPROTO_ICMP:
86✔
142
            break;
86✔
143
        case IPPROTO_UDP:
2,099✔
144
        case IPPROTO_TCP:
9,107✔
145
        case IPPROTO_SCTP:
9,107✔
146
            SCJbSetUint(jb, "dest_port", dp);
9,107✔
147
            break;
9,107✔
148
    }
9,384✔
149

150
    /* ip version */
151
    if (FLOW_IS_IPV4(f)) {
9,384✔
152
        SCJbSetUint(jb, "ip_v", 4);
8,920✔
153
    } else if (FLOW_IS_IPV6(f)) {
8,920✔
154
        SCJbSetUint(jb, "ip_v", 6);
464✔
155
    }
464✔
156

157
    if (SCProtoNameValid(f->proto)) {
9,384✔
158
        SCJbSetString(jb, "proto", known_proto[f->proto]);
9,384✔
159
    } else {
9,384✔
160
        char proto[4];
×
161
        snprintf(proto, sizeof(proto), "%"PRIu8"", f->proto);
×
162
        SCJbSetString(jb, "proto", proto);
×
163
    }
×
164

165
    switch (f->proto) {
9,384✔
166
        case IPPROTO_ICMP:
86✔
167
        case IPPROTO_ICMPV6:
267✔
168
            SCJbSetUint(jb, "icmp_type", f->icmp_s.type);
267✔
169
            SCJbSetUint(jb, "icmp_code", f->icmp_s.code);
267✔
170
            if (f->tosrcpktcnt) {
267✔
171
                SCJbSetUint(jb, "response_icmp_type", f->icmp_d.type);
13✔
172
                SCJbSetUint(jb, "response_icmp_code", f->icmp_d.code);
13✔
173
            }
13✔
174
            break;
267✔
175
        case IPPROTO_ESP:
10✔
176
            SCJbSetUint(jb, "spi", f->esp.spi);
10✔
177
            break;
10✔
178
    }
9,384✔
179
    return jb;
9,384✔
180
}
9,384✔
181

182
void EveAddAppProto(Flow *f, SCJsonBuilder *js)
183
{
108,902✔
184
    if (f->alproto) {
108,902✔
185
        SCJbSetString(js, "app_proto", AppProtoToString(f->alproto));
77,682✔
186
    }
77,682✔
187
    if (f->alproto_ts && f->alproto_ts != f->alproto) {
108,902✔
188
        SCJbSetString(js, "app_proto_ts", AppProtoToString(f->alproto_ts));
645✔
189
    }
645✔
190
    if (f->alproto_tc && f->alproto_tc != f->alproto) {
108,902✔
191
        SCJbSetString(js, "app_proto_tc", AppProtoToString(f->alproto_tc));
1,487✔
192
    }
1,487✔
193
    if (f->alproto_orig != f->alproto && f->alproto_orig != ALPROTO_UNKNOWN) {
108,902✔
194
        SCJbSetString(js, "app_proto_orig", AppProtoToString(f->alproto_orig));
3,595✔
195
    }
3,595✔
196
    if (f->alproto_expect != f->alproto && f->alproto_expect != ALPROTO_UNKNOWN) {
108,902✔
197
        SCJbSetString(js, "app_proto_expected", AppProtoToString(f->alproto_expect));
1,563✔
198
    }
1,563✔
199

200
}
108,902✔
201

202
void EveAddFlow(Flow *f, SCJsonBuilder *js)
203
{
108,902✔
204
    FlowBypassInfo *fc = FlowGetStorageById(f, GetFlowBypassInfoID());
108,902✔
205
    if (fc) {
108,902✔
206
        SCJbSetUint(js, "pkts_toserver", f->todstpktcnt + fc->todstpktcnt);
×
207
        SCJbSetUint(js, "pkts_toclient", f->tosrcpktcnt + fc->tosrcpktcnt);
×
208
        SCJbSetUint(js, "bytes_toserver", f->todstbytecnt + fc->todstbytecnt);
×
209
        SCJbSetUint(js, "bytes_toclient", f->tosrcbytecnt + fc->tosrcbytecnt);
×
210

211
        SCJbOpenObject(js, "bypassed");
×
212
        SCJbSetUint(js, "pkts_toserver", fc->todstpktcnt);
×
213
        SCJbSetUint(js, "pkts_toclient", fc->tosrcpktcnt);
×
214
        SCJbSetUint(js, "bytes_toserver", fc->todstbytecnt);
×
215
        SCJbSetUint(js, "bytes_toclient", fc->tosrcbytecnt);
×
216
        SCJbClose(js);
×
217
    } else {
108,902✔
218
        SCJbSetUint(js, "pkts_toserver", f->todstpktcnt);
108,902✔
219
        SCJbSetUint(js, "pkts_toclient", f->tosrcpktcnt);
108,902✔
220
        SCJbSetUint(js, "bytes_toserver", f->todstbytecnt);
108,902✔
221
        SCJbSetUint(js, "bytes_toclient", f->tosrcbytecnt);
108,902✔
222
    }
108,902✔
223

224
    char timebuf1[64];
108,902✔
225
    CreateIsoTimeString(f->startts, timebuf1, sizeof(timebuf1));
108,902✔
226
    SCJbSetString(js, "start", timebuf1);
108,902✔
227
}
108,902✔
228

229
static void EveExceptionPolicyLog(SCJsonBuilder *js, uint16_t flag)
230
{
4,664✔
231
    if (flag & EXCEPTION_TARGET_FLAG_DEFRAG_MEMCAP) {
4,664✔
232
        SCJbStartObject(js);
×
233
        SCJbSetString(js, "target",
×
234
                ExceptionPolicyTargetFlagToString(EXCEPTION_TARGET_FLAG_DEFRAG_MEMCAP));
×
235
        SCJbSetString(js, "policy",
×
236
                ExceptionPolicyEnumToString(
×
237
                        ExceptionPolicyTargetPolicy(EXCEPTION_TARGET_FLAG_DEFRAG_MEMCAP), true));
×
238
        SCJbClose(js);
×
239
    }
×
240
    if (flag & EXCEPTION_TARGET_FLAG_SESSION_MEMCAP) {
4,664✔
241
        SCJbStartObject(js);
×
242
        SCJbSetString(js, "target",
×
243
                ExceptionPolicyTargetFlagToString(EXCEPTION_TARGET_FLAG_SESSION_MEMCAP));
×
244
        SCJbSetString(js, "policy",
×
245
                ExceptionPolicyEnumToString(
×
246
                        ExceptionPolicyTargetPolicy(EXCEPTION_TARGET_FLAG_SESSION_MEMCAP), true));
×
247
        SCJbClose(js);
×
248
    }
×
249
    if (flag & EXCEPTION_TARGET_FLAG_REASSEMBLY_MEMCAP) {
4,664✔
250
        SCJbStartObject(js);
×
251
        SCJbSetString(js, "target",
×
252
                ExceptionPolicyTargetFlagToString(EXCEPTION_TARGET_FLAG_REASSEMBLY_MEMCAP));
×
253
        SCJbSetString(js, "policy",
×
254
                ExceptionPolicyEnumToString(
×
255
                        ExceptionPolicyTargetPolicy(EXCEPTION_TARGET_FLAG_REASSEMBLY_MEMCAP),
×
256
                        true));
×
257
        SCJbClose(js);
×
258
    }
×
259
    if (flag & EXCEPTION_TARGET_FLAG_FLOW_MEMCAP) {
4,664✔
260
        SCJbStartObject(js);
×
261
        SCJbSetString(
×
262
                js, "target", ExceptionPolicyTargetFlagToString(EXCEPTION_TARGET_FLAG_FLOW_MEMCAP));
×
263
        SCJbSetString(js, "policy",
×
264
                ExceptionPolicyEnumToString(
×
265
                        ExceptionPolicyTargetPolicy(EXCEPTION_TARGET_FLAG_FLOW_MEMCAP), true));
×
266
        SCJbClose(js);
×
267
    }
×
268
    if (flag & EXCEPTION_TARGET_FLAG_MIDSTREAM) {
4,664✔
269
        SCJbStartObject(js);
4,509✔
270
        SCJbSetString(
4,509✔
271
                js, "target", ExceptionPolicyTargetFlagToString(EXCEPTION_TARGET_FLAG_MIDSTREAM));
4,509✔
272
        SCJbSetString(js, "policy",
4,509✔
273
                ExceptionPolicyEnumToString(
4,509✔
274
                        ExceptionPolicyTargetPolicy(EXCEPTION_TARGET_FLAG_MIDSTREAM), true));
4,509✔
275
        SCJbClose(js);
4,509✔
276
    }
4,509✔
277
    if (flag & EXCEPTION_TARGET_FLAG_APPLAYER_ERROR) {
4,664✔
278
        SCJbStartObject(js);
340✔
279
        SCJbSetString(js, "target",
340✔
280
                ExceptionPolicyTargetFlagToString(EXCEPTION_TARGET_FLAG_APPLAYER_ERROR));
340✔
281
        SCJbSetString(js, "policy",
340✔
282
                ExceptionPolicyEnumToString(
340✔
283
                        ExceptionPolicyTargetPolicy(EXCEPTION_TARGET_FLAG_APPLAYER_ERROR), true));
340✔
284
        SCJbClose(js);
340✔
285
    }
340✔
286
}
4,664✔
287

288
/* Eve format logging */
289
static void EveFlowLogJSON(OutputJsonThreadCtx *aft, SCJsonBuilder *jb, Flow *f)
290
{
9,384✔
291
    EveAddAppProto(f, jb);
9,384✔
292
    SCJbOpenObject(jb, "flow");
9,384✔
293
    EveAddFlow(f, jb);
9,384✔
294

295
    char timebuf2[64];
9,384✔
296
    CreateIsoTimeString(f->lastts, timebuf2, sizeof(timebuf2));
9,384✔
297
    SCJbSetString(jb, "end", timebuf2);
9,384✔
298

299
    uint64_t age = (SCTIME_SECS(f->lastts) - SCTIME_SECS(f->startts));
9,384✔
300
    SCJbSetUint(jb, "age", age);
9,384✔
301

302
    if (f->flow_end_flags & FLOW_END_FLAG_EMERGENCY)
9,384✔
303
        JB_SET_TRUE(jb, "emergency");
×
304

305
    const int flow_state = f->flow_state;
9,384✔
306
    switch (flow_state) {
9,384✔
307
        case FLOW_STATE_NEW:
3,529✔
308
            JB_SET_STRING(jb, "state", "new");
3,529✔
309
            break;
3,529✔
310
        case FLOW_STATE_ESTABLISHED:
4,973✔
311
            JB_SET_STRING(jb, "state", "established");
4,973✔
312
            break;
4,973✔
313
        case FLOW_STATE_CLOSED:
882✔
314
            JB_SET_STRING(jb, "state", "closed");
882✔
315
            break;
882✔
UNCOV
316
        case FLOW_STATE_LOCAL_BYPASSED:
×
UNCOV
317
            JB_SET_STRING(jb, "state", "bypassed");
×
UNCOV
318
            JB_SET_STRING(jb, "bypass", "local");
×
UNCOV
319
            break;
×
320
#ifdef CAPTURE_OFFLOAD
321
        case FLOW_STATE_CAPTURE_BYPASSED:
322
            JB_SET_STRING(jb, "state", "bypassed");
323
            JB_SET_STRING(jb, "bypass", "capture");
324
            break;
325
#endif
326
        case FLOW_STATE_SIZE:
×
327
            DEBUG_VALIDATE_BUG_ON(1);
×
328
            SCLogDebug("invalid flow state: %d, contact developers", flow_state);
×
329
    }
9,384✔
330

331
    const char *reason = NULL;
9,384✔
332
    if (f->flow_end_flags & FLOW_END_FLAG_TCPREUSE)
9,384✔
333
        reason = "tcp_reuse";
550✔
334
    else if (f->flow_end_flags & FLOW_END_FLAG_FORCED)
8,834✔
335
        reason = "forced";
×
336
    else if (f->flow_end_flags & FLOW_END_FLAG_SHUTDOWN)
8,834✔
UNCOV
337
        reason = "shutdown";
×
338
    else if (f->flow_end_flags & FLOW_END_FLAG_TIMEOUT)
8,834✔
339
        reason = "timeout";
8,834✔
UNCOV
340
    else
×
UNCOV
341
        reason = "unknown";
×
342

343
    SCJbSetString(jb, "reason", reason);
9,384✔
344

345
    SCJbSetBool(jb, "alerted", FlowHasAlerts(f));
9,384✔
346
    if (f->flags & FLOW_WRONG_THREAD)
9,384✔
347
        JB_SET_TRUE(jb, "wrong_thread");
×
348

349
    if (f->flags & (FLOW_IS_ELEPHANT_TOSERVER | FLOW_IS_ELEPHANT_TOCLIENT)) {
9,384✔
UNCOV
350
        JB_SET_TRUE(jb, "elephant");
×
UNCOV
351
        SCJbOpenArray(jb, "elephant_direction");
×
UNCOV
352
        if (f->flags & FLOW_IS_ELEPHANT_TOSERVER)
×
UNCOV
353
            SCJbAppendString(jb, "toserver");
×
UNCOV
354
        if (f->flags & FLOW_IS_ELEPHANT_TOCLIENT)
×
UNCOV
355
            SCJbAppendString(jb, "toclient");
×
356

UNCOV
357
        SCJbClose(jb);
×
UNCOV
358
    }
×
359

360
    if (f->flags & FLOW_ACTION_DROP) {
9,384✔
361
        JB_SET_STRING(jb, "action", "drop");
17✔
362
    } else if (f->flags & FLOW_ACTION_ACCEPT) {
9,367✔
UNCOV
363
        JB_SET_STRING(jb, "action", "accept");
×
364
    } else if (f->flags & FLOW_ACTION_PASS) {
9,367✔
365
        JB_SET_STRING(jb, "action", "pass");
159✔
366
    }
159✔
367
    if (f->applied_exception_policy != 0) {
9,384✔
368
        SCJbOpenArray(jb, "exception_policy");
4,664✔
369
        EveExceptionPolicyLog(jb, f->applied_exception_policy);
4,664✔
370
        SCJbClose(jb); /* close array */
4,664✔
371
    }
4,664✔
372

373
    if (f->alstate) {
9,384✔
374
        uint64_t tx_id = AppLayerParserGetTxCnt(f, f->alstate);
4,743✔
375
        if (tx_id) {
4,743✔
376
            SCJbSetUint(jb, "tx_cnt", tx_id);
4,254✔
377
        }
4,254✔
378
    }
4,743✔
379

380
    /* Close flow. */
381
    SCJbClose(jb);
9,384✔
382

383
    EveAddCommonOptions(&aft->ctx->cfg, NULL, f, jb, LOG_DIR_FLOW);
9,384✔
384

385
    /* TCP */
386
    if (f->proto == IPPROTO_TCP) {
9,384✔
387
        SCJbOpenObject(jb, "tcp");
7,008✔
388

389
        TcpSession *ssn = f->protoctx;
7,008✔
390

391
        char hexflags[3];
7,008✔
392
        snprintf(hexflags, sizeof(hexflags), "%02x",
7,008✔
393
                ssn ? ssn->tcp_packet_flags : 0);
7,008✔
394
        SCJbSetString(jb, "tcp_flags", hexflags);
7,008✔
395

396
        snprintf(hexflags, sizeof(hexflags), "%02x",
7,008✔
397
                ssn ? ssn->client.tcp_flags : 0);
7,008✔
398
        SCJbSetString(jb, "tcp_flags_ts", hexflags);
7,008✔
399

400
        snprintf(hexflags, sizeof(hexflags), "%02x",
7,008✔
401
                ssn ? ssn->server.tcp_flags : 0);
7,008✔
402
        SCJbSetString(jb, "tcp_flags_tc", hexflags);
7,008✔
403

404
        EveTcpFlags(ssn ? ssn->tcp_packet_flags : 0, jb);
7,008✔
405

406
        if (ssn) {
7,008✔
407
            const char *tcp_state = StreamTcpStateAsString(ssn->state);
6,955✔
408
            if (tcp_state != NULL)
6,955✔
409
                SCJbSetString(jb, "state", tcp_state);
6,955✔
410
            if (ssn->server.flags & STREAMTCP_STREAM_FLAG_HAS_GAP) {
6,955✔
411
                JB_SET_TRUE(jb, "tc_gap");
453✔
412
            }
453✔
413
            if (ssn->client.flags & STREAMTCP_STREAM_FLAG_HAS_GAP) {
6,955✔
414
                JB_SET_TRUE(jb, "ts_gap");
793✔
415
            }
793✔
416

417
            SCJbSetUint(jb, "ts_max_regions", ssn->client.sb.max_regions);
6,955✔
418
            SCJbSetUint(jb, "tc_max_regions", ssn->server.sb.max_regions);
6,955✔
419

420
            if (ssn->urg_offset_ts)
6,955✔
UNCOV
421
                SCJbSetUint(jb, "ts_urgent_oob_data", ssn->urg_offset_ts);
×
422
            if (ssn->urg_offset_tc)
6,955✔
UNCOV
423
                SCJbSetUint(jb, "tc_urgent_oob_data", ssn->urg_offset_tc);
×
424
        }
6,955✔
425

426
        /* Close tcp. */
427
        SCJbClose(jb);
7,008✔
428
    }
7,008✔
429
}
9,384✔
430

431
static int JsonFlowLogger(ThreadVars *tv, void *thread_data, Flow *f)
432
{
9,384✔
433
    SCEnter();
9,384✔
434
    OutputJsonThreadCtx *thread = thread_data;
9,384✔
435

436
    /* reset */
437
    MemBufferReset(thread->buffer);
9,384✔
438

439
    SCJsonBuilder *jb = CreateEveHeaderFromFlow(f, &thread->ctx->cfg);
9,384✔
440
    if (unlikely(jb == NULL)) {
9,384✔
441
        SCReturnInt(TM_ECODE_OK);
×
442
    }
×
443

444
    EveFlowLogJSON(thread, jb, f);
9,384✔
445

446
    OutputJsonBuilderBuffer(tv, NULL, f, jb, thread);
9,384✔
447
    SCJbFree(jb);
9,384✔
448

449
    SCReturnInt(TM_ECODE_OK);
9,384✔
450
}
9,384✔
451

452
void JsonFlowLogRegister (void)
453
{
2✔
454
    /* register as child of eve-log */
455
    OutputRegisterFlowSubModule(LOGGER_JSON_FLOW, "eve-log", "JsonFlowLog", "eve-log.flow",
2✔
456
            OutputJsonLogInitSub, JsonFlowLogger, JsonLogThreadInit, JsonLogThreadDeinit);
2✔
457
}
2✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc