Add pcap-info alert format.

This patch adds a new alert format called pcap-info. It aims at
providing an easy to parse one-line per-alert format containing
the packet id in the parsed pcap for each alert. This permit to
add information inside the pcap parser.

This format is made to be used with suriwire which is a plugin for
wireshark. Its target is to enable the display of suricata results
inside wireshark.

This format doesn't use append mode per default because a clean file
is needed to operate with wireshark.

The format is a list of values separated by ':':
  Packet number:GID of matching signature:SID of signature:REV of signature:Flow:To Server:To Client:0:0:Message of signature
The two zero are not yet used values. Candidate for usage is the
part of the packet that matched the signature.
remotes/origin/master-1.1.x
Eric Leblond 13 years ago committed by Victor Julien
parent 1d1e7667ae
commit 27f1d88374

@ -228,6 +228,7 @@ alert-unified-log.c alert-unified-log.h \
alert-unified-alert.c alert-unified-alert.h \
alert-unified2-alert.c alert-unified2-alert.h \
alert-syslog.c alert-syslog.h \
alert-pcapinfo.c alert-pcapinfo.h \
log-droplog.c log-droplog.h \
log-httplog.c log-httplog.h \
log-pcap.c log-pcap.h \

@ -0,0 +1,237 @@
/* Copyright (C) 2011 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
* \file
*
* \author Eric Leblond <eric@regit.org>
*
* Logs alerts in a line based text format suitable for interaction
* with wireshark or an other pcap file analysis tools.
*
* The format of the logging is:
* Packet number:GID of matching signature:SID of signature:REV of signature:Flow:To Server:To Client:0:0:Signature Message
* The two zeros are reserved for upcoming usage (probably byte start
* and byte end of payload)
*/
#include "suricata-common.h"
#include "debug.h"
#include "detect.h"
#include "flow.h"
#include "conf.h"
#include "threads.h"
#include "tm-threads.h"
#include "threadvars.h"
#include "util-debug.h"
#include "util-unittest.h"
#include "util-unittest-helper.h"
#include "detect.h"
#include "detect-parse.h"
#include "detect-engine.h"
#include "detect-engine-mpm.h"
#include "detect-reference.h"
#include "util-classification-config.h"
#include "output.h"
#include "alert-pcapinfo.h"
#include "util-mpm-b2g-cuda.h"
#include "util-cuda-handlers.h"
#include "util-privs.h"
#include "util-print.h"
#include "util-proto-name.h"
#include "util-optimize.h"
#define DEFAULT_LOG_FILENAME "alert-pcapinfo.log"
/* We need a new file for each pcap */
#define DEFAULT_PCAPINFO_MODE_APPEND "no"
#define MODULE_NAME "AlertPcapInfo"
TmEcode AlertPcapInfo (ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *);
TmEcode AlertPcapInfoThreadInit(ThreadVars *, void *, void **);
TmEcode AlertPcapInfoThreadDeinit(ThreadVars *, void *);
void AlertPcapInfoExitPrintStats(ThreadVars *, void *);
static int AlertPcapInfoOpenFileCtx(LogFileCtx *, const char *, const char *);
static void AlertPcapInfoDeInitCtx(OutputCtx *);
void TmModuleAlertPcapInfoRegister (void) {
tmm_modules[TMM_ALERTPCAPINFO].name = MODULE_NAME;
tmm_modules[TMM_ALERTPCAPINFO].ThreadInit = AlertPcapInfoThreadInit;
tmm_modules[TMM_ALERTPCAPINFO].Func = AlertPcapInfo;
tmm_modules[TMM_ALERTPCAPINFO].ThreadExitPrintStats = AlertPcapInfoExitPrintStats;
tmm_modules[TMM_ALERTPCAPINFO].ThreadDeinit = AlertPcapInfoThreadDeinit;
tmm_modules[TMM_ALERTPCAPINFO].RegisterTests = NULL;
tmm_modules[TMM_ALERTPCAPINFO].cap_flags = 0;
OutputRegisterModule(MODULE_NAME, "pcap-info", AlertPcapInfoInitCtx);
}
typedef struct AlertPcapInfoThread_ {
/** LogFileCtx has the pointer to the file and a mutex to allow multithreading */
LogFileCtx* file_ctx;
} AlertPcapInfoThread;
TmEcode AlertPcapInfo (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{
AlertPcapInfoThread *aft = (AlertPcapInfoThread *)data;
int i;
/* logging is useless if we don't have pcap number */
if ((p->pcap_cnt != 0) && (p->alerts.cnt > 0)) {
SCMutexLock(&aft->file_ctx->fp_mutex);
/* only count logged alert */
aft->file_ctx->alerts += p->alerts.cnt;
for (i = 0; i < p->alerts.cnt; i++) {
PacketAlert *pa = &p->alerts.alerts[i];
fprintf(aft->file_ctx->fp, "%ld:%d:%d:%d:%d:%d:%d:0:0:%s\n",
p->pcap_cnt, pa->s->gid, pa->s->id,
pa->s->rev, pa->alert_msg ? 1 : 0,
p->flowflags & FLOW_PKT_TOSERVER ? 1 : 0,
p->flowflags & FLOW_PKT_TOCLIENT ? 1 : 0,
pa->s->msg);
}
SCMutexUnlock(&aft->file_ctx->fp_mutex);
}
return TM_ECODE_OK;
}
TmEcode AlertPcapInfoThreadInit(ThreadVars *t, void *initdata, void **data)
{
AlertPcapInfoThread *aft = SCMalloc(sizeof(AlertPcapInfoThread));
if (aft == NULL)
return TM_ECODE_FAILED;
memset(aft, 0, sizeof(AlertPcapInfoThread));
if(initdata == NULL)
{
SCLogDebug("Error getting context for AlertPcapInfo. \"initdata\" argument NULL");
SCFree(aft);
return TM_ECODE_FAILED;
}
/** Use the Ouptut Context (file pointer and mutex) */
aft->file_ctx = ((OutputCtx *)initdata)->data;
*data = (void *)aft;
return TM_ECODE_OK;
}
TmEcode AlertPcapInfoThreadDeinit(ThreadVars *t, void *data)
{
AlertPcapInfoThread *aft = (AlertPcapInfoThread *)data;
if (aft == NULL) {
return TM_ECODE_OK;
}
/* clear memory */
memset(aft, 0, sizeof(AlertPcapInfoThread));
SCFree(aft);
return TM_ECODE_OK;
}
void AlertPcapInfoExitPrintStats(ThreadVars *tv, void *data) {
AlertPcapInfoThread *aft = (AlertPcapInfoThread *)data;
if (aft == NULL) {
return;
}
SCLogInfo("(%s) Alerts %" PRIu64 "", tv->name, aft->file_ctx->alerts);
}
/**
* \brief Create a new LogFileCtx for "fast" output style.
* \param conf The configuration node for this output.
* \return A LogFileCtx pointer on success, NULL on failure.
*/
OutputCtx *AlertPcapInfoInitCtx(ConfNode *conf)
{
LogFileCtx *logfile_ctx = LogFileNewCtx();
if (logfile_ctx == NULL) {
SCLogDebug("AlertPcapInfoInitCtx2: Could not create new LogFileCtx");
return NULL;
}
const char *filename = ConfNodeLookupChildValue(conf, "filename");
if (filename == NULL)
filename = DEFAULT_LOG_FILENAME;
const char *mode = ConfNodeLookupChildValue(conf, "append");
if (mode == NULL)
mode = DEFAULT_PCAPINFO_MODE_APPEND;
if (AlertPcapInfoOpenFileCtx(logfile_ctx, filename, mode) < 0) {
LogFileFreeCtx(logfile_ctx);
return NULL;
}
OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
if (output_ctx == NULL)
return NULL;
output_ctx->data = logfile_ctx;
output_ctx->DeInit = AlertPcapInfoDeInitCtx;
SCLogInfo("Fast log output initialized, filename: %s", filename);
return output_ctx;
}
static void AlertPcapInfoDeInitCtx(OutputCtx *output_ctx)
{
LogFileCtx *logfile_ctx = (LogFileCtx *)output_ctx->data;
LogFileFreeCtx(logfile_ctx);
SCFree(output_ctx);
}
/** \brief Read the config set the file pointer, open the file
* \param file_ctx pointer to a created LogFileCtx using LogFileNewCtx()
* \param filename name of log file
* \param mode append mode (bool)
* \return -1 if failure, 0 if succesful
* */
static int AlertPcapInfoOpenFileCtx(LogFileCtx *file_ctx, const char *filename,
const char *mode)
{
char log_path[PATH_MAX];
char *log_dir;
if (ConfGet("default-log-dir", &log_dir) != 1)
log_dir = DEFAULT_LOG_DIR;
snprintf(log_path, PATH_MAX, "%s/%s", log_dir, filename);
if (ConfValIsTrue(mode)) {
file_ctx->fp = fopen(log_path, "a");
} else {
file_ctx->fp = fopen(log_path, "w");
}
if (file_ctx->fp == NULL) {
SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", log_path,
strerror(errno));
return -1;
}
return 0;
}

