aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/suricata/src/runmode-napatech.c
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/suricata/src/runmode-napatech.c')
-rw-r--r--framework/src/suricata/src/runmode-napatech.c235
1 files changed, 235 insertions, 0 deletions
diff --git a/framework/src/suricata/src/runmode-napatech.c b/framework/src/suricata/src/runmode-napatech.c
new file mode 100644
index 00000000..7c161ad8
--- /dev/null
+++ b/framework/src/suricata/src/runmode-napatech.c
@@ -0,0 +1,235 @@
+/* Copyright (C) 2012 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 nPulse Technologies, LLC.
+ * \author Matt Keeler <mk@npulsetech.com>
+ */
+#include "suricata-common.h"
+#include "tm-threads.h"
+#include "conf.h"
+#include "runmodes.h"
+#include "output.h"
+
+#include "util-debug.h"
+#include "util-time.h"
+#include "util-cpu.h"
+#include "util-affinity.h"
+#include "util-runmodes.h"
+#include "util-device.h"
+
+#include "runmode-napatech.h"
+
+// need NapatechStreamDevConf structure
+#include "source-napatech.h"
+
+#define NT_RUNMODE_AUTOFP 1
+#define NT_RUNMODE_WORKERS 2
+
+static const char *default_mode = NULL;
+#ifdef HAVE_NAPATECH
+static int num_configured_streams = 0;
+#endif
+
+const char *RunModeNapatechGetDefaultMode(void)
+{
+ return default_mode;
+}
+
+void RunModeNapatechRegister(void)
+{
+#ifdef HAVE_NAPATECH
+ default_mode = "autofp";
+ RunModeRegisterNewRunMode(RUNMODE_NAPATECH, "autofp",
+ "Multi threaded Napatech mode. Packets from "
+ "each flow are assigned to a single detect "
+ "thread instead of any detect thread",
+ RunModeNapatechAutoFp);
+ RunModeRegisterNewRunMode(RUNMODE_NAPATECH, "workers",
+ "Workers Napatech mode, each thread does all"
+ " tasks from acquisition to logging",
+ RunModeNapatechWorkers);
+ return;
+#endif
+}
+
+#ifdef HAVE_NAPATECH
+int NapatechRegisterDeviceStreams()
+{
+ NtInfoStream_t info_stream;
+ NtInfo_t info;
+ char error_buf[100];
+ int status;
+ int i;
+ char live_dev_buf[9];
+ int use_all_streams;
+ ConfNode *ntstreams;
+ ConfNode *stream_id;
+
+ if (ConfGetBool("napatech.use-all-streams", &use_all_streams) == 0)
+ {
+ SCLogError(SC_ERR_RUNMODE, "Failed retrieving napatech.use-all-streams from Conf");
+ exit(EXIT_FAILURE);
+ }
+
+ if (use_all_streams)
+ {
+ SCLogInfo("Using All Napatech Streams");
+ // When using the default streams we need to query the service for a list of all configured
+ if ((status = NT_InfoOpen(&info_stream, "SuricataStreamInfo")) != NT_SUCCESS)
+ {
+ NT_ExplainError(status, error_buf, sizeof(error_buf) -1);
+ SCLogError(SC_ERR_NAPATECH_STREAMS_REGISTER_FAILED, "NT_InfoOpen failed: %s", error_buf);
+ return -1;
+ }
+
+ info.cmd = NT_INFO_CMD_READ_STREAM;
+ if ((status = NT_InfoRead(info_stream, &info)) != NT_SUCCESS)
+ {
+ NT_ExplainError(status, error_buf, sizeof(error_buf) -1);
+ SCLogError(SC_ERR_NAPATECH_STREAMS_REGISTER_FAILED, "NT_InfoRead failed: %s", error_buf);
+ return -1;
+ }
+
+ num_configured_streams = info.u.stream.data.count;
+ for (i = 0; i < num_configured_streams; i++)
+ {
+ // The Stream IDs do not have to be sequential
+ snprintf(live_dev_buf, sizeof(live_dev_buf), "nt%d", info.u.stream.data.streamIDList[i]);
+ LiveRegisterDevice(live_dev_buf);
+ }
+
+ if ((status = NT_InfoClose(info_stream)) != NT_SUCCESS)
+ {
+ NT_ExplainError(status, error_buf, sizeof(error_buf) -1);
+ SCLogError(SC_ERR_NAPATECH_STREAMS_REGISTER_FAILED, "NT_InfoClose failed: %s", error_buf);
+ return -1;
+ }
+ }
+ else
+ {
+ SCLogInfo("Using Selected Napatech Streams");
+ // When not using the default streams we need to parse the array of streams from the conf
+ if ((ntstreams = ConfGetNode("napatech.streams")) == NULL)
+ {
+ SCLogError(SC_ERR_RUNMODE, "Failed retrieving napatech.streams from Conf");
+ exit(EXIT_FAILURE);
+ }
+
+ // Loop through all stream numbers in the array and register the devices
+ TAILQ_FOREACH(stream_id, &ntstreams->head, next)
+ {
+ if (stream_id == NULL)
+ {
+ SCLogError(SC_ERR_NAPATECH_STREAMS_REGISTER_FAILED, "Couldn't Parse Stream Configuration");
+ exit(EXIT_FAILURE);
+ }
+ num_configured_streams++;
+
+ snprintf(live_dev_buf, sizeof(live_dev_buf), "nt%d", atoi(stream_id->val));
+ LiveRegisterDevice(live_dev_buf);
+ }
+ }
+ return 0;
+}
+
+void *NapatechConfigParser(const char *device)
+{
+ // Expect device to be of the form nt%d where %d is the stream id to use
+ int dev_len = strlen(device);
+ struct NapatechStreamDevConf *conf = SCMalloc(sizeof(struct NapatechStreamDevConf));
+ if (unlikely(conf == NULL))
+ return NULL;
+ if (dev_len < 3 || dev_len > 5)
+ {
+ SCLogError(SC_ERR_NAPATECH_PARSE_CONFIG, "Could not parse config for device: %s - invalid length", device);
+ return NULL;
+ }
+
+ // device+5 is a pointer to the beginning of the stream id after the constant nt portion
+ conf->stream_id = atoi(device+2);
+
+ // Set the host buffer allowance for this stream
+ // Right now we just look at the global default - there is no per-stream hba configuration
+ if (ConfGetInt("napatech.hba", &conf->hba) == 0)
+ conf->hba = -1;
+
+ return (void *) conf;
+}
+
+int NapatechGetThreadsCount(void *conf __attribute__((unused))) {
+ // No matter which live device it is there is no reason to ever use more than 1 thread
+ // 2 or more thread would cause packet duplication
+ return 1;
+}
+
+static int NapatechInit(int runmode)
+{
+ int ret;
+ char errbuf[100];
+
+ RunModeInitialize();
+ TimeModeSetLive();
+
+ /* Initialize the API and check version compatibility */
+ if ((ret = NT_Init(NTAPI_VERSION)) != NT_SUCCESS) {
+ NT_ExplainError(ret, errbuf, sizeof(errbuf));
+ SCLogError(SC_ERR_NAPATECH_INIT_FAILED ,"NT_Init failed. Code 0x%X = %s", ret, errbuf);
+ exit(EXIT_FAILURE);
+ }
+
+ ret = NapatechRegisterDeviceStreams();
+ if (ret < 0 || num_configured_streams <= 0) {
+ SCLogError(SC_ERR_NAPATECH_STREAMS_REGISTER_FAILED, "Unable to setup up Napatech Streams");
+ exit(EXIT_FAILURE);
+ }
+
+ switch(runmode) {
+ case NT_RUNMODE_AUTOFP:
+ ret = RunModeSetLiveCaptureAutoFp(NapatechConfigParser, NapatechGetThreadsCount,
+ "NapatechStream", "NapatechDecode",
+ "RxNT", NULL);
+ break;
+ case NT_RUNMODE_WORKERS:
+ ret = RunModeSetLiveCaptureWorkers(NapatechConfigParser, NapatechGetThreadsCount,
+ "NapatechStream", "NapatechDecode",
+ "RxNT", NULL);
+ break;
+ default:
+ ret = -1;
+ }
+
+ if (ret != 0) {
+ SCLogError(SC_ERR_RUNMODE, "Runmode start failed");
+ exit(EXIT_FAILURE);
+ }
+ return 0;
+}
+
+int RunModeNapatechAutoFp(void)
+{
+ return NapatechInit(NT_RUNMODE_AUTOFP);
+}
+
+int RunModeNapatechWorkers(void)
+{
+ return NapatechInit(NT_RUNMODE_WORKERS);
+}
+
+#endif