suricata
output-flow.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2013 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 "tm-modules.h"
28 #include "output-flow.h"
29 #include "util-profiling.h"
30 #include "util-validate.h"
31 
32 typedef struct OutputLoggerThreadStore_ {
33  void *thread_data;
36 
37 /** per thread data for this module, contains a list of per thread
38  * data for the packet loggers. */
39 typedef struct OutputLoggerThreadData_ {
42 
43 /* logger instance, a module + a output ctx,
44  * it's perfectly valid that have multiple instances of the same
45  * log module (e.g. http.log) with different output ctx'. */
46 typedef struct OutputFlowLogger_ {
50  const char *name;
51  TmEcode (*ThreadInit)(ThreadVars *, const void *, void **);
53  void (*ThreadExitPrintStats)(ThreadVars *, void *);
55 
56 static OutputFlowLogger *list = NULL;
57 
62 {
63  OutputFlowLogger *op = SCMalloc(sizeof(*op));
64  if (op == NULL)
65  return -1;
66  memset(op, 0x00, sizeof(*op));
67 
68  op->LogFunc = LogFunc;
69  op->output_ctx = output_ctx;
70  op->name = name;
71  op->ThreadInit = ThreadInit;
74 
75  if (list == NULL)
76  list = op;
77  else {
78  OutputFlowLogger *t = list;
79  while (t->next)
80  t = t->next;
81  t->next = op;
82  }
83 
84  SCLogDebug("OutputRegisterFlowLogger happy");
85  return 0;
86 }
87 
88 /** \brief Run flow logger(s)
89  * \note flow is already write locked
90  */
92 {
93  DEBUG_VALIDATE_BUG_ON(thread_data == NULL);
94 
95  if (list == NULL)
96  return TM_ECODE_OK;
97 
98  OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data;
99  OutputFlowLogger *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  logger = list;
107  store = op_thread_data->store;
108  while (logger && store) {
109  DEBUG_VALIDATE_BUG_ON(logger->LogFunc == NULL);
110 
111  SCLogDebug("logger %p", logger);
112  //PACKET_PROFILING_LOGGER_START(p, logger->module_id);
113  logger->LogFunc(tv, store->thread_data, f);
114  //PACKET_PROFILING_LOGGER_END(p, logger->module_id);
115 
116  logger = logger->next;
117  store = store->next;
118 
119  DEBUG_VALIDATE_BUG_ON(logger == NULL && store != NULL);
120  DEBUG_VALIDATE_BUG_ON(logger != NULL && store == NULL);
121  }
122 
123  return TM_ECODE_OK;
124 }
125 
126 /** \brief thread init for the flow logger
127  * This will run the thread init functions for the individual registered
128  * loggers */
129 TmEcode OutputFlowLogThreadInit(ThreadVars *tv, void *initdata, void **data)
130 {
131  OutputLoggerThreadData *td = SCMalloc(sizeof(*td));
132  if (td == NULL)
133  return TM_ECODE_FAILED;
134  memset(td, 0x00, sizeof(*td));
135 
136  *data = (void *)td;
137 
138  SCLogDebug("OutputFlowLogThreadInit happy (*data %p)", *data);
139 
140  OutputFlowLogger *logger = list;
141  while (logger) {
142  if (logger->ThreadInit) {
143  void *retptr = NULL;
144  if (logger->ThreadInit(tv, (void *)logger->output_ctx, &retptr) == TM_ECODE_OK) {
145  OutputLoggerThreadStore *ts = SCMalloc(sizeof(*ts));
146 /* todo */ BUG_ON(ts == NULL);
147  memset(ts, 0x00, sizeof(*ts));
148 
149  /* store thread handle */
150  ts->thread_data = retptr;
151 
152  if (td->store == NULL) {
153  td->store = ts;
154  } else {
155  OutputLoggerThreadStore *tmp = td->store;
156  while (tmp->next != NULL)
157  tmp = tmp->next;
158  tmp->next = ts;
159  }
160 
161  SCLogDebug("%s is now set up", logger->name);
162  }
163  }
164 
165  logger = logger->next;
166  }
167 
168  return TM_ECODE_OK;
169 }
170 
172 {
173  OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data;
174  OutputLoggerThreadStore *store = op_thread_data->store;
175  OutputFlowLogger *logger = list;
176 
177  while (logger && store) {
178  if (logger->ThreadDeinit) {
179  logger->ThreadDeinit(tv, store->thread_data);
180  }
181 
182  OutputLoggerThreadStore *next_store = store->next;
183  SCFree(store);
184  store = next_store;
185  logger = logger->next;
186  }
187 
188  SCFree(op_thread_data);
189  return TM_ECODE_OK;
190 }
191 
193 {
194  OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data;
195  OutputLoggerThreadStore *store = op_thread_data->store;
196  OutputFlowLogger *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 
209 {
210  OutputFlowLogger *logger = list;
211  while (logger) {
212  OutputFlowLogger *next_logger = logger->next;
213  SCFree(logger);
214  logger = next_logger;
215  }
216  list = NULL;
217 }
#define SCLogDebug(...)
Definition: util-debug.h:335
#define BUG_ON(x)
void(* ThreadExitPrintStatsFunc)(ThreadVars *, void *)
Definition: tm-modules.h:41
OutputLoggerThreadStore * store
Definition: output-file.c:44
struct OutputFlowLogger_ * next
Definition: output-flow.c:49
TmEcode(* ThreadDeinitFunc)(ThreadVars *, void *)
Definition: tm-modules.h:40
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition: output-flow.c:51
int(* FlowLogger)(ThreadVars *, void *thread_data, Flow *f)
Definition: output-flow.h:32
struct OutputLoggerThreadStore_ * next
Definition: output-file.c:38
FlowLogger LogFunc
Definition: output-flow.c:47
TmEcode OutputFlowLog(ThreadVars *tv, void *thread_data, Flow *f)
Run flow logger(s)
Definition: output-flow.c:91
OutputCtx * output_ctx
Definition: output-flow.c:48
TmEcode(* ThreadDeinit)(ThreadVars *, void *)
Definition: output-flow.c:52
struct OutputFlowLogger_ OutputFlowLogger
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:129
#define SCMalloc(a)
Definition: util-mem.h:166
#define SCFree(a)
Definition: util-mem.h:228
uint64_t ts
struct OutputLoggerThreadStore_ OutputLoggerThreadStore
TmEcode OutputFlowLogThreadDeinit(ThreadVars *tv, void *thread_data)
Definition: output-flow.c:171
void OutputFlowLogExitPrintStats(ThreadVars *tv, void *thread_data)
Definition: output-flow.c:192
int OutputRegisterFlowLogger(const char *name, FlowLogger LogFunc, OutputCtx *output_ctx, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, ThreadExitPrintStatsFunc ThreadExitPrintStats)
Definition: output-flow.c:58
void OutputFlowShutdown(void)
Definition: output-flow.c:208
Per thread variable structure.
Definition: threadvars.h:57
TmEcode(* ThreadInitFunc)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:39
void(* ThreadExitPrintStats)(ThreadVars *, void *)
Definition: output-flow.c:53
Flow data structure.
Definition: flow.h:325
const char * name
Definition: output-flow.c:50
struct OutputLoggerThreadData_ OutputLoggerThreadData
#define DEBUG_VALIDATE_BUG_ON(exp)