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