suricata
output-packet.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-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 Victor Julien <victor@inliniac.net>
22  *
23  * Packet Logger Output registration functions
24  */
25 
26 #include "suricata-common.h"
27 #include "output.h"
28 #include "output-packet.h"
29 #include "util-profiling.h"
30 #include "util-validate.h"
31 
32 /** per thread data for this module, contains a list of per thread
33  * data for the packet loggers. */
37 
38 /* logger instance, a module + a output ctx,
39  * it's perfectly valid that have multiple instances of the same
40  * log module (e.g. fast.log) with different output ctx'. */
41 typedef struct OutputPacketLogger_ {
44  /** Data that will be passed to the ThreadInit callback. */
45  void *initdata;
47  const char *name;
52 
53 static OutputPacketLogger *list = NULL;
54 
58 {
59  OutputPacketLogger *op = SCCalloc(1, sizeof(*op));
60  if (op == NULL)
61  return -1;
62 
63  op->LogFunc = LogFunc;
65  op->initdata = initdata;
66  op->name = name;
67  op->ThreadInit = ThreadInit;
69  op->logger_id = logger_id;
70 
71  if (list == NULL)
72  list = op;
73  else {
74  OutputPacketLogger *t = list;
75  while (t->next)
76  t = t->next;
77  t->next = op;
78  }
79 
80  SCLogDebug("OutputRegisterPacketLogger happy");
81  return 0;
82 }
83 
84 static TmEcode OutputPacketLog(ThreadVars *tv, Packet *p, void *thread_data)
85 {
86  DEBUG_VALIDATE_BUG_ON(thread_data == NULL);
87 
88  if (list == NULL) {
89  /* No child loggers. */
90  return TM_ECODE_OK;
91  }
92 
93  OutputPacketLoggerThreadData *op_thread_data = (OutputPacketLoggerThreadData *)thread_data;
94  OutputPacketLogger *logger = list;
95  OutputLoggerThreadStore *store = op_thread_data->store;
96 
97  DEBUG_VALIDATE_BUG_ON(logger == NULL && store != NULL);
98  DEBUG_VALIDATE_BUG_ON(logger != NULL && store == NULL);
99  DEBUG_VALIDATE_BUG_ON(logger == NULL && store == NULL);
100 
101  while (logger && store) {
102  DEBUG_VALIDATE_BUG_ON(logger->LogFunc == NULL || logger->ConditionFunc == NULL);
103 
104  if (logger->ConditionFunc(tv, store->thread_data, (const Packet *)p)) {
106  logger->LogFunc(tv, store->thread_data, (const Packet *)p);
108  }
109 
110  logger = logger->next;
111  store = store->next;
112 
113  DEBUG_VALIDATE_BUG_ON(logger == NULL && store != NULL);
114  DEBUG_VALIDATE_BUG_ON(logger != NULL && store == NULL);
115  }
116 
117  return TM_ECODE_OK;
118 }
119 
120 /** \brief thread init for the packet logger
121  * This will run the thread init functions for the individual registered
122  * loggers */
123 static TmEcode OutputPacketLogThreadInit(ThreadVars *tv, const void *initdata, void **data)
124 {
125  OutputPacketLoggerThreadData *td = SCCalloc(1, sizeof(*td));
126  if (td == NULL)
127  return TM_ECODE_FAILED;
128 
129  *data = (void *)td;
130 
131  SCLogDebug("OutputPacketLogThreadInit happy (*data %p)", *data);
132 
133  OutputPacketLogger *logger = list;
134  while (logger) {
135  if (logger->ThreadInit) {
136  void *retptr = NULL;
137  if (logger->ThreadInit(tv, (void *)logger->initdata, &retptr) == TM_ECODE_OK) {
138  OutputLoggerThreadStore *ts = SCCalloc(1, sizeof(*ts));
139  /* todo */ BUG_ON(ts == NULL);
140 
141  /* store thread handle */
142  ts->thread_data = retptr;
143 
144  if (td->store == NULL) {
145  td->store = ts;
146  } else {
147  OutputLoggerThreadStore *tmp = td->store;
148  while (tmp->next != NULL)
149  tmp = tmp->next;
150  tmp->next = ts;
151  }
152 
153  SCLogDebug("%s is now set up", logger->name);
154  }
155  }
156 
157  logger = logger->next;
158  }
159 
160  return TM_ECODE_OK;
161 }
162 
163 static TmEcode OutputPacketLogThreadDeinit(ThreadVars *tv, void *thread_data)
164 {
165  OutputPacketLoggerThreadData *op_thread_data = (OutputPacketLoggerThreadData *)thread_data;
166  OutputLoggerThreadStore *store = op_thread_data->store;
167  OutputPacketLogger *logger = list;
168 
169  while (logger && store) {
170  if (logger->ThreadDeinit) {
171  logger->ThreadDeinit(tv, store->thread_data);
172  }
173 
174  OutputLoggerThreadStore *next_store = store->next;
175  SCFree(store);
176  store = next_store;
177 
178  logger = logger->next;
179  }
180 
181  SCFree(op_thread_data);
182  return TM_ECODE_OK;
183 }
184 
185 static uint32_t OutputPacketLoggerGetActiveCount(void)
186 {
187  uint32_t cnt = 0;
188  for (OutputPacketLogger *p = list; p != NULL; p = p->next) {
189  cnt++;
190  }
191  return cnt;
192 }
193 
195 {
196  OutputRegisterRootLogger(OutputPacketLogThreadInit, OutputPacketLogThreadDeinit,
197  OutputPacketLog, OutputPacketLoggerGetActiveCount);
198 }
199 
201 {
202  OutputPacketLogger *logger = list;
203  while (logger) {
204  OutputPacketLogger *next_logger = logger->next;
205  SCFree(logger);
206  logger = next_logger;
207  }
208 
209  /* reset list pointer */
210  list = NULL;
211 }
OutputPacketLoggerThreadData_
Definition: output-packet.c:34
OutputPacketLogger_::ThreadDeinit
ThreadDeinitFunc ThreadDeinit
Definition: output-packet.c:50
OutputPacketLogger_::next
struct OutputPacketLogger_ * next
Definition: output-packet.c:46
ts
uint64_t ts
Definition: source-erf-file.c:55
OutputLoggerThreadStore_
Definition: output.h:33
OutputRegisterRootLogger
void OutputRegisterRootLogger(ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, OutputLogFunc LogFunc, OutputGetActiveCountFunc ActiveCntFunc)
Definition: output.c:779
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
LoggerId
LoggerId
Definition: suricata-common.h:460
OutputLoggerThreadStore_::next
struct OutputLoggerThreadStore_ * next
Definition: output.h:35
output-packet.h
PacketLogger
int(* PacketLogger)(ThreadVars *, void *thread_data, const Packet *)
Packet logger function pointer type.
Definition: output-packet.h:35
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:81
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:80
OutputLoggerThreadStore_::thread_data
void * thread_data
Definition: output.h:34
OutputPacketLogger_::initdata
void * initdata
Definition: output-packet.c:45
OutputPacketShutdown
void OutputPacketShutdown(void)
Definition: output-packet.c:200
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
ThreadInitFunc
TmEcode(* ThreadInitFunc)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:39
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:300
OutputPacketLogger_::ConditionFunc
PacketLogCondition ConditionFunc
Definition: output-packet.c:43
util-profiling.h
Packet_
Definition: decode.h:475
OutputPacketLoggerRegister
void OutputPacketLoggerRegister(void)
Definition: output-packet.c:194
OutputPacketLogger_::name
const char * name
Definition: output-packet.c:47
OutputPacketLoggerThreadData_::store
OutputLoggerThreadStore * store
Definition: output-packet.c:35
TmEcode
TmEcode
Definition: tm-threads-common.h:79
SCOutputRegisterPacketLogger
int SCOutputRegisterPacketLogger(LoggerId logger_id, const char *name, PacketLogger LogFunc, PacketLogCondition ConditionFunc, void *initdata, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit)
Register a packet logger.
Definition: output-packet.c:55
PACKET_PROFILING_LOGGER_END
#define PACKET_PROFILING_LOGGER_END(p, id)
Definition: util-profiling.h:240
cnt
uint32_t cnt
Definition: tmqh-packetpool.h:7
suricata-common.h
OutputPacketLogger
struct OutputPacketLogger_ OutputPacketLogger
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
PacketLogCondition
bool(* PacketLogCondition)(ThreadVars *, void *thread_data, const Packet *)
Packet logger condition function point type.
Definition: output-packet.h:43
util-validate.h
Packet_::next
struct Packet_ * next
Definition: decode.h:603
SCFree
#define SCFree(p)
Definition: util-mem.h:61
PACKET_PROFILING_LOGGER_START
#define PACKET_PROFILING_LOGGER_START(p, id)
Definition: util-profiling.h:233
OutputPacketLogger_
Definition: output-packet.c:41
OutputPacketLoggerThreadData
struct OutputPacketLoggerThreadData_ OutputPacketLoggerThreadData
OutputPacketLogger_::ThreadInit
ThreadInitFunc ThreadInit
Definition: output-packet.c:49
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
OutputPacketLogger_::LogFunc
PacketLogger LogFunc
Definition: output-packet.c:42
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102
output.h
ThreadDeinitFunc
TmEcode(* ThreadDeinitFunc)(ThreadVars *, void *)
Definition: tm-modules.h:40
OutputPacketLogger_::logger_id
LoggerId logger_id
Definition: output-packet.c:48