From 5530a271854442972f88c740c335957488a480ea Mon Sep 17 00:00:00 2001 From: "George Koikara (gkoikara)" Date: Tue, 25 Feb 2020 09:13:59 +0000 Subject: [PATCH] Merge pull request #1985 in SNORT/snort3 from ~PUNEETKU/snort3:snort3_flowip to master Squashed commit of the following: commit a458cd3697d0e8c6dce66a6c83203db2ca29977b Author: Puneeth Kumar C V Date: Thu Jan 30 22:04:29 2020 -0500 perf_monitor: Enable or disable flow-ip-profiling using shell commands. --- .../perf_monitor/perf_module.cc | 96 +++++++++++++++++++ .../perf_monitor/perf_module.h | 1 + .../perf_monitor/perf_monitor.cc | 90 ++++++++++------- .../perf_monitor/perf_monitor.h | 71 ++++++++++++++ 4 files changed, 225 insertions(+), 33 deletions(-) create mode 100644 src/network_inspectors/perf_monitor/perf_monitor.h diff --git a/src/network_inspectors/perf_monitor/perf_module.cc b/src/network_inspectors/perf_monitor/perf_module.cc index 4b215808c..b84f8e9c6 100644 --- a/src/network_inspectors/perf_monitor/perf_module.cc +++ b/src/network_inspectors/perf_monitor/perf_module.cc @@ -28,9 +28,13 @@ #define FLATBUFFERS_ENUM #endif +#include + #include "perf_module.h" +#include "perf_monitor.h" #include "log/messages.h" +#include "main/analyzer_command.h" #include "main/snort.h" #include "managers/module_manager.h" @@ -98,6 +102,95 @@ static const Parameter s_params[] = { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } }; +class PerfMonFlowIPDebug : public AnalyzerCommand +{ +public: + PerfMonFlowIPDebug(PerfMonitorConstraints*); + bool execute(Analyzer&, void**) override; + const char* stringify() override { return "FLOW_IP_PROFILING"; } +private: + bool enable = false; + PerfMonitorConstraints constraints = { }; +}; + +static const Parameter flow_ip_profiling_params[] = +{ + { "time", Parameter::PT_INT, nullptr, nullptr, "sample interval" }, + + { "pkts", Parameter::PT_INT, nullptr, nullptr, "number of packets" }, + + { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } +}; + +PerfMonFlowIPDebug::PerfMonFlowIPDebug(PerfMonitorConstraints* cs) +{ + if (cs) + { + constraints = *cs; + enable = true; + } else { + enable = false; + } +} + +bool PerfMonFlowIPDebug::execute(Analyzer&, void**) +{ + PerfMonitor* perf_monitor = (PerfMonitor*)InspectorManager::get_inspector(PERF_NAME, true); + + if (!perf_monitor) + return false; + + if (enable) + perf_monitor->enable_profiling(&constraints); + else + perf_monitor->disable_profiling(); + + return true; +} + +static int enable_flow_ip_profiling(lua_State* L) +{ + PerfMonitorConstraints constraints; + + constraints.sample_interval = luaL_optint(L, 1, 0); + constraints.packet_count = luaL_optint(L, 2, 0); + + LogMessage("Enabling flow ip profiling with sample interval %d packet count %d\n", + constraints.sample_interval, constraints.packet_count); + + main_broadcast_command(new PerfMonFlowIPDebug(&constraints), true); + return 0; +} + +static int disable_flow_ip_profiling(lua_State*) +{ + LogMessage("Disabling flow ip profiling\n"); + main_broadcast_command(new PerfMonFlowIPDebug(nullptr), true); + return 0; +} + +static int show_flow_ip_profiling(lua_State*) +{ + bool status = false; + + PerfMonitor* perf_monitor = (PerfMonitor*)InspectorManager::get_inspector(PERF_NAME, true); + + if (perf_monitor) + status = perf_monitor->get_config_flags() & PERF_FLOWIP; + + LogMessage("Snort flow ip profiling is %s\n", status ? "enabled" : "disabled"); + + return 0; +} + +static const Command perf_module_cmds[] = +{ + {"enable_flow_ip_profiling", enable_flow_ip_profiling, flow_ip_profiling_params, "enable flow ip profiling"}, + {"disable_flow_ip_profiling", disable_flow_ip_profiling, nullptr, "disable flow ip profiling"}, + {"show_flow_ip_profiling", show_flow_ip_profiling, nullptr, "show flow ip profiling status"}, + {nullptr, nullptr, nullptr, nullptr} +}; + //------------------------------------------------------------------------- // perf attributes //------------------------------------------------------------------------- @@ -234,6 +327,9 @@ const PegInfo* PerfMonModule::get_pegs() const PegCount* PerfMonModule::get_counts() const { return (PegCount*)&pmstats; } +const Command* PerfMonModule::get_commands() const +{ return perf_module_cmds; } + void ModuleConfig::set_name(const std::string& name) { this->name = name; } diff --git a/src/network_inspectors/perf_monitor/perf_module.h b/src/network_inspectors/perf_monitor/perf_module.h index 1bcd8f139..e8229d9b4 100644 --- a/src/network_inspectors/perf_monitor/perf_module.h +++ b/src/network_inspectors/perf_monitor/perf_module.h @@ -99,6 +99,7 @@ public: PerfMonModule(); ~PerfMonModule() override; + const snort::Command* get_commands() const override; bool set(const char*, snort::Value&, snort::SnortConfig*) override; bool begin(const char*, int, snort::SnortConfig*) override; bool end(const char*, int, snort::SnortConfig*) override; diff --git a/src/network_inspectors/perf_monitor/perf_monitor.cc b/src/network_inspectors/perf_monitor/perf_monitor.cc index 9df381e3b..9e3ae21bf 100644 --- a/src/network_inspectors/perf_monitor/perf_monitor.cc +++ b/src/network_inspectors/perf_monitor/perf_monitor.cc @@ -31,16 +31,11 @@ #include "framework/data_bus.h" #include "hash/xhash.h" #include "log/messages.h" -#include "managers/inspector_manager.h" #include "profiler/profiler.h" #include "protocols/packet.h" -#include "base_tracker.h" -#include "cpu_tracker.h" -#include "flow_ip_tracker.h" -#include "flow_tracker.h" #include "perf_module.h" - +#include "perf_monitor.h" #ifdef UNIT_TEST #include "catch/snort_catch.h" @@ -58,31 +53,6 @@ static THREAD_LOCAL FlowIPTracker* flow_ip_tracker = nullptr; // class stuff //------------------------------------------------------------------------- -class FlowIPDataHandler; -class PerfMonitor : public Inspector -{ -public: - PerfMonitor(PerfConfig*); - ~PerfMonitor() override { delete config;} - - bool configure(SnortConfig*) override; - void show(SnortConfig*) override; - - void eval(Packet*) override; - bool ready_to_process(Packet* p); - - void tinit() override; - void tterm() override; - - void rotate(); - - FlowIPTracker* get_flow_ip(); - -private: - PerfConfig* const config; - void disable_tracker(size_t); -}; - class PerfIdleHandler : public DataHandler { public: @@ -143,7 +113,7 @@ private: PerfMonitor& perf_monitor; }; -PerfMonitor::PerfMonitor(PerfConfig* pcfg) : config(pcfg) +PerfMonitor::PerfMonitor(PerfConfig* pcfg) : config(pcfg), flow_ip_data_handler(nullptr) { assert (config != nullptr); } void PerfMonitor::show(SnortConfig*) @@ -223,7 +193,7 @@ bool PerfMonitor::configure(SnortConfig* sc) new PerfRotateHandler(*this, sc); if ( config->perf_flags & PERF_FLOWIP ) - new FlowIPDataHandler(*this, sc); + flow_ip_data_handler = new FlowIPDataHandler(*this, sc); return config->resolve(); } @@ -303,6 +273,60 @@ void PerfMonitor::rotate() disable_tracker(i--); } +void PerfMonitor::enable_profiling(PerfMonitorConstraints* constraints) +{ + if (flow_ip_data_handler == nullptr) + { + flow_ip_data_handler = new FlowIPDataHandler(*this, SnortConfig::get_conf()); + } else { + if (flow_ip_tracker) + return; + } + + config->perf_flags |= PERF_FLOWIP; + config->sample_interval = constraints->sample_interval; + config->pkt_cnt = constraints->packet_count; + + flow_ip_tracker = new FlowIPTracker(config); + trackers->emplace_back(flow_ip_tracker); + + for (unsigned i = 0; i < trackers->size(); i++) + { + if (trackers->at(i) == flow_ip_tracker) + { + if (!(*trackers)[i]->open(true)) + disable_tracker(i); + flow_ip_tracker->reset(); + break; + } + } +} + +void PerfMonitor::disable_profiling() +{ + config->perf_flags &= ~PERF_FLOWIP; + + if (flow_ip_tracker) + { + for (unsigned i = 0; i < trackers->size(); i++) + { + if (trackers->at(i) == flow_ip_tracker) + { + disable_tracker(i); + break; + } + } + flow_ip_tracker = nullptr; + } + + if (flow_ip_data_handler) + { + DataBus::unsubscribe_global(FLOW_STATE_EVENT, flow_ip_data_handler, SnortConfig::get_conf()); + delete flow_ip_data_handler; + flow_ip_data_handler = nullptr; + } +} + void PerfMonitor::eval(Packet* p) { Profile profile(perfmonStats); diff --git a/src/network_inspectors/perf_monitor/perf_monitor.h b/src/network_inspectors/perf_monitor/perf_monitor.h new file mode 100644 index 000000000..79993850c --- /dev/null +++ b/src/network_inspectors/perf_monitor/perf_monitor.h @@ -0,0 +1,71 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License Version 2 as published +// by the Free Software Foundation. You may not use, modify or distribute +// this program under any other version of the GNU General Public License. +// +// 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 along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +//-------------------------------------------------------------------------- + +// perf_monitor.h author Puneeth Kumar C V + +#ifndef PERF_MONITOR_H +#define PERF_MONITOR_H + +#include "managers/inspector_manager.h" +#include "protocols/packet.h" + +#include "base_tracker.h" +#include "cpu_tracker.h" +#include "flow_ip_tracker.h" +#include "flow_tracker.h" + +class FlowIPDataHandler; + +struct PerfMonitorConstraints +{ + uint32_t sample_interval; + uint32_t packet_count; +}; + +class PerfMonitor : public snort::Inspector +{ +public: + PerfMonitor(PerfConfig*); + ~PerfMonitor() override { delete config;} + + bool configure(snort::SnortConfig*) override; + void show(snort::SnortConfig*) override; + + void eval(snort::Packet*) override; + bool ready_to_process(snort::Packet* p); + + void tinit() override; + void tterm() override; + + void rotate(); + + void enable_profiling(PerfMonitorConstraints*); + void disable_profiling(); + + inline int get_config_flags() + { return config->perf_flags; } + + FlowIPTracker* get_flow_ip(); + +private: + PerfConfig* const config; + FlowIPDataHandler* flow_ip_data_handler; + void disable_tracker(size_t); +}; + +#endif -- 2.47.3