~ubuntu-branches/ubuntu/utopic/suricata/utopic

« back to all changes in this revision

Viewing changes to src/alert-pcapinfo.c

  • Committer: Package Import Robot
  • Author(s): Pierre Chifflier
  • Date: 2011-11-17 23:20:51 UTC
  • mfrom: (1.1.10)
  • Revision ID: package-import@ubuntu.com-20111117232051-wlo0g2fyinx0zi25
Tags: 1.1-1
* Imported Upstream version 1.1
* Add instructions on getting new rules using oinkmaster
* Add Recommends on oinkmaster
* Move snort-rules-default to Recommends

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2011 Open Information Security Foundation
 
2
 *
 
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
 
5
 * Software Foundation.
 
6
 *
 
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.
 
11
 *
 
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
 
15
 * 02110-1301, USA.
 
16
 */
 
17
 
 
18
/**
 
19
 * \file
 
20
 *
 
21
 * \author Eric Leblond <eric@regit.org>
 
22
 *
 
23
 * Logs alerts in a line based text format suitable for interaction
 
24
 * with wireshark or an other pcap file analysis tools.
 
25
 *
 
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)
 
30
 */
 
31
 
 
32
#include "suricata-common.h"
 
33
#include "debug.h"
 
34
#include "detect.h"
 
35
#include "flow.h"
 
36
#include "conf.h"
 
37
 
 
38
#include "threads.h"
 
39
#include "tm-threads.h"
 
40
#include "threadvars.h"
 
41
#include "util-debug.h"
 
42
 
 
43
#include "util-unittest.h"
 
44
#include "util-unittest-helper.h"
 
45
 
 
46
#include "detect.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"
 
52
 
 
53
#include "output.h"
 
54
#include "alert-pcapinfo.h"
 
55
 
 
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"
 
62
 
 
63
#define DEFAULT_LOG_FILENAME "alert-pcapinfo.log"
 
64
/* We need a new file for each pcap */
 
65
#define DEFAULT_PCAPINFO_MODE_APPEND "no"
 
66
 
 
67
#define MODULE_NAME "AlertPcapInfo"
 
68
 
 
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 *);
 
75
 
 
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;
 
84
 
 
85
    OutputRegisterModule(MODULE_NAME, "pcap-info", AlertPcapInfoInitCtx);
 
86
}
 
87
 
 
88
typedef struct AlertPcapInfoThread_ {
 
89
    /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */
 
90
    LogFileCtx* file_ctx;
 
91
} AlertPcapInfoThread;
 
92
 
 
93
 
 
94
TmEcode AlertPcapInfo (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
 
95
{
 
96
    AlertPcapInfoThread *aft = (AlertPcapInfoThread *)data;
 
97
    int i;
 
98
 
 
99
 
 
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];
 
107
 
 
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,
 
113
                    pa->s->msg);
 
114
        }
 
115
        SCMutexUnlock(&aft->file_ctx->fp_mutex);
 
116
    }
 
117
 
 
118
    return TM_ECODE_OK;
 
119
}
 
120
 
 
121
TmEcode AlertPcapInfoThreadInit(ThreadVars *t, void *initdata, void **data)
 
122
{
 
123
    AlertPcapInfoThread *aft = SCMalloc(sizeof(AlertPcapInfoThread));
 
124
    if (aft == NULL)
 
125
        return TM_ECODE_FAILED;
 
126
    memset(aft, 0, sizeof(AlertPcapInfoThread));
 
127
    if(initdata == NULL)
 
128
    {
 
129
        SCLogDebug("Error getting context for AlertPcapInfo.  \"initdata\" argument NULL");
 
130
        SCFree(aft);
 
131
        return TM_ECODE_FAILED;
 
132
    }
 
133
    /** Use the Ouptut Context (file pointer and mutex) */
 
134
    aft->file_ctx = ((OutputCtx *)initdata)->data;
 
135
 
 
136
    *data = (void *)aft;
 
137
    return TM_ECODE_OK;
 
138
}
 
