From ebccb9ffcd707b4b68588a78e1b62a27bf9859fa Mon Sep 17 00:00:00 2001 From: Matt Keeler Date: Tue, 19 Feb 2013 11:49:06 -0500 Subject: [PATCH] Added host buffer allowance and stream configuration for Napatech 3GD Added a napatech section in the yaml configuration. hba - host buffer allowance use-all-streams - whether all streams should be used streams - list of stream numbers to use when use-all-streams is no The source-napatech.* files were modified to support the host buffer allowance configuration. The runmode-napatech.c file was modified to support both the host buffer allowance configuration and stream configuration Signed-off-by: Matt Keeler --- src/runmode-napatech.c | 90 +++++++++++++++++++++++++++++++----------- src/source-napatech.c | 4 +- src/source-napatech.h | 1 + suricata.yaml.in | 13 ++++++ 4 files changed, 83 insertions(+), 25 deletions(-) diff --git a/src/runmode-napatech.c b/src/runmode-napatech.c index 2f6a9d1841..a395d8bc04 100644 --- a/src/runmode-napatech.c +++ b/src/runmode-napatech.c @@ -21,7 +21,6 @@ * \author nPulse Technologies, LLC. * \author Matt Keeler */ - #include "suricata-common.h" #include "tm-threads.h" #include "conf.h" @@ -89,36 +88,73 @@ int NapatechRegisterDeviceStreams() int status; int i; char live_dev_buf[9]; + int use_all_streams; + ConfNode *ntstreams; + ConfNode *stream_id; - if ((status = NT_InfoOpen(&info_stream, "Test")) != 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) + if (ConfGetBool("napatech.use-all-streams", &use_all_streams) == 0) { - NT_ExplainError(status, error_buf, sizeof(error_buf) -1); - SCLogError(SC_ERR_NAPATECH_STREAMS_REGISTER_FAILED, "NT_InfoRead failed: %s", error_buf); - return -1; + SCLogError(SC_ERR_RUNMODE, "Failed retrieving napatech.use-all-streams from Conf"); + exit(EXIT_FAILURE); } - num_configured_streams = info.u.stream.data.count; - for (i = 0; i < num_configured_streams; i++) + if (use_all_streams) { - // 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); + 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; + } } - - if ((status = NT_InfoClose(info_stream)) != NT_SUCCESS) + else { - NT_ExplainError(status, error_buf, sizeof(error_buf) -1); - SCLogError(SC_ERR_NAPATECH_STREAMS_REGISTER_FAILED, "NT_InfoClose failed: %s", error_buf); - return -1; + 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; } @@ -137,6 +173,12 @@ void *NapatechConfigParser(const char *device) { // 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; } diff --git a/src/source-napatech.c b/src/source-napatech.c index 0a4f4e031c..86895ee364 100644 --- a/src/source-napatech.c +++ b/src/source-napatech.c @@ -83,6 +83,7 @@ typedef struct NapatechThreadVars_ { ThreadVars *tv; NtNetStreamRx_t rx_stream; uint64_t stream_id; + int hba; uint64_t pkts; uint64_t drops; uint64_t bytes; @@ -164,6 +165,7 @@ TmEcode NapatechStreamThreadInit(ThreadVars *tv, void *initdata, void **data) memset(ntv, 0, sizeof (NapatechThreadVars)); ntv->stream_id = stream_id; ntv->tv = tv; + ntv->hba = conf->hba; SCLogInfo("Started processing packets from NAPATECH Stream: %lu", ntv->stream_id); @@ -189,7 +191,7 @@ TmEcode NapatechStreamLoop(ThreadVars *tv, void *data, void *slot) SCLogInfo("Opening NAPATECH Stream: %lu for processing", ntv->stream_id); - if ((status = NT_NetRxOpen(&(ntv->rx_stream), "SuricataStream", NT_NET_INTERFACE_PACKET, ntv->stream_id, -1)) != NT_SUCCESS) { + if ((status = NT_NetRxOpen(&(ntv->rx_stream), "SuricataStream", NT_NET_INTERFACE_PACKET, ntv->stream_id, ntv->hba)) != NT_SUCCESS) { NT_ExplainError(status, errbuf, sizeof(errbuf)); SCLogError(SC_ERR_NAPATECH_OPEN_FAILED, "Failed to open NAPATECH Stream: %lu - %s", ntv->stream_id, errbuf); SCFree(ntv); diff --git a/src/source-napatech.h b/src/source-napatech.h index 8d3e8525fb..eee79dc76d 100644 --- a/src/source-napatech.h +++ b/src/source-napatech.h @@ -32,6 +32,7 @@ void TmModuleNapatechDecodeRegister (void); struct NapatechStreamDevConf { int stream_id; + intmax_t hba; }; #ifdef HAVE_NAPATECH diff --git a/suricata.yaml.in b/suricata.yaml.in index 73f7cd2b20..4d7552ffc0 100644 --- a/suricata.yaml.in +++ b/suricata.yaml.in @@ -1038,3 +1038,16 @@ profiling: coredump: max-dump: unlimited + +napatech: + # The Host Buffer Allowance for all streams + # (-1 = OFF, 1 - 100 = percentage of the host buffer that can be held back) + hba: -1 + + # use_all_streams set to "yes" will query the Napatech service for all configured + # streams and listen on all of them. When set to "no" the streams config array + # will be used. + use-all-streams: yes + + # The streams to listen on + streams: [1, 2, 3]