suricata
output-flow.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  * 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. fast.log) with different output ctx'. */
41 typedef struct OutputFlowLogger_ {
43 
44  /** Data that will be passed to the ThreadInit callback. */
45  void *initdata;
46 
48 
49  /** A name for this logger, used for debugging only. */
50  const char *name;
51 
52  TmEcode (*ThreadInit)(ThreadVars *, const void *, void **);
55 
56 static OutputFlowLogger *list = NULL;
57 
60 {
61  OutputFlowLogger *op = SCCalloc(1, sizeof(*op));
62  if (op == NULL)
63  return -1;
64 
65  op->LogFunc = LogFunc;
66  op->initdata = initdata;
67  op->name = name;
68  op->ThreadInit = ThreadInit;
70 
71  if (list == NULL)
72  list = op;
73  else {
74  OutputFlowLogger *t = list;
75  while (t->next)
76  t = t->next;
77  t->next = op;
78  }
79 
80  SCLogDebug("OutputRegisterFlowLogger happy");
81  return 0;
82 }
83 
84 /** \brief Run flow logger(s)
85  * \note flow is already write locked
86  */
87 TmEcode OutputFlowLog(ThreadVars *tv, void *thread_data, Flow *f)
88 {
89  DEBUG_VALIDATE_BUG_ON(thread_data == NULL);
90 
91  if (list == NULL)
92  return TM_ECODE_OK;
93 
94  OutputFlowLoggerThreadData *op_thread_data = (OutputFlowLoggerThreadData *)thread_data;
95  OutputFlowLogger *logger = list;
96  OutputLoggerThreadStore *store = op_thread_data->store;
97 
98  DEBUG_VALIDATE_BUG_ON(store == NULL);
99 
100  while (logger && store) {
101  DEBUG_VALIDATE_BUG_ON(logger->LogFunc == NULL);
102 
103  SCLogDebug("logger %p", logger);
104  //PACKET_PROFILING_LOGGER_START(p, logger->module_id);
105  logger->LogFunc(tv, store->thread_data, f);
106  //PACKET_PROFILING_LOGGER_END(p, logger->module_id);
107 
108  logger = logger->next;
109  store = store->next;
110 
111  DEBUG_VALIDATE_BUG_ON(logger == NULL && store != NULL);
112  DEBUG_VALIDATE_BUG_ON(logger != NULL && store == NULL);
113  }
114 
115  return TM_ECODE_OK;
116 }
117 
118 /** \brief thread init for the flow logger
119  * This will run the thread init functions for the individual registered
120  * loggers */
122 {
123  OutputFlowLoggerThreadData *td = SCCalloc(1, sizeof(*td));
124  if (td == NULL)
125  return TM_ECODE_FAILED;
126 
127  *data = (void *)td;
128 
129  SCLogDebug("OutputFlowLogThreadInit happy (*data %p)", *data);
130 
131  OutputFlowLogger *logger = list;
132  while (logger) {
133  if (logger->ThreadInit) {
134  void *retptr = NULL;
135  if (logger->ThreadInit(tv, (void *)logger->initdata, &retptr) == TM_ECODE_OK) {
136  OutputLoggerThreadStore *ts = SCCalloc(1, sizeof(*ts));
137  /* todo */ BUG_ON(ts == NULL);
138 
139  /* store thread handle */
140  ts->thread_data = retptr;
141 
142  if (td->store == NULL) {
143  td->store = ts;
144  } else {
145  OutputLoggerThreadStore *tmp = td->store;
146  while (tmp->next != NULL)
147  tmp = tmp->next;
148  tmp->next = ts;
149  }
150 
151  SCLogDebug("%s is now set up", logger->name);
152  }
153  }
154 
155  logger = logger->next;
156  }
157 
158  return TM_ECODE_OK;
159 }
160 
162 {
163  OutputFlowLoggerThreadData *op_thread_data = (OutputFlowLoggerThreadData *)thread_data;
164  if (op_thread_data == NULL)
165  return TM_ECODE_OK;
166 
167  OutputLoggerThreadStore *store = op_thread_data->store;
168  OutputFlowLogger *logger = list;
169 
170  while (logger && store) {
171  if (logger->ThreadDeinit) {
172  logger->ThreadDeinit(tv, store->thread_data);
173  }
174 
175  OutputLoggerThreadStore *next_store = store->next;
176  SCFree(store);
177  store = next_store;
178  logger = logger->next;
179  }
180 
181  SCFree(op_thread_data);
182  return TM_ECODE_OK;
183 }
184 
186 {
187  OutputFlowLogger *logger = list;
188  while (logger) {
189  OutputFlowLogger *next_logger = logger->next;
190  SCFree(logger);
191  logger = next_logger;
192  }
193  list = NULL;
194 }
OutputFlowLog
TmEcode OutputFlowLog(ThreadVars *tv, void *thread_data, Flow *f)
Run flow logger(s)
Definition: output-flow.c:87
ts
uint64_t ts
Definition: source-erf-file.c:55
OutputFlowLogThreadInit
TmEcode OutputFlowLogThreadInit(ThreadVars *tv, void **data)
thread init for the flow logger This will run the thread init functions for the individual registered...
Definition: output-flow.c:121
OutputLoggerThreadStore_
Definition: output.h:33
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
OutputFlowLogger_
Definition: output-flow.c:41
OutputFlowLogger_::initdata
void * initdata
Definition: output-flow.c:45
name
const char * name
Definition: detect-engine-proto.c:48
Flow_
Flow data structure.
Definition: flow.h:354
OutputLoggerThreadStore_::next
struct OutputLoggerThreadStore_ * next
Definition: output.h:35
FlowLogger
int(* FlowLogger)(ThreadVars *, void *thread_data, Flow *f)
Flow logger function pointer type.
Definition: output-flow.h:36
OutputFlowLoggerThreadData
struct OutputFlowLoggerThreadData_ OutputFlowLoggerThreadData
SCOutputRegisterFlowLogger
int SCOutputRegisterFlowLogger(const char *name, FlowLogger LogFunc, void *initdata, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit)
Register a flow logger.
Definition: output-flow.c:58
OutputFlowLogger_::next
struct OutputFlowLogger_ * next
Definition: output-flow.c:47
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:82
OutputFlowLogger
struct OutputFlowLogger_ OutputFlowLogger
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:81
OutputLoggerThreadStore_::thread_data
void * thread_data
Definition: output.h:34
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
ThreadInitFunc
TmEcode(* ThreadInitFunc)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:43
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:325
util-profiling.h
OutputFlowLogger_::ThreadInit
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition: output-flow.c:52
TmEcode
TmEcode
Definition: tm-threads-common.h:80
output-flow.h
OutputFlowLoggerThreadData_::store
OutputLoggerThreadStore * store
Definition: output-flow.c:35
OutputFlowLogger_::name
const char * name
Definition: output-flow.c:50
OutputFlowLogger_::LogFunc
FlowLogger LogFunc
Definition: output-flow.c:42
suricata-common.h
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:33
util-validate.h
OutputFlowLogThreadDeinit
TmEcode OutputFlowLogThreadDeinit(ThreadVars *tv, void *thread_data)
Definition: output-flow.c:161
OutputFlowLoggerThreadData_
Definition: output-flow.c:34
SCFree
#define SCFree(p)
Definition: util-mem.h:61
OutputFlowShutdown
void OutputFlowShutdown(void)
Definition: output-flow.c:185
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:109
output.h
OutputFlowLogger_::ThreadDeinit
TmEcode(* ThreadDeinit)(ThreadVars *, void *)
Definition: output-flow.c:53
ThreadDeinitFunc
TmEcode(* ThreadDeinitFunc)(ThreadVars *, void *)
Definition: tm-modules.h:44