@ -0,0 +1,30 @@
/* Copyright (C) 2011 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
* \file
*
* \author Eric Leblond <eric@regit.org>
*/
#ifndef __ALERT_PCAPINFO_H__
#define __ALERT_PCAPINFO_H__
void TmModuleAlertPcapInfoRegister (void);
OutputCtx *AlertPcapInfoInitCtx(ConfNode *);
#endif /* __ALERT_PCAPINFO_H__ */

@ -82,6 +82,7 @@
#include "alert-debuglog.h"
#include "alert-prelude.h"
#include "alert-syslog.h"
#include "alert-pcapinfo.h"
#include "log-droplog.h"
#include "log-httplog.h"
@ -1208,6 +1209,7 @@ int main(int argc, char **argv)
TmModuleAlertUnifiedAlertRegister();
TmModuleUnified2AlertRegister();
TmModuleAlertSyslogRegister();
TmModuleAlertPcapInfoRegister();
TmModuleLogDropLogRegister();
TmModuleStreamTcpRegister();
TmModuleLogHttpLogRegister();

@ -72,6 +72,7 @@ typedef enum {
TMM_DECODEERFDAG,
TMM_RECEIVEAFP,
TMM_DECODEAFP,
TMM_ALERTPCAPINFO,
TMM_SIZE,
} TmmId;

@ -77,6 +77,13 @@ outputs:
filename: http.log
append: yes
# a line based log to used with pcap file study.
# this module is dedicated to offline pcap parsing (empty output
# if used with an other kind of input). It can interoperate with
# pcap parser like wireshark via the suriwire plugin.
- pcap-info:
enabled: no
# Packet log... log packets in pcap format. 2 modes of operation: "normal"
# and "sguil".
#

Loading…
Cancel
Save