Coverage Report

Created: 2025-12-31 06:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata7/src/output-json-template.c
Line
Count
Source
1
/* Copyright (C) 2018-2022 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
 * TODO: Update \author in this file and in output-json-template.h.
20
 * TODO: Remove SCLogNotice statements, or convert to debug.
21
 * TODO: Implement your app-layers logging.
22
 */
23
24
/**
25
 * \file
26
 *
27
 * \author FirstName LastName <yourname@domain>
28
 *
29
 * Implement JSON/eve logging app-layer Template.
30
 */
31
32
#include "suricata-common.h"
33
#include "detect.h"
34
#include "pkt-var.h"
35
#include "conf.h"
36
37
#include "threads.h"
38
#include "threadvars.h"
39
#include "tm-threads.h"
40
41
#include "util-unittest.h"
42
#include "util-buffer.h"
43
#include "util-debug.h"
44
#include "util-byte.h"
45
46
#include "output.h"
47
#include "output-json.h"
48
49
#include "app-layer.h"
50
#include "app-layer-parser.h"
51
52
#include "output-json-template.h"
53
#include "rust.h"
54
55
typedef struct LogTemplateFileCtx_ {
56
    uint32_t flags;
57
    OutputJsonCtx *eve_ctx;
58
} LogTemplateFileCtx;
59
60
typedef struct LogTemplateLogThread_ {
61
    LogTemplateFileCtx *templatelog_ctx;
62
    OutputJsonThreadCtx *ctx;
63
} LogTemplateLogThread;
64
65
static int JsonTemplateLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f,
66
        void *state, void *tx, uint64_t tx_id)
67
0
{
68
0
    SCLogNotice("JsonTemplateLogger");
69
0
    LogTemplateLogThread *thread = thread_data;
70
71
0
    JsonBuilder *js =
72
0
            CreateEveHeader(p, LOG_DIR_PACKET, "template", NULL, thread->templatelog_ctx->eve_ctx);
73
0
    if (unlikely(js == NULL)) {
74
0
        return TM_ECODE_FAILED;
75
0
    }
76
77
0
    jb_open_object(js, "template");
78
0
    if (!rs_template_logger_log(tx, js)) {
79
0
        goto error;
80
0
    }
81
0
    jb_close(js);
82
83
0
    OutputJsonBuilderBuffer(js, thread->ctx);
84
0
    jb_free(js);
85
86
0
    return TM_ECODE_OK;
87
88
0
error:
89
0
    jb_free(js);
90
0
    return TM_ECODE_FAILED;
91
0
}
92
93
static void OutputTemplateLogDeInitCtxSub(OutputCtx *output_ctx)
94
0
{
95
0
    LogTemplateFileCtx *templatelog_ctx = (LogTemplateFileCtx *)output_ctx->data;
96
0
    SCFree(templatelog_ctx);
97
0
    SCFree(output_ctx);
98
0
}
99
100
static OutputInitResult OutputTemplateLogInitSub(ConfNode *conf, OutputCtx *parent_ctx)
101
0
{
102
0
    OutputInitResult result = { NULL, false };
103
0
    OutputJsonCtx *ajt = parent_ctx->data;
104
105
0
    LogTemplateFileCtx *templatelog_ctx = SCCalloc(1, sizeof(*templatelog_ctx));
106
0
    if (unlikely(templatelog_ctx == NULL)) {
107
0
        return result;
108
0
    }
109
0
    templatelog_ctx->eve_ctx = ajt;
110
111
0
    OutputCtx *output_ctx = SCCalloc(1, sizeof(*output_ctx));
112
0
    if (unlikely(output_ctx == NULL)) {
113
0
        SCFree(templatelog_ctx);
114
0
        return result;
115
0
    }
116
0
    output_ctx->data = templatelog_ctx;
117
0
    output_ctx->DeInit = OutputTemplateLogDeInitCtxSub;
118
119
0
    SCLogNotice("Template log sub-module initialized.");
120
121
0
    AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_TEMPLATE);
122
123
0
    result.ctx = output_ctx;
124
0
    result.ok = true;
125
0
    return result;
126
0
}
127
128
static TmEcode JsonTemplateLogThreadInit(ThreadVars *t, const void *initdata, void **data)
129
0
{
130
0
    LogTemplateLogThread *thread = SCCalloc(1, sizeof(*thread));
131
0
    if (unlikely(thread == NULL)) {
132
0
        return TM_ECODE_FAILED;
133
0
    }
134
135
0
    if (initdata == NULL) {
136
0
        SCLogDebug("Error getting context for EveLogTemplate.  \"initdata\" is NULL.");
137
0
        goto error_exit;
138
0
    }
139
140
0
    thread->templatelog_ctx = ((OutputCtx *)initdata)->data;
141
0
    thread->ctx = CreateEveThreadCtx(t, thread->templatelog_ctx->eve_ctx);
142
0
    if (!thread->ctx) {
143
0
        goto error_exit;
144
0
    }
145
0
    *data = (void *)thread;
146
147
0
    return TM_ECODE_OK;
148
149
0
error_exit:
150
0
    SCFree(thread);
151
0
    return TM_ECODE_FAILED;
152
0
}
153
154
static TmEcode JsonTemplateLogThreadDeinit(ThreadVars *t, void *data)
155
0
{
156
0
    LogTemplateLogThread *thread = (LogTemplateLogThread *)data;
157
0
    if (thread == NULL) {
158
0
        return TM_ECODE_OK;
159
0
    }
160
0
    FreeEveThreadCtx(thread->ctx);
161
0
    SCFree(thread);
162
0
    return TM_ECODE_OK;
163
0
}
164
165
void JsonTemplateLogRegister(void)
166
33
{
167
    /* TEMPLATE_START_REMOVE */
168
33
    if (ConfGetNode("app-layer.protocols.template") == NULL) {
169
1
        return;
170
1
    }
171
    /* TEMPLATE_END_REMOVE */
172
    /* Register as an eve sub-module. */
173
32
    OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonTemplateLog", "eve-log.template",
174
32
            OutputTemplateLogInitSub, ALPROTO_TEMPLATE, JsonTemplateLogger,
175
32
            JsonTemplateLogThreadInit, JsonTemplateLogThreadDeinit, NULL);
176
177
32
    SCLogNotice("Template JSON logger registered.");
178
32
}