[Oisf-devel] [Reworked PATCH] Add pcap-info alert format.

Eric Leblond eric at regit.org
Wed Oct 5 12:09:57 UTC 2011


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.
---
 src/Makefile.am         |    1 +
 src/alert-pcapinfo.c    |  237 +++++++++++++++++++++++++++++++++++++++++++++++
 src/alert-pcapinfo.h    |   31 ++++++
 src/suricata.c          |    2 +
 src/tm-threads-common.h |    1 +
 suricata.yaml           |    7 ++
 6 files changed, 279 insertions(+), 0 deletions(-)
 create mode 100644 src/alert-pcapinfo.c
 create mode 100644 src/alert-pcapinfo.h

diff --git a/src/Makefile.am b/src/Makefile.am
index 3b490e9..5e98e9c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -227,6 +227,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 \
diff --git a/src/alert-pcapinfo.c b/src/alert-pcapinfo.c
new file mode 100644
index 0000000..e487ccf
--- /dev/null
+++ b/src/alert-pcapinfo.c
@@ -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 at 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;
+}
diff --git a/src/alert-pcapinfo.h b/src/alert-pcapinfo.h
new file mode 100644
index 0000000..203409f
--- /dev/null
+++ b/src/alert-pcapinfo.h
@@ -0,0 +1,31 @@
+/* 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 at regit.org>
+ */
+
+#ifndef __ALERT_PCAPINFO_H__
+#define __ALERT_PCAPINFO_H__
+
+void TmModuleAlertPcapInfoRegister (void);
+OutputCtx *AlertPcapInfoInitCtx(ConfNode *);
+
+#endif /* __ALERT_PCAPINFO_H__ */
+
diff --git a/src/suricata.c b/src/suricata.c
index 3524bfb..a13d222 100644
--- a/src/suricata.c
+++ b/src/suricata.c
@@ -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"
@@ -1179,6 +1180,7 @@ int main(int argc, char **argv)
     TmModuleAlertUnifiedAlertRegister();
     TmModuleUnified2AlertRegister();
     TmModuleAlertSyslogRegister();
+    TmModuleAlertPcapInfoRegister();
     TmModuleLogDropLogRegister();
     TmModuleStreamTcpRegister();
     TmModuleLogHttpLogRegister();
diff --git a/src/tm-threads-common.h b/src/tm-threads-common.h
index 7b075da..d506cd1 100644
--- a/src/tm-threads-common.h
+++ b/src/tm-threads-common.h
@@ -72,6 +72,7 @@ typedef enum {
     TMM_DECODEERFDAG,
     TMM_RECEIVEAFP,
     TMM_DECODEAFP,
+    TMM_ALERTPCAPINFO,
     TMM_SIZE,
 } TmmId;
 
diff --git a/suricata.yaml b/suricata.yaml
index 4eb185e..825cde3 100644
--- a/suricata.yaml
+++ b/suricata.yaml
@@ -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".
   #
-- 
1.7.6.3




More information about the Oisf-devel mailing list