set (FLOW_INCLUDES
expect_cache.h
flow.h
+ flow_data.h
flow_key.h
flow_stash.h
ha.h
flow_config.h
flow_control.cc
flow_control.h
+ flow_data.cc
flow_key.cc
flow_stash.cc
flow_stash.h
#include "flow/session.h"
#include "framework/data_bus.h"
#include "ips_options/ips_flowbits.h"
-#include "memory/memory_cap.h"
#include "protocols/packet.h"
#include "sfip/sf_ip.h"
#include "utils/bitop.h"
using namespace snort;
-unsigned FlowData::flow_data_id = 0;
-
-FlowData::FlowData(unsigned u, Inspector* ph)
-{
- assert(u > 0);
- id = u;
- handler = ph;
- prev = next = nullptr;
- if ( handler )
- handler->add_ref();
-}
-
-FlowData::~FlowData()
-{
- if ( handler )
- handler->rem_ref();
-
- assert(mem_in_use == 0);
-}
-
-void FlowData::update_allocations(size_t n)
-{
- memory::MemoryCap::free_space(n);
- memory::MemoryCap::update_allocations(n);
- mem_in_use += n;
-}
-
-void FlowData::update_deallocations(size_t n)
-{
- assert(mem_in_use >= n);
- memory::MemoryCap::update_deallocations(n);
- mem_in_use -= n;
-}
-
-size_t FlowData::size_of()
-{ return 1024; } // FIXIT-H remove this default impl
-
Flow::Flow()
{
memset(this, 0, sizeof(*this));
#include <sys/time.h>
#include "detection/ips_context_chain.h"
+#include "flow/flow_data.h"
#include "flow/flow_stash.h"
#include "framework/data_bus.h"
#include "framework/decode_data.h"
typedef void (* StreamAppDataFree)(void*);
-class SO_PUBLIC FlowData
-{
-public:
- FlowData(unsigned u, Inspector* = nullptr);
- virtual ~FlowData();
-
- unsigned get_id()
- { return id; }
-
- static unsigned create_flow_data_id()
- { return ++flow_data_id; }
-
- void update_allocations(size_t);
- void update_deallocations(size_t);
- Inspector* get_handler() { return handler; }
-
- // return fixed size (could be an approx avg)
- // this must be fixed for life of flow data instance
- // track significant supplemental allocations with the above updaters
- virtual size_t size_of() = 0;
-
- virtual void handle_expected(Packet*) { }
- virtual void handle_retransmit(Packet*) { }
- virtual void handle_eof(Packet*) { }
-
-public: // FIXIT-L privatize
- FlowData* next;
- FlowData* prev;
-
-private:
- static unsigned flow_data_id;
- Inspector* handler;
- size_t mem_in_use = 0;
- unsigned id;
-};
-
struct FlowStats
{
uint64_t client_pkts;
--- /dev/null
+//--------------------------------------------------------------------------
+// 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.
+//--------------------------------------------------------------------------
+// flow_data.cc author Russ Combs <rucombs@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "flow_data.h"
+
+#include <cassert>
+
+#include "framework/inspector.h"
+#include "main/snort_config.h"
+#include "managers/so_manager.h"
+#include "memory/memory_cap.h"
+
+using namespace snort;
+
+unsigned FlowData::flow_data_id = 0;
+
+FlowData::FlowData(unsigned u, Inspector* ph)
+{
+ assert(u > 0);
+ id = u;
+ handler = ph;
+ prev = next = nullptr;
+ if ( handler )
+ handler->add_ref();
+}
+
+FlowData::~FlowData()
+{
+ if ( handler )
+ handler->rem_ref();
+
+ assert(mem_in_use == 0);
+}
+
+void FlowData::update_allocations(size_t n)
+{
+ memory::MemoryCap::free_space(n);
+ memory::MemoryCap::update_allocations(n);
+ mem_in_use += n;
+}
+
+void FlowData::update_deallocations(size_t n)
+{
+ assert(mem_in_use >= n);
+ memory::MemoryCap::update_deallocations(n);
+ mem_in_use -= n;
+}
+
+RuleFlowData::RuleFlowData(unsigned u) : FlowData(u,
+ SnortConfig::get_conf()->so_rules->proxy) { }
+
--- /dev/null
+//--------------------------------------------------------------------------
+// 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.
+//--------------------------------------------------------------------------
+// flow_data.h author Russ Combs <rucombs@cisco.com>
+
+#ifndef FLOW_DATA_H
+#define FLOW_DATA_H
+
+#include "main/snort_types.h"
+
+namespace snort
+{
+class Inspector;
+struct Packet;
+
+class SO_PUBLIC FlowData
+{
+public:
+ FlowData(unsigned u, Inspector* = nullptr);
+ virtual ~FlowData();
+
+ unsigned get_id()
+ { return id; }
+
+ static unsigned create_flow_data_id()
+ { return ++flow_data_id; }
+
+ void update_allocations(size_t);
+ void update_deallocations(size_t);
+ Inspector* get_handler() { return handler; }
+
+ // return fixed size (could be an approx avg)
+ // this must be fixed for life of flow data instance
+ // track significant supplemental allocations with the above updaters
+ virtual size_t size_of() = 0;
+
+ virtual void handle_expected(Packet*) { }
+ virtual void handle_retransmit(Packet*) { }
+ virtual void handle_eof(Packet*) { }
+
+public: // FIXIT-L privatize
+ FlowData* next;
+ FlowData* prev;
+
+private:
+ static unsigned flow_data_id;
+ Inspector* handler;
+ size_t mem_in_use = 0;
+ unsigned id;
+};
+
+// The flow data created from SO rules must use RuleFlowData
+// to support reload
+class SO_PUBLIC RuleFlowData : public FlowData
+{
+protected:
+ RuleFlowData(unsigned u);
+public:
+ virtual ~RuleFlowData() { }
+};
+
+}
+#endif
add_cpputest( session_test )
add_cpputest( flow_test
- SOURCES ../flow.cc
+ SOURCES
+ ../flow.cc
+ ../flow_data.cc
)
#include "config.h"
#endif
-#include "protocols/ip.h"
-#include "protocols/layer.h"
-#include "protocols/packet.h"
+#include "detection/detection_engine.h"
#include "flow/flow.h"
#include "flow/flow_stash.h"
#include "flow/ha.h"
-#include "main/snort_debug.h"
#include "framework/inspector.h"
#include "framework/data_bus.h"
+#include "main/snort_config.h"
+#include "main/snort_debug.h"
#include "memory/memory_cap.h"
-#include "detection/detection_engine.h"
+#include "protocols/ip.h"
+#include "protocols/layer.h"
+#include "protocols/packet.h"
#include <CppUTest/CommandLineTestRunner.h>
#include <CppUTest/TestHarness.h>
void DataBus::publish(const char*, Packet*, Flow*) {}
+SnortConfig* SnortConfig::get_conf() { return nullptr; }
+
TEST_GROUP(nondefault_timeout)
{
void setup() override
// this is the current version of the base api
// must be prefixed to subtype version
-#define BASE_API_VERSION 1
+#define BASE_API_VERSION 2
// set options to API_OPTIONS to ensure compatibility
#ifndef API_OPTIONS
lru = &host_cache;
}
+template <class T>
+void HostCacheAlloc<T>::deallocate(T* p, std::size_t n) noexcept
+{
+ size_t sz = n*sizeof(T);
+ std::allocator<T>::deallocate(p, n);
+ lru->update( -(int) sz);
+}
+
TEST_GROUP(host_cache_module)
{
void setup() override
packets = { }
process = { }
search_engine = { }
+so_proxy = { }
-- exceptions:
void PluginManager::load_plugins(const std::string& paths)
{
+ SoManager::load_so_proxy();
+
// dynamic plugins
if ( !paths.empty() )
::load_plugins(paths);
#include <sstream>
#include "log/messages.h"
+#include "framework/decode_data.h"
+#include "framework/inspector.h"
+#include "framework/module.h"
#include "main/snort_config.h"
#include "parser/parse_so_rule.h"
cout << "static const unsigned rule_" << var << "_len = 0;" << endl;
}
+//-------------------------------------------------------------------------
+// so_proxy inspector
+//-------------------------------------------------------------------------
+static const char* sp_name = "so_proxy";
+static const char* sp_help = "a proxy inspector to track flow data from SO rules (internal use only)";
+class SoProxy : public Inspector
+{
+public:
+ void eval(Packet*) override { }
+ bool configure(SnortConfig* sc) override
+ {
+ for( auto i : sc->so_rules->handles )
+ handles.emplace_back(i);
+ sc->so_rules->proxy = this;
+ return true;
+ }
+ ~SoProxy() override { handles.clear(); }
+
+private:
+ std::list<SoHandlePtr> handles;
+};
+
+static const Parameter sp_params[] =
+{
+ { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
+};
+
+class SoProxyModule : public Module
+{
+public:
+ SoProxyModule() : Module(sp_name, sp_help, sp_params) { }
+ Usage get_usage() const override
+ { return GLOBAL; }
+};
+
+static Module* mod_ctor()
+{ return new SoProxyModule; }
+
+static void mod_dtor(Module* m)
+{ delete m; }
+
+static Inspector* sp_ctor(Module*)
+{
+ return new SoProxy;
+}
+
+static void sp_dtor(Inspector* p)
+{
+ delete p;
+}
+
+static const InspectApi so_proxy_api
+{
+ {
+ PT_INSPECTOR,
+ sizeof(InspectApi),
+ INSAPI_VERSION,
+ 0,
+ API_RESERVED,
+ API_OPTIONS,
+ sp_name,
+ sp_help,
+ mod_ctor,
+ mod_dtor
+ },
+ IT_PASSIVE,
+ PROTO_BIT__NONE,
+ nullptr, // buffers
+ nullptr, // service
+ nullptr, // pinit
+ nullptr, // pterm
+ nullptr, // tinit,
+ nullptr, // tterm,
+ sp_ctor,
+ sp_dtor,
+ nullptr, // ssn
+ nullptr // reset
+};
+
+const BaseApi* so_proxy_plugins[] =
+{
+ &so_proxy_api.base,
+ nullptr
+};
+
+void SoManager::load_so_proxy()
+{
+ PluginManager::load_plugins(so_proxy_plugins);
+}
namespace snort
{
struct SnortConfig;
+class Inspector;
}
//-------------------------------------------------------------------------
{
std::list<const SoApi*> api;
std::list<SoHandlePtr> handles;
+ snort::Inspector* proxy = nullptr;
~SoRules();
};
static void rule_to_hex(const char* file);
static void rule_to_text(const char* file);
static void dump_rule_stubs(const char*, snort::SnortConfig*);
+ static void load_so_proxy();
};
#endif
// Stubs for AppIdPegCounts
void AppIdPegCounts::inc_payload_count(AppId) { }
+void AppIdPegCounts::inc_client_count(AppId) { }
THREAD_LOCAL AppIdStats appid_stats;