139
 
 
140
TmEcode AlertPcapInfoThreadDeinit(ThreadVars *t, void *data)
 
141
{
 
142
    AlertPcapInfoThread *aft = (AlertPcapInfoThread *)data;
 
143
    if (aft == NULL) {
 
144
        return TM_ECODE_OK;
 
145
    }
 
146
 
 
147
    /* clear memory */
 
148
    memset(aft, 0, sizeof(AlertPcapInfoThread));
 
149
 
 
150
    SCFree(aft);
 
151
    return TM_ECODE_OK;
 
152
}
 
153
 
 
154
void AlertPcapInfoExitPrintStats(ThreadVars *tv, void *data) {
 
155
    AlertPcapInfoThread *aft = (AlertPcapInfoThread *)data;
 
156
    if (aft == NULL) {
 
157
        return;
 
158
    }
 
159
 
 
160
    SCLogInfo("(%s) Alerts %" PRIu64 "", tv->name, aft->file_ctx->alerts);
 
161
}
 
162
 
 
163
/**
 
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.
 
167
 */
 
168
OutputCtx *AlertPcapInfoInitCtx(ConfNode *conf)
 
169
{
 
170
    LogFileCtx *logfile_ctx = LogFileNewCtx();
 
171
    if (logfile_ctx == NULL) {
 
172
        SCLogDebug("AlertPcapInfoInitCtx2: Could not create new LogFileCtx");
 
173
        return NULL;
 
174
    }
 
175
 
 
176
    const char *filename = ConfNodeLookupChildValue(conf, "filename");
 
177
    if (filename == NULL)
 
178
        filename = DEFAULT_LOG_FILENAME;
 
179
 
 
180
    const char *mode = ConfNodeLookupChildValue(conf, "append");
 
181
    if (mode == NULL)
 
182
        mode = DEFAULT_PCAPINFO_MODE_APPEND;
 
183
 
 
184
    if (AlertPcapInfoOpenFileCtx(logfile_ctx, filename, mode) < 0) {
 
185
        LogFileFreeCtx(logfile_ctx);
 
186
        return NULL;
 
187
    }
 
188
 
 
189
    OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
 
190
    if (output_ctx == NULL)
 
191
        return NULL;
 
192
    output_ctx->data = logfile_ctx;
 
193
    output_ctx->DeInit = AlertPcapInfoDeInitCtx;
 
194
 
 
195
    SCLogInfo("Fast log output initialized, filename: %s", filename);
 
196
 
 
197
    return output_ctx;
 
198
}
 
199
 
 
200
static void AlertPcapInfoDeInitCtx(OutputCtx *output_ctx)
 
201
{
 
202
    LogFileCtx *logfile_ctx = (LogFileCtx *)output_ctx->data;
 
203
    LogFileFreeCtx(logfile_ctx);
 
204
    SCFree(output_ctx);
 
205
}
 
206
 
 
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
 
212
 * */
 
213
static int AlertPcapInfoOpenFileCtx(LogFileCtx *file_ctx, const char *filename,
 
214
                                    const char *mode)
 
215
{
 
216
    char log_path[PATH_MAX];
 
217
    char *log_dir;
 
218
 
 
219
    if (ConfGet("default-log-dir", &log_dir) != 1)
 
220
        log_dir = DEFAULT_LOG_DIR;
 
221
 
 
222
    snprintf(log_path, PATH_MAX, "%s/%s", log_dir, filename);
 
223
 
 
224
    if (ConfValIsTrue(mode)) {
 
225
        file_ctx->fp = fopen(log_path, "a");
 
226
    } else {
 
227
        file_ctx->fp = fopen(log_path, "w");
 
228
    }
 
229
 
 
230
    if (file_ctx->fp == NULL) {
 
231
        SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", log_path,
 
232
                strerror(errno));
 
233
        return -1;
 
234
    }
 
235
 
 
236
    return 0;
 
237
}