suricata
output-filestore.c
Go to the documentation of this file.
1 /* Copyright (C) 2018-2025 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 #include "suricata-common.h"
19 #include "output-filestore.h"
20 
21 #include "stream-tcp.h"
22 
23 #include "feature.h"
24 
25 #include "output.h"
26 #include "output-json-file.h"
27 
28 #include "util-conf.h"
29 #include "util-misc.h"
30 #include "util-path.h"
31 #include "util-print.h"
32 
33 #ifdef OS_WIN32
34 #include "win32-misc.h"
35 #endif /* OS_WIN32 */
36 
37 #define MODULE_NAME "OutputFilestore"
38 
39 /* Create a filestore specific PATH_MAX that is less than the system
40  * PATH_MAX to prevent newer gcc truncation warnings with snprint. */
41 #define SHA256_STRING_LEN (SC_SHA256_LEN * 2)
42 #define LEAF_DIR_MAX_LEN 4
43 #define FILESTORE_PREFIX_MAX (PATH_MAX - SHA256_STRING_LEN - LEAF_DIR_MAX_LEN)
44 
45 /* The default log directory, relative to the default log
46  * directory. */
47 static const char *default_log_dir = "filestore";
48 
49 /* Atomic counter of simultaneously open files. */
50 static SC_ATOMIC_DECLARE(uint32_t, filestore_open_file_cnt);
51 
52 typedef struct OutputFilestoreCtx_ {
55  bool fileinfo;
58 
59 typedef struct OutputFilestoreLogThread_ {
64 
71 
73 };
74 
75 /* For WARN_ONCE, a record of warnings that have already been
76  * issued. */
77 static thread_local bool once_errs[WOT_MAX];
78 
79 #define WARN_ONCE(wot_type, ...) \
80  do { \
81  if (!once_errs[wot_type]) { \
82  once_errs[wot_type] = true; \
83  SCLogWarning(__VA_ARGS__); \
84  } \
85  } while (0)
86 
87 static uint64_t OutputFilestoreOpenFilesCounter(void)
88 {
89  return SC_ATOMIC_GET(filestore_open_file_cnt);
90 }
91 
92 static uint32_t g_file_store_max_open_files = 0;
93 
94 static void FileSetMaxOpenFiles(uint32_t count)
95 {
96  g_file_store_max_open_files = count;
97 }
98 
99 static uint32_t FileGetMaxOpenFiles(void)
100 {
101  return g_file_store_max_open_files;
102 }
103 
104 /**
105  * \brief Update the timestamps on a file to match those of another
106  * file.
107  *
108  * \param src_filename Filename to use as timestamp source.
109  * \param filename Filename to apply timestamps to.
110  */
111 static void OutputFilestoreUpdateFileTime(const char *src_filename, const char *filename)
112 {
113  struct stat sb;
114  if (stat(src_filename, &sb) != 0) {
115  SCLogDebug("Failed to stat %s: %s", filename, strerror(errno));
116  return;
117  }
118  struct utimbuf utimbuf = {
119  .actime = sb.st_atime,
120  .modtime = sb.st_mtime,
121  };
122  if (utime(filename, &utimbuf) != 0) {
123  SCLogDebug("Failed to update file timestamps: %s: %s", filename, strerror(errno));
124  }
125 }
126 
127 static void OutputFilestoreFinalizeFiles(ThreadVars *tv, const OutputFilestoreLogThread *oft,
128  const OutputFilestoreCtx *ctx, const Packet *p, File *ff, void *tx, const uint64_t tx_id,
129  uint8_t dir)
130 {
131  /* Stringify the SHA256 which will be used in the final
132  * filename. */
133  char sha256string[(SC_SHA256_LEN * 2) + 1];
134  PrintHexString(sha256string, sizeof(sha256string), ff->sha256, sizeof(ff->sha256));
135 
136  /* construct tmp file path */
137  char tmp_filename[PATH_MAX] = "";
138  char tmp_filepath[PATH_MAX] = "";
139  snprintf(tmp_filename, sizeof(tmp_filename), "file.%u", ff->file_store_id);
140  if (PathMerge(tmp_filepath, sizeof(tmp_filepath), ctx->tmpdir, tmp_filename) < 0)
141  return;
142 
143  /* construct final path */
144  char final_sha_short[3];
145  snprintf(final_sha_short, sizeof(final_sha_short), "%c%c", sha256string[0], sha256string[1]);
146  char final_sha_portion[PATH_MAX];
147  if (PathMerge(final_sha_portion, sizeof(final_sha_portion), final_sha_short, sha256string) < 0)
148  return;
149  char final_filename[PATH_MAX] = "";
150  if (PathMerge(final_filename, sizeof(final_filename), ctx->prefix, final_sha_portion) < 0)
151  return;
152 
153  if (SCPathExists(final_filename)) {
154  OutputFilestoreUpdateFileTime(tmp_filepath, final_filename);
155  if (unlink(tmp_filepath) != 0) {
157  WARN_ONCE(WOT_UNLINK, "Failed to remove temporary file %s: %s", tmp_filepath,
158  strerror(errno));
159  }
160  } else if (rename(tmp_filepath, final_filename) != 0) {
162  WARN_ONCE(WOT_RENAME, "Failed to rename %s to %s: %s", tmp_filepath, final_filename,
163  strerror(errno));
164  if (unlink(tmp_filepath) != 0) {
165  /* Just increment, don't log as has_fs_errors would
166  * already be set above. */
168  }
169  return;
170  }
171 
172  if (ctx->fileinfo) {
173  char js_metadata_filename_suffix[PATH_MAX];
174  if (snprintf(js_metadata_filename_suffix, sizeof(js_metadata_filename_suffix),
175  ".%" PRIuMAX ".%u.json", (uintmax_t)SCTIME_SECS(p->ts),
176  ff->file_store_id) == (int)sizeof(js_metadata_filename_suffix)) {
177  WARN_ONCE(WOT_SNPRINTF, "Failed to write file info record. Output filename truncated.");
178  return;
179  }
180  char js_metadata_filename[PATH_MAX];
181  strlcpy(js_metadata_filename, final_filename, sizeof(js_metadata_filename));
182  strlcat(js_metadata_filename, js_metadata_filename_suffix, sizeof(js_metadata_filename));
183 
184  SCJsonBuilder *js_fileinfo =
185  JsonBuildFileInfoRecord(p, ff, tx, tx_id, true, dir, ctx->xff_cfg, NULL);
186  if (likely(js_fileinfo != NULL)) {
187  SCJbClose(js_fileinfo);
188  FILE *out = fopen(js_metadata_filename, "w");
189  if (out != NULL) {
190  size_t js_len = SCJbLen(js_fileinfo);
191  fwrite(SCJbPtr(js_fileinfo), js_len, 1, out);
192  fclose(out);
193  }
194  SCJbFree(js_fileinfo);
195  }
196  }
197 }
198 
199 /**
200  * \note `filestore_open_file_cnt` should only be used when FileGetMaxOpenFiles() is non-zero
201  */
202 static int OutputFilestoreLogger(ThreadVars *tv, void *thread_data, const Packet *p, File *ff,
203  void *tx, const uint64_t tx_id, const uint8_t *data, uint32_t data_len, uint8_t flags,
204  uint8_t dir)
205 {
206  SCEnter();
208  OutputFilestoreCtx *ctx = aft->ctx;
209  char filename[PATH_MAX] = "";
210  int file_fd = -1;
211  bool close_file = false;
212 
213  SCLogDebug("ff %p, data %p, data_len %u", ff, data, data_len);
214 
216  /* construct tmp file path */
217  char tmp_filename[PATH_MAX] = "";
218  snprintf(tmp_filename, sizeof(tmp_filename), "file.%u", ff->file_store_id);
219  if (PathMerge(filename, sizeof(filename), ctx->tmpdir, tmp_filename) < 0)
220  return -1;
221 
222  file_fd = open(filename, O_CREAT | O_TRUNC | O_NOFOLLOW | O_WRONLY, 0644);
223  if (file_fd == -1) {
225  SCLogWarning("Filestore (v2) failed to create %s: %s", filename, strerror(errno));
226  return -1;
227  }
228 
229  /* SC_ATOMIC_ADD returns value before the addition. */
230  if (FileGetMaxOpenFiles() > 0 &&
231  SC_ATOMIC_ADD(filestore_open_file_cnt, 1) >= FileGetMaxOpenFiles()) {
232  (void)SC_ATOMIC_SUB(filestore_open_file_cnt, 1);
234  ff->fd = -1;
235  close_file = true; /* not storing it, so need to close */
236  } else if (FileGetMaxOpenFiles() == 0) {
237  close_file = true; /* max open files 0 means we immediately close */
238  } else {
239  ff->fd = file_fd;
240  }
241  /* we can get called with NULL data when we need to close */
242  } else if (data != NULL) {
243  file_fd = ff->fd;
244  if (file_fd == -1) {
245  /* construct tmp file path */
246  char tmp_filename[PATH_MAX] = "";
247  snprintf(tmp_filename, sizeof(tmp_filename), "file.%u", ff->file_store_id);
248  if (PathMerge(filename, sizeof(filename), ctx->tmpdir, tmp_filename) < 0)
249  return -1;
250  file_fd = open(filename, O_APPEND | O_NOFOLLOW | O_WRONLY);
251  if (file_fd == -1) {
253  WARN_ONCE(WOT_OPEN, "Filestore (v2) failed to open file %s: %s", filename,
254  strerror(errno));
255  return -1;
256  }
257  close_file = true; /* close temporary open */
258  }
259  } else if (flags & OUTPUT_FILEDATA_FLAG_CLOSE) {
260  file_fd = ff->fd;
261  }
262 
263  if (file_fd != -1 && data != NULL && data_len > 0) {
264  ssize_t r = write(file_fd, (const void *)data, (size_t)data_len);
265  if (r == -1 || (ssize_t)data_len != r) {
266  /* construct tmp file path */
267  char tmp_filename[PATH_MAX] = "";
268  snprintf(tmp_filename, sizeof(tmp_filename), "file.%u", ff->file_store_id);
269  (void)PathMerge(filename, sizeof(filename), ctx->tmpdir, tmp_filename);
271  WARN_ONCE(WOT_WRITE, "Filestore (v2) failed to write to %s: %s", filename,
272  strerror(errno));
273  close_file = true; /* close in the error case */
274  }
275  }
276 
277  /* close the open file if needed */
278  if (file_fd != -1 && ((flags & OUTPUT_FILEDATA_FLAG_CLOSE) != 0 || close_file)) {
279  /* if it was stored in the ff, disconnect */
280  if (ff->fd != -1) {
281  if (FileGetMaxOpenFiles()) {
282  SC_ATOMIC_SUB(filestore_open_file_cnt, 1);
283  }
284  ff->fd = -1;
285  }
286  close(file_fd);
287  }
288 
290  OutputFilestoreFinalizeFiles(tv, aft, ctx, p, ff, tx, tx_id, dir);
291  }
292 
293  return 0;
294 }
295 
296 static TmEcode OutputFilestoreLogThreadInit(ThreadVars *t, const void *initdata, void **data)
297 {
299  if (unlikely(aft == NULL))
300  return TM_ECODE_FAILED;
301 
302  if (initdata == NULL) {
303  SCLogDebug("Error getting context for LogFileStore. \"initdata\" argument NULL");
304  SCFree(aft);
305  return TM_ECODE_FAILED;
306  }
307 
308  OutputFilestoreCtx *ctx = ((OutputCtx *)initdata)->data;
309  aft->ctx = ctx;
310 
311  aft->counter_max_hits = StatsRegisterCounter("file_store.open_files_max_hit", &t->stats);
312 
313  /* File system type errors (open, write, rename) will only be
314  * logged once. But this stat will be incremented for every
315  * occurrence. */
316  aft->fs_error_counter = StatsRegisterCounter("file_store.fs_errors", &t->stats);
317 
318  *data = (void *)aft;
319  return TM_ECODE_OK;
320 }
321 
322 static TmEcode OutputFilestoreLogThreadDeinit(ThreadVars *t, void *data)
323 {
325  if (aft == NULL) {
326  return TM_ECODE_OK;
327  }
328 
329  /* clear memory */
330  memset(aft, 0, sizeof(OutputFilestoreLogThread));
331 
332  SCFree(aft);
333  return TM_ECODE_OK;
334 }
335 
336 static void OutputFilestoreLogDeInitCtx(OutputCtx *output_ctx)
337 {
338  OutputFilestoreCtx *ctx = (OutputFilestoreCtx *)output_ctx->data;
339  if (ctx->xff_cfg != NULL) {
340  SCFree(ctx->xff_cfg);
341  }
342  SCFree(ctx);
343  SCFree(output_ctx);
344 }
345 
346 static int GetLogDirectory(const SCConfNode *conf, char *out, size_t out_size)
347 {
348  const char *log_base_dir = SCConfNodeLookupChildValue(conf, "dir");
349  if (log_base_dir == NULL) {
350  SCLogConfig("Filestore (v2) default log directory %s", default_log_dir);
351  log_base_dir = default_log_dir;
352  }
353  if (PathIsAbsolute(log_base_dir)) {
354  size_t r = strlcpy(out, log_base_dir, out_size);
355  if (r >= out_size)
356  return -1;
357  } else {
358  const char *default_log_prefix = SCConfigGetLogDirectory();
359  if (PathMerge(out, out_size, default_log_prefix, log_base_dir) < 0)
360  return -1;
361  }
362  return 0;
363 }
364 
365 static bool InitFilestoreDirectory(const char *dir)
366 {
367  const uint8_t dir_count = 0xff;
368 
369  if (!SCPathExists(dir)) {
370  SCLogInfo("Filestore (v2) creating directory %s", dir);
371  if (SCCreateDirectoryTree(dir, true) != 0) {
372  SCLogError("Filestore (v2) failed to create directory %s: %s", dir, strerror(errno));
373  return false;
374  }
375  }
376 
377  for (int i = 0; i <= dir_count; i++) {
378  char hex[3];
379  snprintf(hex, sizeof(hex), "%02x", i);
380  char leaf[PATH_MAX];
381  if (PathMerge(leaf, sizeof(leaf), dir, hex) < 0) {
382  SCLogError("Filestore (v2) failed to create leaf directory: "
383  "path too long");
384  return false;
385  }
386  if (!SCPathExists(leaf)) {
387  SCLogInfo("Filestore (v2) creating directory %s", leaf);
388  if (SCDefaultMkDir(leaf) != 0) {
389  SCLogError(
390  "Filestore (v2) failed to create directory %s: %s", leaf, strerror(errno));
391  return false;
392  }
393  }
394  }
395 
396  /* Make sure the tmp directory exists. */
397  char tmpdir[PATH_MAX];
398  if (PathMerge(tmpdir, sizeof(tmpdir), dir, "tmp") < 0) {
399  SCLogError("Filestore (v2) failed to create tmp directory: path too long");
400  return false;
401  }
402  if (!SCPathExists(tmpdir)) {
403  SCLogInfo("Filestore (v2) creating directory %s", tmpdir);
404  if (SCDefaultMkDir(tmpdir) != 0) {
405  SCLogError("Filestore (v2) failed to create directory %s: %s", tmpdir, strerror(errno));
406  return false;
407  }
408  }
409 
410  return true;
411 }
412 
413 /** \brief Create a new http log OutputFilestoreCtx.
414  * \param conf Pointer to ConfNode containing this loggers configuration.
415  * \return NULL if failure, OutputFilestoreCtx* to the file_ctx if succesful
416  * */
417 static OutputInitResult OutputFilestoreLogInitCtx(SCConfNode *conf)
418 {
419  OutputInitResult result = { NULL, false };
420 
421  intmax_t version = 0;
422  if (!SCConfGetChildValueInt(conf, "version", &version) || version < 2) {
423  SCLogWarning("File-store v1 has been removed. Please update to file-store v2.");
424  return result;
425  }
426 
428  SCLogWarning("A file data logger is already enabled. Filestore (v2) "
429  "will not be enabled.");
430  return result;
431  }
432 
433  char log_directory[PATH_MAX] = "";
434  if (GetLogDirectory(conf, log_directory, sizeof(log_directory)) < 0) {
435  SCLogError("File-store output path too long.");
436  return result;
437  }
438  if (!InitFilestoreDirectory(log_directory)) {
439  return result;
440  }
441 
442  OutputFilestoreCtx *ctx = SCCalloc(1, sizeof(*ctx));
443  if (unlikely(ctx == NULL)) {
444  return result;
445  }
446 
447  strlcpy(ctx->prefix, log_directory, sizeof(ctx->prefix));
448 
449  if (PathMerge(ctx->tmpdir, sizeof(ctx->tmpdir), log_directory, "tmp") < 0) {
450  SCLogError("File-store output directory overflow.");
451  SCFree(ctx);
452  return result;
453  }
454 
455  ctx->xff_cfg = SCCalloc(1, sizeof(HttpXFFCfg));
456  if (ctx->xff_cfg != NULL) {
457  HttpXFFGetCfg(conf, ctx->xff_cfg);
458  }
459 
460  OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
461  if (unlikely(output_ctx == NULL)) {
462  SCFree(ctx->xff_cfg);
463  SCFree(ctx);
464  return result;
465  }
466 
467  output_ctx->data = ctx;
468  output_ctx->DeInit = OutputFilestoreLogDeInitCtx;
469 
470  const char *write_fileinfo = SCConfNodeLookupChildValue(conf, "write-fileinfo");
471  if (write_fileinfo != NULL && SCConfValIsTrue(write_fileinfo)) {
472  SCLogConfig("Filestore (v2) will output fileinfo records.");
473  ctx->fileinfo = true;
474  }
475 
476  const char *force_filestore = SCConfNodeLookupChildValue(conf, "force-filestore");
477  if (force_filestore != NULL && SCConfValIsTrue(force_filestore)) {
479  SCLogInfo("forcing filestore of all files");
480  }
481 
482  const char *force_magic = SCConfNodeLookupChildValue(conf, "force-magic");
483  if (force_magic != NULL && SCConfValIsTrue(force_magic)) {
485  SCLogConfig("Filestore (v2) forcing magic lookup for stored files");
486  }
487 
488  FileForceHashParseCfg(conf);
489 
490  /* The new filestore requires SHA256. */
492 
494 
495  const char *stream_depth_str = SCConfNodeLookupChildValue(conf, "stream-depth");
496  if (stream_depth_str != NULL && strcmp(stream_depth_str, "no")) {
497  uint32_t stream_depth = 0;
498  if (ParseSizeStringU32(stream_depth_str, &stream_depth) < 0) {
499  SCLogError("Error parsing "
500  "file-store.stream-depth "
501  "from conf file - %s. Killing engine",
502  stream_depth_str);
503  exit(EXIT_FAILURE);
504  }
505  if (stream_depth) {
506  if (stream_depth <= stream_config.reassembly_depth) {
507  SCLogWarning("file-store.stream-depth value %" PRIu32 " has "
508  "no effect since it's less than stream.reassembly.depth "
509  "value.",
510  stream_depth);
511  } else {
512  FileReassemblyDepthEnable(stream_depth);
513  }
514  }
515  }
516 
517  const char *file_count_str = SCConfNodeLookupChildValue(conf, "max-open-files");
518  if (file_count_str != NULL) {
519  uint32_t file_count = 0;
520  if (ParseSizeStringU32(file_count_str, &file_count) < 0) {
521  SCLogError("Error parsing "
522  "file-store.max-open-files "
523  "from conf file - %s. Killing engine",
524  file_count_str);
525  exit(EXIT_FAILURE);
526  } else {
527  if (file_count != 0) {
528  FileSetMaxOpenFiles(file_count);
529  SCLogConfig("Filestore (v2) will keep a max of %d "
530  "simultaneously open files",
531  file_count);
532  }
533  }
534  }
535 
536  result.ctx = output_ctx;
537  result.ok = true;
538  SCReturnCT(result, "OutputInitResult");
539 }
540 
542 {
544  OutputFilestoreLogInitCtx, OutputFilestoreLogger, OutputFilestoreLogThreadInit,
545  OutputFilestoreLogThreadDeinit);
546 
547  SC_ATOMIC_INIT(filestore_open_file_cnt);
548  SC_ATOMIC_SET(filestore_open_file_cnt, 0);
549 }
550 
552 {
553  StatsRegisterGlobalCounter("file_store.open_files", OutputFilestoreOpenFilesCounter);
554 }
win32-misc.h
SCJsonBuilder
struct SCJsonBuilder SCJsonBuilder
Definition: detect-engine-helper.h:83
StatsRegisterGlobalCounter
StatsCounterGlobalId StatsRegisterGlobalCounter(const char *name, uint64_t(*Func)(void))
Registers a counter, which represents a global value.
Definition: counters.c:1093
OutputFilestoreLogThread_::fs_error_counter
StatsCounterId fs_error_counter
Definition: output-filestore.c:62
SCConfValIsTrue
int SCConfValIsTrue(const char *val)
Check if a value is true.
Definition: conf.c:577
OutputFilestoreCtx_::prefix
char prefix[FILESTORE_PREFIX_MAX]
Definition: output-filestore.c:53
O_NOFOLLOW
#define O_NOFOLLOW
Definition: win32-misc.h:30
FileForceHashParseCfg
void FileForceHashParseCfg(SCConfNode *conf)
Function to parse forced file hashing configuration.
Definition: util-file.c:169
SC_ATOMIC_INIT
#define SC_ATOMIC_INIT(name)
wrapper for initializing an atomic variable.
Definition: util-atomic.h:314
FileReassemblyDepthEnable
void FileReassemblyDepthEnable(uint32_t size)
Definition: util-file.c:127
JsonBuildFileInfoRecord
SCJsonBuilder * JsonBuildFileInfoRecord(const Packet *p, const File *ff, void *tx, const uint64_t tx_id, const bool stored, uint8_t dir, HttpXFFCfg *xff_cfg, OutputJsonCtx *eve_ctx)
Definition: output-json-file.c:80
stream-tcp.h
HttpXFFGetCfg
void HttpXFFGetCfg(SCConfNode *conf, HttpXFFCfg *result)
Function to return XFF configuration from a configuration node.
Definition: app-layer-htp-xff.c:116
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
SC_ATOMIC_SET
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
Definition: util-atomic.h:386
PathMerge
int PathMerge(char *out_buf, size_t buf_size, const char *const dir, const char *const fname)
Definition: util-path.c:74
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
StatsRegisterCounter
StatsCounterId StatsRegisterCounter(const char *name, StatsThreadContext *stats)
Registers a normal, unqualified counter.
Definition: counters.c:1038
OutputFilestoreCtx_::tmpdir
char tmpdir[FILESTORE_PREFIX_MAX]
Definition: output-filestore.c:54
WOT_MAX
@ WOT_MAX
Definition: output-filestore.c:72
SC_SHA256_LEN
#define SC_SHA256_LEN
Definition: util-file.h:104
OutputFilestoreCtx_::fileinfo
bool fileinfo
Definition: output-filestore.c:55
TcpStreamCnf_::reassembly_depth
uint32_t reassembly_depth
Definition: stream-tcp.h:75
ctx
struct Thresholds ctx
SC_ATOMIC_ADD
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
Definition: util-atomic.h:332
File_::file_store_id
uint32_t file_store_id
Definition: util-file.h:152
PrintHexString
void PrintHexString(char *str, size_t size, uint8_t *buf, size_t buf_len)
Definition: util-print.c:262
FileForceMagicEnable
void FileForceMagicEnable(void)
Definition: util-file.c:98
p
Packet * p
Definition: fuzz_dataset.c:30
StatsCounterId
Definition: counters.h:30
OutputRegisterFiledataModule
void OutputRegisterFiledataModule(LoggerId id, const char *name, const char *conf_name, OutputInitFunc InitFunc, SCFiledataLogger FiledataLogFunc, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit)
Register a file data output module.
Definition: output.c:464
SCConfNodeLookupChildValue
const char * SCConfNodeLookupChildValue(const SCConfNode *node, const char *name)
Lookup the value of a child configuration node by name.
Definition: conf.c:877
OutputFilestoreCtx_::xff_cfg
HttpXFFCfg * xff_cfg
Definition: output-filestore.c:56
stream_config
TcpStreamCnf stream_config
Definition: stream-tcp.c:227
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:82
WOT_OPEN
@ WOT_OPEN
Definition: output-filestore.c:66
OutputFilestoreCtx_
Definition: output-filestore.c:52
OUTPUT_FILEDATA_FLAG_CLOSE
#define OUTPUT_FILEDATA_FLAG_CLOSE
Definition: output-filedata.h:30
OutputCtx_::data
void * data
Definition: tm-modules.h:91
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:81
SCDefaultMkDir
int SCDefaultMkDir(const char *path)
Wrapper around SCMkDir with default mode arguments.
Definition: util-path.c:123
OutputCtx_
Definition: tm-modules.h:88
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
OutputFilestoreLogThread_
Definition: output-filestore.c:59
feature.h
OutputFilestoreLogThread_::counter_max_hits
StatsCounterId counter_max_hits
Definition: output-filestore.c:61
WARN_ONCE
#define WARN_ONCE(wot_type,...)
Definition: output-filestore.c:79
OutputFilestoreCtx
struct OutputFilestoreCtx_ OutputFilestoreCtx
OutputInitResult_::ctx
OutputCtx * ctx
Definition: output.h:47
strlcat
size_t strlcat(char *, const char *src, size_t siz)
Definition: util-strlcatu.c:45
Packet_::ts
SCTime_t ts
Definition: decode.h:570
File_::fd
int fd
Definition: util-file.h:153
output-json-file.h
WOT_WRITE
@ WOT_WRITE
Definition: output-filestore.c:67
util-print.h
SCEnter
#define SCEnter(...)
Definition: util-debug.h:284
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
StatsCounterIncr
void StatsCounterIncr(StatsThreadContext *stats, StatsCounterId id)
Increments the local counter.
Definition: counters.c:163
OutputInitResult_::ok
bool ok
Definition: output.h:48
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:262
OutputFilestoreRegister
void OutputFilestoreRegister(void)
Definition: output-filestore.c:541
SC_ATOMIC_SUB
#define SC_ATOMIC_SUB(name, val)
sub a value from our atomic variable
Definition: util-atomic.h:341
SC_ATOMIC_DECLARE
#define SC_ATOMIC_DECLARE(type, name)
wrapper for declaring atomic variables.
Definition: util-atomic.h:280
Packet_
Definition: decode.h:516
SCConfGetChildValueInt
int SCConfGetChildValueInt(const SCConfNode *base, const char *name, intmax_t *val)
Definition: conf.c:475
SCConfigGetLogDirectory
const char * SCConfigGetLogDirectory(void)
Definition: util-conf.c:38
TmEcode
TmEcode
Definition: tm-threads-common.h:80
HttpXFFCfg_
Definition: app-layer-htp-xff.h:41
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:232
FILESTORE_PREFIX_MAX
#define FILESTORE_PREFIX_MAX
Definition: output-filestore.c:43
SCPathExists
bool SCPathExists(const char *path)
Check if a path exists.
Definition: util-path.c:183
WOT_SNPRINTF
@ WOT_SNPRINTF
Definition: output-filestore.c:70
File_
Definition: util-file.h:146
OutputInitResult_
Definition: output.h:46
util-conf.h
FEATURE_OUTPUT_FILESTORE
#define FEATURE_OUTPUT_FILESTORE
Definition: feature.h:28
flags
uint8_t flags
Definition: decode-gre.h:0
suricata-common.h
FileForceFilestoreEnable
void FileForceFilestoreEnable(void)
Definition: util-file.c:92
OutputCtx_::DeInit
void(* DeInit)(struct OutputCtx_ *)
Definition: tm-modules.h:94
util-path.h
WOT_RENAME
@ WOT_RENAME
Definition: output-filestore.c:69
OUTPUT_FILEDATA_FLAG_OPEN
#define OUTPUT_FILEDATA_FLAG_OPEN
Definition: output-filedata.h:29
SCTIME_SECS
#define SCTIME_SECS(t)
Definition: util-time.h:57
PathIsAbsolute
int PathIsAbsolute(const char *path)
Check if a path is absolute.
Definition: util-path.c:44
version
uint8_t version
Definition: decode-gre.h:1
output-filestore.h
WarnOnceTypes
WarnOnceTypes
Definition: output-filestore.c:65
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:34
File_::sha256
uint8_t sha256[SC_SHA256_LEN]
Definition: util-file.h:165
ParseSizeStringU32
int ParseSizeStringU32(const char *size, uint32_t *res)
Definition: util-misc.c:173
SCLogConfig
struct SCLogConfig_ SCLogConfig
Holds the config state used by the logging api.
MODULE_NAME
#define MODULE_NAME
Definition: output-filestore.c:37
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:274
SCFree
#define SCFree(p)
Definition: util-mem.h:61
OutputFilestoreLogThread
struct OutputFilestoreLogThread_ OutputFilestoreLogThread
LOGGER_FILE_STORE
@ LOGGER_FILE_STORE
Definition: suricata-common.h:504
WOT_UNLINK
@ WOT_UNLINK
Definition: output-filestore.c:68
ProvidesFeature
void ProvidesFeature(const char *feature_name)
Definition: feature.c:106
SCReturnCT
#define SCReturnCT(x, type)
Definition: util-debug.h:298
OutputFilestoreLogThread_::ctx
OutputFilestoreCtx * ctx
Definition: output-filestore.c:60
likely
#define likely(expr)
Definition: util-optimize.h:32
RunModeOutputFiledataEnabled
int RunModeOutputFiledataEnabled(void)
Definition: runmodes.c:538
OutputFilestoreRegisterGlobalCounters
void OutputFilestoreRegisterGlobalCounters(void)
Definition: output-filestore.c:551
FileForceSha256Enable
void FileForceSha256Enable(void)
Definition: util-file.c:116
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:375
util-misc.h
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
ThreadVars_::stats
StatsThreadContext stats
Definition: threadvars.h:120
SCConfNode_
Definition: conf.h:37
output.h
SCCreateDirectoryTree
int SCCreateDirectoryTree(const char *path, const bool final)
Recursively create a directory.
Definition: util-path.c:137