suricata
output-flow.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  * Flow Logger Output registration functions
24  */
25 
26 #include "suricata-common.h"
27 #include "output.h"
28 #include "output-flow.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. http.log) with different output ctx'. */
41 typedef struct OutputFlowLogger_ {
45  const char *name;
46  TmEcode (*ThreadInit)(ThreadVars *, const void *, void **);
48  void (*ThreadExitPrintStats)(ThreadVars *, void *);
50 
51 static OutputFlowLogger *list = NULL;
52 
57 {
58  OutputFlowLogger *op = SCMalloc(sizeof(*op));
59  if (op == NULL)
60  return -1;
61  memset(op, 0x00, sizeof(*op));
62 
63  op->LogFunc = LogFunc;
64  op->output_ctx = output_ctx;
65  op->name = name;
66  op->ThreadInit = ThreadInit;
69 
70  if (list == NULL)
71  list = op;
72  else {
73  OutputFlowLogger *t = list;
74  while (t->next)
75  t = t->next;
76  t->next = op;
77  }
78 
79  SCLogDebug("OutputRegisterFlowLogger happy");
80  return 0;
81 }
82 
83 /** \brief Run flow logger(s)
84  * \note flow is already write locked
85  */
86 TmEcode OutputFlowLog(ThreadVars *tv, void *thread_data, Flow *f)
87 {
88  DEBUG_VALIDATE_BUG_ON(thread_data == NULL);
89 
90  if (list == NULL)
91  return TM_ECODE_OK;
92 
93  FlowSetEndFlags(f);
94 
95  OutputFlowLoggerThreadData *op_thread_data = (OutputFlowLoggerThreadData *)thread_data;
96  OutputFlowLogger *logger = list;
97  OutputLoggerThreadStore *store = op_thread_data->store;
98 
99  DEBUG_VALIDATE_BUG_ON(logger == NULL && store != NULL);
100  DEBUG_VALIDATE_BUG_ON(logger != NULL && store == NULL);
101  DEBUG_VALIDATE_BUG_ON(logger == NULL && store == NULL);
102 
103  while (logger && store) {
104  DEBUG_VALIDATE_BUG_ON(logger->LogFunc == NULL);
105 
106  SCLogDebug("logger %p", logger);
107  //PACKET_PROFILING_LOGGER_START(p, logger->module_id);
108  logger->LogFunc(tv, store->thread_data, f);
109  //PACKET_PROFILING_LOGGER_END(p, logger->module_id);
110 
111  logger = logger->next;
112  store = store->next;
113 
114  DEBUG_VALIDATE_BUG_ON(logger == NULL && store != NULL);
115  DEBUG_VALIDATE_BUG_ON(logger != NULL && store == NULL);
116  }
117 
118  return TM_ECODE_OK;
119 }
120 
121 /** \brief thread init for the flow logger
122  * This will run the thread init functions for the individual registered
123  * loggers */
124 TmEcode OutputFlowLogThreadInit(ThreadVars *tv, void *initdata, void **data)
125 {
126  OutputFlowLoggerThreadData *td = SCMalloc(sizeof(*td));
127  if (td == NULL)
128  return TM_ECODE_FAILED;
129  memset(td, 0x00, sizeof(*td));
130 
131  *data = (void *)td;
132 
133  SCLogDebug("OutputFlowLogThreadInit happy (*data %p)", *data);
134 
135  OutputFlowLogger *logger = list;
136  while (logger) {
137  if (logger->ThreadInit) {
138  void *retptr = NULL;
139  if (logger->ThreadInit(tv, (void *)logger->output_ctx, &retptr) == TM_ECODE_OK) {
140  OutputLoggerThreadStore *ts = SCMalloc(sizeof(*ts));
141 /* todo */ BUG_ON(ts == NULL);
142  memset(ts, 0x00, sizeof(*ts));
143 
144  /* store thread handle */
145  ts->thread_data = retptr;
146 
147  if (td->store == NULL) {
148  td->store = ts;
149  } else {
150  OutputLoggerThreadStore *tmp = td->store;
151  while (tmp->next != NULL)
152  tmp = tmp->next;
153  tmp->next = ts;
154  }
155 
156  SCLogDebug("%s is now set up", logger->name);
157  }
158  }
159 
160  logger = logger->next;
161  }
162 
163  return TM_ECODE_OK;
164 }
165 
167 {
168  OutputFlowLoggerThreadData *op_thread_data = (OutputFlowLoggerThreadData *)thread_data;
169  if (op_thread_data == NULL)
170  return TM_ECODE_OK;
171 
172  OutputLoggerThreadStore *store = op_thread_data->store;
173  OutputFlowLogger *logger = list;
174 
175  while (logger && store) {
176  if (logger->ThreadDeinit) {
177  logger->ThreadDeinit(tv, store->thread_data);
178  }
179 
180  OutputLoggerThreadStore *next_store = store->next;
181  SCFree(store);
182  store = next_store;
183  logger = logger->next;
184  }
185 
186  SCFree(op_thread_data);
187  return TM_ECODE_OK;
188 }
189 
190 void OutputFlowLogExitPrintStats(ThreadVars *tv, void *thread_data)
191 {
192  OutputFlowLoggerThreadData *op_thread_data = (OutputFlowLoggerThreadData *)thread_data;
193  OutputLoggerThreadStore *store = op_thread_data->store;
194  OutputFlowLogger *logger = list;
195 
196  while (logger && store) {
197  if (logger->ThreadExitPrintStats) {
198  logger->ThreadExitPrintStats(tv, store->thread_data);
199  }
200 
201  logger = logger->next;
202  store = store->next;
203  }
204 }
205 
207 {
208  OutputFlowLogger *logger = list;
209  while (logger) {
210  OutputFlowLogger *next_logger = logger->next;
211  SCFree(logger);
212  logger = next_logger;
213  }
214  list = NULL;
215 }
OutputFlowLog
TmEcode OutputFlowLog(ThreadVars *tv, void *thread_data, Flow *f)
Run flow logger(s)
Definition: output-flow.c:86
ts
uint64_t ts
Definition: source-erf-file.c:55
OutputLoggerThreadStore_
Definition: output.h:33
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
OutputFlowLogger_
Definition: output-flow.c:41
Flow_
Flow data structure.
Definition: flow.h:347
OutputLoggerThreadStore_::next
struct OutputLoggerThreadStore_ * next
Definition: output.h:35
FlowLogger
int(* FlowLogger)(ThreadVars *, void *thread_data, Flow *f)
Definition: output-flow.h:32
OutputFlowLoggerThreadData
struct OutputFlowLoggerThreadData_ OutputFlowLoggerThreadData
OutputFlowLogger_::next
struct OutputFlowLogger_ * next
Definition: output-flow.c:44
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:85
OutputFlowLogger
struct OutputFlowLogger_ OutputFlowLogger
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:84
OutputFlowLogger_::ThreadExitPrintStats
void(* ThreadExitPrintStats)(ThreadVars *, void *)
Definition: output-flow.c:48
OutputCtx_
Definition: tm-modules.h:84
OutputRegisterFlowLogger
int OutputRegisterFlowLogger(const char *name, FlowLogger LogFunc, OutputCtx *output_ctx, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, ThreadExitPrintStatsFunc ThreadExitPrintStats)
Definition: output-flow.c:53
OutputLoggerThreadStore_::thread_data
void * thread_data
Definition: output.h:34
OutputFlowLogThreadInit
TmEcode OutputFlowLogThreadInit(ThreadVars *tv, void *initdata, void **data)
thread init for the flow logger This will run the thread init functions for the individual registered...
Definition: output-flow.c:124
OutputFlowLogger_::output_ctx
OutputCtx * output_ctx
Definition: output-flow.c:43
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
ThreadInitFunc
TmEcode(* ThreadInitFunc)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:39
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:295
util-profiling.h
OutputFlowLogger_::ThreadInit
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition: output-flow.c:46
TmEcode
TmEcode
Definition: tm-threads-common.h:83
output-flow.h
OutputFlowLoggerThreadData_::store
OutputLoggerThreadStore * store
Definition: output-flow.c:35
OutputFlowLogger_::name
const char * name
Definition: output-flow.c:45
OutputFlowLogger_::LogFunc
FlowLogger LogFunc
Definition: output-flow.c:42
suricata-common.h
ThreadExitPrintStatsFunc
void(* ThreadExitPrintStatsFunc)(ThreadVars *, void *)
Definition: tm-modules.h:41
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
util-validate.h
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
OutputFlowLogExitPrintStats
void OutputFlowLogExitPrintStats(ThreadVars *tv, void *thread_data)
Definition: output-flow.c:190
OutputFlowLogThreadDeinit
TmEcode OutputFlowLogThreadDeinit(ThreadVars *tv, void *thread_data)
Definition: output-flow.c:166
OutputFlowLoggerThreadData_
Definition: output-flow.c:34
SCFree
#define SCFree(p)
Definition: util-mem.h:61
OutputFlowShutdown
void OutputFlowShutdown(void)
Definition: output-flow.c:206
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:104
output.h
OutputFlowLogger_::ThreadDeinit
TmEcode(* ThreadDeinit)(ThreadVars *, void *)
Definition: output-flow.c:47
ThreadDeinitFunc
TmEcode(* ThreadDeinitFunc)(ThreadVars *, void *)
Definition: tm-modules.h:40