suricata
output-packet.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-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  * \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 "tm-modules.h"
28 #include "output.h"
29 #include "output-packet.h"
30 #include "util-profiling.h"
31 #include "util-validate.h"
32 
33 /** per thread data for this module, contains a list of per thread
34  * data for the packet loggers. */
38 
39 /* logger instance, a module + a output ctx,
40  * it's perfectly valid that have multiple instances of the same
41  * log module (e.g. fast.log) with different output ctx'. */
42 typedef struct OutputPacketLogger_ {
47  const char *name;
53 
54 static OutputPacketLogger *list = NULL;
55 
61 {
62  OutputPacketLogger *op = SCMalloc(sizeof(*op));
63  if (op == NULL)
64  return -1;
65  memset(op, 0x00, sizeof(*op));
66 
67  op->LogFunc = LogFunc;
69  op->output_ctx = output_ctx;
70  op->name = name;
71  op->ThreadInit = ThreadInit;
74  op->logger_id = logger_id;
75 
76  if (list == NULL)
77  list = op;
78  else {
79  OutputPacketLogger *t = list;
80  while (t->next)
81  t = t->next;
82  t->next = op;
83  }
84 
85  SCLogDebug("OutputRegisterPacketLogger happy");
86  return 0;
87 }
88 
89 static TmEcode OutputPacketLog(ThreadVars *tv, Packet *p, void *thread_data)
90 {
91  DEBUG_VALIDATE_BUG_ON(thread_data == NULL);
92 
93  if (list == NULL) {
94  /* No child loggers. */
95  return TM_ECODE_OK;
96  }
97 
98  OutputPacketLoggerThreadData *op_thread_data = (OutputPacketLoggerThreadData *)thread_data;
99  OutputPacketLogger *logger = list;
100  OutputLoggerThreadStore *store = op_thread_data->store;
101 
102  DEBUG_VALIDATE_BUG_ON(logger == NULL && store != NULL);
103  DEBUG_VALIDATE_BUG_ON(logger != NULL && store == NULL);
104  DEBUG_VALIDATE_BUG_ON(logger == NULL && store == NULL);
105 
106  while (logger && store) {
107  DEBUG_VALIDATE_BUG_ON(logger->LogFunc == NULL || logger->ConditionFunc == NULL);
108 
109  if ((logger->ConditionFunc(tv, store->thread_data, (const Packet *)p)) == TRUE) {
111  logger->LogFunc(tv, store->thread_data, (const Packet *)p);
113  }
114 
115  logger = logger->next;
116  store = store->next;
117 
118  DEBUG_VALIDATE_BUG_ON(logger == NULL && store != NULL);
119  DEBUG_VALIDATE_BUG_ON(logger != NULL && store == NULL);
120  }
121 
122  return TM_ECODE_OK;
123 }
124 
125 /** \brief thread init for the packet logger
126  * This will run the thread init functions for the individual registered
127  * loggers */
128 static TmEcode OutputPacketLogThreadInit(ThreadVars *tv, const void *initdata, void **data)
129 {
130  OutputPacketLoggerThreadData *td = SCMalloc(sizeof(*td));
131  if (td == NULL)
132  return TM_ECODE_FAILED;
133  memset(td, 0x00, sizeof(*td));
134 
135  *data = (void *)td;
136 
137  SCLogDebug("OutputPacketLogThreadInit happy (*data %p)", *data);
138 
139  OutputPacketLogger *logger = list;
140  while (logger) {
141  if (logger->ThreadInit) {
142  void *retptr = NULL;
143  if (logger->ThreadInit(tv, (void *)logger->output_ctx, &retptr) == TM_ECODE_OK) {
144  OutputLoggerThreadStore *ts = SCMalloc(sizeof(*ts));
145 /* todo */ BUG_ON(ts == NULL);
146  memset(ts, 0x00, sizeof(*ts));
147 
148  /* store thread handle */
149  ts->thread_data = retptr;
150 
151  if (td->store == NULL) {
152  td->store = ts;
153  } else {
154  OutputLoggerThreadStore *tmp = td->store;
155  while (tmp->next != NULL)
156  tmp = tmp->next;
157  tmp->next = ts;
158  }
159 
160  SCLogDebug("%s is now set up", logger->name);
161  }
162  }
163 
164  logger = logger->next;
165  }
166 
167  return TM_ECODE_OK;
168 }
169 
170 static TmEcode OutputPacketLogThreadDeinit(ThreadVars *tv, void *thread_data)
171 {
172  OutputPacketLoggerThreadData *op_thread_data = (OutputPacketLoggerThreadData *)thread_data;
173  OutputLoggerThreadStore *store = op_thread_data->store;
174  OutputPacketLogger *logger = list;
175 
176  while (logger && store) {
177  if (logger->ThreadDeinit) {
178  logger->ThreadDeinit(tv, store->thread_data);
179  }
180 
181  OutputLoggerThreadStore *next_store = store->next;
182  SCFree(store);
183  store = next_store;
184 
185  logger = logger->next;
186  }
187 
188  SCFree(op_thread_data);
189  return TM_ECODE_OK;
190 }
191 
192 static void OutputPacketLogExitPrintStats(ThreadVars *tv, void *thread_data)
193 {
194  OutputPacketLoggerThreadData *op_thread_data = (OutputPacketLoggerThreadData *)thread_data;
195  OutputLoggerThreadStore *store = op_thread_data->store;
196  OutputPacketLogger *logger = list;
197 
198  while (logger && store) {
199  if (logger->ThreadExitPrintStats) {
200  logger->ThreadExitPrintStats(tv, store->thread_data);
201  }
202 
203  logger = logger->next;
204  store = store->next;
205  }
206 }
207 
208 static uint32_t OutputPacketLoggerGetActiveCount(void)
209 {
210  uint32_t cnt = 0;
211  for (OutputPacketLogger *p = list; p != NULL; p = p->next) {
212  cnt++;
213  }
214  return cnt;
215 }
216 
218 {
219  OutputRegisterRootLogger(OutputPacketLogThreadInit,
220  OutputPacketLogThreadDeinit, OutputPacketLogExitPrintStats,
221  OutputPacketLog, OutputPacketLoggerGetActiveCount);
222 }
223 
225 {
226  OutputPacketLogger *logger = list;
227  while (logger) {
228  OutputPacketLogger *next_logger = logger->next;
229  SCFree(logger);
230  logger = next_logger;
231  }
232 
233  /* reset list pointer */
234  list = NULL;
235 }
OutputPacketLoggerThreadData_
Definition: output-packet.c:35
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-stats.c:31
OutputLoggerThreadStore_::next
struct OutputLoggerThreadStore_ * next
Definition: output-stats.c:33
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:296
LoggerId
LoggerId
Definition: suricata-common.h:437
tm-modules.h
output-packet.h
PacketLogger
int(* PacketLogger)(ThreadVars *, void *thread_data, const Packet *)
Definition: output-packet.h:33
OutputPacketLogger_::output_ctx
OutputCtx * output_ctx
Definition: output-packet.c:45
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:83
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:82
OutputLoggerThreadStore_::thread_data
void * thread_data
Definition: output-stats.c:32
OutputCtx_
Definition: tm-modules.h:78
OutputPacketLogger_::ThreadExitPrintStats
ThreadExitPrintStatsFunc ThreadExitPrintStats
Definition: output-packet.c:51
OutputPacketShutdown
void OutputPacketShutdown(void)
Definition: output-packet.c:224
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:56
ThreadInitFunc
TmEcode(* ThreadInitFunc)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:39
TRUE
#define TRUE
Definition: suricata-common.h:33
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:281
OutputPacketLogger_::ConditionFunc
PacketLogCondition ConditionFunc
Definition: output-packet.c:44
util-profiling.h
Packet_
Definition: decode.h:433
OutputPacketLoggerRegister
void OutputPacketLoggerRegister(void)
Definition: output-packet.c:217
OutputPacketLogger_::name
const char * name
Definition: output-packet.c:47
OutputPacketLoggerThreadData_::store
OutputLoggerThreadStore * store
Definition: output-packet.c:36
TmEcode
TmEcode
Definition: tm-threads-common.h:81
PACKET_PROFILING_LOGGER_END
#define PACKET_PROFILING_LOGGER_END(p, id)
Definition: util-profiling.h:258
suricata-common.h
OutputPacketLogger
struct OutputPacketLogger_ OutputPacketLogger
ThreadExitPrintStatsFunc
void(* ThreadExitPrintStatsFunc)(ThreadVars *, void *)
Definition: tm-modules.h:41
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:31
util-validate.h
PacketLogCondition
int(* PacketLogCondition)(ThreadVars *, void *thread_data, const Packet *)
Definition: output-packet.h:38
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
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:251
OutputRegisterRootLogger
void OutputRegisterRootLogger(ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, ThreadExitPrintStatsFunc ThreadExitPrintStats, OutputLogFunc LogFunc, OutputGetActiveCountFunc ActiveCntFunc)
Definition: output.c:965
OutputPacketLogger_
Definition: output-packet.c:42
OutputPacketLoggerThreadData
struct OutputPacketLoggerThreadData_ OutputPacketLoggerThreadData
OutputPacketLogger_::ThreadInit
ThreadInitFunc ThreadInit
Definition: output-packet.c:49
OutputPacketLogger_::LogFunc
PacketLogger LogFunc
Definition: output-packet.c:43
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:111
output.h
ThreadDeinitFunc
TmEcode(* ThreadDeinitFunc)(ThreadVars *, void *)
Definition: tm-modules.h:40
OutputPacketLogger_::logger_id
LoggerId logger_id
Definition: output-packet.c:48
OutputRegisterPacketLogger
int OutputRegisterPacketLogger(LoggerId logger_id, const char *name, PacketLogger LogFunc, PacketLogCondition ConditionFunc, OutputCtx *output_ctx, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, ThreadExitPrintStatsFunc ThreadExitPrintStats)
Definition: output-packet.c:56