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