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