1
/* Copyright (C) 2011 Open Information Security Foundation
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
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.
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
21
* \author Eric Leblond <eric@regit.org>
23
* Logs alerts in a line based text format suitable for interaction
24
* with wireshark or an other pcap file analysis tools.
26
* The format of the logging is:
27
* Packet number:GID of matching signature:SID of signature:REV of signature:Flow:To Server:To Client:0:0:Signature Message
28
* The two zeros are reserved for upcoming usage (probably byte start
29
* and byte end of payload)
32
#include "suricata-common.h"
39
#include "tm-threads.h"
40
#include "threadvars.h"
41
#include "util-debug.h"
43
#include "util-unittest.h"
44
#include "util-unittest-helper.h"
47
#include "detect-parse.h"
48
#include "detect-engine.h"
49
#include "detect-engine-mpm.h"
50
#include "detect-reference.h"
51
#include "util-classification-config.h"
54
#include "alert-pcapinfo.h"
56
#include "util-mpm-b2g-cuda.h"
57
#include "util-cuda-handlers.h"
58
#include "util-privs.h"
59
#include "util-print.h"
60
#include "util-proto-name.h"
61
#include "util-optimize.h"
63
#define DEFAULT_LOG_FILENAME "alert-pcapinfo.log"
64
/* We need a new file for each pcap */
65
#define DEFAULT_PCAPINFO_MODE_APPEND "no"
67
#define MODULE_NAME "AlertPcapInfo"
69
TmEcode AlertPcapInfo (ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *);
70
TmEcode AlertPcapInfoThreadInit(ThreadVars *, void *, void **);
71
TmEcode AlertPcapInfoThreadDeinit(ThreadVars *, void *);
72
void AlertPcapInfoExitPrintStats(ThreadVars *, void *);
73
static int AlertPcapInfoOpenFileCtx(LogFileCtx *, const char *, const char *);
74
static void AlertPcapInfoDeInitCtx(OutputCtx *);
76
void TmModuleAlertPcapInfoRegister (void) {
77
tmm_modules[TMM_ALERTPCAPINFO].name = MODULE_NAME;
78
tmm_modules[TMM_ALERTPCAPINFO].ThreadInit = AlertPcapInfoThreadInit;
79
tmm_modules[TMM_ALERTPCAPINFO].Func = AlertPcapInfo;
80
tmm_modules[TMM_ALERTPCAPINFO].ThreadExitPrintStats = AlertPcapInfoExitPrintStats;
81
tmm_modules[TMM_ALERTPCAPINFO].ThreadDeinit = AlertPcapInfoThreadDeinit;
82
tmm_modules[TMM_ALERTPCAPINFO].RegisterTests = NULL;
83
tmm_modules[TMM_ALERTPCAPINFO].cap_flags = 0;
85
OutputRegisterModule(MODULE_NAME, "pcap-info", AlertPcapInfoInitCtx);
88
typedef struct AlertPcapInfoThread_ {
89
/** LogFileCtx has the pointer to the file and a mutex to allow multithreading */
91
} AlertPcapInfoThread;
94
TmEcode AlertPcapInfo (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
96
AlertPcapInfoThread *aft = (AlertPcapInfoThread *)data;
100
/* logging is useless if we don't have pcap number */
101
if ((p->pcap_cnt != 0) && (p->alerts.cnt > 0)) {
102
SCMutexLock(&aft->file_ctx->fp_mutex);
103
/* only count logged alert */
104
aft->file_ctx->alerts += p->alerts.cnt;
105
for (i = 0; i < p->alerts.cnt; i++) {
106
PacketAlert *pa = &p->alerts.alerts[i];
108
fprintf(aft->file_ctx->fp, "%" PRIu64 ":%" PRIu32 ":%" PRIu32 ":%d:%d:%d:%d:0:0:%s\n",
109
p->pcap_cnt, pa->s->gid, pa->s->id,
110
pa->s->rev, pa->alert_msg ? 1 : 0,
111
p->flowflags & FLOW_PKT_TOSERVER ? 1 : 0,
112
p->flowflags & FLOW_PKT_TOCLIENT ? 1 : 0,
115
SCMutexUnlock(&aft->file_ctx->fp_mutex);
121
TmEcode AlertPcapInfoThreadInit(ThreadVars *t, void *initdata, void **data)
123
AlertPcapInfoThread *aft = SCMalloc(sizeof(AlertPcapInfoThread));
125
return TM_ECODE_FAILED;
126
memset(aft, 0, sizeof(AlertPcapInfoThread));
129
SCLogDebug("Error getting context for AlertPcapInfo. \"initdata\" argument NULL");
131
return TM_ECODE_FAILED;
133
/** Use the Ouptut Context (file pointer and mutex) */
134
aft->file_ctx = ((OutputCtx *)initdata)->data;
140
TmEcode AlertPcapInfoThreadDeinit(ThreadVars *t, void *data)
142
AlertPcapInfoThread *aft = (AlertPcapInfoThread *)data;
148
memset(aft, 0, sizeof(AlertPcapInfoThread));
154
void AlertPcapInfoExitPrintStats(ThreadVars *tv, void *data) {
155
AlertPcapInfoThread *aft = (AlertPcapInfoThread *)data;
160
SCLogInfo("(%s) Alerts %" PRIu64 "", tv->name, aft->file_ctx->alerts);
164
* \brief Create a new LogFileCtx for "fast" output style.
165
* \param conf The configuration node for this output.
166
* \return A LogFileCtx pointer on success, NULL on failure.
168
OutputCtx *AlertPcapInfoInitCtx(ConfNode *conf)
170
LogFileCtx *logfile_ctx = LogFileNewCtx();
171
if (logfile_ctx == NULL) {
172
SCLogDebug("AlertPcapInfoInitCtx2: Could not create new LogFileCtx");
176
const char *filename = ConfNodeLookupChildValue(conf, "filename");
177
if (filename == NULL)
178
filename = DEFAULT_LOG_FILENAME;
180
const char *mode = ConfNodeLookupChildValue(conf, "append");
182
mode = DEFAULT_PCAPINFO_MODE_APPEND;
184
if (AlertPcapInfoOpenFileCtx(logfile_ctx, filename, mode) < 0) {
185
LogFileFreeCtx(logfile_ctx);
189
OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
190
if (output_ctx == NULL)
192
output_ctx->data = logfile_ctx;
193
output_ctx->DeInit = AlertPcapInfoDeInitCtx;
195
SCLogInfo("Fast log output initialized, filename: %s", filename);
200
static void AlertPcapInfoDeInitCtx(OutputCtx *output_ctx)
202
LogFileCtx *logfile_ctx = (LogFileCtx *)output_ctx->data;
203
LogFileFreeCtx(logfile_ctx);
207
/** \brief Read the config set the file pointer, open the file
208
* \param file_ctx pointer to a created LogFileCtx using LogFileNewCtx()
209
* \param filename name of log file
210
* \param mode append mode (bool)
211
* \return -1 if failure, 0 if succesful
213
static int AlertPcapInfoOpenFileCtx(LogFileCtx *file_ctx, const char *filename,
216
char log_path[PATH_MAX];
219
if (ConfGet("default-log-dir", &log_dir) != 1)
220
log_dir = DEFAULT_LOG_DIR;
222
snprintf(log_path, PATH_MAX, "%s/%s", log_dir, filename);
224
if (ConfValIsTrue(mode)) {
225
file_ctx->fp = fopen(log_path, "a");
227
file_ctx->fp = fopen(log_path, "w");
230
if (file_ctx->fp == NULL) {
231
SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", log_path,