suricata
output-file.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2014 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  * AppLayer File Logger Output registration functions
24  */
25 
26 #include "suricata-common.h"
27 #include "tm-modules.h"
28 #include "output.h"
29 #include "output-file.h"
30 #include "app-layer.h"
31 #include "app-layer-parser.h"
32 #include "detect-filemagic.h"
33 #include "util-profiling.h"
34 #include "util-validate.h"
35 
36 typedef struct OutputLoggerThreadStore_ {
37  void *thread_data;
40 
41 /** per thread data for this module, contains a list of per thread
42  * data for the packet loggers. */
43 typedef struct OutputLoggerThreadData_ {
46 
47 /* logger instance, a module + a output ctx,
48  * it's perfectly valid that have multiple instances of the same
49  * log module (e.g. http.log) with different output ctx'. */
50 typedef struct OutputFileLogger_ {
54  const char *name;
60 
61 static OutputFileLogger *list = NULL;
62 
67 {
68  OutputFileLogger *op = SCMalloc(sizeof(*op));
69  if (op == NULL)
70  return -1;
71  memset(op, 0x00, sizeof(*op));
72 
73  op->LogFunc = LogFunc;
74  op->output_ctx = output_ctx;
75  op->name = name;
76  op->logger_id = id;
77  op->ThreadInit = ThreadInit;
80 
81  if (list == NULL)
82  list = op;
83  else {
84  OutputFileLogger *t = list;
85  while (t->next)
86  t = t->next;
87  t->next = op;
88  }
89 
90  SCLogDebug("OutputRegisterFileLogger happy");
91  return 0;
92 }
93 
94 static void OutputFileLogFfc(ThreadVars *tv,
95  OutputLoggerThreadData *op_thread_data,
96  Packet *p,
97  FileContainer *ffc, const bool file_close, const bool file_trunc,
98  uint8_t dir)
99 {
100  SCLogDebug("ffc %p", ffc);
101  if (ffc != NULL) {
102  File *ff;
103  for (ff = ffc->head; ff != NULL; ff = ff->next) {
104  if (ff->flags & FILE_LOGGED)
105  continue;
106 
107  SCLogDebug("ff %p", ff);
108 
109  if (file_trunc && ff->state < FILE_STATE_CLOSED)
111 
112  if (file_close && ff->state < FILE_STATE_CLOSED)
114 
115  SCLogDebug("ff %p state %u", ff, ff->state);
116 
117  if (ff->state > FILE_STATE_OPENED) {
118  bool file_logged = false;
119 #ifdef HAVE_MAGIC
120  if (FileForceMagic() && ff->magic == NULL) {
121  FilemagicGlobalLookup(ff);
122  }
123 #endif
124  const OutputFileLogger *logger = list;
125  const OutputLoggerThreadStore *store = op_thread_data->store;
126  while (logger && store) {
127  DEBUG_VALIDATE_BUG_ON(logger->LogFunc == NULL);
128 
129  SCLogDebug("logger %p", logger);
131  logger->LogFunc(tv, store->thread_data, (const Packet *)p, (const File *)ff, dir);
133  file_logged = true;
134 
135  logger = logger->next;
136  store = store->next;
137 
138  DEBUG_VALIDATE_BUG_ON(logger == NULL && store != NULL);
139  DEBUG_VALIDATE_BUG_ON(logger != NULL && store == NULL);
140  }
141 
142  if (file_logged) {
143  ff->flags |= FILE_LOGGED;
144  }
145  }
146  }
147  }
148 }
149 
150 static TmEcode OutputFileLog(ThreadVars *tv, Packet *p, void *thread_data)
151 {
152  DEBUG_VALIDATE_BUG_ON(thread_data == NULL);
153 
154  if (list == NULL) {
155  /* No child loggers. */
156  return TM_ECODE_OK;
157  }
158 
159  OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data;
160 
161  /* no flow, no files */
162  Flow * const f = p->flow;
163  if (f == NULL || f->alstate == NULL) {
165  }
166 
167  const bool file_close_ts = ((p->flags & PKT_PSEUDO_STREAM_END) &&
169  const bool file_close_tc = ((p->flags & PKT_PSEUDO_STREAM_END) &&
171  const bool file_trunc = StreamTcpReassembleDepthReached(p);
172 
175 
176  OutputFileLogFfc(tv, op_thread_data, p, ffc_ts, file_close_ts, file_trunc, STREAM_TOSERVER);
177  OutputFileLogFfc(tv, op_thread_data, p, ffc_tc, file_close_tc, file_trunc, STREAM_TOCLIENT);
178 
179  return TM_ECODE_OK;
180 }
181 
182 /** \brief thread init for the tx logger
183  * This will run the thread init functions for the individual registered
184  * loggers */
185 static TmEcode OutputFileLogThreadInit(ThreadVars *tv, const void *initdata, void **data)
186 {
187  OutputLoggerThreadData *td = SCMalloc(sizeof(*td));
188  if (td == NULL)
189  return TM_ECODE_FAILED;
190  memset(td, 0x00, sizeof(*td));
191 
192  *data = (void *)td;
193 
194  SCLogDebug("OutputFileLogThreadInit happy (*data %p)", *data);
195 
196  OutputFileLogger *logger = list;
197  while (logger) {
198  if (logger->ThreadInit) {
199  void *retptr = NULL;
200  if (logger->ThreadInit(tv, (void *)logger->output_ctx, &retptr) == TM_ECODE_OK) {
201  OutputLoggerThreadStore *ts = SCMalloc(sizeof(*ts));
202 /* todo */ BUG_ON(ts == NULL);
203  memset(ts, 0x00, sizeof(*ts));
204 
205  /* store thread handle */
206  ts->thread_data = retptr;
207 
208  if (td->store == NULL) {
209  td->store = ts;
210  } else {
211  OutputLoggerThreadStore *tmp = td->store;
212  while (tmp->next != NULL)
213  tmp = tmp->next;
214  tmp->next = ts;
215  }
216 
217  SCLogDebug("%s is now set up", logger->name);
218  }
219  }
220 
221  logger = logger->next;
222  }
223 
224  return TM_ECODE_OK;
225 }
226 
227 static TmEcode OutputFileLogThreadDeinit(ThreadVars *tv, void *thread_data)
228 {
229  OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data;
230  OutputLoggerThreadStore *store = op_thread_data->store;
231  OutputFileLogger *logger = list;
232 
233  while (logger && store) {
234  if (logger->ThreadDeinit) {
235  logger->ThreadDeinit(tv, store->thread_data);
236  }
237 
238  OutputLoggerThreadStore *next_store = store->next;
239  SCFree(store);
240  store = next_store;
241  logger = logger->next;
242  }
243 
244  SCFree(op_thread_data);
245  return TM_ECODE_OK;
246 }
247 
248 static void OutputFileLogExitPrintStats(ThreadVars *tv, void *thread_data)
249 {
250  OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data;
251  OutputLoggerThreadStore *store = op_thread_data->store;
252  OutputFileLogger *logger = list;
253 
254  while (logger && store) {
255  if (logger->ThreadExitPrintStats) {
256  logger->ThreadExitPrintStats(tv, store->thread_data);
257  }
258 
259  logger = logger->next;
260  store = store->next;
261  }
262 }
263 
264 static uint32_t OutputFileLoggerGetActiveCount(void)
265 {
266  uint32_t cnt = 0;
267  for (OutputFileLogger *p = list; p != NULL; p = p->next) {
268  cnt++;
269  }
270  return cnt;
271 }
272 
274 {
275  OutputRegisterRootLogger(OutputFileLogThreadInit,
276  OutputFileLogThreadDeinit, OutputFileLogExitPrintStats,
277  OutputFileLog, OutputFileLoggerGetActiveCount);
278 }
279 
281 {
282  OutputFileLogger *logger = list;
283  while (logger) {
284  OutputFileLogger *next_logger = logger->next;
285  SCFree(logger);
286  logger = next_logger;
287  }
288 
289  list = NULL;
290 }
FileContainer_
Definition: util-file.h:100
ts
uint64_t ts
Definition: source-erf-file.c:2
OutputLoggerThreadStore_
Definition: output-file.c:36
OutputLoggerThreadStore_::next
struct OutputLoggerThreadStore_ * next
Definition: output-file.c:38
SCFree
#define SCFree(a)
Definition: util-mem.h:322
OutputFileLogger_::logger_id
LoggerId logger_id
Definition: output-file.c:55
StreamTcpReassembleDepthReached
int StreamTcpReassembleDepthReached(Packet *p)
check if stream in pkt direction has depth reached
Definition: stream-tcp-reassemble.c:486
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:335
OutputFileLoggerRegister
void OutputFileLoggerRegister(void)
Definition: output-file.c:273
OutputRegisterFileLogger
int OutputRegisterFileLogger(LoggerId id, const char *name, FileLogger LogFunc, OutputCtx *output_ctx, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, ThreadExitPrintStatsFunc ThreadExitPrintStats)
Definition: output-file.c:63
OutputFileLogger
struct OutputFileLogger_ OutputFileLogger
Packet_::flags
uint32_t flags
Definition: decode.h:444
FILE_STATE_OPENED
@ FILE_STATE_OPENED
Definition: util-file.h:54
Flow_
Flow data structure.
Definition: flow.h:342
File_::state
FileState state
Definition: util-file.h:66
LoggerId
LoggerId
Definition: suricata-common.h:416
OutputFileLogger_::next
struct OutputFileLogger_ * next
Definition: output-file.c:53
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:218
tm-modules.h
AppLayerParserGetFiles
FileContainer * AppLayerParserGetFiles(const Flow *f, const uint8_t direction)
Definition: app-layer-parser.c:874
FILE_STATE_TRUNCATED
@ FILE_STATE_TRUNCATED
Definition: util-file.h:57
OutputLoggerThreadData
struct OutputLoggerThreadData_ OutputLoggerThreadData
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:440
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:79
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:78
OutputLoggerThreadStore_::thread_data
void * thread_data
Definition: output-file.c:37
OutputCtx_
Definition: tm-modules.h:78
OutputLoggerThreadData_
Definition: output-file.c:43
FileForceMagic
int FileForceMagic(void)
Definition: util-file.c:143
OutputFileLogger_::LogFunc
FileLogger LogFunc
Definition: output-file.c:51
output-file.h
PKT_PSEUDO_STREAM_END
#define PKT_PSEUDO_STREAM_END
Definition: decode.h:1078
STREAM_TOSERVER
#define STREAM_TOSERVER
Definition: stream.h:31
detect-filemagic.h
FileContainer_::head
File * head
Definition: util-file.h:101
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
ThreadInitFunc
TmEcode(* ThreadInitFunc)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:39
OutputFileLogger_::ThreadExitPrintStats
ThreadExitPrintStatsFunc ThreadExitPrintStats
Definition: output-file.c:58
app-layer-parser.h
SCMalloc
#define SCMalloc(a)
Definition: util-mem.h:222
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:265
util-profiling.h
OutputFileLogger_
Definition: output-file.c:50
Packet_
Definition: decode.h:408
OutputLoggerThreadStore
struct OutputLoggerThreadStore_ OutputLoggerThreadStore
OutputLoggerThreadData_::store
OutputLoggerThreadStore * store
Definition: output-file.c:44
OutputFileShutdown
void OutputFileShutdown(void)
Definition: output-file.c:280
TmEcode
TmEcode
Definition: tm-threads-common.h:77
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:219
File_::flags
uint16_t flags
Definition: util-file.h:64
PACKET_PROFILING_LOGGER_END
#define PACKET_PROFILING_LOGGER_END(p, id)
Definition: util-profiling.h:260
FILE_STATE_CLOSED
@ FILE_STATE_CLOSED
Definition: util-file.h:55
File_
Definition: util-file.h:63
Packet_::flow
struct Flow_ * flow
Definition: decode.h:446
suricata-common.h
ThreadExitPrintStatsFunc
void(* ThreadExitPrintStatsFunc)(ThreadVars *, void *)
Definition: tm-modules.h:41
File_::next
struct File_ * next
Definition: util-file.h:77
STREAM_TOCLIENT
#define STREAM_TOCLIENT
Definition: stream.h:32
OutputFileLogger_::ThreadDeinit
ThreadDeinitFunc ThreadDeinit
Definition: output-file.c:57
FileLogger
int(* FileLogger)(ThreadVars *, void *thread_data, const Packet *, const File *, uint8_t direction)
Definition: output-file.h:33
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
util-validate.h
Packet_::next
struct Packet_ * next
Definition: decode.h:571
FILE_LOGGED
#define FILE_LOGGED
Definition: util-file.h:44
Flow_::alstate
void * alstate
Definition: flow.h:454
OutputFileLogger_::output_ctx
OutputCtx * output_ctx
Definition: output-file.c:52
PACKET_PROFILING_LOGGER_START
#define PACKET_PROFILING_LOGGER_START(p, id)
Definition: util-profiling.h:253
OutputRegisterRootLogger
void OutputRegisterRootLogger(ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, ThreadExitPrintStatsFunc ThreadExitPrintStats, OutputLogFunc LogFunc, OutputGetActiveCountFunc ActiveCntFunc)
Definition: output.c:1012
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:341
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:111
OutputFileLogger_::name
const char * name
Definition: output-file.c:54
OutputFileLogger_::ThreadInit
ThreadInitFunc ThreadInit
Definition: output-file.c:56
output.h
ThreadDeinitFunc
TmEcode(* ThreadDeinitFunc)(ThreadVars *, void *)
Definition: tm-modules.h:40
app-layer.h