38 #if defined(HAVE_DIRENT_H) && defined(HAVE_FNMATCH_H)
39 #define INIT_RING_BUFFER
71 #define DEFAULT_LOG_FILENAME "pcaplog"
72 #define MODULE_NAME "PcapLog"
73 #define MIN_LIMIT 4 * 1024 * 1024
74 #define DEFAULT_LIMIT 100 * 1024 * 1024
75 #define DEFAULT_FILE_LIMIT 0
77 #define LOGMODE_NORMAL 0
78 #define LOGMODE_SGUIL 1
79 #define LOGMODE_MULTI 2
87 #define RING_BUFFER_MODE_DISABLED 0
88 #define RING_BUFFER_MODE_ENABLED 1
90 #define TS_FORMAT_SEC 0
91 #define TS_FORMAT_USEC 1
93 #define USE_STREAM_DEPTH_DISABLED 0
94 #define USE_STREAM_DEPTH_ENABLED 1
96 #define HONOR_PASS_RULES_DISABLED 0
97 #define HONOR_PASS_RULES_ENABLED 1
99 #define PCAP_SNAPLEN 262144
100 #define PCAP_BUFFER_TIMEOUT 1000000 // microseconds
126 #define MAX_FILENAMELEN 513
138 LZ4F_compressionContext_t lz4f_context;
139 LZ4F_preferences_t lz4f_prefs;
159 struct pcap_pkthdr *
h;
183 uint32_t thread_number;
185 int timestamp_format;
192 int filename_part_cnt;
193 struct timeval last_pcap_dump;
204 static const char timestamp_pattern[] =
".*?(\\d+)(\\.(\\d+))?";
205 static pcre2_code *pcre_timestamp_code = NULL;
206 static pcre2_match_data *pcre_timestamp_match = NULL;
216 static void PcapLogFileDeInitCtx(
OutputCtx *);
224 PcapLogInitCtx, PcapLog, PcapLogCondition, PcapLogDataInit,
225 PcapLogDataDeinit, NULL);
232 #define PCAPLOG_PROFILE_START \
233 uint64_t pcaplog_profile_ticks = UtilCpuGetTicks()
235 #define PCAPLOG_PROFILE_END(prof) \
236 (prof).total += (UtilCpuGetTicks() - pcaplog_profile_ticks); \
315 uint64_t bytes_written = LZ4F_compressEnd(comp->lz4f_context,
317 if (LZ4F_isError(bytes_written)) {
319 LZ4F_getErrorName(bytes_written));
322 if (fwrite(comp->
buffer, 1, bytes_written, comp->
file) < bytes_written) {
368 if (PcapLogCloseFile(t,pl) < 0) {
389 SCLogDebug(
"Current entry dir %s and next entry %s "
390 "are equal: not removing dir",
394 "not equal: removing dir",
397 if (remove(pf->
dirname) != 0) {
399 "failed to remove sguil log %s: %s",
400 pf->
dirname, strerror( errno ));
406 PcapFileNameFree(pf);
410 if (PcapLogOpenFileCtx(pl) < 0) {
431 SCLogDebug(
"Setting pcap-log link type to %u", datalink);
456 if (comp->
file == NULL) {
458 "Error opening file for compressed output: %s",
463 uint64_t bytes_written = LZ4F_compressBegin(comp->lz4f_context,
465 if (LZ4F_isError(bytes_written)) {
467 LZ4F_getErrorName(bytes_written));
470 if (fwrite(comp->
buffer, 1, bytes_written, comp->
file) < bytes_written) {
508 static inline int PcapWrite(
511 struct timeval current_dump;
512 gettimeofday(¤t_dump, NULL);
521 uint64_t out_size = LZ4F_compressUpdate(
523 if (LZ4F_isError(
len)) {
527 if (fseek(pl->compression.pcap_buf_wrapper, 0, SEEK_SET) != 0) {
531 if (fwrite(comp->
buffer, 1, out_size, comp->
file) < out_size) {
546 pl->last_pcap_dump = current_dump;
556 static int PcapLogSegmentCallback(
557 const Packet *p,
TcpSegment *seg,
void *data,
const uint8_t *buf, uint32_t buflen)
575 static void PcapLogDumpSegments(
614 pl->
h->ts.tv_sec = p->
ts.tv_sec;
615 pl->
h->ts.tv_usec = p->
ts.tv_usec;
628 ret = PcapLogOpenFileCtx(
pl);
648 if (PcapLogRotateFile(t,pl) < 0) {
665 if (PcapLogRotateFile(t,pl) < 0) {
691 PcapLogDumpSegments(td, comp, p);
693 PcapLogDumpSegments(td, NULL, p);
701 pl->
h->ts.tv_sec = p->
ts.tv_sec;
702 pl->
h->ts.tv_usec = p->
ts.tv_usec;
739 SCLogDebug(
"pl->size_current %"PRIu64
", pl->size_limit %"PRIu64,
760 copy->prefix =
SCStrdup(pl->prefix);
761 if (
unlikely(copy->prefix == NULL)) {
767 copy->suffix = pl->suffix;
773 copy->use_ringbuffer = pl->use_ringbuffer;
774 copy->timestamp_format = pl->timestamp_format;
789 copy_comp->lz4f_prefs = comp->lz4f_prefs;
794 if (copy_comp->
buffer == NULL) {
823 LZ4F_errorCode_t errcode =
824 LZ4F_createCompressionContext(©_comp->lz4f_context, 1);
825 if (LZ4F_isError(errcode)) {
827 "LZ4F_createCompressionContext failed: %s",
828 LZ4F_getErrorName(errcode));
839 copy_comp->
file = NULL;
847 strlcpy(copy->dir, pl->dir,
sizeof(copy->dir));
850 for (i = 0; i < pl->filename_part_cnt && i <
MAX_TOKS; i++)
851 copy->filename_parts[i] = pl->filename_parts[i];
852 copy->filename_part_cnt = pl->filename_part_cnt;
861 #ifdef INIT_RING_BUFFER
862 static int PcapLogGetTimeOfFile(
const char *filename, uint64_t *secs,
868 int n = pcre2_match(pcre_timestamp_code, (PCRE2_SPTR8)filename, strlen(filename), 0, 0,
869 pcre_timestamp_match, NULL);
870 if (n != 2 && n != 4) {
877 copylen =
sizeof(buf);
878 if (pcre2_substring_copy_bynumber(pcre_timestamp_match, 1, (PCRE2_UCHAR8 *)buf, ©len) <
888 copylen =
sizeof(buf);
889 if (pcre2_substring_copy_bynumber(pcre_timestamp_match, 3, (PCRE2_UCHAR8 *)buf, ©len) <
903 char pattern[PATH_MAX];
905 SCLogInfo(
"Initializing PCAP ring buffer for %s/%s.",
906 pl->dir, pl->prefix);
908 strlcpy(pattern, pl->dir, PATH_MAX);
909 if (pattern[strlen(pattern) - 1] !=
'/') {
910 strlcat(pattern,
"/", PATH_MAX);
913 for (
int i = 0; i < pl->filename_part_cnt; i++) {
914 char *part = pl->filename_parts[i];
915 if (part == NULL || strlen(part) == 0) {
918 if (part[0] !=
'%' || strlen(part) < 2) {
919 strlcat(pattern, part, PATH_MAX);
929 snprintf(tmp, PATH_MAX,
"%"PRIu32, pl->thread_number);
930 strlcat(pattern, tmp, PATH_MAX);
934 strlcat(pattern,
"*", PATH_MAX);
938 "Unsupported format character: %%%s", part);
943 strlcat(pattern, pl->prefix, PATH_MAX);
944 strlcat(pattern,
".*", PATH_MAX);
946 strlcat(pattern, pl->suffix, PATH_MAX);
948 char *basename = strrchr(pattern,
'/');
952 DIR *dir = opendir(pattern);
955 pattern, strerror(errno));
960 struct dirent *entry = readdir(dir);
964 if (fnmatch(basename, entry->d_name, 0) != 0) {
971 if (!PcapLogGetTimeOfFile(entry->d_name, &secs, &usecs)) {
982 if (snprintf(path, PATH_MAX,
"%s/%s", pattern, entry->d_name) == PATH_MAX)
1034 "Failed to remove PCAP file %s: %s", pf->
filename,
1038 PcapFileNameFree(pf);
1053 static TmEcode PcapLogDataInit(
ThreadVars *t,
const void *initdata,
void **data)
1055 if (initdata == NULL) {
1056 SCLogDebug(
"Error getting context for LogPcap. \"initdata\" argument NULL");
1067 td->
pcap_log = PcapLogDataCopy(pl);
1075 "Pcap logging with multiple link type is not supported.");
1087 "Can't have multiple link types in pcap conditional mode.");
1091 "Using multiple link types can result in invalid pcap output");
1107 memset(&
ts, 0x00,
sizeof(
struct timeval));
1129 #ifdef INIT_RING_BUFFER
1134 SCLogInfo(
"Unable to initialize ring buffer on this platform.");
1142 PcapLogOpenFileCtx(pl);
1151 dst->profile_open.total +=
src->profile_open.total;
1152 dst->profile_open.cnt +=
src->profile_open.cnt;
1154 dst->profile_close.total +=
src->profile_close.total;
1155 dst->profile_close.cnt +=
src->profile_close.cnt;
1157 dst->profile_write.total +=
src->profile_write.total;
1158 dst->profile_write.cnt +=
src->profile_write.cnt;
1160 dst->profile_rotate.total +=
src->profile_rotate.total;
1161 dst->profile_rotate.cnt +=
src->profile_rotate.cnt;
1163 dst->profile_handles.total +=
src->profile_handles.total;
1164 dst->profile_handles.cnt +=
src->profile_handles.cnt;
1166 dst->profile_lock.total +=
src->profile_lock.total;
1167 dst->profile_lock.cnt +=
src->profile_lock.cnt;
1169 dst->profile_unlock.total +=
src->profile_unlock.total;
1170 dst->profile_unlock.cnt +=
src->profile_unlock.cnt;
1172 dst->profile_data_size +=
src->profile_data_size;
1179 while ((pf =
TAILQ_FIRST(&pl->pcap_file_list)) != NULL) {
1181 PcapFileNameFree(pf);
1183 if (pl == g_pcap_data) {
1184 for (
int i = 0; i <
MAX_TOKS; i++) {
1185 if (pl->filename_parts[i] != NULL) {
1186 SCFree(pl->filename_parts[i]);
1196 SCFree(pl->compression.buffer);
1197 fclose(pl->compression.pcap_buf_wrapper);
1198 SCFree(pl->compression.pcap_buf);
1199 LZ4F_errorCode_t errcode =
1200 LZ4F_freeCompressionContext(pl->compression.lz4f_context);
1201 if (LZ4F_isError(errcode)) {
1223 if (PcapLogCloseFile(t,pl) < 0) {
1230 StatsMerge(g_pcap_data, pl);
1231 g_pcap_data->reported++;
1232 if (g_pcap_data->threads == g_pcap_data->reported)
1233 PcapLogProfilingDump(g_pcap_data);
1236 if (pl->reported == 0) {
1237 PcapLogProfilingDump(pl);
1242 if (pl != g_pcap_data) {
1243 PcapLogDataFree(pl);
1254 static int ParseFilename(
PcapLogData *pl,
const char *filename)
1262 size_t filename_len = 0;
1265 filename_len = strlen(filename);
1271 for (i = 0; i < (int)strlen(filename); i++) {
1274 "invalid filename option. Max 2 %%-sign options");
1278 str[s++] = filename[i];
1280 if (filename[i] ==
'%') {
1291 if (i+1 < (
int)strlen(filename)) {
1294 "invalid filename option. Max 2 %%-sign options");
1298 if (filename[i+1] !=
'n' && filename[i+1] !=
't' && filename[i+1] !=
'i') {
1300 "invalid filename option. Valid %%-sign options: %%n, %%i and %%t");
1304 str[1] = filename[i+1];
1317 "Invalid filename for multimode. Need at list one %%-sign option");
1324 "invalid filename option. Max 3 %%-sign options");
1336 for (i = 0; i < tok; i++) {
1337 if (toks[i] == NULL)
1341 pl->filename_parts[i] = toks[i];
1343 pl->filename_part_cnt = tok;
1348 if (toks[x] != NULL)
1371 if (pl->
h == NULL) {
1373 "Failed to allocate Memory for pcap header struct");
1390 pcre_timestamp_code =
1391 pcre2_compile((PCRE2_SPTR8)timestamp_pattern, PCRE2_ZERO_TERMINATED, 0, &en, &eo, NULL);
1392 if (pcre_timestamp_code == NULL) {
1393 PCRE2_UCHAR errbuffer[256];
1394 pcre2_get_error_message(en, errbuffer,
sizeof(errbuffer));
1396 timestamp_pattern, (
int)eo, errbuffer);
1398 pcre_timestamp_match = pcre2_match_data_create_from_pattern(pcre_timestamp_code, NULL);
1402 const char *filename = NULL;
1408 if (filename == NULL)
1411 if ((pl->prefix =
SCStrdup(filename)) == NULL) {
1419 const char *s_limit = NULL;
1421 if (s_limit != NULL) {
1424 "Failed to initialize pcap output, invalid limit: %s",
1429 SCLogInfo(
"pcap-log \"limit\" value of %"PRIu64
" assumed to be pre-1.2 "
1431 uint64_t size = pl->
size_limit * 1024 * 1024;
1435 "Fail to initialize pcap-log output, limit less than "
1436 "allowed minimum.");
1442 const char *s_mode = NULL;
1444 if (s_mode != NULL) {
1445 if (strcasecmp(s_mode,
"sguil") == 0) {
1447 }
else if (strcasecmp(s_mode,
"multi") == 0) {
1449 }
else if (strcasecmp(s_mode,
"normal") != 0) {
1451 "log-pcap: invalid mode \"%s\". Valid options: \"normal\", "
1452 "\"sguil\", or \"multi\" mode ", s_mode);
1457 const char *s_dir = NULL;
1459 if (s_dir == NULL) {
1462 if (s_dir == NULL) {
1465 "log-pcap \"sguil\" mode requires \"sguil-base-dir\" "
1466 "option to be set.");
1468 const char *log_dir = NULL;
1472 log_dir,
sizeof(pl->dir));
1478 s_dir,
sizeof(pl->dir));
1480 const char *log_dir = NULL;
1483 snprintf(pl->dir,
sizeof(pl->dir),
"%s/%s",
1487 struct stat stat_buf;
1488 if (stat(pl->dir, &stat_buf) != 0) {
1490 "supplied doesn't exist. Shutting down the engine",
1501 if (compression_str == NULL || strcmp(compression_str,
"none") == 0) {
1509 }
else if (strcmp(compression_str,
"lz4") == 0) {
1513 "logs are not possible in sguil mode");
1540 memset(&comp->lz4f_prefs,
'\0',
sizeof(comp->lz4f_prefs));
1541 comp->lz4f_prefs.frameInfo.blockSizeID = LZ4F_max4MB;
1542 comp->lz4f_prefs.frameInfo.blockMode = LZ4F_blockLinked;
1544 comp->lz4f_prefs.frameInfo.contentChecksumFlag = 1;
1547 comp->lz4f_prefs.frameInfo.contentChecksumFlag = 0;
1553 }
else if (lvl < 0) {
1559 comp->lz4f_prefs.compressionLevel = lvl;
1563 LZ4F_errorCode_t errcode =
1564 LZ4F_createCompressionContext(&pl->compression.lz4f_context, 1);
1566 if (LZ4F_isError(errcode)) {
1568 "LZ4F_createCompressionContext failed: %s",
1569 LZ4F_getErrorName(errcode));
1581 "lz4 output buffer.");
1588 pl->suffix =
".lz4";
1591 "in pcap-log, but suricata was not compiled with lz4 "
1593 PcapLogDataFree(pl);
1599 "compression format: %s", compression_str);
1600 PcapLogDataFree(pl);
1604 SCLogInfo(
"Selected pcap-log compression method: %s",
1605 compression_str ? compression_str :
"none");
1608 if (s_conditional != NULL) {
1609 if (strcasecmp(s_conditional,
"alerts") == 0) {
1612 }
else if (strcasecmp(s_conditional,
"tag") == 0) {
1615 }
else if (strcasecmp(s_conditional,
"all") != 0) {
1617 "log-pcap: invalid conditional \"%s\". Valid options: \"all\", "
1618 "\"alerts\", or \"tag\" mode ",
1624 "Selected pcap-log conditional logging: %s", s_conditional ? s_conditional :
"all");
1627 if (ParseFilename(pl, filename) != 0)
1635 const char *max_number_of_files_s = NULL;
1637 if (max_number_of_files_s != NULL) {
1639 max_number_of_files_s) == -1) {
1641 "pcap-log output, invalid number of files limit: %s",
1642 max_number_of_files_s);
1644 }
else if (max_file_limit < 1) {
1646 "Failed to initialize pcap-log output, limit less than "
1647 "allowed minimum.");
1655 const char *ts_format = NULL;
1659 if (ts_format != NULL) {
1660 if (strcasecmp(ts_format,
"usec") == 0) {
1662 }
else if (strcasecmp(ts_format,
"sec") != 0) {
1664 "log-pcap ts_format specified %s is invalid must be"
1665 " \"sec\" or \"usec\"", ts_format);
1670 const char *use_stream_depth = NULL;
1674 if (use_stream_depth != NULL) {
1681 "log-pcap use_stream_depth specified is invalid must be");
1685 const char *honor_pass_rules = NULL;
1689 if (honor_pass_rules != NULL) {
1696 "log-pcap honor-pass-rules specified is invalid");
1703 if (
unlikely(output_ctx == NULL)) {
1706 output_ctx->
data = pl;
1707 output_ctx->
DeInit = PcapLogFileDeInitCtx;
1710 result.
ctx = output_ctx;
1715 static void PcapLogFileDeInitCtx(
OutputCtx *output_ctx)
1717 if (output_ctx == NULL)
1726 PcapLogDataFree(pl);
1729 pcre2_code_free(pcre_timestamp_code);
1730 pcre2_match_data_free(pcre_timestamp_match);
1745 char *filename = NULL;
1761 memset(&
ts, 0x00,
sizeof(
struct timeval));
1775 char dirname[32], dirfull[PATH_MAX] =
"";
1777 snprintf(dirname,
sizeof(dirname),
"%04d-%02d-%02d",
1778 tms->tm_year + 1900, tms->tm_mon + 1, tms->tm_mday);
1781 int ret = snprintf(dirfull,
sizeof(dirfull),
"%s/%s", pl->dir, dirname);
1782 if (ret < 0 || (
size_t)ret >=
sizeof(dirfull)) {
1798 written = snprintf(filename, PATH_MAX,
"%s/%s.%" PRIu32
"%s",
1799 dirfull, pl->prefix, (uint32_t)
ts.tv_sec, pl->suffix);
1801 written = snprintf(filename, PATH_MAX,
"%s/%s.%" PRIu32
".%" PRIu32
"%s",
1802 dirfull, pl->prefix, (uint32_t)
ts.tv_sec,
1803 (uint32_t)
ts.tv_usec, pl->suffix);
1805 if (written == PATH_MAX) {
1813 ret = snprintf(filename, PATH_MAX,
"%s/%s.%" PRIu32
"%s", pl->dir,
1814 pl->prefix, (uint32_t)
ts.tv_sec, pl->suffix);
1816 ret = snprintf(filename, PATH_MAX,
1817 "%s/%s.%" PRIu32
".%" PRIu32
"%s", pl->dir, pl->prefix,
1818 (uint32_t)
ts.tv_sec, (uint32_t)
ts.tv_usec, pl->suffix);
1820 if (ret < 0 || (
size_t)ret >= PATH_MAX) {
1825 if (pl->filename_part_cnt > 0) {
1828 strlcpy(filename, pl->dir, PATH_MAX);
1829 strlcat(filename,
"/", PATH_MAX);
1832 for (i = 0; i < pl->filename_part_cnt; i++) {
1833 if (pl->filename_parts[i] == NULL ||strlen(pl->filename_parts[i]) == 0)
1837 if (pl->filename_parts[i][0] ==
'%') {
1839 if (strlen(pl->filename_parts[i]) < 2)
1842 switch(pl->filename_parts[i][1]) {
1844 snprintf(
str,
sizeof(
str),
"%u", pl->thread_number);
1849 snprintf(
str,
sizeof(
str),
"%"PRIu64, (uint64_t)thread_id);
1855 snprintf(
str,
sizeof(
str),
"%"PRIu32, (uint32_t)
ts.tv_sec);
1857 snprintf(
str,
sizeof(
str),
"%"PRIu32
".%"PRIu32,
1858 (uint32_t)
ts.tv_sec, (uint32_t)
ts.tv_usec);
1865 strlcat(filename, pl->filename_parts[i], PATH_MAX);
1868 strlcat(filename, pl->suffix, PATH_MAX);
1873 ret = snprintf(filename, PATH_MAX,
"%s/%s.%u.%" PRIu32
"%s",
1874 pl->dir, pl->prefix, pl->thread_number,
1875 (uint32_t)
ts.tv_sec, pl->suffix);
1877 ret = snprintf(filename, PATH_MAX,
1878 "%s/%s.%u.%" PRIu32
".%" PRIu32
"%s", pl->dir,
1879 pl->prefix, pl->thread_number, (uint32_t)
ts.tv_sec,
1880 (uint32_t)
ts.tv_usec, pl->suffix);
1882 if (ret < 0 || (
size_t)ret >= PATH_MAX) {
1887 SCLogDebug(
"multi-mode: filename %s", filename);
1904 PcapFileNameFree(pf);
1917 static int profiling_pcaplog_enabled = 0;
1918 static int profiling_pcaplog_output_to_file = 0;
1919 static char *profiling_pcaplog_file_name = NULL;
1920 static const char *profiling_pcaplog_file_mode =
"a";
1922 static void FormatNumber(uint64_t num,
char *
str,
size_t size)
1925 snprintf(
str, size,
"%"PRIu64, num);
1926 else if (num < 1000000UL)
1927 snprintf(
str, size,
"%3.1fk", (
float)num/1000UL);
1928 else if (num < 1000000000UL)
1929 snprintf(
str, size,
"%3.1fm", (
float)num/1000000UL);
1931 snprintf(
str, size,
"%3.1fb", (
float)num/1000000000UL);
1936 char ticks_str[32] =
"n/a";
1937 char cnt_str[32] =
"n/a";
1938 char avg_str[32] =
"n/a";
1940 FormatNumber((uint64_t)p->
cnt, cnt_str,
sizeof(cnt_str));
1941 FormatNumber((uint64_t)p->
total, ticks_str,
sizeof(ticks_str));
1943 FormatNumber((uint64_t)(p->
total/p->
cnt), avg_str,
sizeof(avg_str));
1945 fprintf(fp,
"%-28s %-10s %-10s %-10s\n", name, cnt_str, avg_str, ticks_str);
1948 static void ProfileReport(FILE *fp,
PcapLogData *pl)
1953 ProfileReportPair(fp,
"rotate (incl open/close)", &pl->
profile_rotate);
1959 static void FormatBytes(uint64_t num,
char *
str,
size_t size)
1962 snprintf(
str, size,
"%"PRIu64, num);
1963 else if (num < 1048576UL)
1964 snprintf(
str, size,
"%3.1fKiB", (
float)num/1000UL);
1965 else if (num < 1073741824UL)
1966 snprintf(
str, size,
"%3.1fMiB", (
float)num/1000000UL);
1968 snprintf(
str, size,
"%3.1fGiB", (
float)num/1000000000UL);
1975 if (profiling_pcaplog_enabled == 0)
1978 if (profiling_pcaplog_output_to_file == 1) {
1979 fp = fopen(profiling_pcaplog_file_name, profiling_pcaplog_file_mode);
1982 profiling_pcaplog_file_name, strerror(errno));
1990 fprintf(fp,
"\n\nOperation Cnt Avg ticks Total ticks\n");
1991 fprintf(fp,
"---------------------------- ---------- ---------- -----------\n");
1993 ProfileReport(fp, pl);
2000 fprintf(fp,
"\nOverall: %"PRIu64
" bytes written, average %d bytes per write.\n",
2003 fprintf(fp,
" PCAP data structure overhead: %"PRIuMAX
" per write.\n",
2004 (uintmax_t)
sizeof(
struct pcap_pkthdr));
2009 fprintf(fp,
" Size written: %s\n", bytes_str);
2012 uint64_t ticks_per_mib = 0, ticks_per_gib = 0;
2015 ticks_per_mib = total/mib;
2016 char ticks_per_mib_str[32] =
"n/a";
2017 if (ticks_per_mib > 0)
2018 FormatNumber(ticks_per_mib, ticks_per_mib_str,
sizeof(ticks_per_mib_str));
2019 fprintf(fp,
" Ticks per MiB: %s\n", ticks_per_mib_str);
2023 ticks_per_gib = total/gib;
2024 char ticks_per_gib_str[32] =
"n/a";
2025 if (ticks_per_gib > 0)
2026 FormatNumber(ticks_per_gib, ticks_per_gib_str,
sizeof(ticks_per_gib_str));
2027 fprintf(fp,
" Ticks per GiB: %s\n", ticks_per_gib_str);
2037 profiling_pcaplog_enabled = 1;
2038 SCLogInfo(
"pcap-log profiling enabled");
2041 if (filename != NULL) {
2042 const char *log_dir;
2045 profiling_pcaplog_file_name =
SCMalloc(PATH_MAX);
2046 if (
unlikely(profiling_pcaplog_file_name == NULL)) {
2050 snprintf(profiling_pcaplog_file_name, PATH_MAX,
"%s/%s", log_dir, filename);
2054 profiling_pcaplog_file_mode =
"a";
2056 profiling_pcaplog_file_mode =
"w";
2059 profiling_pcaplog_output_to_file = 1;
2060 SCLogInfo(
"pcap-log profiling output goes to %s (mode %s)",
2061 profiling_pcaplog_file_name, profiling_pcaplog_file_mode);