You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
suricata/src/suricata.c

2774 lines
92 KiB
C

/* Copyright (C) 2007-2014 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 Victor Julien <victor@inliniac.net>
*/
#include "suricata-common.h"
#include "config.h"
#if HAVE_GETOPT_H
#include <getopt.h>
#endif
#if HAVE_SIGNAL_H
#include <signal.h>
#endif
#ifdef HAVE_NSS
#include <prinit.h>
#include <nss.h>
#endif
#include "suricata.h"
#include "decode.h"
#include "detect.h"
#include "packet-queue.h"
#include "threads.h"
#include "threadvars.h"
#include "flow-worker.h"
#include "util-atomic.h"
#include "util-spm.h"
#include "util-cpu.h"
#include "util-action.h"
#include "util-pidfile.h"
#include "util-ioctl.h"
#include "util-device.h"
#include "util-misc.h"
#include "util-running-modes.h"
#include "detect-engine.h"
#include "detect-parse.h"
#include "detect-fast-pattern.h"
#include "detect-engine-tag.h"
#include "detect-engine-threshold.h"
#include "detect-engine-address.h"
#include "detect-engine-port.h"
#include "detect-engine-mpm.h"
#include "tm-queuehandlers.h"
#include "tm-queues.h"
#include "tm-threads.h"
#include "tmqh-flow.h"
#include "conf.h"
#include "conf-yaml-loader.h"
#include "stream-tcp.h"
#include "source-nfq.h"
#include "source-nfq-prototypes.h"
13 years ago
#include "source-nflog.h"
#include "source-ipfw.h"
#include "source-pcap.h"
#include "source-pcap-file.h"
#include "source-pfring.h"
#include "source-erf-file.h"
#include "source-erf-dag.h"
#include "source-napatech.h"
#include "source-af-packet.h"
12 years ago
#include "source-netmap.h"
Add TILE-Gx mPIPE packet processing support. The TILE-Gx processor includes a packet processing engine, called mPIPE, that can deliver packets directly into user space memory. It handles buffer allocation and load balancing (either static 5-tuple hashing, or dynamic flow affinity hashing are used here). The new packet source code is in source-mpipe.c and source-mpipe.h A new Tile runmode is added that configures the Suricata pipelines in worker mode, where each thread does the entire packet processing pipeline. It scales across all the Gx chips sizes of 9, 16, 36 or 72 cores. The new runmode is in runmode-tile.c and runmode-tile.h The configure script detects the TILE-Gx architecture and defines HAVE_MPIPE, which is then used to conditionally enable the code to support mPIPE packet processing. Suricata runs on TILE-Gx even without mPIPE support enabled. The Suricata Packet structures are allocated by the mPIPE hardware by allocating the Suricata Packet structure immediatley before the mPIPE packet buffer and then pushing the mPIPE packet buffer pointer onto the mPIPE buffer stack. This way, mPIPE writes the packet data into the buffer, returns the mPIPE packet buffer pointer, which is then converted into a Suricata Packet pointer for processing inside Suricata. When the Packet is freed, the buffer is returned to mPIPE's buffer stack, by setting ReleasePacket to an mPIPE release specific function. The code checks for the largest Huge page available in Linux when Suricata is started. TILE-Gx supports Huge pages sizes of 16MB, 64MB, 256MB, 1GB and 4GB. Suricata then divides one of those page into packet buffers for mPIPE. The code is not yet optimized for high performance. Performance improvements will follow shortly. The code was originally written by Tom Decanio and then further modified by Tilera. This code has been tested with Tilera's Multicore Developement Environment (MDE) version 4.1.5. The TILEncore-Gx36 (PCIe card) and TILEmpower-Gx (1U Rack mount).
13 years ago
#include "source-mpipe.h"
#include "respond-reject.h"
#include "flow.h"
#include "flow-timeout.h"
#include "flow-manager.h"
#include "flow-var.h"
#include "flow-bit.h"
#include "pkt-var.h"
#include "host-bit.h"
#include "ippair.h"
#include "ippair-bit.h"
#include "host.h"
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
#include "unix-manager.h"
App layer API rewritten. The main files in question are: app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch]. Things addressed in this commit: - Brings out a proper separation between protocol detection phase and the parser phase. - The dns app layer now is registered such that we don't use "dnstcp" and "dnsudp" in the rules. A user who previously wrote a rule like this - "alert dnstcp....." or "alert dnsudp....." would now have to use, alert dns (ipproto:tcp;) or alert udp (app-layer-protocol:dns;) or alert ip (ipproto:udp; app-layer-protocol:dns;) The same rules extend to other another such protocol, dcerpc. - The app layer parser api now takes in the ipproto while registering callbacks. - The app inspection/detection engine also takes an ipproto. - All app layer parser functions now take direction as STREAM_TOSERVER or STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the functions. - FlowInitialize() and FlowRecycle() now resets proto to 0. This is needed by unittests, which would try to clean the flow, and that would call the api, AppLayerParserCleanupParserState(), which would try to clean the app state, but the app layer now needs an ipproto to figure out which api to internally call to clean the state, and if the ipproto is 0, it would return without trying to clean the state. - A lot of unittests are now updated where if they are using a flow and they need to use the app layer, we would set a flow ipproto. - The "app-layer" section in the yaml conf has also been updated as well.
13 years ago
#include "app-layer.h"
#include "app-layer-parser.h"
#include "app-layer-htp.h"
#include "app-layer-ssl.h"
#include "app-layer-dns-tcp.h"
#include "app-layer-ssh.h"
#include "app-layer-ftp.h"
#include "app-layer-smtp.h"
#include "app-layer-smb.h"
#include "app-layer-modbus.h"
#include "app-layer-enip.h"
#include "util-decode-der.h"
#include "util-radix-tree.h"
#include "util-host-os-info.h"
#include "util-cidr.h"
#include "util-unittest.h"
#include "util-unittest-helper.h"
#include "util-time.h"
#include "util-rule-vars.h"
#include "util-classification-config.h"
#include "util-threshold-config.h"
#include "util-reference-config.h"
#include "util-profiling.h"
#include "util-magic.h"
#include "util-signal.h"
#include "util-coredump-config.h"
#include "util-decode-mime.h"
#include "defrag.h"
#include "runmodes.h"
#include "runmode-unittests.h"
17 years ago
#include "util-cuda.h"
#include "util-decode-asn1.h"
#include "util-debug.h"
#include "util-error.h"
#include "util-daemon.h"
#include "reputation.h"
#include "output.h"
#include "util-privs.h"
#include "tmqh-packetpool.h"
#include "util-proto-name.h"
#ifdef __SC_CUDA_SUPPORT__
#include "util-cuda-buffer.h"
#include "util-mpm-ac.h"
#endif
#include "util-mpm-hs.h"
#include "util-storage.h"
#include "host-storage.h"
/*
* we put this here, because we only use it here in main.
*/
17 years ago
volatile sig_atomic_t sigint_count = 0;
volatile sig_atomic_t sighup_count = 0;
volatile sig_atomic_t sigterm_count = 0;
volatile sig_atomic_t sigusr2_count = 0;
/*
* Flag to indicate if the engine is at the initialization
* or already processing packets. 3 stages: SURICATA_INIT,
* SURICATA_RUNTIME and SURICATA_FINALIZE
*/
SC_ATOMIC_DECLARE(unsigned int, engine_stage);
/* Max packets processed simultaniously per thread. */
#define DEFAULT_MAX_PENDING_PACKETS 1024
/** suricata engine control flags */
volatile uint8_t suricata_ctl_flags = 0;
/** Run mode selected */
int run_mode = RUNMODE_UNKNOWN;
/** Engine mode: inline (ENGINE_MODE_IPS) or just
* detection mode (ENGINE_MODE_IDS by default) */
static enum EngineMode g_engine_mode = ENGINE_MODE_IDS;
/** Host mode: set if box is sniffing only
* or is a router */
uint8_t host_mode = SURI_HOST_IS_SNIFFER_ONLY;
/** Maximum packets to simultaneously process. */
intmax_t max_pending_packets;
/** global indicating if detection is enabled */
int g_detect_disabled = 0;
/** set caps or not */
int sc_set_caps;
int EngineModeIsIPS(void)
{
return (g_engine_mode == ENGINE_MODE_IPS);
}
int EngineModeIsIDS(void)
{
return (g_engine_mode == ENGINE_MODE_IDS);
}
void EngineModeSetIPS(void)
{
g_engine_mode = ENGINE_MODE_IPS;
}
void EngineModeSetIDS(void)
{
g_engine_mode = ENGINE_MODE_IDS;
}
int RunmodeIsUnittests(void)
{
if (run_mode == RUNMODE_UNITTEST)
return 1;
return 0;
}
int RunmodeGetCurrent(void)
{
return run_mode;
}
signals: cleanup signal handling Simplify handling of USR2 signal. The SCLogInfo usage could lead to dead locks as the SCLog API can do many complicated things including memory allocations, syslog calls, libjansson message construction. If an existing malloc call was interupted, it could lead to the following dead lock: 0 __lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:97 1 0x0000003140c7d2df in _L_lock_10176 () from /lib64/libc.so.6 2 0x0000003140c7ab83 in __libc_malloc (bytes=211543457408) at malloc.c:3655 3 0x0000003140c80ec2 in __strdup (s=0x259ca40 "[%i] %t - (%f:%l) <%d> (%n) -- ") at strdup.c:43 4 0x000000000059dd4a in SCLogMessageGetBuffer (tval=0x7fff52b47360, color=1, type=SC_LOG_OP_TYPE_REGULAR, buffer=0x7fff52b47370 "", buffer_size=2048, log_format=0x259ca40 "[%i] %t - (%f:%l) <%d> (%n) -- ", log_level=SC_LOG_INFO, file=0x63dd00 "suricata.c", line=287, function=0x640f50 "SignalHandlerSigusr2StartingUp", error_code=SC_OK, message=0x7fff52b47bb0 "Live rule reload only possible after engine completely started.") at util-debug.c:307 5 0x000000000059e940 in SCLogMessage (log_level=SC_LOG_INFO, file=0x63dd00 "suricata.c", line=287, function=0x640f50 "SignalHandlerSigusr2StartingUp", error_code=SC_OK, message=0x7fff52b47bb0 "Live rule reload only possible after engine completely started.") at util-debug.c:549 6 0x000000000057e374 in SignalHandlerSigusr2StartingUp (sig=12) at suricata.c:287 7 <signal handler called> 8 _int_malloc (av=0x3140f8fe80, bytes=<value optimized out>) at malloc.c:4751 9 0x0000003140c7ab1c in __libc_malloc (bytes=296) at malloc.c:3657 10 0x0000000000504d55 in FlowAlloc () at flow-util.c:60 11 0x00000000004fd909 in FlowInitConfig (quiet=0 '\000') at flow.c:454 12 0x0000000000584c8e in main (argc=6, argv=0x7fff52b4a3b8) at suricata.c:2300 This patch simply sets a variable and lets the main loop act on that.
11 years ago
/** signal handlers
*
* WARNING: don't use the SCLog* API in the handlers. The API is complex
* with memory allocation possibly happening, calls to syslog, json message
* construction, etc.
*/
static void SignalHandlerSigint(/*@unused@*/ int sig)
{
sigint_count = 1;
}
static void SignalHandlerSigterm(/*@unused@*/ int sig)
{
sigterm_count = 1;
}
/**
* SIGUSR2 handler. Just set sigusr2_count. The main loop will act on
* it.
*/
signals: cleanup signal handling Simplify handling of USR2 signal. The SCLogInfo usage could lead to dead locks as the SCLog API can do many complicated things including memory allocations, syslog calls, libjansson message construction. If an existing malloc call was interupted, it could lead to the following dead lock: 0 __lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:97 1 0x0000003140c7d2df in _L_lock_10176 () from /lib64/libc.so.6 2 0x0000003140c7ab83 in __libc_malloc (bytes=211543457408) at malloc.c:3655 3 0x0000003140c80ec2 in __strdup (s=0x259ca40 "[%i] %t - (%f:%l) <%d> (%n) -- ") at strdup.c:43 4 0x000000000059dd4a in SCLogMessageGetBuffer (tval=0x7fff52b47360, color=1, type=SC_LOG_OP_TYPE_REGULAR, buffer=0x7fff52b47370 "", buffer_size=2048, log_format=0x259ca40 "[%i] %t - (%f:%l) <%d> (%n) -- ", log_level=SC_LOG_INFO, file=0x63dd00 "suricata.c", line=287, function=0x640f50 "SignalHandlerSigusr2StartingUp", error_code=SC_OK, message=0x7fff52b47bb0 "Live rule reload only possible after engine completely started.") at util-debug.c:307 5 0x000000000059e940 in SCLogMessage (log_level=SC_LOG_INFO, file=0x63dd00 "suricata.c", line=287, function=0x640f50 "SignalHandlerSigusr2StartingUp", error_code=SC_OK, message=0x7fff52b47bb0 "Live rule reload only possible after engine completely started.") at util-debug.c:549 6 0x000000000057e374 in SignalHandlerSigusr2StartingUp (sig=12) at suricata.c:287 7 <signal handler called> 8 _int_malloc (av=0x3140f8fe80, bytes=<value optimized out>) at malloc.c:4751 9 0x0000003140c7ab1c in __libc_malloc (bytes=296) at malloc.c:3657 10 0x0000000000504d55 in FlowAlloc () at flow-util.c:60 11 0x00000000004fd909 in FlowInitConfig (quiet=0 '\000') at flow.c:454 12 0x0000000000584c8e in main (argc=6, argv=0x7fff52b4a3b8) at suricata.c:2300 This patch simply sets a variable and lets the main loop act on that.
11 years ago
static void SignalHandlerSigusr2(int sig)
{
if (sigusr2_count < 16) {
sigusr2_count++;
} else {
SCLogWarning(SC_ERR_LIVE_RULE_SWAP, "Too many USR2 signals pending, ignoring new ones!");
}
}
/**
* SIGHUP handler. Just set sighup_count. The main loop will act on
* it.
*/
static void SignalHandlerSigHup(/*@unused@*/ int sig)
{
sighup_count = 1;
}
#ifdef DBG_MEM_ALLOC
#ifndef _GLOBAL_MEM_
#define _GLOBAL_MEM_
/* This counter doesn't complain realloc's(), it's gives
* an aproximation for the startup */
size_t global_mem = 0;
#ifdef DBG_MEM_ALLOC_SKIP_STARTUP
uint8_t print_mem_flag = 0;
#else
uint8_t print_mem_flag = 1;
#endif
#endif
#endif
void CreateLowercaseTable()
{
/* create table for O(1) lowercase conversion lookup. It was removed, but
* we still need it for cuda. So resintalling it back into the codebase */
int c = 0;
memset(g_u8_lowercasetable, 0x00, sizeof(g_u8_lowercasetable));
for ( ; c < 256; c++) {
if (c >= 'A' && c <= 'Z')
g_u8_lowercasetable[c] = (c + ('a' - 'A'));
else
g_u8_lowercasetable[c] = c;
}
}
void GlobalInits()
{
memset(trans_q, 0, sizeof(trans_q));
memset(data_queues, 0, sizeof(data_queues));
/* Initialize the trans_q mutex */
int blah;
int r = 0;
for(blah=0;blah<256;blah++) {
r |= SCMutexInit(&trans_q[blah].mutex_q, NULL);
r |= SCCondInit(&trans_q[blah].cond_q, NULL);
r |= SCMutexInit(&data_queues[blah].mutex_q, NULL);
r |= SCCondInit(&data_queues[blah].cond_q, NULL);
}
if (r != 0) {
SCLogInfo("Trans_Q Mutex not initialized correctly");
exit(EXIT_FAILURE);
}
CreateLowercaseTable();
}
/** \brief make sure threads can stop the engine by calling this
* function. Purpose: pcap file mode needs to be able to tell the
* engine the file eof is reached. */
void EngineStop(void)
{
suricata_ctl_flags |= SURICATA_STOP;
}
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
/**
* \brief Used to indicate that the current task is done.
*
* This is mainly used by pcap-file to tell it has finished
* to treat a pcap files when running in unix-socket mode.
*/
void EngineDone(void)
{
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
suricata_ctl_flags |= SURICATA_DONE;
}
static int SetBpfString(int optind, char *argv[])
{
char *bpf_filter = NULL;
uint32_t bpf_len = 0;
int tmpindex = 0;
/* attempt to parse remaining args as bpf filter */
tmpindex = optind;
while(argv[tmpindex] != NULL) {
bpf_len+=strlen(argv[tmpindex]) + 1;
tmpindex++;
}
if (bpf_len == 0)
return TM_ECODE_OK;
if (EngineModeIsIPS()) {
SCLogError(SC_ERR_NOT_SUPPORTED,
"BPF filter not available in IPS mode."
" Use firewall filtering if possible.");
return TM_ECODE_FAILED;
}
bpf_filter = SCMalloc(bpf_len);
if (unlikely(bpf_filter == NULL))
return TM_ECODE_OK;
memset(bpf_filter, 0x00, bpf_len);
tmpindex = optind;
while(argv[tmpindex] != NULL) {
strlcat(bpf_filter, argv[tmpindex],bpf_len);
if(argv[tmpindex + 1] != NULL) {
strlcat(bpf_filter," ", bpf_len);
}
tmpindex++;
}
if(strlen(bpf_filter) > 0) {
if (ConfSetFinal("bpf-filter", bpf_filter) != 1) {
SCLogError(SC_ERR_FATAL, "Failed to set bpf filter.");
SCFree(bpf_filter);
return TM_ECODE_FAILED;
}
}
SCFree(bpf_filter);
return TM_ECODE_OK;
}
static void SetBpfStringFromFile(char *filename)
{
char *bpf_filter = NULL;
char *bpf_comment_tmp = NULL;
char *bpf_comment_start = NULL;
uint32_t bpf_len = 0;
#ifdef OS_WIN32
struct _stat st;
#else
struct stat st;
#endif /* OS_WIN32 */
FILE *fp = NULL;
size_t nm = 0;
if (EngineModeIsIPS()) {
SCLogError(SC_ERR_NOT_SUPPORTED,
"BPF filter not available in IPS mode."
" Use firewall filtering if possible.");
exit(EXIT_FAILURE);
}
#ifdef OS_WIN32
if(_stat(filename, &st) != 0) {
#else
if(stat(filename, &st) != 0) {
#endif /* OS_WIN32 */
SCLogError(SC_ERR_FOPEN, "Failed to stat file %s", filename);
exit(EXIT_FAILURE);
}
bpf_len = st.st_size + 1;
fp = fopen(filename,"r");
if (fp == NULL) {
SCLogError(SC_ERR_FOPEN, "Failed to open file %s", filename);
exit(EXIT_FAILURE);
}
bpf_filter = SCMalloc(bpf_len * sizeof(char));
if (unlikely(bpf_filter == NULL)) {
SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate buffer for bpf filter in file %s", filename);
exit(EXIT_FAILURE);
}
memset(bpf_filter, 0x00, bpf_len);
nm = fread(bpf_filter, 1, bpf_len - 1, fp);
if ((ferror(fp) != 0) || (nm != (bpf_len - 1))) {
SCLogError(SC_ERR_BPF, "Failed to read complete BPF file %s", filename);
SCFree(bpf_filter);
fclose(fp);
exit(EXIT_FAILURE);
}
fclose(fp);
bpf_filter[nm] = '\0';
if(strlen(bpf_filter) > 0) {
/*replace comments with space*/
bpf_comment_start = bpf_filter;
while((bpf_comment_tmp = strchr(bpf_comment_start, '#')) != NULL) {
while((*bpf_comment_tmp !='\0') &&
(*bpf_comment_tmp != '\r') && (*bpf_comment_tmp != '\n'))
{
*bpf_comment_tmp++ = ' ';
}
bpf_comment_start = bpf_comment_tmp;
}
/*remove remaining '\r' and '\n' */
while((bpf_comment_tmp = strchr(bpf_filter, '\r')) != NULL) {
*bpf_comment_tmp = ' ';
}
while((bpf_comment_tmp = strchr(bpf_filter, '\n')) != NULL) {
*bpf_comment_tmp = ' ';
}
/* cut trailing spaces */
while (strlen(bpf_filter) > 0 &&
bpf_filter[strlen(bpf_filter)-1] == ' ')
{
bpf_filter[strlen(bpf_filter)-1] = '\0';
}
if (strlen(bpf_filter) > 0) {
if(ConfSetFinal("bpf-filter", bpf_filter) != 1) {
SCLogError(SC_ERR_FOPEN, "ERROR: Failed to set bpf filter!");
SCFree(bpf_filter);
exit(EXIT_FAILURE);
}
}
}
SCFree(bpf_filter);
}
17 years ago
void usage(const char *progname)
{
#ifdef REVISION
printf("%s %s (rev %s)\n", PROG_NAME, PROG_VER, xstr(REVISION));
#else
printf("%s %s\n", PROG_NAME, PROG_VER);
#endif
printf("USAGE: %s [OPTIONS] [BPF FILTER]\n\n", progname);
printf("\t-c <path> : path to configuration file\n");
printf("\t-T : test configuration file (use with -c)\n");
printf("\t-i <dev or ip> : run in pcap live mode\n");
printf("\t-F <bpf filter file> : bpf filter file\n");
printf("\t-r <path> : run in pcap file/offline mode\n");
#ifdef NFQ
printf("\t-q <qid> : run in inline nfqueue mode\n");
#endif /* NFQ */
#ifdef IPFW
printf("\t-d <divert port> : run in inline ipfw divert mode\n");
#endif /* IPFW */
printf("\t-s <path> : path to signature file loaded in addition to suricata.yaml settings (optional)\n");
printf("\t-S <path> : path to signature file loaded exclusively (optional)\n");
printf("\t-l <dir> : default log directory\n");
#ifndef OS_WIN32
printf("\t-D : run as daemon\n");
#else
printf("\t--service-install : install as service\n");
printf("\t--service-remove : remove service\n");
printf("\t--service-change-params : change service startup parameters\n");
#endif /* OS_WIN32 */
printf("\t-k [all|none] : force checksum check (all) or disabled it (none)\n");
printf("\t-V : display Suricata version\n");
printf("\t-v[v] : increase default Suricata verbosity\n");
17 years ago
#ifdef UNITTESTS
printf("\t-u : run the unittests and exit\n");
printf("\t-U, --unittest-filter=REGEX : filter unittests with a regex\n");
printf("\t--list-unittests : list unit tests\n");
printf("\t--fatal-unittests : enable fatal failure on unittest error\n");
printf("\t--unittests-coverage : display unittest coverage report\n");
17 years ago
#endif /* UNITTESTS */
printf("\t--list-app-layer-protos : list supported app layer protocols\n");
printf("\t--list-keywords[=all|csv|<kword>] : list keywords implemented by the engine\n");
#ifdef __SC_CUDA_SUPPORT__
printf("\t--list-cuda-cards : list cuda supported cards\n");
#endif
printf("\t--list-runmodes : list supported runmodes\n");
printf("\t--runmode <runmode_id> : specific runmode modification the engine should run. The argument\n"
"\t supplied should be the id for the runmode obtained by running\n"
"\t --list-runmodes\n");
printf("\t--engine-analysis : print reports on analysis of different sections in the engine and exit.\n"
"\t Please have a look at the conf parameter engine-analysis on what reports\n"
"\t can be printed\n");
printf("\t--pidfile <file> : write pid to this file\n");
printf("\t--init-errors-fatal : enable fatal failure on signature init error\n");
printf("\t--disable-detection : disable detection engine\n");
printf("\t--dump-config : show the running configuration\n");
printf("\t--build-info : display build information\n");
printf("\t--pcap[=<dev>] : run in pcap mode, no value select interfaces from suricata.yaml\n");
#ifdef HAVE_PCAP_SET_BUFF
printf("\t--pcap-buffer-size : size of the pcap buffer value from 0 - %i\n",INT_MAX);
#endif /* HAVE_SET_PCAP_BUFF */
#ifdef HAVE_AF_PACKET
printf("\t--af-packet[=<dev>] : run in af-packet mode, no value select interfaces from suricata.yaml\n");
#endif
12 years ago
#ifdef HAVE_NETMAP
printf("\t--netmap[=<dev>] : run in netmap mode, no value select interfaces from suricata.yaml\n");
#endif
#ifdef HAVE_PFRING
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
printf("\t--pfring[=<dev>] : run in pfring mode, use interfaces from suricata.yaml\n");
printf("\t--pfring-int <dev> : run in pfring mode, use interface <dev>\n");
printf("\t--pfring-cluster-id <id> : pfring cluster id \n");
printf("\t--pfring-cluster-type <type> : pfring cluster type for PF_RING 4.1.2 and later cluster_round_robin|cluster_flow\n");
#endif /* HAVE_PFRING */
printf("\t--simulate-ips : force engine into IPS mode. Useful for QA\n");
#ifdef HAVE_LIBCAP_NG
printf("\t--user <user> : run suricata as this user after init\n");
printf("\t--group <group> : run suricata as this group after init\n");
#endif /* HAVE_LIBCAP_NG */
printf("\t--erf-in <path> : process an ERF file\n");
#ifdef HAVE_DAG
printf("\t--dag <dagX:Y> : process ERF records from DAG interface X, stream Y\n");
#endif
#ifdef HAVE_NAPATECH
printf("\t--napatech : run Napatech Streams using the API\n");
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
#endif
#ifdef BUILD_UNIX_SOCKET
printf("\t--unix-socket[=<file>] : use unix socket to control suricata work\n");
Add TILE-Gx mPIPE packet processing support. The TILE-Gx processor includes a packet processing engine, called mPIPE, that can deliver packets directly into user space memory. It handles buffer allocation and load balancing (either static 5-tuple hashing, or dynamic flow affinity hashing are used here). The new packet source code is in source-mpipe.c and source-mpipe.h A new Tile runmode is added that configures the Suricata pipelines in worker mode, where each thread does the entire packet processing pipeline. It scales across all the Gx chips sizes of 9, 16, 36 or 72 cores. The new runmode is in runmode-tile.c and runmode-tile.h The configure script detects the TILE-Gx architecture and defines HAVE_MPIPE, which is then used to conditionally enable the code to support mPIPE packet processing. Suricata runs on TILE-Gx even without mPIPE support enabled. The Suricata Packet structures are allocated by the mPIPE hardware by allocating the Suricata Packet structure immediatley before the mPIPE packet buffer and then pushing the mPIPE packet buffer pointer onto the mPIPE buffer stack. This way, mPIPE writes the packet data into the buffer, returns the mPIPE packet buffer pointer, which is then converted into a Suricata Packet pointer for processing inside Suricata. When the Packet is freed, the buffer is returned to mPIPE's buffer stack, by setting ReleasePacket to an mPIPE release specific function. The code checks for the largest Huge page available in Linux when Suricata is started. TILE-Gx supports Huge pages sizes of 16MB, 64MB, 256MB, 1GB and 4GB. Suricata then divides one of those page into packet buffers for mPIPE. The code is not yet optimized for high performance. Performance improvements will follow shortly. The code was originally written by Tom Decanio and then further modified by Tilera. This code has been tested with Tilera's Multicore Developement Environment (MDE) version 4.1.5. The TILEncore-Gx36 (PCIe card) and TILEmpower-Gx (1U Rack mount).
13 years ago
#endif
#ifdef HAVE_MPIPE
printf("\t--mpipe : run with tilegx mpipe interface(s)\n");
#endif
printf("\t--set name=value : set a configuration value\n");
17 years ago
printf("\n");
printf("\nTo run the engine with default configuration on "
"interface eth0 with signature file \"signatures.rules\", run the "
"command as:\n\n%s -c suricata.yaml -s signatures.rules -i eth0 \n\n",
progname);
17 years ago
}
void SCPrintBuildInfo(void)
{
char *bits = "<unknown>-bits";
char *endian = "<unknown>-endian";
char features[2048] = "";
char *tls = "pthread key";
#ifdef REVISION
printf("This is %s version %s (rev %s)\n", PROG_NAME, PROG_VER, xstr(REVISION));
#elif defined RELEASE
printf("This is %s version %s RELEASE\n", PROG_NAME, PROG_VER);
#else
printf("This is %s version %s\n", PROG_NAME, PROG_VER);
#endif
#ifdef DEBUG
strlcat(features, "DEBUG ", sizeof(features));
#endif
#ifdef DEBUG_VALIDATION
strlcat(features, "DEBUG_VALIDATION ", sizeof(features));
#endif
#ifdef UNITTESTS
strlcat(features, "UNITTESTS ", sizeof(features));
#endif
#ifdef NFQ
strlcat(features, "NFQ ", sizeof(features));
#endif
#ifdef IPFW
strlcat(features, "IPFW ", sizeof(features));
#endif
#ifdef HAVE_PCAP_SET_BUFF
strlcat(features, "PCAP_SET_BUFF ", sizeof(features));
#endif
#if LIBPCAP_VERSION_MAJOR == 1
strlcat(features, "LIBPCAP_VERSION_MAJOR=1 ", sizeof(features));
#elif LIBPCAP_VERSION_MAJOR == 0
strlcat(features, "LIBPCAP_VERSION_MAJOR=0 ", sizeof(features));
#endif
#ifdef __SC_CUDA_SUPPORT__
strlcat(features, "CUDA ", sizeof(features));
#endif
#ifdef HAVE_PFRING
strlcat(features, "PF_RING ", sizeof(features));
#endif
#ifdef HAVE_AF_PACKET
strlcat(features, "AF_PACKET ", sizeof(features));
#endif
12 years ago
#ifdef HAVE_NETMAP
strlcat(features, "NETMAP ", sizeof(features));
#endif
#ifdef HAVE_PACKET_FANOUT
strlcat(features, "HAVE_PACKET_FANOUT ", sizeof(features));
#endif
#ifdef HAVE_DAG
strlcat(features, "DAG ", sizeof(features));
#endif
#ifdef HAVE_LIBCAP_NG
strlcat(features, "LIBCAP_NG ", sizeof(features));
#endif
#ifdef HAVE_LIBNET11
strlcat(features, "LIBNET1.1 ", sizeof(features));
#endif
#ifdef HAVE_HTP_URI_NORMALIZE_HOOK
strlcat(features, "HAVE_HTP_URI_NORMALIZE_HOOK ", sizeof(features));
#endif
#ifdef PCRE_HAVE_JIT
strlcat(features, "PCRE_JIT ", sizeof(features));
#endif
#ifdef HAVE_NSS
strlcat(features, "HAVE_NSS ", sizeof(features));
#endif
#ifdef HAVE_LUA
strlcat(features, "HAVE_LUA ", sizeof(features));
#endif
#ifdef HAVE_LUAJIT
strlcat(features, "HAVE_LUAJIT ", sizeof(features));
#endif
#ifdef HAVE_LIBJANSSON
strlcat(features, "HAVE_LIBJANSSON ", sizeof(features));
#endif
#ifdef PROFILING
strlcat(features, "PROFILING ", sizeof(features));
#endif
#ifdef PROFILE_LOCKING
strlcat(features, "PROFILE_LOCKING ", sizeof(features));
#endif
#ifdef TLS
strlcat(features, "TLS ", sizeof(features));
#endif
if (strlen(features) == 0) {
strlcat(features, "none", sizeof(features));
}
printf("Features: %s\n", features);
/* SIMD stuff */
memset(features, 0x00, sizeof(features));
#if defined(__SSE4_2__)
strlcat(features, "SSE_4_2 ", sizeof(features));
#endif
#if defined(__SSE4_1__)
strlcat(features, "SSE_4_1 ", sizeof(features));
#endif
#if defined(__SSE3__)
strlcat(features, "SSE_3 ", sizeof(features));
#endif
#if defined(__tile__)
strlcat(features, "Tilera ", sizeof(features));
#endif
if (strlen(features) == 0) {
strlcat(features, "none", sizeof(features));
}
printf("SIMD support: %s\n", features);
/* atomics stuff */
memset(features, 0x00, sizeof(features));
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1)
strlcat(features, "1 ", sizeof(features));
#endif
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2)
strlcat(features, "2 ", sizeof(features));
#endif
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
strlcat(features, "4 ", sizeof(features));
#endif
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)
strlcat(features, "8 ", sizeof(features));
#endif
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
strlcat(features, "16 ", sizeof(features));
#endif
if (strlen(features) == 0) {
strlcat(features, "none", sizeof(features));
} else {
strlcat(features, "byte(s)", sizeof(features));
}
printf("Atomic intrisics: %s\n", features);
#if __WORDSIZE == 64
bits = "64-bits";
#elif __WORDSIZE == 32
bits = "32-bits";
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
endian = "Big-endian";
#elif __BYTE_ORDER == __LITTLE_ENDIAN
endian = "Little-endian";
#endif
printf("%s, %s architecture\n", bits, endian);
#ifdef __GNUC__
printf("GCC version %s, C version %"PRIiMAX"\n", __VERSION__, (intmax_t)__STDC_VERSION__);
#else
printf("C version %"PRIiMAX"\n", (intmax_t)__STDC_VERSION__);
#endif
#if __SSP__ == 1
printf("compiled with -fstack-protector\n");
#endif
#if __SSP_ALL__ == 2
printf("compiled with -fstack-protector-all\n");
#endif
/*
* Workaround for special defines of _FORTIFY_SOURCE like
* FORTIFY_SOURCE=((defined __OPTIMIZE && OPTIMIZE > 0) ? 2 : 0)
* which is used by Gentoo for example and would result in the error
* 'defined' undeclared when _FORTIFY_SOURCE used via %d in printf func
*
*/
#if _FORTIFY_SOURCE == 2
printf("compiled with _FORTIFY_SOURCE=2\n");
#elif _FORTIFY_SOURCE == 1
printf("compiled with _FORTIFY_SOURCE=1\n");
#elif _FORTIFY_SOURCE == 0
printf("compiled with _FORTIFY_SOURCE=0\n");
#endif
#ifdef CLS
printf("L1 cache line size (CLS)=%d\n", CLS);
#endif
#ifdef TLS
tls = "__thread";
#endif
printf("thread local storage method: %s\n", tls);
printf("compiled with %s, linked against %s\n",
HTP_VERSION_STRING_FULL, htp_get_version());
printf("\n");
#include "build-info.h"
}
int coverage_unittests;
int g_ut_modules;
int g_ut_covered;
void RegisterAllModules()
{
/* commanders */
TmModuleUnixManagerRegister();
/* managers */
TmModuleFlowManagerRegister();
TmModuleFlowRecyclerRegister();
/* nfq */
TmModuleReceiveNFQRegister();
TmModuleVerdictNFQRegister();
TmModuleDecodeNFQRegister();
/* ipfw */
TmModuleReceiveIPFWRegister();
TmModuleVerdictIPFWRegister();
TmModuleDecodeIPFWRegister();
/* pcap live */
TmModuleReceivePcapRegister();
TmModuleDecodePcapRegister();
/* pcap file */
TmModuleReceivePcapFileRegister();
TmModuleDecodePcapFileRegister();
#ifdef HAVE_MPIPE
/* mpipe */
TmModuleReceiveMpipeRegister();
TmModuleDecodeMpipeRegister();
#endif
/* af-packet */
TmModuleReceiveAFPRegister();
TmModuleDecodeAFPRegister();
12 years ago
/* netmap */
TmModuleReceiveNetmapRegister();
TmModuleDecodeNetmapRegister();
/* pfring */
TmModuleReceivePfringRegister();
TmModuleDecodePfringRegister();
/* dag file */
TmModuleReceiveErfFileRegister();
TmModuleDecodeErfFileRegister();
/* dag live */
TmModuleReceiveErfDagRegister();
TmModuleDecodeErfDagRegister();
/* napatech */
TmModuleNapatechStreamRegister();
TmModuleNapatechDecodeRegister();
/* flow worker */
TmModuleFlowWorkerRegister();
/* respond-reject */
TmModuleRespondRejectRegister();
/* log api */
TmModuleLoggerRegister();
TmModuleStatsLoggerRegister();
TmModuleDebugList();
13 years ago
/* nflog */
TmModuleReceiveNFLOGRegister();
TmModuleDecodeNFLOGRegister();
}
static TmEcode LoadYamlConfig(SCInstance *suri)
{
SCEnter();
if (suri->conf_filename == NULL)
suri->conf_filename = DEFAULT_CONF_FILE;
if (ConfYamlLoadFile(suri->conf_filename) != 0) {
/* Error already displayed. */
SCReturnInt(TM_ECODE_FAILED);
}
SCReturnInt(TM_ECODE_OK);
}
static TmEcode ParseInterfacesList(int run_mode, char *pcap_dev)
{
SCEnter();
/* run the selected runmode */
if (run_mode == RUNMODE_PCAP_DEV) {
if (strlen(pcap_dev) == 0) {
int ret = LiveBuildDeviceList("pcap");
if (ret == 0) {
SCLogError(SC_ERR_INITIALIZATION, "No interface found in config for pcap");
SCReturnInt(TM_ECODE_FAILED);
}
}
#ifdef HAVE_MPIPE
} else if (run_mode == RUNMODE_TILERA_MPIPE) {
if (strlen(pcap_dev)) {
if (ConfSetFinal("mpipe.single_mpipe_dev", pcap_dev) != 1) {
fprintf(stderr, "ERROR: Failed to set mpipe.single_mpipe_dev\n");
SCReturnInt(TM_ECODE_FAILED);
}
} else {
int ret = LiveBuildDeviceList("mpipe.inputs");
if (ret == 0) {
fprintf(stderr, "ERROR: No interface found in config for mpipe\n");
SCReturnInt(TM_ECODE_FAILED);
}
}
#endif
} else if (run_mode == RUNMODE_PFRING) {
/* FIXME add backward compat support */
/* iface has been set on command line */
if (strlen(pcap_dev)) {
if (ConfSetFinal("pfring.live-interface", pcap_dev) != 1) {
SCLogError(SC_ERR_INITIALIZATION, "Failed to set pfring.live-interface");
SCReturnInt(TM_ECODE_FAILED);
}
} else {
/* not an error condition if we have a 1.0 config */
LiveBuildDeviceList("pfring");
}
#ifdef HAVE_AF_PACKET
} else if (run_mode == RUNMODE_AFP_DEV) {
/* iface has been set on command line */
if (strlen(pcap_dev)) {
if (ConfSetFinal("af-packet.live-interface", pcap_dev) != 1) {
SCLogError(SC_ERR_INITIALIZATION, "Failed to set af-packet.live-interface");
SCReturnInt(TM_ECODE_FAILED);
}
} else {
int ret = LiveBuildDeviceList("af-packet");
if (ret == 0) {
SCLogError(SC_ERR_INITIALIZATION, "No interface found in config for af-packet");
SCReturnInt(TM_ECODE_FAILED);
}
if (AFPRunModeIsIPS()) {
SCLogInfo("AF_PACKET: Setting IPS mode");
EngineModeSetIPS();
}
}
#endif
12 years ago
#ifdef HAVE_NETMAP
} else if (run_mode == RUNMODE_NETMAP) {
/* iface has been set on command line */
if (strlen(pcap_dev)) {
if (ConfSetFinal("netmap.live-interface", pcap_dev) != 1) {
SCLogError(SC_ERR_INITIALIZATION, "Failed to set netmap.live-interface");
SCReturnInt(TM_ECODE_FAILED);
}
} else {
int ret = LiveBuildDeviceList("netmap");
if (ret == 0) {
SCLogError(SC_ERR_INITIALIZATION, "No interface found in config for netmap");
SCReturnInt(TM_ECODE_FAILED);
}
if (NetmapRunModeIsIPS()) {
SCLogInfo("Netmap: Setting IPS mode");
EngineModeSetIPS();
}
}
#endif
13 years ago
#ifdef HAVE_NFLOG
} else if (run_mode == RUNMODE_NFLOG) {
int ret = LiveBuildDeviceListCustom("nflog", "group");
if (ret == 0) {
SCLogError(SC_ERR_INITIALIZATION, "No group found in config for nflog");
SCReturnInt(TM_ECODE_FAILED);
}
#endif
}
SCReturnInt(TM_ECODE_OK);
}
static void SCInstanceInit(SCInstance *suri)
{
memset(suri, 0x00, sizeof(*suri));
suri->run_mode = RUNMODE_UNKNOWN;
memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
suri->sig_file = NULL;
suri->sig_file_exclusive = FALSE;
suri->pid_filename = NULL;
suri->regex_arg = NULL;
suri->keyword_info = NULL;
suri->runmode_custom_mode = NULL;
#ifndef OS_WIN32
suri->user_name = NULL;
suri->group_name = NULL;
suri->do_setuid = FALSE;
suri->do_setgid = FALSE;
suri->userid = 0;
suri->groupid = 0;
#endif /* OS_WIN32 */
suri->delayed_detect = 0;
suri->daemon = 0;
suri->offline = 0;
suri->verbose = 0;
/* use -1 as unknown */
suri->checksum_validation = -1;
#if HAVE_DETECT_DISABLED==1
g_detect_disabled = suri->disabled_detect = 1;
#else
g_detect_disabled = suri->disabled_detect = 0;
#endif
}
static TmEcode PrintVersion()
{
#ifdef REVISION
printf("This is %s version %s (rev %s)\n", PROG_NAME, PROG_VER, xstr(REVISION));
#elif defined RELEASE
printf("This is %s version %s RELEASE\n", PROG_NAME, PROG_VER);
#else
printf("This is %s version %s\n", PROG_NAME, PROG_VER);
#endif
return TM_ECODE_OK;
}
static TmEcode SCPrintVersion()
{
#ifdef REVISION
SCLogNotice("This is %s version %s (rev %s)", PROG_NAME, PROG_VER, xstr(REVISION));
#elif defined RELEASE
SCLogNotice("This is %s version %s RELEASE", PROG_NAME, PROG_VER);
#else
SCLogNotice("This is %s version %s", PROG_NAME, PROG_VER);
#endif
return TM_ECODE_OK;
}
static void SCSetStartTime(SCInstance *suri)
{
memset(&suri->start_time, 0, sizeof(suri->start_time));
gettimeofday(&suri->start_time, NULL);
}
static void SCPrintElapsedTime(SCInstance *suri)
{
struct timeval end_time;
memset(&end_time, 0, sizeof(end_time));
gettimeofday(&end_time, NULL);
uint64_t milliseconds = ((end_time.tv_sec - suri->start_time.tv_sec) * 1000) +
(((1000000 + end_time.tv_usec - suri->start_time.tv_usec) / 1000) - 1000);
SCLogInfo("time elapsed %.3fs", (float)milliseconds/(float)1000);
}
static int ParseCommandLineAfpacket(SCInstance *suri, const char *optarg)
{
#ifdef HAVE_AF_PACKET
if (suri->run_mode == RUNMODE_UNKNOWN) {
suri->run_mode = RUNMODE_AFP_DEV;
if (optarg) {
LiveRegisterDevice(optarg);
memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
strlcpy(suri->pcap_dev, optarg, sizeof(suri->pcap_dev));
}
} else if (suri->run_mode == RUNMODE_AFP_DEV) {
SCLogWarning(SC_WARN_PCAP_MULTI_DEV_EXPERIMENTAL, "using "
"multiple devices to get packets is experimental.");
if (optarg) {
LiveRegisterDevice(optarg);
} else {
SCLogInfo("Multiple af-packet option without interface on each is useless");
}
} else {
SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
"has been specified");
usage(suri->progname);
return TM_ECODE_FAILED;
}
return TM_ECODE_OK;
#else
SCLogError(SC_ERR_NO_AF_PACKET,"AF_PACKET not enabled. On Linux "
"host, make sure to pass --enable-af-packet to "
"configure when building.");
return TM_ECODE_FAILED;
#endif
}
static int ParseCommandLinePcapLive(SCInstance *suri, const char *optarg)
{
memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
if (optarg != NULL) {
/* some windows shells require escaping of the \ in \Device. Otherwise
* the backslashes are stripped. We put them back here. */
if (strlen(optarg) > 9 && strncmp(optarg, "DeviceNPF", 9) == 0) {
snprintf(suri->pcap_dev, sizeof(suri->pcap_dev), "\\Device\\NPF%s", optarg+9);
} else {
strlcpy(suri->pcap_dev, optarg, sizeof(suri->pcap_dev));
PcapTranslateIPToDevice(suri->pcap_dev, sizeof(suri->pcap_dev));
}
if (strcmp(suri->pcap_dev, optarg) != 0) {
SCLogInfo("translated %s to pcap device %s", optarg, suri->pcap_dev);
} else if (strlen(suri->pcap_dev) > 0 && isdigit((unsigned char)suri->pcap_dev[0])) {
SCLogError(SC_ERR_PCAP_TRANSLATE, "failed to find a pcap device for IP %s", optarg);
return TM_ECODE_FAILED;
}
}
if (suri->run_mode == RUNMODE_UNKNOWN) {
suri->run_mode = RUNMODE_PCAP_DEV;
if (optarg) {
LiveRegisterDevice(suri->pcap_dev);
}
} else if (suri->run_mode == RUNMODE_PCAP_DEV) {
#ifdef OS_WIN32
SCLogError(SC_ERR_PCAP_MULTI_DEV_NO_SUPPORT, "pcap multi dev "
"support is not (yet) supported on Windows.");
return TM_ECODE_FAILED;
#else
SCLogWarning(SC_WARN_PCAP_MULTI_DEV_EXPERIMENTAL, "using "
"multiple pcap devices to get packets is experimental.");
LiveRegisterDevice(suri->pcap_dev);
#endif
} else {
SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
"has been specified");
usage(suri->progname);
return TM_ECODE_FAILED;
}
return TM_ECODE_OK;
}
static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri)
{
int opt;
int dump_config = 0;
int list_app_layer_protocols = 0;
int list_unittests = 0;
int list_cuda_cards = 0;
int list_runmodes = 0;
int list_keywords = 0;
int build_info = 0;
int conf_test = 0;
#ifdef AFLFUZZ_CONF_TEST
int conf_test_force_success = 0;
#endif
int engine_analysis = 0;
int set_log_directory = 0;
int ret = TM_ECODE_OK;
#ifdef UNITTESTS
coverage_unittests = 0;
g_ut_modules = 0;
g_ut_covered = 0;
#endif
struct option long_opts[] = {
{"dump-config", 0, &dump_config, 1},
{"pfring", optional_argument, 0, 0},
{"pfring-int", required_argument, 0, 0},
{"pfring-cluster-id", required_argument, 0, 0},
{"pfring-cluster-type", required_argument, 0, 0},
{"af-packet", optional_argument, 0, 0},
12 years ago
{"netmap", optional_argument, 0, 0},
{"pcap", optional_argument, 0, 0},
{"simulate-ips", 0, 0 , 0},
{"afl-rules", required_argument, 0 , 0},
{"afl-http-request", required_argument, 0 , 0},
{"afl-http", required_argument, 0 , 0},
{"afl-tls-request", required_argument, 0 , 0},
{"afl-tls", required_argument, 0 , 0},
{"afl-dns-request", required_argument, 0 , 0},
{"afl-dns", required_argument, 0 , 0},
{"afl-ssh-request", required_argument, 0 , 0},
{"afl-ssh", required_argument, 0 , 0},
{"afl-ftp-request", required_argument, 0 , 0},
{"afl-ftp", required_argument, 0 , 0},
{"afl-smtp-request", required_argument, 0 , 0},
{"afl-smtp", required_argument, 0 , 0},
{"afl-smb-request", required_argument, 0 , 0},
{"afl-smb", required_argument, 0 , 0},
{"afl-modbus-request", required_argument, 0 , 0},
{"afl-modbus", required_argument, 0 , 0},
{"afl-enip-request", required_argument, 0 , 0},
{"afl-enip", required_argument, 0 , 0},
{"afl-mime", required_argument, 0 , 0},
{"afl-decoder-ppp", required_argument, 0 , 0},
{"afl-der", required_argument, 0, 0},
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
#ifdef BUILD_UNIX_SOCKET
{"unix-socket", optional_argument, 0, 0},
#endif
{"pcap-buffer-size", required_argument, 0, 0},
{"unittest-filter", required_argument, 0, 'U'},
{"list-app-layer-protos", 0, &list_app_layer_protocols, 1},
{"list-unittests", 0, &list_unittests, 1},
{"list-cuda-cards", 0, &list_cuda_cards, 1},
{"list-runmodes", 0, &list_runmodes, 1},
{"list-keywords", optional_argument, &list_keywords, 1},
{"runmode", required_argument, NULL, 0},
{"engine-analysis", 0, &engine_analysis, 1},
#ifdef OS_WIN32
{"service-install", 0, 0, 0},
{"service-remove", 0, 0, 0},
{"service-change-params", 0, 0, 0},
#endif /* OS_WIN32 */
{"pidfile", required_argument, 0, 0},
{"init-errors-fatal", 0, 0, 0},
{"disable-detection", 0, 0, 0},
{"fatal-unittests", 0, 0, 0},
{"unittests-coverage", 0, &coverage_unittests, 1},
{"user", required_argument, 0, 0},
{"group", required_argument, 0, 0},
{"erf-in", required_argument, 0, 0},
{"dag", required_argument, 0, 0},
{"napatech", 0, 0, 0},
{"build-info", 0, &build_info, 1},
Add TILE-Gx mPIPE packet processing support. The TILE-Gx processor includes a packet processing engine, called mPIPE, that can deliver packets directly into user space memory. It handles buffer allocation and load balancing (either static 5-tuple hashing, or dynamic flow affinity hashing are used here). The new packet source code is in source-mpipe.c and source-mpipe.h A new Tile runmode is added that configures the Suricata pipelines in worker mode, where each thread does the entire packet processing pipeline. It scales across all the Gx chips sizes of 9, 16, 36 or 72 cores. The new runmode is in runmode-tile.c and runmode-tile.h The configure script detects the TILE-Gx architecture and defines HAVE_MPIPE, which is then used to conditionally enable the code to support mPIPE packet processing. Suricata runs on TILE-Gx even without mPIPE support enabled. The Suricata Packet structures are allocated by the mPIPE hardware by allocating the Suricata Packet structure immediatley before the mPIPE packet buffer and then pushing the mPIPE packet buffer pointer onto the mPIPE buffer stack. This way, mPIPE writes the packet data into the buffer, returns the mPIPE packet buffer pointer, which is then converted into a Suricata Packet pointer for processing inside Suricata. When the Packet is freed, the buffer is returned to mPIPE's buffer stack, by setting ReleasePacket to an mPIPE release specific function. The code checks for the largest Huge page available in Linux when Suricata is started. TILE-Gx supports Huge pages sizes of 16MB, 64MB, 256MB, 1GB and 4GB. Suricata then divides one of those page into packet buffers for mPIPE. The code is not yet optimized for high performance. Performance improvements will follow shortly. The code was originally written by Tom Decanio and then further modified by Tilera. This code has been tested with Tilera's Multicore Developement Environment (MDE) version 4.1.5. The TILEncore-Gx36 (PCIe card) and TILEmpower-Gx (1U Rack mount).
13 years ago
#ifdef HAVE_MPIPE
{"mpipe", optional_argument, 0, 0},
#endif
{"set", required_argument, 0, 0},
13 years ago
#ifdef HAVE_NFLOG
{"nflog", optional_argument, 0, 0},
#endif
#ifdef AFLFUZZ_CONF_TEST
{"afl-parse-rules", 0, &conf_test_force_success, 1},
13 years ago
#endif
{NULL, 0, NULL, 0}
};
/* getopt_long stores the option index here. */
int option_index = 0;
char short_opts[] = "c:TDhi:l:q:d:r:us:S:U:VF:vk:";
while ((opt = getopt_long(argc, argv, short_opts, long_opts, &option_index)) != -1) {
switch (opt) {
case 0:
if (strcmp((long_opts[option_index]).name , "pfring") == 0 ||
strcmp((long_opts[option_index]).name , "pfring-int") == 0) {
#ifdef HAVE_PFRING
suri->run_mode = RUNMODE_PFRING;
if (optarg != NULL) {
13 years ago
memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
strlcpy(suri->pcap_dev, optarg,
((strlen(optarg) < sizeof(suri->pcap_dev)) ?
(strlen(optarg) + 1) : sizeof(suri->pcap_dev)));
LiveRegisterDevice(optarg);
}
#else
SCLogError(SC_ERR_NO_PF_RING,"PF_RING not enabled. Make sure "
"to pass --enable-pfring to configure when building.");
return TM_ECODE_FAILED;
#endif /* HAVE_PFRING */
}
else if(strcmp((long_opts[option_index]).name , "pfring-cluster-id") == 0){
#ifdef HAVE_PFRING
if (ConfSetFinal("pfring.cluster-id", optarg) != 1) {
fprintf(stderr, "ERROR: Failed to set pfring.cluster-id.\n");
return TM_ECODE_FAILED;
}
#else
SCLogError(SC_ERR_NO_PF_RING,"PF_RING not enabled. Make sure "
"to pass --enable-pfring to configure when building.");
return TM_ECODE_FAILED;
#endif /* HAVE_PFRING */
}
else if(strcmp((long_opts[option_index]).name , "pfring-cluster-type") == 0){
#ifdef HAVE_PFRING
if (ConfSetFinal("pfring.cluster-type", optarg) != 1) {
fprintf(stderr, "ERROR: Failed to set pfring.cluster-type.\n");
return TM_ECODE_FAILED;
}
#else
SCLogError(SC_ERR_NO_PF_RING,"PF_RING not enabled. Make sure "
"to pass --enable-pfring to configure when building.");
return TM_ECODE_FAILED;
#endif /* HAVE_PFRING */
}
else if (strcmp((long_opts[option_index]).name , "af-packet") == 0)
{
if (ParseCommandLineAfpacket(suri, optarg) != TM_ECODE_OK) {
return TM_ECODE_FAILED;
}
12 years ago
} else if (strcmp((long_opts[option_index]).name , "netmap") == 0){
#ifdef HAVE_NETMAP
if (suri->run_mode == RUNMODE_UNKNOWN) {
suri->run_mode = RUNMODE_NETMAP;
if (optarg) {
LiveRegisterDevice(optarg);
memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
strlcpy(suri->pcap_dev, optarg,
((strlen(optarg) < sizeof(suri->pcap_dev)) ?
(strlen(optarg) + 1) : sizeof(suri->pcap_dev)));
}
} else if (suri->run_mode == RUNMODE_NETMAP) {
SCLogWarning(SC_WARN_PCAP_MULTI_DEV_EXPERIMENTAL, "using "
"multiple devices to get packets is experimental.");
if (optarg) {
LiveRegisterDevice(optarg);
} else {
SCLogInfo("Multiple netmap option without interface on each is useless");
break;
}
} else {
SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
"has been specified");
usage(argv[0]);
return TM_ECODE_FAILED;
}
#else
SCLogError(SC_ERR_NO_NETMAP, "NETMAP not enabled.");
return TM_ECODE_FAILED;
#endif
13 years ago
} else if (strcmp((long_opts[option_index]).name, "nflog") == 0) {
#ifdef HAVE_NFLOG
if (suri->run_mode == RUNMODE_UNKNOWN) {
suri->run_mode = RUNMODE_NFLOG;
LiveBuildDeviceListCustom("nflog", "group");
}
#else
SCLogError(SC_ERR_NFLOG_NOSUPPORT, "NFLOG not enabled.");
return TM_ECODE_FAILED;
#endif /* HAVE_NFLOG */
} else if (strcmp((long_opts[option_index]).name , "pcap") == 0) {
if (ParseCommandLinePcapLive(suri, optarg) != TM_ECODE_OK) {
return TM_ECODE_FAILED;
}
#ifdef AFLFUZZ_RULES
} else if(strcmp((long_opts[option_index]).name, "afl-rules") == 0) {
MpmTableSetup();
SpmTableSetup();
exit(RuleParseDataFromFile(optarg));
#endif
#ifdef AFLFUZZ_APPLAYER
} else if(strcmp((long_opts[option_index]).name, "afl-http-request") == 0) {
//printf("arg: //%s\n", optarg);
MpmTableSetup();
SpmTableSetup();
AppLayerProtoDetectSetup();
AppLayerParserSetup();
RegisterHTPParsers();
exit(AppLayerParserRequestFromFile(ALPROTO_HTTP, optarg));
} else if(strcmp((long_opts[option_index]).name, "afl-http") == 0) {
//printf("arg: //%s\n", optarg);
MpmTableSetup();
SpmTableSetup();
AppLayerProtoDetectSetup();
AppLayerParserSetup();
RegisterHTPParsers();
exit(AppLayerParserFromFile(ALPROTO_HTTP, optarg));
} else if(strcmp((long_opts[option_index]).name, "afl-tls-request") == 0) {
//printf("arg: //%s\n", optarg);
MpmTableSetup();
SpmTableSetup();
AppLayerProtoDetectSetup();
AppLayerParserSetup();
RegisterSSLParsers();
exit(AppLayerParserRequestFromFile(ALPROTO_TLS, optarg));
} else if(strcmp((long_opts[option_index]).name, "afl-tls") == 0) {
//printf("arg: //%s\n", optarg);
MpmTableSetup();
SpmTableSetup();
AppLayerProtoDetectSetup();
AppLayerParserSetup();
RegisterSSLParsers();
exit(AppLayerParserFromFile(ALPROTO_TLS, optarg));
} else if(strcmp((long_opts[option_index]).name, "afl-dns-request") == 0) {
//printf("arg: //%s\n", optarg);
RegisterDNSTCPParsers();
exit(AppLayerParserRequestFromFile(ALPROTO_DNS, optarg));
} else if(strcmp((long_opts[option_index]).name, "afl-dns") == 0) {
//printf("arg: //%s\n", optarg);
AppLayerParserSetup();
RegisterDNSTCPParsers();
exit(AppLayerParserFromFile(ALPROTO_DNS, optarg));
} else if(strcmp((long_opts[option_index]).name, "afl-ssh-request") == 0) {
//printf("arg: //%s\n", optarg);
MpmTableSetup();
SpmTableSetup();
AppLayerProtoDetectSetup();
RegisterSSHParsers();
exit(AppLayerParserRequestFromFile(ALPROTO_SSH, optarg));
} else if(strcmp((long_opts[option_index]).name, "afl-ssh") == 0) {
//printf("arg: //%s\n", optarg);
MpmTableSetup();
SpmTableSetup();
AppLayerProtoDetectSetup();
AppLayerParserSetup();
RegisterSSHParsers();
exit(AppLayerParserFromFile(ALPROTO_SSH, optarg));
} else if(strcmp((long_opts[option_index]).name, "afl-ftp-request") == 0) {
//printf("arg: //%s\n", optarg);
MpmTableSetup();
SpmTableSetup();
AppLayerProtoDetectSetup();
AppLayerParserSetup();
RegisterFTPParsers();
exit(AppLayerParserRequestFromFile(ALPROTO_FTP, optarg));
} else if(strcmp((long_opts[option_index]).name, "afl-ftp") == 0) {
//printf("arg: //%s\n", optarg);
MpmTableSetup();
SpmTableSetup();
AppLayerProtoDetectSetup();
AppLayerParserSetup();
RegisterFTPParsers();
exit(AppLayerParserFromFile(ALPROTO_FTP, optarg));
} else if(strcmp((long_opts[option_index]).name, "afl-smtp-request") == 0) {
//printf("arg: //%s\n", optarg);
MpmTableSetup();
SpmTableSetup();
AppLayerProtoDetectSetup();
AppLayerParserSetup();
RegisterSMTPParsers();
exit(AppLayerParserRequestFromFile(ALPROTO_SMTP, optarg));
} else if(strcmp((long_opts[option_index]).name, "afl-smtp") == 0) {
//printf("arg: //%s\n", optarg);
MpmTableSetup();
SpmTableSetup();
AppLayerProtoDetectSetup();
AppLayerParserSetup();
RegisterSMTPParsers();
exit(AppLayerParserFromFile(ALPROTO_SMTP, optarg));
} else if(strcmp((long_opts[option_index]).name, "afl-smb-request") == 0) {
//printf("arg: //%s\n", optarg);
MpmTableSetup();
SpmTableSetup();
AppLayerProtoDetectSetup();
RegisterSMBParsers();
exit(AppLayerParserRequestFromFile(ALPROTO_SMB, optarg));
} else if(strcmp((long_opts[option_index]).name, "afl-smb") == 0) {
//printf("arg: //%s\n", optarg);
MpmTableSetup();
SpmTableSetup();
AppLayerProtoDetectSetup();
AppLayerParserSetup();
RegisterSMBParsers();
exit(AppLayerParserFromFile(ALPROTO_SMB, optarg));
} else if(strcmp((long_opts[option_index]).name, "afl-modbus-request") == 0) {
//printf("arg: //%s\n", optarg);
AppLayerParserSetup();
RegisterModbusParsers();
exit(AppLayerParserRequestFromFile(ALPROTO_MODBUS, optarg));
} else if(strcmp((long_opts[option_index]).name, "afl-modbus") == 0) {
//printf("arg: //%s\n", optarg);
AppLayerParserSetup();
RegisterModbusParsers();
exit(AppLayerParserFromFile(ALPROTO_MODBUS, optarg));
} else if(strcmp((long_opts[option_index]).name, "afl-enip-request") == 0) {
//printf("arg: //%s\n", optarg);
AppLayerParserSetup();
RegisterENIPTCPParsers();
exit(AppLayerParserRequestFromFile(ALPROTO_ENIP, optarg));
} else if(strcmp((long_opts[option_index]).name, "afl-enip") == 0) {
//printf("arg: //%s\n", optarg);
AppLayerParserSetup();
RegisterENIPTCPParsers();
exit(AppLayerParserFromFile(ALPROTO_ENIP, optarg));
#endif
#ifdef AFLFUZZ_MIME
} else if(strcmp((long_opts[option_index]).name, "afl-mime") == 0) {
//printf("arg: //%s\n", optarg);
exit(MimeParserDataFromFile(optarg));
#endif
#ifdef AFLFUZZ_DECODER
} else if(strcmp((long_opts[option_index]).name, "afl-decoder-ppp") == 0) {
StatsInit();
MpmTableSetup();
SpmTableSetup();
AppLayerProtoDetectSetup();
DefragInit();
FlowInitConfig(FLOW_QUIET);
//printf("arg: //%s\n", optarg);
exit(DecoderParseDataFromFile(optarg, DecodePPP));
#endif
#ifdef AFLFUZZ_DER
} else if(strcmp((long_opts[option_index]).name, "afl-der") == 0) {
//printf("arg: //%s\n", optarg);
exit(DerParseDataFromFile(optarg));
#endif
} else if(strcmp((long_opts[option_index]).name, "simulate-ips") == 0) {
SCLogInfo("Setting IPS mode");
EngineModeSetIPS();
} else if(strcmp((long_opts[option_index]).name, "init-errors-fatal") == 0) {
if (ConfSetFinal("engine.init-failure-fatal", "1") != 1) {
fprintf(stderr, "ERROR: Failed to set engine init-failure-fatal.\n");
return TM_ECODE_FAILED;
}
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
#ifdef BUILD_UNIX_SOCKET
} else if (strcmp((long_opts[option_index]).name , "unix-socket") == 0) {
if (suri->run_mode == RUNMODE_UNKNOWN) {
suri->run_mode = RUNMODE_UNIX_SOCKET;
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
if (optarg) {
if (ConfSetFinal("unix-command.filename", optarg) != 1) {
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
fprintf(stderr, "ERROR: Failed to set unix-command.filename.\n");
return TM_ECODE_FAILED;
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
}
}
} else {
SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
"has been specified");
usage(argv[0]);
return TM_ECODE_FAILED;
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
}
#endif
}
else if(strcmp((long_opts[option_index]).name, "list-app-layer-protocols") == 0) {
/* listing all supported app layer protocols */
}
else if(strcmp((long_opts[option_index]).name, "list-unittests") == 0) {
#ifdef UNITTESTS
suri->run_mode = RUNMODE_LIST_UNITTEST;
#else
fprintf(stderr, "ERROR: Unit tests not enabled. Make sure to pass --enable-unittests to configure when building.\n");
return TM_ECODE_FAILED;
#endif /* UNITTESTS */
} else if(strcmp((long_opts[option_index]).name, "list-cuda-cards") == 0) {
#ifndef __SC_CUDA_SUPPORT__
fprintf(stderr, "ERROR: Cuda not enabled. Make sure to pass "
"--enable-cuda to configure when building.\n");
return TM_ECODE_FAILED;
#endif /* UNITTESTS */
} else if (strcmp((long_opts[option_index]).name, "list-runmodes") == 0) {
suri->run_mode = RUNMODE_LIST_RUNMODES;
return TM_ECODE_OK;
} else if (strcmp((long_opts[option_index]).name, "list-keywords") == 0) {
if (optarg) {
if (strcmp("short",optarg)) {
suri->keyword_info = optarg;
}
}
} else if (strcmp((long_opts[option_index]).name, "runmode") == 0) {
suri->runmode_custom_mode = optarg;
} else if(strcmp((long_opts[option_index]).name, "engine-analysis") == 0) {
// do nothing for now
}
#ifdef OS_WIN32
else if(strcmp((long_opts[option_index]).name, "service-install") == 0) {
suri->run_mode = RUNMODE_INSTALL_SERVICE;
return TM_ECODE_OK;
}
else if(strcmp((long_opts[option_index]).name, "service-remove") == 0) {
suri->run_mode = RUNMODE_REMOVE_SERVICE;
return TM_ECODE_OK;
}
else if(strcmp((long_opts[option_index]).name, "service-change-params") == 0) {
suri->run_mode = RUNMODE_CHANGE_SERVICE_PARAMS;
return TM_ECODE_OK;
}
#endif /* OS_WIN32 */
else if(strcmp((long_opts[option_index]).name, "pidfile") == 0) {
suri->pid_filename = optarg;
}
else if(strcmp((long_opts[option_index]).name, "disable-detection") == 0) {
g_detect_disabled = suri->disabled_detect = 1;
SCLogInfo("detection engine disabled");
}
else if(strcmp((long_opts[option_index]).name, "fatal-unittests") == 0) {
#ifdef UNITTESTS
unittests_fatal = 1;
#else
fprintf(stderr, "ERROR: Unit tests not enabled. Make sure to pass --enable-unittests to configure when building.\n");
return TM_ECODE_FAILED;
#endif /* UNITTESTS */
}
else if(strcmp((long_opts[option_index]).name, "user") == 0) {
#ifndef HAVE_LIBCAP_NG
SCLogError(SC_ERR_LIBCAP_NG_REQUIRED, "libcap-ng is required to"
" drop privileges, but it was not compiled into Suricata.");
return TM_ECODE_FAILED;
#else
suri->user_name = optarg;
suri->do_setuid = TRUE;
#endif /* HAVE_LIBCAP_NG */
}
else if(strcmp((long_opts[option_index]).name, "group") == 0) {
#ifndef HAVE_LIBCAP_NG
SCLogError(SC_ERR_LIBCAP_NG_REQUIRED, "libcap-ng is required to"
" drop privileges, but it was not compiled into Suricata.");
return TM_ECODE_FAILED;
#else
suri->group_name = optarg;
suri->do_setgid = TRUE;
#endif /* HAVE_LIBCAP_NG */
}
else if (strcmp((long_opts[option_index]).name, "erf-in") == 0) {
suri->run_mode = RUNMODE_ERF_FILE;
if (ConfSetFinal("erf-file.file", optarg) != 1) {
fprintf(stderr, "ERROR: Failed to set erf-file.file\n");
return TM_ECODE_FAILED;
}
}
else if (strcmp((long_opts[option_index]).name, "dag") == 0) {
#ifdef HAVE_DAG
if (suri->run_mode == RUNMODE_UNKNOWN) {
suri->run_mode = RUNMODE_DAG;
}
else if (suri->run_mode != RUNMODE_DAG) {
SCLogError(SC_ERR_MULTIPLE_RUN_MODE,
"more than one run mode has been specified");
usage(argv[0]);
return TM_ECODE_FAILED;
}
LiveRegisterDevice(optarg);
#else
SCLogError(SC_ERR_DAG_REQUIRED, "libdag and a DAG card are required"
" to receive packets using --dag.");
return TM_ECODE_FAILED;
#endif /* HAVE_DAG */
}
else if (strcmp((long_opts[option_index]).name, "napatech") == 0) {
#ifdef HAVE_NAPATECH
suri->run_mode = RUNMODE_NAPATECH;
#else
SCLogError(SC_ERR_NAPATECH_REQUIRED, "libntapi and a Napatech adapter are required"
" to capture packets using --napatech.");
return TM_ECODE_FAILED;
#endif /* HAVE_NAPATECH */
}
else if(strcmp((long_opts[option_index]).name, "pcap-buffer-size") == 0) {
#ifdef HAVE_PCAP_SET_BUFF
if (ConfSetFinal("pcap.buffer-size", optarg) != 1) {
fprintf(stderr, "ERROR: Failed to set pcap-buffer-size.\n");
return TM_ECODE_FAILED;
}
#else
SCLogError(SC_ERR_NO_PCAP_SET_BUFFER_SIZE, "The version of libpcap you have"
" doesn't support setting buffer size.");
#endif /* HAVE_PCAP_SET_BUFF */
}
else if(strcmp((long_opts[option_index]).name, "build-info") == 0) {
suri->run_mode = RUNMODE_PRINT_BUILDINFO;
return TM_ECODE_OK;
}
Add TILE-Gx mPIPE packet processing support. The TILE-Gx processor includes a packet processing engine, called mPIPE, that can deliver packets directly into user space memory. It handles buffer allocation and load balancing (either static 5-tuple hashing, or dynamic flow affinity hashing are used here). The new packet source code is in source-mpipe.c and source-mpipe.h A new Tile runmode is added that configures the Suricata pipelines in worker mode, where each thread does the entire packet processing pipeline. It scales across all the Gx chips sizes of 9, 16, 36 or 72 cores. The new runmode is in runmode-tile.c and runmode-tile.h The configure script detects the TILE-Gx architecture and defines HAVE_MPIPE, which is then used to conditionally enable the code to support mPIPE packet processing. Suricata runs on TILE-Gx even without mPIPE support enabled. The Suricata Packet structures are allocated by the mPIPE hardware by allocating the Suricata Packet structure immediatley before the mPIPE packet buffer and then pushing the mPIPE packet buffer pointer onto the mPIPE buffer stack. This way, mPIPE writes the packet data into the buffer, returns the mPIPE packet buffer pointer, which is then converted into a Suricata Packet pointer for processing inside Suricata. When the Packet is freed, the buffer is returned to mPIPE's buffer stack, by setting ReleasePacket to an mPIPE release specific function. The code checks for the largest Huge page available in Linux when Suricata is started. TILE-Gx supports Huge pages sizes of 16MB, 64MB, 256MB, 1GB and 4GB. Suricata then divides one of those page into packet buffers for mPIPE. The code is not yet optimized for high performance. Performance improvements will follow shortly. The code was originally written by Tom Decanio and then further modified by Tilera. This code has been tested with Tilera's Multicore Developement Environment (MDE) version 4.1.5. The TILEncore-Gx36 (PCIe card) and TILEmpower-Gx (1U Rack mount).
13 years ago
#ifdef HAVE_MPIPE
else if(strcmp((long_opts[option_index]).name , "mpipe") == 0) {
13 years ago
if (suri->run_mode == RUNMODE_UNKNOWN) {
suri->run_mode = RUNMODE_TILERA_MPIPE;
Add TILE-Gx mPIPE packet processing support. The TILE-Gx processor includes a packet processing engine, called mPIPE, that can deliver packets directly into user space memory. It handles buffer allocation and load balancing (either static 5-tuple hashing, or dynamic flow affinity hashing are used here). The new packet source code is in source-mpipe.c and source-mpipe.h A new Tile runmode is added that configures the Suricata pipelines in worker mode, where each thread does the entire packet processing pipeline. It scales across all the Gx chips sizes of 9, 16, 36 or 72 cores. The new runmode is in runmode-tile.c and runmode-tile.h The configure script detects the TILE-Gx architecture and defines HAVE_MPIPE, which is then used to conditionally enable the code to support mPIPE packet processing. Suricata runs on TILE-Gx even without mPIPE support enabled. The Suricata Packet structures are allocated by the mPIPE hardware by allocating the Suricata Packet structure immediatley before the mPIPE packet buffer and then pushing the mPIPE packet buffer pointer onto the mPIPE buffer stack. This way, mPIPE writes the packet data into the buffer, returns the mPIPE packet buffer pointer, which is then converted into a Suricata Packet pointer for processing inside Suricata. When the Packet is freed, the buffer is returned to mPIPE's buffer stack, by setting ReleasePacket to an mPIPE release specific function. The code checks for the largest Huge page available in Linux when Suricata is started. TILE-Gx supports Huge pages sizes of 16MB, 64MB, 256MB, 1GB and 4GB. Suricata then divides one of those page into packet buffers for mPIPE. The code is not yet optimized for high performance. Performance improvements will follow shortly. The code was originally written by Tom Decanio and then further modified by Tilera. This code has been tested with Tilera's Multicore Developement Environment (MDE) version 4.1.5. The TILEncore-Gx36 (PCIe card) and TILEmpower-Gx (1U Rack mount).
13 years ago
if (optarg != NULL) {
13 years ago
memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
strlcpy(suri->pcap_dev, optarg,
((strlen(optarg) < sizeof(suri->pcap_dev)) ?
(strlen(optarg) + 1) : sizeof(suri->pcap_dev)));
Add TILE-Gx mPIPE packet processing support. The TILE-Gx processor includes a packet processing engine, called mPIPE, that can deliver packets directly into user space memory. It handles buffer allocation and load balancing (either static 5-tuple hashing, or dynamic flow affinity hashing are used here). The new packet source code is in source-mpipe.c and source-mpipe.h A new Tile runmode is added that configures the Suricata pipelines in worker mode, where each thread does the entire packet processing pipeline. It scales across all the Gx chips sizes of 9, 16, 36 or 72 cores. The new runmode is in runmode-tile.c and runmode-tile.h The configure script detects the TILE-Gx architecture and defines HAVE_MPIPE, which is then used to conditionally enable the code to support mPIPE packet processing. Suricata runs on TILE-Gx even without mPIPE support enabled. The Suricata Packet structures are allocated by the mPIPE hardware by allocating the Suricata Packet structure immediatley before the mPIPE packet buffer and then pushing the mPIPE packet buffer pointer onto the mPIPE buffer stack. This way, mPIPE writes the packet data into the buffer, returns the mPIPE packet buffer pointer, which is then converted into a Suricata Packet pointer for processing inside Suricata. When the Packet is freed, the buffer is returned to mPIPE's buffer stack, by setting ReleasePacket to an mPIPE release specific function. The code checks for the largest Huge page available in Linux when Suricata is started. TILE-Gx supports Huge pages sizes of 16MB, 64MB, 256MB, 1GB and 4GB. Suricata then divides one of those page into packet buffers for mPIPE. The code is not yet optimized for high performance. Performance improvements will follow shortly. The code was originally written by Tom Decanio and then further modified by Tilera. This code has been tested with Tilera's Multicore Developement Environment (MDE) version 4.1.5. The TILEncore-Gx36 (PCIe card) and TILEmpower-Gx (1U Rack mount).
13 years ago
LiveRegisterDevice(optarg);
}
} else {
13 years ago
SCLogError(SC_ERR_MULTIPLE_RUN_MODE,
Add TILE-Gx mPIPE packet processing support. The TILE-Gx processor includes a packet processing engine, called mPIPE, that can deliver packets directly into user space memory. It handles buffer allocation and load balancing (either static 5-tuple hashing, or dynamic flow affinity hashing are used here). The new packet source code is in source-mpipe.c and source-mpipe.h A new Tile runmode is added that configures the Suricata pipelines in worker mode, where each thread does the entire packet processing pipeline. It scales across all the Gx chips sizes of 9, 16, 36 or 72 cores. The new runmode is in runmode-tile.c and runmode-tile.h The configure script detects the TILE-Gx architecture and defines HAVE_MPIPE, which is then used to conditionally enable the code to support mPIPE packet processing. Suricata runs on TILE-Gx even without mPIPE support enabled. The Suricata Packet structures are allocated by the mPIPE hardware by allocating the Suricata Packet structure immediatley before the mPIPE packet buffer and then pushing the mPIPE packet buffer pointer onto the mPIPE buffer stack. This way, mPIPE writes the packet data into the buffer, returns the mPIPE packet buffer pointer, which is then converted into a Suricata Packet pointer for processing inside Suricata. When the Packet is freed, the buffer is returned to mPIPE's buffer stack, by setting ReleasePacket to an mPIPE release specific function. The code checks for the largest Huge page available in Linux when Suricata is started. TILE-Gx supports Huge pages sizes of 16MB, 64MB, 256MB, 1GB and 4GB. Suricata then divides one of those page into packet buffers for mPIPE. The code is not yet optimized for high performance. Performance improvements will follow shortly. The code was originally written by Tom Decanio and then further modified by Tilera. This code has been tested with Tilera's Multicore Developement Environment (MDE) version 4.1.5. The TILEncore-Gx36 (PCIe card) and TILEmpower-Gx (1U Rack mount).
13 years ago
"more than one run mode has been specified");
usage(argv[0]);
exit(EXIT_FAILURE);
}
}
#endif
else if (strcmp((long_opts[option_index]).name, "set") == 0) {
if (optarg != NULL) {
/* Quick validation. */
char *val = strchr(optarg, '=');
if (val == NULL) {
SCLogError(SC_ERR_CMD_LINE,
"Invalid argument for --set, must be key=val.");
exit(EXIT_FAILURE);
}
if (!ConfSetFromString(optarg, 1)) {
fprintf(stderr, "Failed to set configuration value %s.",
optarg);
exit(EXIT_FAILURE);
}
}
}
break;
case 'c':
suri->conf_filename = optarg;
break;
case 'T':
SCLogInfo("Running suricata under test mode");
conf_test = 1;
if (ConfSetFinal("engine.init-failure-fatal", "1") != 1) {
fprintf(stderr, "ERROR: Failed to set engine init-failure-fatal.\n");
return TM_ECODE_FAILED;
}
break;
#ifndef OS_WIN32
case 'D':
suri->daemon = 1;
break;
#endif /* OS_WIN32 */
17 years ago
case 'h':
suri->run_mode = RUNMODE_PRINT_USAGE;
return TM_ECODE_OK;
case 'i':
if (optarg == NULL) {
SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -i");
return TM_ECODE_FAILED;
}
#ifdef HAVE_AF_PACKET
if (ParseCommandLineAfpacket(suri, optarg) != TM_ECODE_OK) {
return TM_ECODE_FAILED;
}
#else /* not afpacket */
/* warn user if netmap or pf-ring are available */
#if defined HAVE_PFRING || HAVE_NETMAP
int i = 0;
#ifdef HAVE_PFRING
i++;
#endif
#ifdef HAVE_NETMAP
i++;
#endif
SCLogWarning(SC_WARN_FASTER_CAPTURE_AVAILABLE, "faster capture "
"option%s %s available:"
#ifdef HAVE_PFRING
" PF_RING (--pfring-int=%s)"
#endif
#ifdef HAVE_NETMAP
" NETMAP (--netmap=%s)"
#endif
". Use --pcap=%s to suppress this warning",
i == 1 ? "" : "s", i == 1 ? "is" : "are"
#ifdef HAVE_PFRING
, optarg
#endif
#ifdef HAVE_NETMAP
, optarg
#endif
, optarg
);
#endif /* have faster methods */
if (ParseCommandLinePcapLive(suri, optarg) != TM_ECODE_OK) {
return TM_ECODE_FAILED;
}
#endif
break;
case 'l':
if (optarg == NULL) {
SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -l");
return TM_ECODE_FAILED;
}
if (ConfigSetLogDirectory(optarg) != TM_ECODE_OK) {
SCLogError(SC_ERR_FATAL, "Failed to set log directory.\n");
return TM_ECODE_FAILED;
}
if (ConfigCheckLogDirectory(optarg) != TM_ECODE_OK) {
SCLogError(SC_ERR_LOGDIR_CMDLINE, "The logging directory \"%s\""
" supplied at the commandline (-l %s) doesn't "
"exist. Shutting down the engine.", optarg, optarg);
return TM_ECODE_FAILED;
}
set_log_directory = 1;
break;
case 'q':
#ifdef NFQ
if (suri->run_mode == RUNMODE_UNKNOWN) {
suri->run_mode = RUNMODE_NFQ;
EngineModeSetIPS();
if (NFQRegisterQueue(optarg) == -1)
return TM_ECODE_FAILED;
} else if (suri->run_mode == RUNMODE_NFQ) {
if (NFQRegisterQueue(optarg) == -1)
return TM_ECODE_FAILED;
17 years ago
} else {
SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
"has been specified");
usage(argv[0]);
return TM_ECODE_FAILED;
17 years ago
}
#else
SCLogError(SC_ERR_NFQ_NOSUPPORT,"NFQUEUE not enabled. Make sure to pass --enable-nfqueue to configure when building.");
return TM_ECODE_FAILED;
#endif /* NFQ */
break;
case 'd':
#ifdef IPFW
if (suri->run_mode == RUNMODE_UNKNOWN) {
suri->run_mode = RUNMODE_IPFW;
EngineModeSetIPS();
if (IPFWRegisterQueue(optarg) == -1)
return TM_ECODE_FAILED;
} else if (suri->run_mode == RUNMODE_IPFW) {
if (IPFWRegisterQueue(optarg) == -1)
return TM_ECODE_FAILED;
17 years ago
} else {
SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
"has been specified");
usage(argv[0]);
return TM_ECODE_FAILED;
17 years ago
}
#else
SCLogError(SC_ERR_IPFW_NOSUPPORT,"IPFW not enabled. Make sure to pass --enable-ipfw to configure when building.");
return TM_ECODE_FAILED;
#endif /* IPFW */
break;
case 'r':
if (suri->run_mode == RUNMODE_UNKNOWN) {
suri->run_mode = RUNMODE_PCAP_FILE;
17 years ago
} else {
SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
"has been specified");
usage(argv[0]);
return TM_ECODE_FAILED;
17 years ago
}
if (ConfSetFinal("pcap-file.file", optarg) != 1) {
fprintf(stderr, "ERROR: Failed to set pcap-file.file\n");
return TM_ECODE_FAILED;
}
break;
case 's':
if (suri->sig_file != NULL) {
SCLogError(SC_ERR_CMD_LINE, "can't have multiple -s options or mix -s and -S.");
return TM_ECODE_FAILED;
}
suri->sig_file = optarg;
break;
case 'S':
if (suri->sig_file != NULL) {
SCLogError(SC_ERR_CMD_LINE, "can't have multiple -S options or mix -s and -S.");
return TM_ECODE_FAILED;
}
suri->sig_file = optarg;
suri->sig_file_exclusive = TRUE;
break;
case 'u':
#ifdef UNITTESTS
if (suri->run_mode == RUNMODE_UNKNOWN) {
suri->run_mode = RUNMODE_UNITTEST;
17 years ago
} else {
SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode has"
" been specified");
usage(argv[0]);
return TM_ECODE_FAILED;
17 years ago
}
#else
fprintf(stderr, "ERROR: Unit tests not enabled. Make sure to pass --enable-unittests to configure when building.\n");
return TM_ECODE_FAILED;
#endif /* UNITTESTS */
break;
case 'U':
#ifdef UNITTESTS
suri->regex_arg = optarg;
if(strlen(suri->regex_arg) == 0)
suri->regex_arg = NULL;
#endif
break;
case 'V':
suri->run_mode = RUNMODE_PRINT_VERSION;
return TM_ECODE_OK;
case 'F':
if (optarg == NULL) {
SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -F");
return TM_ECODE_FAILED;
}
SetBpfStringFromFile(optarg);
break;
case 'v':
suri->verbose++;
break;
case 'k':
if (optarg == NULL) {
SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -k");
return TM_ECODE_FAILED;
}
if (!strcmp("all", optarg))
suri->checksum_validation = 1;
else if (!strcmp("none", optarg))
suri->checksum_validation = 0;
else {
SCLogError(SC_ERR_INITIALIZATION, "option '%s' invalid for -k", optarg);
return TM_ECODE_FAILED;
}
break;
default:
17 years ago
usage(argv[0]);
return TM_ECODE_FAILED;
}
}
if (suri->disabled_detect && suri->sig_file != NULL) {
SCLogError(SC_ERR_INITIALIZATION, "can't use -s/-S when detection is disabled");
return TM_ECODE_FAILED;
}
#ifdef AFLFUZZ_CONF_TEST
if (conf_test && conf_test_force_success) {
(void)ConfSetFinal("engine.init-failure-fatal", "0");
}
#endif
if ((suri->run_mode == RUNMODE_UNIX_SOCKET) && set_log_directory) {
SCLogError(SC_ERR_INITIALIZATION, "can't use -l and unix socket runmode at the same time");
return TM_ECODE_FAILED;
}
if (list_app_layer_protocols)
suri->run_mode = RUNMODE_LIST_APP_LAYERS;
if (list_cuda_cards)
suri->run_mode = RUNMODE_LIST_CUDA_CARDS;
if (list_keywords)
suri->run_mode = RUNMODE_LIST_KEYWORDS;
if (list_unittests)
suri->run_mode = RUNMODE_LIST_UNITTEST;
if (dump_config)
suri->run_mode = RUNMODE_DUMP_CONFIG;
if (conf_test)
suri->run_mode = RUNMODE_CONF_TEST;
if (engine_analysis)
suri->run_mode = RUNMODE_ENGINE_ANALYSIS;
ret = SetBpfString(optind, argv);
if (ret != TM_ECODE_OK)
return ret;
return TM_ECODE_OK;
}
#ifdef OS_WIN32
static int WindowsInitService(int argc, char **argv)
{
if (SCRunningAsService()) {
char path[MAX_PATH];
char *p = NULL;
strlcpy(path, argv[0], MAX_PATH);
if ((p = strrchr(path, '\\'))) {
*p = '\0';
}
if (!SetCurrentDirectory(path)) {
SCLogError(SC_ERR_FATAL, "Can't set current directory to: %s", path);
return -1;
}
SCLogInfo("Current directory is set to: %s", path);
daemon = 1;
SCServiceInit(argc, argv);
}
/* Windows socket subsystem initialization */
WSADATA wsaData;
if (0 != WSAStartup(MAKEWORD(2, 2), &wsaData)) {
SCLogError(SC_ERR_FATAL, "Can't initialize Windows sockets: %d", WSAGetLastError());
return -1;
}
return 0;
}
#endif /* OS_WIN32 */
static int MayDaemonize(SCInstance *suri)
{
if (suri->daemon == 1 && suri->pid_filename == NULL) {
if (ConfGet("pid-file", &suri->pid_filename) == 1) {
SCLogInfo("Use pid file %s from config file.", suri->pid_filename);
} else {
suri->pid_filename = DEFAULT_PID_FILENAME;
}
}
if (suri->pid_filename != NULL && SCPidfileTestRunning(suri->pid_filename) != 0) {
suri->pid_filename = NULL;
return TM_ECODE_FAILED;
}
if (suri->daemon == 1) {
Daemonize();
}
if (suri->pid_filename != NULL) {
if (SCPidfileCreate(suri->pid_filename) != 0) {
suri->pid_filename = NULL;
SCLogError(SC_ERR_PIDFILE_DAEMON,
"Unable to create PID file, concurrent run of"
" Suricata can occur.");
SCLogError(SC_ERR_PIDFILE_DAEMON,
"PID file creation WILL be mandatory for daemon mode"
" in future version");
}
}
return TM_ECODE_OK;
}
static int InitSignalHandler(SCInstance *suri)
{
/* registering signals we use */
UtilSignalHandlerSetup(SIGINT, SignalHandlerSigint);
signals: cleanup signal handling Simplify handling of USR2 signal. The SCLogInfo usage could lead to dead locks as the SCLog API can do many complicated things including memory allocations, syslog calls, libjansson message construction. If an existing malloc call was interupted, it could lead to the following dead lock: 0 __lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:97 1 0x0000003140c7d2df in _L_lock_10176 () from /lib64/libc.so.6 2 0x0000003140c7ab83 in __libc_malloc (bytes=211543457408) at malloc.c:3655 3 0x0000003140c80ec2 in __strdup (s=0x259ca40 "[%i] %t - (%f:%l) <%d> (%n) -- ") at strdup.c:43 4 0x000000000059dd4a in SCLogMessageGetBuffer (tval=0x7fff52b47360, color=1, type=SC_LOG_OP_TYPE_REGULAR, buffer=0x7fff52b47370 "", buffer_size=2048, log_format=0x259ca40 "[%i] %t - (%f:%l) <%d> (%n) -- ", log_level=SC_LOG_INFO, file=0x63dd00 "suricata.c", line=287, function=0x640f50 "SignalHandlerSigusr2StartingUp", error_code=SC_OK, message=0x7fff52b47bb0 "Live rule reload only possible after engine completely started.") at util-debug.c:307 5 0x000000000059e940 in SCLogMessage (log_level=SC_LOG_INFO, file=0x63dd00 "suricata.c", line=287, function=0x640f50 "SignalHandlerSigusr2StartingUp", error_code=SC_OK, message=0x7fff52b47bb0 "Live rule reload only possible after engine completely started.") at util-debug.c:549 6 0x000000000057e374 in SignalHandlerSigusr2StartingUp (sig=12) at suricata.c:287 7 <signal handler called> 8 _int_malloc (av=0x3140f8fe80, bytes=<value optimized out>) at malloc.c:4751 9 0x0000003140c7ab1c in __libc_malloc (bytes=296) at malloc.c:3657 10 0x0000000000504d55 in FlowAlloc () at flow-util.c:60 11 0x00000000004fd909 in FlowInitConfig (quiet=0 '\000') at flow.c:454 12 0x0000000000584c8e in main (argc=6, argv=0x7fff52b4a3b8) at suricata.c:2300 This patch simply sets a variable and lets the main loop act on that.
11 years ago
UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2);
UtilSignalHandlerSetup(SIGTERM, SignalHandlerSigterm);
UtilSignalHandlerSetup(SIGPIPE, SIG_IGN);
UtilSignalHandlerSetup(SIGSYS, SIG_IGN);
#ifndef OS_WIN32
/* SIGHUP is not implemented on WIN32 */
UtilSignalHandlerSetup(SIGHUP, SignalHandlerSigHup);
/* Try to get user/group to run suricata as if
command line as not decide of that */
if (suri->do_setuid == FALSE && suri->do_setgid == FALSE) {
char *id;
if (ConfGet("run-as.user", &id) == 1) {
suri->do_setuid = TRUE;
suri->user_name = id;
}
if (ConfGet("run-as.group", &id) == 1) {
suri->do_setgid = TRUE;
suri->group_name = id;
}
}
/* Get the suricata user ID to given user ID */
if (suri->do_setuid == TRUE) {
if (SCGetUserID(suri->user_name, suri->group_name,
&suri->userid, &suri->groupid) != 0) {
SCLogError(SC_ERR_UID_FAILED, "failed in getting user ID");
return TM_ECODE_FAILED;
}
sc_set_caps = TRUE;
/* Get the suricata group ID to given group ID */
} else if (suri->do_setgid == TRUE) {
if (SCGetGroupID(suri->group_name, &suri->groupid) != 0) {
SCLogError(SC_ERR_GID_FAILED, "failed in getting group ID");
return TM_ECODE_FAILED;
}
sc_set_caps = TRUE;
}
#endif /* OS_WIN32 */
return TM_ECODE_OK;
}
int StartInternalRunMode(SCInstance *suri, int argc, char **argv)
{
/* Treat internal running mode */
switch(suri->run_mode) {
case RUNMODE_LIST_KEYWORDS:
ListKeywords(suri->keyword_info);
return TM_ECODE_DONE;
case RUNMODE_LIST_APP_LAYERS:
ListAppLayerProtocols();
return TM_ECODE_DONE;
case RUNMODE_PRINT_VERSION:
PrintVersion();
return TM_ECODE_DONE;
case RUNMODE_PRINT_BUILDINFO:
SCPrintBuildInfo();
return TM_ECODE_DONE;
case RUNMODE_PRINT_USAGE:
usage(argv[0]);
return TM_ECODE_DONE;
#ifdef __SC_CUDA_SUPPORT__
case RUNMODE_LIST_CUDA_CARDS:
return ListCudaCards();
#endif
case RUNMODE_LIST_RUNMODES:
RunModeListRunmodes();
return TM_ECODE_DONE;
case RUNMODE_LIST_UNITTEST:
RunUnittests(1, suri->regex_arg);
case RUNMODE_UNITTEST:
RunUnittests(0, suri->regex_arg);
#ifdef OS_WIN32
case RUNMODE_INSTALL_SERVICE:
if (SCServiceInstall(argc, argv)) {
return TM_ECODE_FAILED;
}
SCLogInfo("Suricata service has been successfuly installed.");
return TM_ECODE_DONE;
case RUNMODE_REMOVE_SERVICE:
if (SCServiceRemove(argc, argv)) {
return TM_ECODE_FAILED;
}
SCLogInfo("Suricata service has been successfuly removed.");
return TM_ECODE_DONE;
case RUNMODE_CHANGE_SERVICE_PARAMS:
if (SCServiceChangeParams(argc, argv)) {
return TM_ECODE_FAILED;
}
SCLogInfo("Suricata service startup parameters has been successfuly changed.");
return TM_ECODE_DONE;
#endif /* OS_WIN32 */
default:
/* simply continue for other running mode */
break;
}
return TM_ECODE_OK;
}
static int FinalizeRunMode(SCInstance *suri, char **argv)
{
switch (suri->run_mode) {
case RUNMODE_PCAP_FILE:
case RUNMODE_ERF_FILE:
case RUNMODE_ENGINE_ANALYSIS:
suri->offline = 1;
break;
case RUNMODE_UNKNOWN:
usage(argv[0]);
return TM_ECODE_FAILED;
default:
break;
}
/* Set the global run mode */
run_mode = suri->run_mode;
if (!CheckValidDaemonModes(suri->daemon, suri->run_mode)) {
return TM_ECODE_FAILED;
}
return TM_ECODE_OK;
}
static void SetupDelayedDetect(SCInstance *suri)
{
/* In offline mode delayed init of detect is a bad idea */
if (suri->offline) {
suri->delayed_detect = 0;
} else {
if (ConfGetBool("detect.delayed-detect", &suri->delayed_detect) != 1) {
ConfNode *denode = NULL;
ConfNode *decnf = ConfGetNode("detect-engine");
if (decnf != NULL) {
TAILQ_FOREACH(denode, &decnf->head, next) {
if (strcmp(denode->val, "delayed-detect") == 0) {
(void)ConfGetChildValueBool(denode, "delayed-detect", &suri->delayed_detect);
}
}
}
}
}
SCLogConfig("Delayed detect %s", suri->delayed_detect ? "enabled" : "disabled");
if (suri->delayed_detect) {
SCLogInfo("Packets will start being processed before signatures are active.");
}
}
static int LoadSignatures(DetectEngineCtx *de_ctx, SCInstance *suri)
{
if (SigLoadSignatures(de_ctx, suri->sig_file, suri->sig_file_exclusive) < 0) {
SCLogError(SC_ERR_NO_RULES_LOADED, "Loading signatures failed.");
if (de_ctx->failure_fatal)
return TM_ECODE_FAILED;
}
SCThresholdConfInitContext(de_ctx, NULL);
return TM_ECODE_OK;
}
static int ConfigGetCaptureValue(SCInstance *suri)
{
/* Pull the max pending packets from the config, if not found fall
* back on a sane default. */
if (ConfGetInt("max-pending-packets", &max_pending_packets) != 1)
max_pending_packets = DEFAULT_MAX_PENDING_PACKETS;
if (max_pending_packets >= 65535) {
SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY,
"Maximum max-pending-packets setting is 65534. "
"Please check %s for errors", suri->conf_filename);
return TM_ECODE_FAILED;
}
SCLogDebug("Max pending packets set to %"PRIiMAX, max_pending_packets);
/* Pull the default packet size from the config, if not found fall
* back on a sane default. */
char *temp_default_packet_size;
if ((ConfGet("default-packet-size", &temp_default_packet_size)) != 1) {
int lthread;
int nlive;
int strip_trailing_plus = 0;
switch (suri->run_mode) {
case RUNMODE_PCAP_DEV:
case RUNMODE_AFP_DEV:
12 years ago
case RUNMODE_NETMAP:
/* in netmap igb0+ has a special meaning, however the
* interface really is igb0 */
strip_trailing_plus = 1;
/* fall through */
case RUNMODE_PFRING:
nlive = LiveGetDeviceCount();
for (lthread = 0; lthread < nlive; lthread++) {
const char *live_dev = LiveGetDeviceName(lthread);
char dev[32];
(void)strlcpy(dev, live_dev, sizeof(dev));
if (strip_trailing_plus) {
size_t len = strlen(dev);
if (len && dev[len-1] == '+') {
dev[len-1] = '\0';
}
}
unsigned int iface_max_packet_size = GetIfaceMaxPacketSize(dev);
if (iface_max_packet_size > default_packet_size)
default_packet_size = iface_max_packet_size;
}
if (default_packet_size)
break;
/* fall through */
default:
default_packet_size = DEFAULT_PACKET_SIZE;
}
} else {
if (ParseSizeStringU32(temp_default_packet_size, &default_packet_size) < 0) {
SCLogError(SC_ERR_SIZE_PARSE, "Error parsing max-pending-packets "
"from conf file - %s. Killing engine",
temp_default_packet_size);
return TM_ECODE_FAILED;
}
}
SCLogDebug("Default packet size set to %"PRIu32, default_packet_size);
return TM_ECODE_OK;
}
/**
* This function is meant to contain code that needs
* to be run once the configuration has been loaded.
*/
static int PostConfLoadedSetup(SCInstance *suri)
{
char *hostmode = NULL;
/* load the pattern matchers */
MpmTableSetup();
#ifdef __SC_CUDA_SUPPORT__
MpmCudaEnvironmentSetup();
#endif
SpmTableSetup();
int disable_offloading;
if (ConfGetBool("capture.disable-offloading", &disable_offloading) == 0)
disable_offloading = 1;
if (disable_offloading) {
LiveSetOffloadDisable();
} else {
LiveSetOffloadWarn();
}
if (suri->checksum_validation == -1) {
char *cv = NULL;
if (ConfGet("capture.checksum-validation", &cv) == 1) {
if (strcmp(cv, "none") == 0) {
suri->checksum_validation = 0;
} else if (strcmp(cv, "all") == 0) {
suri->checksum_validation = 1;
}
}
}
switch (suri->checksum_validation) {
case 0:
ConfSet("stream.checksum-validation", "0");
break;
case 1:
ConfSet("stream.checksum-validation", "1");
break;
}
App layer API rewritten. The main files in question are: app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch]. Things addressed in this commit: - Brings out a proper separation between protocol detection phase and the parser phase. - The dns app layer now is registered such that we don't use "dnstcp" and "dnsudp" in the rules. A user who previously wrote a rule like this - "alert dnstcp....." or "alert dnsudp....." would now have to use, alert dns (ipproto:tcp;) or alert udp (app-layer-protocol:dns;) or alert ip (ipproto:udp; app-layer-protocol:dns;) The same rules extend to other another such protocol, dcerpc. - The app layer parser api now takes in the ipproto while registering callbacks. - The app inspection/detection engine also takes an ipproto. - All app layer parser functions now take direction as STREAM_TOSERVER or STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the functions. - FlowInitialize() and FlowRecycle() now resets proto to 0. This is needed by unittests, which would try to clean the flow, and that would call the api, AppLayerParserCleanupParserState(), which would try to clean the app state, but the app layer now needs an ipproto to figure out which api to internally call to clean the state, and if the ipproto is 0, it would return without trying to clean the state. - A lot of unittests are now updated where if they are using a flow and they need to use the app layer, we would set a flow ipproto. - The "app-layer" section in the yaml conf has also been updated as well.
13 years ago
AppLayerSetup();
/* Check for the existance of the default logging directory which we pick
* from suricata.yaml. If not found, shut the engine down */
suri->log_dir = ConfigGetLogDirectory();
if (ConfigCheckLogDirectory(suri->log_dir) != TM_ECODE_OK) {
SCLogError(SC_ERR_LOGDIR_CONFIG, "The logging directory \"%s\" "
"supplied by %s (default-log-dir) doesn't exist. "
"Shutting down the engine", suri->log_dir, suri->conf_filename);
SCReturnInt(TM_ECODE_FAILED);
}
if (ConfigGetCaptureValue(suri) != TM_ECODE_OK) {
SCReturnInt(TM_ECODE_FAILED);
}
if (ConfGet("host-mode", &hostmode) == 1) {
if (!strcmp(hostmode, "router")) {
host_mode = SURI_HOST_IS_ROUTER;
} else if (!strcmp(hostmode, "sniffer-only")) {
host_mode = SURI_HOST_IS_SNIFFER_ONLY;
} else {
if (strcmp(hostmode, "auto") != 0) {
WarnInvalidConfEntry("host-mode", "%s", "auto");
}
if (EngineModeIsIPS()) {
host_mode = SURI_HOST_IS_ROUTER;
} else {
host_mode = SURI_HOST_IS_SNIFFER_ONLY;
}
}
} else {
if (EngineModeIsIPS()) {
host_mode = SURI_HOST_IS_ROUTER;
SCLogInfo("No 'host-mode': suricata is in IPS mode, using "
"default setting 'router'");
} else {
host_mode = SURI_HOST_IS_SNIFFER_ONLY;
SCLogInfo("No 'host-mode': suricata is in IDS mode, using "
"default setting 'sniffer-only'");
}
}
#ifdef NFQ
if (suri->run_mode == RUNMODE_NFQ)
NFQInitConfig(FALSE);
#endif
/* Load the Host-OS lookup. */
SCHInfoLoadFromConfig();
if (suri->run_mode != RUNMODE_UNIX_SOCKET) {
DefragInit();
}
if (suri->run_mode == RUNMODE_ENGINE_ANALYSIS) {
SCLogInfo("== Carrying out Engine Analysis ==");
char *temp = NULL;
if (ConfGet("engine-analysis", &temp) == 0) {
SCLogInfo("no engine-analysis parameter(s) defined in conf file. "
"Please define/enable them in the conf to use this "
"feature.");
SCReturnInt(TM_ECODE_FAILED);
}
}
/* hardcoded initialization code */
SigTableSetup(); /* load the rule keywords */
TmqhSetup();
StorageInit();
CIDRInit();
SigParsePrepare();
#ifdef PROFILING
if (suri->run_mode != RUNMODE_UNIX_SOCKET) {
SCProfilingRulesGlobalInit();
SCProfilingKeywordsGlobalInit();
SCProfilingSghsGlobalInit();
SCProfilingInit();
}
#endif /* PROFILING */
SCReputationInitCtx();
SCProtoNameInit();
TagInitCtx();
PacketAlertTagInit();
ThresholdInit();
HostBitInitCtx();
IPPairBitInitCtx();
if (DetectAddressTestConfVars() < 0) {
SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY,
"basic address vars test failed. Please check %s for errors",
suri->conf_filename);
SCReturnInt(TM_ECODE_FAILED);
}
if (DetectPortTestConfVars() < 0) {
SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY,
"basic port vars test failed. Please check %s for errors",
suri->conf_filename);
SCReturnInt(TM_ECODE_FAILED);
}
RegisterAllModules();
AppLayerHtpNeedFileInspection();
StorageFinalize();
TmModuleRunInit();
if (MayDaemonize(suri) != TM_ECODE_OK)
SCReturnInt(TM_ECODE_FAILED);
if (InitSignalHandler(suri) != TM_ECODE_OK)
SCReturnInt(TM_ECODE_FAILED);
#ifdef HAVE_NSS
if (suri->run_mode != RUNMODE_CONF_TEST) {
/* init NSS for hashing */
PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
NSS_NoDB_Init(NULL);
}
#endif
if (suri->disabled_detect) {
/* disable raw reassembly */
(void)ConfSetFinal("stream.reassembly.raw", "false");
}
HostInitConfig(HOST_VERBOSE);
if (MagicInit() != 0)
SCReturnInt(TM_ECODE_FAILED);
SCAsn1LoadConfig();
CoredumpLoadConfig();
SCReturnInt(TM_ECODE_OK);
}
int main(int argc, char **argv)
{
SCInstance suri;
SCInstanceInit(&suri);
suri.progname = argv[0];
sc_set_caps = FALSE;
SC_ATOMIC_INIT(engine_stage);
/* initialize the logging subsys */
SCLogInitLogModule(NULL);
if (SCSetThreadName("Suricata-Main") < 0) {
SCLogWarning(SC_ERR_THREAD_INIT, "Unable to set thread name");
}
ParseSizeInit();
RunModeRegisterRunModes();
/* By default use IDS mode, but if nfq or ipfw
* are specified, IPS mode will overwrite this */
EngineModeSetIDS();
#ifdef OS_WIN32
/* service initialization */
if (WindowsInit(argc, argv) != 0) {
exit(EXIT_FAILURE);
}
#endif /* OS_WIN32 */
/* Initialize the configuration module. */
ConfInit();
if (ParseCommandLine(argc, argv, &suri) != TM_ECODE_OK) {
exit(EXIT_FAILURE);
}
if (FinalizeRunMode(&suri, argv) != TM_ECODE_OK) {
exit(EXIT_FAILURE);
}
switch (StartInternalRunMode(&suri, argc, argv)) {
case TM_ECODE_DONE:
exit(EXIT_SUCCESS);
case TM_ECODE_FAILED:
exit(EXIT_FAILURE);
}
#ifdef __SC_CUDA_SUPPORT__
/* Init the CUDA environment */
SCCudaInitCudaEnvironment();
CudaBufferInit();
#endif
/* Initializations for global vars, queues, etc (memsets, mutex init..) */
GlobalInits();
TimeInit();
SupportFastPatternForSigMatchTypes();
if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
StatsInit();
}
/* Load yaml configuration file if provided. */
if (LoadYamlConfig(&suri) != TM_ECODE_OK) {
exit(EXIT_FAILURE);
}
if (suri.run_mode == RUNMODE_DUMP_CONFIG) {
ConfDump();
exit(EXIT_SUCCESS);
}
/* Since our config is now loaded we can finish configurating the
* logging module. */
SCLogLoadConfig(suri.daemon, suri.verbose);
SCPrintVersion();
UtilCpuPrintSummary();
if (ParseInterfacesList(suri.run_mode, suri.pcap_dev) != TM_ECODE_OK) {
exit(EXIT_FAILURE);
}
if (PostConfLoadedSetup(&suri) != TM_ECODE_OK) {
exit(EXIT_FAILURE);
}
if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
FlowInitConfig(FLOW_VERBOSE);
StreamTcpInitConfig(STREAM_VERBOSE);
IPPairInitConfig(IPPAIR_VERBOSE);
AppLayerRegisterGlobalCounters();
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
}
DetectEngineCtx *de_ctx = NULL;
if (!suri.disabled_detect) {
SCClassConfInit();
SCReferenceConfInit();
SetupDelayedDetect(&suri);
int mt_enabled = 0;
(void)ConfGetBool("multi-detect.enabled", &mt_enabled);
int default_tenant = 0;
if (mt_enabled)
(void)ConfGetBool("multi-detect.default", &default_tenant);
if (DetectEngineMultiTenantSetup() == -1) {
SCLogError(SC_ERR_INITIALIZATION, "initializing multi-detect "
"detection engine contexts failed.");
exit(EXIT_FAILURE);
}
if ((suri.delayed_detect || (mt_enabled && !default_tenant)) &&
(suri.run_mode != RUNMODE_CONF_TEST)) {
de_ctx = DetectEngineCtxInitMinimal();
} else {
de_ctx = DetectEngineCtxInit();
}
if (de_ctx == NULL) {
SCLogError(SC_ERR_INITIALIZATION, "initializing detection engine "
"context failed.");
exit(EXIT_FAILURE);
}
#ifdef __SC_CUDA_SUPPORT__
if (PatternMatchDefaultMatcher() == MPM_AC_CUDA)
CudaVarsSetDeCtx(de_ctx);
#endif /* __SC_CUDA_SUPPORT__ */
if (!de_ctx->minimal) {
if (LoadSignatures(de_ctx, &suri) != TM_ECODE_OK)
exit(EXIT_FAILURE);
if (suri.run_mode == RUNMODE_ENGINE_ANALYSIS) {
exit(EXIT_SUCCESS);
}
}
DetectEngineAddToMaster(de_ctx);
} else {
/* tell the app layer to consider only the log id */
RegisterAppLayerGetActiveTxIdFunc(AppLayerTransactionGetActiveLogOnly);
}
SCSetStartTime(&suri);
SCDropMainThreadCaps(suri.userid, suri.groupid);
if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
RunModeInitializeOutputs();
StatsSetupPostConfig();
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
}
if (suri.run_mode == RUNMODE_CONF_TEST){
SCLogNotice("Configuration provided was successfully loaded. Exiting.");
MagicDeinit();
exit(EXIT_SUCCESS);
}
RunModeDispatch(suri.run_mode, suri.runmode_custom_mode);
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
/* In Unix socket runmode, Flow manager is started on demand */
if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
/* Spawn the unix socket manager thread */
int unix_socket = ConfUnixSocketIsEnable();
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
if (unix_socket == 1) {
UnixManagerThreadSpawn(0);
#ifdef BUILD_UNIX_SOCKET
UnixManagerRegisterCommand("iface-stat", LiveDeviceIfaceStat, NULL,
UNIX_CMD_TAKE_ARGS);
UnixManagerRegisterCommand("iface-list", LiveDeviceIfaceList, NULL, 0);
#endif
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
}
/* Spawn the flow manager thread */
FlowManagerThreadSpawn();
FlowRecyclerThreadSpawn();
StatsSpawnThreads();
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
}
/* Wait till all the threads have been initialized */
if (TmThreadWaitOnThreadInit() == TM_ECODE_FAILED) {
SCLogError(SC_ERR_INITIALIZATION, "Engine initialization failed, "
"aborting...");
exit(EXIT_FAILURE);
}
(void) SC_ATOMIC_CAS(&engine_stage, SURICATA_INIT, SURICATA_RUNTIME);
PacketPoolPostRunmodes();
/* Un-pause all the paused threads */
TmThreadContinueThreads();
/* registering singal handlers we use. We register usr2 here, so that one
* can't call it during the first sig load phase or while threads are still
* starting up. */
if (DetectEngineEnabled() && suri.sig_file == NULL &&
suri.delayed_detect == 0)
UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2);
if (suri.delayed_detect) {
/* force 'reload', this will load the rules and swap engines */
DetectEngineReload(&suri);
SCLogNotice("Signature(s) loaded, Detect thread(s) activated.");
}
#ifdef DBG_MEM_ALLOC
SCLogInfo("Memory used at startup: %"PRIdMAX, (intmax_t)global_mem);
#ifdef DBG_MEM_ALLOC_SKIP_STARTUP
print_mem_flag = 1;
#endif
#endif
int engine_retval = EXIT_SUCCESS;
while(1) {
if (sigterm_count || sigint_count) {
suricata_ctl_flags |= SURICATA_STOP;
}
if (suricata_ctl_flags & SURICATA_STOP) {
SCLogNotice("Signal Received. Stopping engine.");
break;
}
TmThreadCheckThreadState();
if (sighup_count > 0) {
OutputNotifyFileRotation();
sighup_count--;
}
if (sigusr2_count > 0) {
signals: cleanup signal handling Simplify handling of USR2 signal. The SCLogInfo usage could lead to dead locks as the SCLog API can do many complicated things including memory allocations, syslog calls, libjansson message construction. If an existing malloc call was interupted, it could lead to the following dead lock: 0 __lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:97 1 0x0000003140c7d2df in _L_lock_10176 () from /lib64/libc.so.6 2 0x0000003140c7ab83 in __libc_malloc (bytes=211543457408) at malloc.c:3655 3 0x0000003140c80ec2 in __strdup (s=0x259ca40 "[%i] %t - (%f:%l) <%d> (%n) -- ") at strdup.c:43 4 0x000000000059dd4a in SCLogMessageGetBuffer (tval=0x7fff52b47360, color=1, type=SC_LOG_OP_TYPE_REGULAR, buffer=0x7fff52b47370 "", buffer_size=2048, log_format=0x259ca40 "[%i] %t - (%f:%l) <%d> (%n) -- ", log_level=SC_LOG_INFO, file=0x63dd00 "suricata.c", line=287, function=0x640f50 "SignalHandlerSigusr2StartingUp", error_code=SC_OK, message=0x7fff52b47bb0 "Live rule reload only possible after engine completely started.") at util-debug.c:307 5 0x000000000059e940 in SCLogMessage (log_level=SC_LOG_INFO, file=0x63dd00 "suricata.c", line=287, function=0x640f50 "SignalHandlerSigusr2StartingUp", error_code=SC_OK, message=0x7fff52b47bb0 "Live rule reload only possible after engine completely started.") at util-debug.c:549 6 0x000000000057e374 in SignalHandlerSigusr2StartingUp (sig=12) at suricata.c:287 7 <signal handler called> 8 _int_malloc (av=0x3140f8fe80, bytes=<value optimized out>) at malloc.c:4751 9 0x0000003140c7ab1c in __libc_malloc (bytes=296) at malloc.c:3657 10 0x0000000000504d55 in FlowAlloc () at flow-util.c:60 11 0x00000000004fd909 in FlowInitConfig (quiet=0 '\000') at flow.c:454 12 0x0000000000584c8e in main (argc=6, argv=0x7fff52b4a3b8) at suricata.c:2300 This patch simply sets a variable and lets the main loop act on that.
11 years ago
if (suri.sig_file != NULL) {
SCLogWarning(SC_ERR_LIVE_RULE_SWAP, "Live rule reload not "
"possible if -s or -S option used at runtime.");
sigusr2_count--;
signals: cleanup signal handling Simplify handling of USR2 signal. The SCLogInfo usage could lead to dead locks as the SCLog API can do many complicated things including memory allocations, syslog calls, libjansson message construction. If an existing malloc call was interupted, it could lead to the following dead lock: 0 __lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:97 1 0x0000003140c7d2df in _L_lock_10176 () from /lib64/libc.so.6 2 0x0000003140c7ab83 in __libc_malloc (bytes=211543457408) at malloc.c:3655 3 0x0000003140c80ec2 in __strdup (s=0x259ca40 "[%i] %t - (%f:%l) <%d> (%n) -- ") at strdup.c:43 4 0x000000000059dd4a in SCLogMessageGetBuffer (tval=0x7fff52b47360, color=1, type=SC_LOG_OP_TYPE_REGULAR, buffer=0x7fff52b47370 "", buffer_size=2048, log_format=0x259ca40 "[%i] %t - (%f:%l) <%d> (%n) -- ", log_level=SC_LOG_INFO, file=0x63dd00 "suricata.c", line=287, function=0x640f50 "SignalHandlerSigusr2StartingUp", error_code=SC_OK, message=0x7fff52b47bb0 "Live rule reload only possible after engine completely started.") at util-debug.c:307 5 0x000000000059e940 in SCLogMessage (log_level=SC_LOG_INFO, file=0x63dd00 "suricata.c", line=287, function=0x640f50 "SignalHandlerSigusr2StartingUp", error_code=SC_OK, message=0x7fff52b47bb0 "Live rule reload only possible after engine completely started.") at util-debug.c:549 6 0x000000000057e374 in SignalHandlerSigusr2StartingUp (sig=12) at suricata.c:287 7 <signal handler called> 8 _int_malloc (av=0x3140f8fe80, bytes=<value optimized out>) at malloc.c:4751 9 0x0000003140c7ab1c in __libc_malloc (bytes=296) at malloc.c:3657 10 0x0000000000504d55 in FlowAlloc () at flow-util.c:60 11 0x00000000004fd909 in FlowInitConfig (quiet=0 '\000') at flow.c:454 12 0x0000000000584c8e in main (argc=6, argv=0x7fff52b4a3b8) at suricata.c:2300 This patch simply sets a variable and lets the main loop act on that.
11 years ago
} else {
if (!(DetectEngineReloadIsStart())) {
DetectEngineReloadStart();
DetectEngineReload(&suri);
DetectEngineReloadSetDone();
sigusr2_count--;
}
signals: cleanup signal handling Simplify handling of USR2 signal. The SCLogInfo usage could lead to dead locks as the SCLog API can do many complicated things including memory allocations, syslog calls, libjansson message construction. If an existing malloc call was interupted, it could lead to the following dead lock: 0 __lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:97 1 0x0000003140c7d2df in _L_lock_10176 () from /lib64/libc.so.6 2 0x0000003140c7ab83 in __libc_malloc (bytes=211543457408) at malloc.c:3655 3 0x0000003140c80ec2 in __strdup (s=0x259ca40 "[%i] %t - (%f:%l) <%d> (%n) -- ") at strdup.c:43 4 0x000000000059dd4a in SCLogMessageGetBuffer (tval=0x7fff52b47360, color=1, type=SC_LOG_OP_TYPE_REGULAR, buffer=0x7fff52b47370 "", buffer_size=2048, log_format=0x259ca40 "[%i] %t - (%f:%l) <%d> (%n) -- ", log_level=SC_LOG_INFO, file=0x63dd00 "suricata.c", line=287, function=0x640f50 "SignalHandlerSigusr2StartingUp", error_code=SC_OK, message=0x7fff52b47bb0 "Live rule reload only possible after engine completely started.") at util-debug.c:307 5 0x000000000059e940 in SCLogMessage (log_level=SC_LOG_INFO, file=0x63dd00 "suricata.c", line=287, function=0x640f50 "SignalHandlerSigusr2StartingUp", error_code=SC_OK, message=0x7fff52b47bb0 "Live rule reload only possible after engine completely started.") at util-debug.c:549 6 0x000000000057e374 in SignalHandlerSigusr2StartingUp (sig=12) at suricata.c:287 7 <signal handler called> 8 _int_malloc (av=0x3140f8fe80, bytes=<value optimized out>) at malloc.c:4751 9 0x0000003140c7ab1c in __libc_malloc (bytes=296) at malloc.c:3657 10 0x0000000000504d55 in FlowAlloc () at flow-util.c:60 11 0x00000000004fd909 in FlowInitConfig (quiet=0 '\000') at flow.c:454 12 0x0000000000584c8e in main (argc=6, argv=0x7fff52b4a3b8) at suricata.c:2300 This patch simply sets a variable and lets the main loop act on that.
11 years ago
}
} else if (DetectEngineReloadIsStart()) {
signals: cleanup signal handling Simplify handling of USR2 signal. The SCLogInfo usage could lead to dead locks as the SCLog API can do many complicated things including memory allocations, syslog calls, libjansson message construction. If an existing malloc call was interupted, it could lead to the following dead lock: 0 __lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:97 1 0x0000003140c7d2df in _L_lock_10176 () from /lib64/libc.so.6 2 0x0000003140c7ab83 in __libc_malloc (bytes=211543457408) at malloc.c:3655 3 0x0000003140c80ec2 in __strdup (s=0x259ca40 "[%i] %t - (%f:%l) <%d> (%n) -- ") at strdup.c:43 4 0x000000000059dd4a in SCLogMessageGetBuffer (tval=0x7fff52b47360, color=1, type=SC_LOG_OP_TYPE_REGULAR, buffer=0x7fff52b47370 "", buffer_size=2048, log_format=0x259ca40 "[%i] %t - (%f:%l) <%d> (%n) -- ", log_level=SC_LOG_INFO, file=0x63dd00 "suricata.c", line=287, function=0x640f50 "SignalHandlerSigusr2StartingUp", error_code=SC_OK, message=0x7fff52b47bb0 "Live rule reload only possible after engine completely started.") at util-debug.c:307 5 0x000000000059e940 in SCLogMessage (log_level=SC_LOG_INFO, file=0x63dd00 "suricata.c", line=287, function=0x640f50 "SignalHandlerSigusr2StartingUp", error_code=SC_OK, message=0x7fff52b47bb0 "Live rule reload only possible after engine completely started.") at util-debug.c:549 6 0x000000000057e374 in SignalHandlerSigusr2StartingUp (sig=12) at suricata.c:287 7 <signal handler called> 8 _int_malloc (av=0x3140f8fe80, bytes=<value optimized out>) at malloc.c:4751 9 0x0000003140c7ab1c in __libc_malloc (bytes=296) at malloc.c:3657 10 0x0000000000504d55 in FlowAlloc () at flow-util.c:60 11 0x00000000004fd909 in FlowInitConfig (quiet=0 '\000') at flow.c:454 12 0x0000000000584c8e in main (argc=6, argv=0x7fff52b4a3b8) at suricata.c:2300 This patch simply sets a variable and lets the main loop act on that.
11 years ago
if (suri.sig_file != NULL) {
SCLogWarning(SC_ERR_LIVE_RULE_SWAP, "Live rule reload not "
"possible if -s or -S option used at runtime.");
DetectEngineReloadSetDone();
signals: cleanup signal handling Simplify handling of USR2 signal. The SCLogInfo usage could lead to dead locks as the SCLog API can do many complicated things including memory allocations, syslog calls, libjansson message construction. If an existing malloc call was interupted, it could lead to the following dead lock: 0 __lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:97 1 0x0000003140c7d2df in _L_lock_10176 () from /lib64/libc.so.6 2 0x0000003140c7ab83 in __libc_malloc (bytes=211543457408) at malloc.c:3655 3 0x0000003140c80ec2 in __strdup (s=0x259ca40 "[%i] %t - (%f:%l) <%d> (%n) -- ") at strdup.c:43 4 0x000000000059dd4a in SCLogMessageGetBuffer (tval=0x7fff52b47360, color=1, type=SC_LOG_OP_TYPE_REGULAR, buffer=0x7fff52b47370 "", buffer_size=2048, log_format=0x259ca40 "[%i] %t - (%f:%l) <%d> (%n) -- ", log_level=SC_LOG_INFO, file=0x63dd00 "suricata.c", line=287, function=0x640f50 "SignalHandlerSigusr2StartingUp", error_code=SC_OK, message=0x7fff52b47bb0 "Live rule reload only possible after engine completely started.") at util-debug.c:307 5 0x000000000059e940 in SCLogMessage (log_level=SC_LOG_INFO, file=0x63dd00 "suricata.c", line=287, function=0x640f50 "SignalHandlerSigusr2StartingUp", error_code=SC_OK, message=0x7fff52b47bb0 "Live rule reload only possible after engine completely started.") at util-debug.c:549 6 0x000000000057e374 in SignalHandlerSigusr2StartingUp (sig=12) at suricata.c:287 7 <signal handler called> 8 _int_malloc (av=0x3140f8fe80, bytes=<value optimized out>) at malloc.c:4751 9 0x0000003140c7ab1c in __libc_malloc (bytes=296) at malloc.c:3657 10 0x0000000000504d55 in FlowAlloc () at flow-util.c:60 11 0x00000000004fd909 in FlowInitConfig (quiet=0 '\000') at flow.c:454 12 0x0000000000584c8e in main (argc=6, argv=0x7fff52b4a3b8) at suricata.c:2300 This patch simply sets a variable and lets the main loop act on that.
11 years ago
} else {
DetectEngineReload(&suri);
signals: cleanup signal handling Simplify handling of USR2 signal. The SCLogInfo usage could lead to dead locks as the SCLog API can do many complicated things including memory allocations, syslog calls, libjansson message construction. If an existing malloc call was interupted, it could lead to the following dead lock: 0 __lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:97 1 0x0000003140c7d2df in _L_lock_10176 () from /lib64/libc.so.6 2 0x0000003140c7ab83 in __libc_malloc (bytes=211543457408) at malloc.c:3655 3 0x0000003140c80ec2 in __strdup (s=0x259ca40 "[%i] %t - (%f:%l) <%d> (%n) -- ") at strdup.c:43 4 0x000000000059dd4a in SCLogMessageGetBuffer (tval=0x7fff52b47360, color=1, type=SC_LOG_OP_TYPE_REGULAR, buffer=0x7fff52b47370 "", buffer_size=2048, log_format=0x259ca40 "[%i] %t - (%f:%l) <%d> (%n) -- ", log_level=SC_LOG_INFO, file=0x63dd00 "suricata.c", line=287, function=0x640f50 "SignalHandlerSigusr2StartingUp", error_code=SC_OK, message=0x7fff52b47bb0 "Live rule reload only possible after engine completely started.") at util-debug.c:307 5 0x000000000059e940 in SCLogMessage (log_level=SC_LOG_INFO, file=0x63dd00 "suricata.c", line=287, function=0x640f50 "SignalHandlerSigusr2StartingUp", error_code=SC_OK, message=0x7fff52b47bb0 "Live rule reload only possible after engine completely started.") at util-debug.c:549 6 0x000000000057e374 in SignalHandlerSigusr2StartingUp (sig=12) at suricata.c:287 7 <signal handler called> 8 _int_malloc (av=0x3140f8fe80, bytes=<value optimized out>) at malloc.c:4751 9 0x0000003140c7ab1c in __libc_malloc (bytes=296) at malloc.c:3657 10 0x0000000000504d55 in FlowAlloc () at flow-util.c:60 11 0x00000000004fd909 in FlowInitConfig (quiet=0 '\000') at flow.c:454 12 0x0000000000584c8e in main (argc=6, argv=0x7fff52b4a3b8) at suricata.c:2300 This patch simply sets a variable and lets the main loop act on that.
11 years ago
DetectEngineReloadSetDone();
}
}
usleep(10* 1000);
}
/* Update the engine stage/status flag */
(void) SC_ATOMIC_CAS(&engine_stage, SURICATA_RUNTIME, SURICATA_DEINIT);
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
UnixSocketKillSocketThread();
if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
/* First we need to disable the flow manager thread */
FlowDisableFlowManagerThread();
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
}
/* Disable packet acquisition first */
TmThreadDisableReceiveThreads();
if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
/* we need a packet pool for FlowForceReassembly */
PacketPoolInit();
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
FlowForceReassembly();
/* kill receive threads when they have processed all
* flow timeout packets */
TmThreadDisablePacketThreads();
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
}
SCPrintElapsedTime(&suri);
/* before TmThreadKillThreads, as otherwise that kills it
* but more slowly */
if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
FlowDisableFlowRecyclerThread();
}
/* kill remaining threads */
TmThreadKillThreads();
if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
/* destroy the packet pool for flow reassembly after all
* the other threads are gone. */
PacketPoolDestroy();
StatsReleaseResources();
IPPairShutdown();
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
FlowShutdown();
StreamTcpFreeConfig(STREAM_VERBOSE);
}
HostShutdown();
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
HTPFreeConfig();
HTPAtExitPrintStats();
#ifdef DBG_MEM_ALLOC
SCLogInfo("Total memory used (without SCFree()): %"PRIdMAX, (intmax_t)global_mem);
#ifdef DBG_MEM_ALLOC_SKIP_STARTUP
print_mem_flag = 0;
#endif
#endif
SCPidfileRemove(suri.pid_filename);
AppLayerHtpPrintStats();
/** TODO this can do into it's own func */
de_ctx = DetectEngineGetCurrent();
if (de_ctx) {
DetectEngineMoveToFreeList(de_ctx);
DetectEngineDeReference(&de_ctx);
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
}
DetectEnginePruneFreeList();
App layer API rewritten. The main files in question are: app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch]. Things addressed in this commit: - Brings out a proper separation between protocol detection phase and the parser phase. - The dns app layer now is registered such that we don't use "dnstcp" and "dnsudp" in the rules. A user who previously wrote a rule like this - "alert dnstcp....." or "alert dnsudp....." would now have to use, alert dns (ipproto:tcp;) or alert udp (app-layer-protocol:dns;) or alert ip (ipproto:udp; app-layer-protocol:dns;) The same rules extend to other another such protocol, dcerpc. - The app layer parser api now takes in the ipproto while registering callbacks. - The app inspection/detection engine also takes an ipproto. - All app layer parser functions now take direction as STREAM_TOSERVER or STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the functions. - FlowInitialize() and FlowRecycle() now resets proto to 0. This is needed by unittests, which would try to clean the flow, and that would call the api, AppLayerParserCleanupParserState(), which would try to clean the app state, but the app layer now needs an ipproto to figure out which api to internally call to clean the state, and if the ipproto is 0, it would return without trying to clean the state. - A lot of unittests are now updated where if they are using a flow and they need to use the app layer, we would set a flow ipproto. - The "app-layer" section in the yaml conf has also been updated as well.
13 years ago
AppLayerDeSetup();
TagDestroyCtx();
LiveDeviceListClean();
RunModeShutDown();
OutputDeregisterAll();
TimeDeinit();
SCProtoNameDeInit();
if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
unix-manager: add unix command socket and associated script This patch introduces a unix command socket. JSON formatted messages can be exchanged between suricata and a program connecting to a dedicated socket. The protocol is the following: * Client connects to the socket * It sends a version message: { "version": "$VERSION_ID" } * Server answers with { "return": "OK|NOK" } If server returns OK, the client is now allowed to send command. The format of command is the following: { "command": "pcap-file", "arguments": { "filename": "smtp-clean.pcap", "output-dir": "/tmp/out" } } The server will try to execute the "command" specified with the (optional) provided "arguments". The answer by server is the following: { "return": "OK|NOK", "message": JSON_OBJECT or information string } A simple script is provided and is available under scripts/suricatasc. It is not intended to be enterprise-grade tool but it is more a proof of concept/example code. The first command line argument of suricatasc is used to specify the socket to connect to. Configuration of the feature is made in the YAML under the 'unix-command' section: unix-command: enabled: yes filename: custom.socket The path specified in 'filename' is not absolute and is relative to the state directory. A new running mode called 'unix-socket' is also added. When starting in this mode, only a unix socket manager is started. When it receives a 'pcap-file' command, the manager start a 'pcap-file' running mode which does not really leave at the end of file but simply exit. The manager is then able to start a new running mode with a new file. To start this mode, Suricata must be started with the --unix-socket option which has an optional argument which fix the file name of the socket. The path is not absolute and is relative to the state directory. THe 'pcap-file' command adds a file to the list of files to treat. For each pcap file, a pcap file running mode is started and the output directory is changed to what specified in the command. The running mode specified in the 'runmode' YAML setting is used to select which running mode must be use for the pcap file treatment. This requires modification in suricata.c file where initialisation code is now conditional to the fact 'unix-socket' mode is not used. Two other commands exists to get info on the remaining tasks: * pcap-file-number: return the number of files in the waiting queue * pcap-file-list: return the list of waiting files 'pcap-file-list' returns a structured object as message. The structure is the following: { 'count': 2, 'files': ['file1.pcap', 'file2.pcap'] }
15 years ago
DefragDestroy();
}
if (!suri.disabled_detect) {
SCReferenceConfDeinit();
SCClassConfDeinit();
}
MagicDeinit();
TmqhCleanup();
TmModuleRunDeInit();
ParseSizeDeinit();
#ifdef HAVE_NSS
NSS_Shutdown();
PR_Cleanup();
#endif
#ifdef HAVE_AF_PACKET
af-packet: IPS and TAP feature This patch adds a new feature to AF_PACKET capture mode. It is now possible to use AF_PACKET in IPS and TAP mode: all traffic received on a interface will be forwarded (at the Ethernet level) to an other interface. To do so, Suricata create a raw socket and sends the receive packets to a interface designed in the configuration file. This patch adds two variables to the configuration of af-packet interface: copy-mode: ips or tap copy-iface: eth1 #the interface where packet are copied If copy-mode is set to ips then the packet wth action DROP are not copied to the destination interface. If copy-mode is set to tap, all packets are copied to the destination interface. Any other value of copy-mode results in the feature to be unused. There is no default interface for copy-iface and the variable has to be set for the ids or tap mode to work. For now, this feature depends of the release data system. This implies you need to activate the ring mode and zero copy. Basically use-mmap has to be set to yes. This patch adds a peering of AF_PACKET sockets from the thread on one interface to the threads on another interface. Peering is necessary as if we use an other socket the capture socket receives all emitted packets. This is made using a new AFPPeer structure to avoid direct interaction between AFPTreadVars. There is currently a bug in Linux kernel (prior to 3.6) and it is not possible to use multiple threads. You need to setup two interfaces with equality on the threads variable. copy-mode variable must be set on the two interfaces and use-mmap must be set to activated. A valid configuration for an IPS using eth0 and vboxnet1 interfaces will look like: af-packet: - interface: eth0 threads: 1 defrag: yes cluster-type: cluster_flow cluster-id: 98 copy-mode: ips copy-iface: vboxnet1 buffer-size: 64535 use-mmap: yes - interface: vboxnet1 threads: 1 cluster-id: 97 defrag: yes cluster-type: cluster_flow copy-mode: ips copy-iface: eth0 buffer-size: 64535 use-mmap: yes
14 years ago
AFPPeersListClean();
#endif
af-packet: IPS and TAP feature This patch adds a new feature to AF_PACKET capture mode. It is now possible to use AF_PACKET in IPS and TAP mode: all traffic received on a interface will be forwarded (at the Ethernet level) to an other interface. To do so, Suricata create a raw socket and sends the receive packets to a interface designed in the configuration file. This patch adds two variables to the configuration of af-packet interface: copy-mode: ips or tap copy-iface: eth1 #the interface where packet are copied If copy-mode is set to ips then the packet wth action DROP are not copied to the destination interface. If copy-mode is set to tap, all packets are copied to the destination interface. Any other value of copy-mode results in the feature to be unused. There is no default interface for copy-iface and the variable has to be set for the ids or tap mode to work. For now, this feature depends of the release data system. This implies you need to activate the ring mode and zero copy. Basically use-mmap has to be set to yes. This patch adds a peering of AF_PACKET sockets from the thread on one interface to the threads on another interface. Peering is necessary as if we use an other socket the capture socket receives all emitted packets. This is made using a new AFPPeer structure to avoid direct interaction between AFPTreadVars. There is currently a bug in Linux kernel (prior to 3.6) and it is not possible to use multiple threads. You need to setup two interfaces with equality on the threads variable. copy-mode variable must be set on the two interfaces and use-mmap must be set to activated. A valid configuration for an IPS using eth0 and vboxnet1 interfaces will look like: af-packet: - interface: eth0 threads: 1 defrag: yes cluster-type: cluster_flow cluster-id: 98 copy-mode: ips copy-iface: vboxnet1 buffer-size: 64535 use-mmap: yes - interface: vboxnet1 threads: 1 cluster-id: 97 defrag: yes cluster-type: cluster_flow copy-mode: ips copy-iface: eth0 buffer-size: 64535 use-mmap: yes
14 years ago
#ifdef PROFILING
if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
if (profiling_rules_enabled)
SCProfilingDump();
SCProfilingDestroy();
}
#endif
#ifdef OS_WIN32
if (daemon) {
return 0;
}
#endif /* OS_WIN32 */
SC_ATOMIC_DESTROY(engine_stage);
#ifdef BUILD_HYPERSCAN
MpmHSGlobalCleanup();
#endif
#ifdef __SC_CUDA_SUPPORT__
if (PatternMatchDefaultMatcher() == MPM_AC_CUDA)
MpmCudaBufferDeSetup();
CudaHandlerFreeProfiles();
#endif
ConfDeInit();
SCLogDeInitLogModule();
DetectParseFreeRegexes();
exit(engine_retval);
}