suricata
output-json-mdns.c
Go to the documentation of this file.
1/* Copyright (C) 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#include "suricata-common.h"
19#include "conf.h"
20
21#include "threadvars.h"
22
23#include "util-debug.h"
24#include "app-layer-parser.h"
25#include "output.h"
26
27#include "output-json.h"
28#include "output-json-mdns.h"
29#include "rust.h"
30
31typedef struct SCDnsLogFileCtx_ {
32 uint64_t flags; /** Store mode */
34 uint8_t version;
36
41
42bool AlertJsonMdns(void *txptr, SCJsonBuilder *js)
43{
44 return SCMdnsLogJson(txptr, js);
45}
46
47static int JsonMdnsLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f,
48 void *alstate, void *txptr, uint64_t tx_id)
49{
50 SCDnsLogThread *td = (SCDnsLogThread *)thread_data;
51 SCDnsLogFileCtx *dnslog_ctx = td->dnslog_ctx;
52
53 SCJsonBuilder *jb = CreateEveHeader(p, LOG_DIR_FLOW, "mdns", NULL, dnslog_ctx->eve_ctx);
54 if (unlikely(jb == NULL)) {
55 return TM_ECODE_OK;
56 }
57
58 if (SCMdnsLogJson(txptr, jb)) {
59 OutputJsonBuilderBuffer(tv, p, p->flow, jb, td->ctx);
60 }
61 SCJbFree(jb);
62
63 return TM_ECODE_OK;
64}
65
66static TmEcode SCDnsLogThreadInit(ThreadVars *t, const void *initdata, void **data)
67{
68 SCDnsLogThread *aft = SCCalloc(1, sizeof(SCDnsLogThread));
69 if (unlikely(aft == NULL))
70 return TM_ECODE_FAILED;
71
72 if (initdata == NULL) {
73 SCLogDebug("Error getting log context for eve-log.mdns. \"initdata\" argument NULL");
74 goto error_exit;
75 }
76
77 /* Use the Output Context (file pointer and mutex) */
78 aft->dnslog_ctx = ((OutputCtx *)initdata)->data;
80 if (!aft->ctx) {
81 goto error_exit;
82 }
83
84 *data = (void *)aft;
85 return TM_ECODE_OK;
86
87error_exit:
88 SCFree(aft);
89 return TM_ECODE_FAILED;
90}
91
92static TmEcode SCDnsLogThreadDeinit(ThreadVars *t, void *data)
93{
94 SCDnsLogThread *aft = (SCDnsLogThread *)data;
95 if (aft == NULL) {
96 return TM_ECODE_OK;
97 }
99
100 /* clear memory */
101 memset(aft, 0, sizeof(SCDnsLogThread));
102
103 SCFree(aft);
104 return TM_ECODE_OK;
105}
106
107static void DnsLogDeInitCtxSub(OutputCtx *output_ctx)
108{
109 SCDnsLogFileCtx *dnslog_ctx = (SCDnsLogFileCtx *)output_ctx->data;
110 SCFree(dnslog_ctx);
111 SCFree(output_ctx);
112}
113
114static OutputInitResult DnsLogInitCtxSub(SCConfNode *conf, OutputCtx *parent_ctx)
115{
116 OutputInitResult result = { NULL, false };
117 const char *enabled = SCConfNodeLookupChildValue(conf, "enabled");
118 if (enabled != NULL && !SCConfValIsTrue(enabled)) {
119 result.ok = true;
120 return result;
121 }
122
123 OutputJsonCtx *ojc = parent_ctx->data;
124
125 SCDnsLogFileCtx *dnslog_ctx = SCCalloc(1, sizeof(SCDnsLogFileCtx));
126 if (unlikely(dnslog_ctx == NULL)) {
127 return result;
128 }
129
130 dnslog_ctx->eve_ctx = ojc;
131 dnslog_ctx->version = DNS_LOG_VERSION_3;
132
133 /* For mDNS, log everything.
134 *
135 * TODO: Maybe add flags for request and/or response only.
136 */
137 dnslog_ctx->flags = ~0ULL;
138
139 OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
140 if (unlikely(output_ctx == NULL)) {
141 SCFree(dnslog_ctx);
142 return result;
143 }
144
145 output_ctx->data = dnslog_ctx;
146 output_ctx->DeInit = DnsLogDeInitCtxSub;
147
149
150 result.ctx = output_ctx;
151 result.ok = true;
152 return result;
153}
154
156{
157 OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonMdnsLog", "eve-log.mdns",
158 DnsLogInitCtxSub, ALPROTO_MDNS, JsonMdnsLogger, SCDnsLogThreadInit,
159 SCDnsLogThreadDeinit);
160}
void SCAppLayerParserRegisterLogger(uint8_t ipproto, AppProto alproto)
@ ALPROTO_MDNS
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
ThreadVars * tv
@ LOG_DIR_FLOW
OutputJsonThreadCtx * CreateEveThreadCtx(ThreadVars *t, OutputJsonCtx *ctx)
void FreeEveThreadCtx(OutputJsonThreadCtx *ctx)
struct SCDnsLogThread_ SCDnsLogThread
struct SCDnsLogFileCtx_ SCDnsLogFileCtx
void JsonMdnsLogRegister(void)
bool AlertJsonMdns(void *txptr, SCJsonBuilder *js)
SCJsonBuilder * CreateEveHeader(const Packet *p, enum SCOutputJsonLogDirection dir, const char *event_type, JsonAddrInfo *addr, OutputJsonCtx *eve_ctx)
void OutputJsonBuilderBuffer(ThreadVars *tv, const Packet *p, Flow *f, SCJsonBuilder *js, OutputJsonThreadCtx *ctx)
void OutputRegisterTxSubModule(LoggerId id, const char *parent_name, const char *name, const char *conf_name, OutputInitSubFunc InitFunc, AppProto alproto, TxLogger TxLogFunc, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit)
Definition output.c:406
Flow data structure.
Definition flow.h:356
void * data
Definition tm-modules.h:91
void(* DeInit)(struct OutputCtx_ *)
Definition tm-modules.h:94
OutputCtx * ctx
Definition output.h:47
struct Flow_ * flow
Definition decode.h:546
OutputJsonCtx * eve_ctx
SCDnsLogFileCtx * dnslog_ctx
OutputJsonThreadCtx * ctx
Per thread variable structure.
Definition threadvars.h:58
@ LOGGER_JSON_TX
@ TM_ECODE_FAILED
@ TM_ECODE_OK
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCFree(p)
Definition util-mem.h:61
#define SCCalloc(nm, sz)
Definition util-mem.h:53
#define unlikely(expr)