return result;
}
-static int AlertDebugLogCondition(ThreadVars *tv, const Packet *p)
+static int AlertDebugLogCondition(ThreadVars *tv, void *thread_data, const Packet *p)
{
return (p->alerts.cnt ? TRUE : FALSE);
}
void AlertFastLogRegisterTests(void);
static void AlertFastLogDeInitCtx(OutputCtx *);
-int AlertFastLogCondition(ThreadVars *tv, const Packet *p);
+int AlertFastLogCondition(ThreadVars *tv, void *thread_data, const Packet *p);
int AlertFastLogger(ThreadVars *tv, void *data, const Packet *p);
void AlertFastLogRegister(void)
LogFileCtx* file_ctx;
} AlertFastLogThread;
-int AlertFastLogCondition(ThreadVars *tv, const Packet *p)
+int AlertFastLogCondition(ThreadVars *tv, void *thread_data, const Packet *p)
{
return (p->alerts.cnt ? TRUE : FALSE);
}
return TM_ECODE_OK;
}
-static int AlertSyslogCondition(ThreadVars *tv, const Packet *p)
+static int AlertSyslogCondition(ThreadVars *tv, void *thread_data, const Packet *p)
{
return (p->alerts.cnt > 0 ? TRUE : FALSE);
}
#define LOGMODE_SGUIL 1
#define LOGMODE_MULTI 2
+typedef enum LogModeConditionalType_ {
+ LOGMODE_COND_ALL,
+ LOGMODE_COND_ALERTS
+} LogModeConditionalType;
+
#define RING_BUFFER_MODE_DISABLED 0
#define RING_BUFFER_MODE_ENABLED 1
uint64_t profile_data_size; /**< track in bytes how many bytes we wrote */
uint32_t file_cnt; /**< count of pcap files we currently have */
uint32_t max_files; /**< maximum files to use in ring buffer mode */
+ LogModeConditionalType
+ conditional; /**< log all packets or just packets and flows with alerts */
PcapLogProfileData profile_lock;
PcapLogProfileData profile_write;
static void PcapLogFileDeInitCtx(OutputCtx *);
static OutputInitResult PcapLogInitCtx(ConfNode *);
static void PcapLogProfilingDump(PcapLogData *);
-static int PcapLogCondition(ThreadVars *, const Packet *);
+static int PcapLogCondition(ThreadVars *, void *, const Packet *);
void PcapLogRegister(void)
{
(prof).total += (UtilCpuGetTicks() - pcaplog_profile_ticks); \
(prof).cnt++
-static int PcapLogCondition(ThreadVars *tv, const Packet *p)
+static int PcapLogCondition(ThreadVars *tv, void *thread_data, const Packet *p)
{
+ PcapLogThreadData *ptd = (PcapLogThreadData *)thread_data;
+
if (p->flags & PKT_PSEUDO_STREAM_END) {
return FALSE;
}
if (IS_TUNNEL_PKT(p) && !IS_TUNNEL_ROOT_PKT(p)) {
return FALSE;
}
+ /* Log alerted flow */
+ if (ptd->pcap_log->conditional == LOGMODE_COND_ALERTS) {
+ if (p->alerts.cnt || (p->flow && FlowHasAlerts(p->flow))) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ }
return TRUE;
}
copy->timestamp_format = pl->timestamp_format;
copy->use_stream_depth = pl->use_stream_depth;
copy->size_limit = pl->size_limit;
+ copy->conditional = pl->conditional;
const PcapLogCompressionData *comp = &pl->compression;
PcapLogCompressionData *copy_comp = ©->compression;
pl->timestamp_format = TS_FORMAT_SEC;
pl->use_stream_depth = USE_STREAM_DEPTH_DISABLED;
pl->honor_pass_rules = HONOR_PASS_RULES_DISABLED;
+ pl->conditional = LOGMODE_COND_ALL;
TAILQ_INIT(&pl->pcap_file_list);
SCLogInfo("Selected pcap-log compression method: %s",
compression_str ? compression_str : "none");
+
+ const char *s_conditional = ConfNodeLookupChildValue(conf, "conditional");
+ if (s_conditional != NULL) {
+ if (strcasecmp(s_conditional, "alerts") == 0) {
+ pl->conditional = LOGMODE_COND_ALERTS;
+ } else if (strcasecmp(s_conditional, "all") != 0) {
+ FatalError(SC_ERR_INVALID_ARGUMENT,
+ "log-pcap: invalid conditional \"%s\". Valid options: \"all\", "
+ "or \"alerts\" mode ",
+ s_conditional);
+ }
+ }
+
+ SCLogInfo(
+ "Selected pcap-log conditional logging: %s", s_conditional ? s_conditional : "all");
}
if (ParseFilename(pl, filename) != 0)
return 0;
}
-static int JsonAlertLogCondition(ThreadVars *tv, const Packet *p)
+static int JsonAlertLogCondition(ThreadVars *tv, void *thread_data, const Packet *p)
{
if (p->alerts.cnt || (p->flags & PKT_HAS_TAG)) {
return TRUE;
return AnomalyJson(tv, aft, p);
}
-static int JsonAnomalyLogCondition(ThreadVars *tv, const Packet *p)
+static int JsonAnomalyLogCondition(ThreadVars *tv, void *thread_data, const Packet *p)
{
return p->events.cnt > 0 ||
(p->app_layer_events && p->app_layer_events->cnt > 0) ||
*
* \retval bool TRUE or FALSE
*/
-static int JsonDropLogCondition(ThreadVars *tv, const Packet *p)
+static int JsonDropLogCondition(ThreadVars *tv, void *data, const Packet *p)
{
if (!EngineModeIsIPS()) {
SCLogDebug("engine is not running in inline mode, so returning");
return FrameJson(tv, aft, p);
}
-static int JsonFrameLogCondition(ThreadVars *tv, const Packet *p)
+static int JsonFrameLogCondition(ThreadVars *tv, void *thread_data, const Packet *p)
{
if (p->flow == NULL || p->flow->alproto == ALPROTO_UNKNOWN)
return FALSE;
return MetadataJson(tv, aft, p);
}
-static int JsonMetadataLogCondition(ThreadVars *tv, const Packet *p)
+static int JsonMetadataLogCondition(ThreadVars *tv, void *data, const Packet *p)
{
if (p->pktvar) {
return TRUE;
SCReturnInt(0);
}
-static int LuaPacketConditionAlerts(ThreadVars *tv, const Packet *p)
+static int LuaPacketConditionAlerts(ThreadVars *tv, void *data, const Packet *p)
{
if (p->alerts.cnt > 0)
return TRUE;
SCReturnInt(0);
}
-static int LuaPacketCondition(ThreadVars *tv, const Packet *p)
+static int LuaPacketCondition(ThreadVars *tv, void *data, const Packet *p)
{
return TRUE;
}
while (logger && store) {
DEBUG_VALIDATE_BUG_ON(logger->LogFunc == NULL || logger->ConditionFunc == NULL);
- if ((logger->ConditionFunc(tv, (const Packet *)p)) == TRUE) {
+ if ((logger->ConditionFunc(tv, store->thread_data, (const Packet *)p)) == TRUE) {
PACKET_PROFILING_LOGGER_START(p, logger->logger_id);
logger->LogFunc(tv, store->thread_data, (const Packet *)p);
PACKET_PROFILING_LOGGER_END(p, logger->logger_id);
/** packet logger condition function pointer type,
* must return true for packets that should be logged
*/
-typedef int (*PacketLogCondition)(ThreadVars *, const Packet *);
+typedef int (*PacketLogCondition)(ThreadVars *, void *thread_data, const Packet *);
int OutputRegisterPacketLogger(LoggerId logger_id, const char *name,
PacketLogger LogFunc, PacketLogCondition ConditionFunc, OutputCtx *,
#ts-format: usec # sec or usec second format (default) is filename.sec usec is filename.sec.usec
use-stream-depth: no #If set to "yes" packets seen after reaching stream inspection depth are ignored. "no" logs all packets
honor-pass-rules: no # If set to "yes", flows in which a pass rule matched will stop being logged.
+ # Use "all" to log all packets or use "alerts" to log only alerted packets and flows
+ #conditional: all
# a full alert log containing much information for signature writers
# or for investigating suspected false positives.