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