const ReferenceSystem* reference_system_add(
SnortConfig* sc, const std::string& name, const char* url)
{
- if ( !sc->alert_refs() )
- return nullptr;
-
assert(!name.empty());
ReferenceSystem* sys = new ReferenceSystem(name, url);
return sys;
}
-static const ReferenceSystem* reference_system_lookup(SnortConfig* sc, const std::string& key)
+const ReferenceSystem* reference_system_lookup(const SnortConfig* sc, const std::string& key)
{
const auto it = sc->references.find(key);
const ReferenceSystem* reference_system_add(snort::SnortConfig*, const std::string&, const char* = "");
+const ReferenceSystem* reference_system_lookup(const snort::SnortConfig*, const std::string& key);
+
struct ReferenceNode
{
ReferenceNode(const ReferenceSystem* sys, const std::string& id) : system(sys), id(id) { }
return false;
}
-const SigInfo& Event::get_sig_info() const
-{ return sig_info; }
+bool Event::get_reference(unsigned idx, const char*& name, const char*& id, const char*& url) const
+{
+ if ( idx >= sig_info.refs.size() )
+ return false;
+
+ name = sig_info.refs[idx]->system->name.c_str();
+ id = sig_info.refs[idx]->id.c_str();
+
+ auto* ref = reference_system_lookup(SnortConfig::get_conf(), sig_info.refs[idx]->system->name);
+ url = (ref ? ref->url.c_str() : nullptr);
+
+ return true;
+}
static uint16_t get_next_seq_num();
static uint32_t get_next_event_id();
- const SigInfo& get_sig_info() const;
-
uint32_t get_seconds() const;
void get_timestamp(uint32_t& sec, uint32_t& usec) const;
uint32_t get_class_id() const;
uint32_t get_priority() const;
+ // start at idx 0 and increment while true to get all refs
+ bool get_reference(unsigned idx, const char*& name, const char*& id, const char*& url) const;
+
// returns false if not specified; otherwise src indicates target is source or dest
bool get_target(bool& src) const;
// depends on includes installed in framework/snort_api.h
// see framework/plugins.h
-#define BASE_API_VERSION 20
+#define BASE_API_VERSION 21
// set the reserved field to this to be future proof
#define API_RESERVED 0
sc.global_dbus->_subscribe(key, eid, h);
}
-void DataBus::unsubscribe(const PubKey& key, unsigned eid, DataHandler* h)
-{
- get_data_bus()._unsubscribe(key, eid, h);
-}
-
-void DataBus::unsubscribe_network(const PubKey& key, unsigned eid, DataHandler* h)
-{
- get_network_data_bus()._unsubscribe(key, eid, h);
-}
-
-void DataBus::unsubscribe_global(const PubKey& key, unsigned eid, DataHandler* h, SnortConfig& sc)
-{
- sc.global_dbus->_unsubscribe(key, eid, h);
-}
-
// notify subscribers of event
void DataBus::publish(unsigned pid, unsigned eid, DataEvent& e, Flow* f)
{
_subscribe(pid, eid, h);
}
-void DataBus::_unsubscribe(const PubKey& key, unsigned eid, const DataHandler* h)
-{
- unsigned pid = get_id(key);
- unsigned idx = pid + eid;
- assert(idx < pub_sub.size());
-
- SubList& subs = pub_sub[idx];
-
- for ( unsigned i = 0; i < subs.size(); i++ )
- {
- if ( subs[i] == h )
- {
- subs.erase(subs.begin() + i--);
- break;
- }
- }
-}
-
void DataBus::_publish(unsigned pid, unsigned eid, DataEvent& e, Flow* f) const
{
unsigned idx = pid + eid;
static void subscribe_network(const PubKey&, unsigned id, DataHandler*);
static void subscribe_global(const PubKey&, unsigned id, DataHandler*, SnortConfig&);
- // FIXIT-L these should be called during cleanup
- static void unsubscribe(const PubKey&, unsigned id, DataHandler*);
- static void unsubscribe_network(const PubKey&, unsigned id, DataHandler*);
- static void unsubscribe_global(const PubKey&, unsigned id, DataHandler*, SnortConfig&);
-
// runtime methods
static void publish(unsigned pub_id, unsigned evt_id, DataEvent&, Flow* = nullptr);
private:
void _subscribe(unsigned pub_id, unsigned evt_id, DataHandler*);
void _subscribe(const PubKey&, unsigned evt_id, DataHandler*);
- void _unsubscribe(const PubKey&, unsigned evt_id, const DataHandler*);
void _publish(unsigned pub_id, unsigned evt_id, DataEvent&, Flow*) const;
private:
static void set_priority(const IpsInfo&, uint32_t);
static void set_classtype(IpsInfo&, const char*);
- static void set_reference(IpsInfo&, const char* scheme, const char* id);
enum Enable { NO, YES, INHERIT };
static void set_enabled(IpsInfo&, Enable);
// the LOGAPI_VERSION will change if anything in this file changes.
// see also framework/base_api.h.
+#include "events/event.h"
#include "framework/base_api.h"
#include "main/snort_types.h"
-class Event;
-
namespace snort
{
struct Packet;
// this is the current version of the api
-#define LOGAPI_VERSION ((BASE_API_VERSION << 16) | 1)
+#define LOGAPI_VERSION ((BASE_API_VERSION << 16) | 2)
#define OUTPUT_TYPE_FLAG__NONE 0x0
#define OUTPUT_TYPE_FLAG__ALERT 0x1
TEST(data_bus, subscribe_global)
{
- UTestHandler h;
- DataBus::subscribe_global(pub_key, DbUtIds::EVENT, &h, *snort_conf);
+ UTestHandler* h = new UTestHandler();
+ DataBus::subscribe_global(pub_key, DbUtIds::EVENT, h, *snort_conf);
UTestEvent event(100);
DataBus::publish(pub_id, DbUtIds::EVENT, event);
- CHECK(100 == h.evt_msg);
+ CHECK(100 == h->evt_msg);
UTestEvent event1(200);
DataBus::publish(pub_id, DbUtIds::EVENT, event1);
- CHECK(200 == h.evt_msg);
-
- DataBus::unsubscribe_global(pub_key, DbUtIds::EVENT, &h, *snort_conf);
-
- UTestEvent event2(300);
- DataBus::publish(pub_id, DbUtIds::EVENT, event2);
- CHECK(200 == h.evt_msg); // unsubscribed!
+ CHECK(200 == h->evt_msg);
}
TEST(data_bus, subscribe_network)
UTestEvent event1(200);
DataBus::publish(pub_id, DbUtIds::EVENT, event1);
CHECK(200 == h->evt_msg);
-
- DataBus::unsubscribe_network(pub_key, DbUtIds::EVENT, h);
-
- UTestEvent event2(300);
- DataBus::publish(pub_id, DbUtIds::EVENT, event2);
- CHECK(200 == h->evt_msg); // unsubscribed!
-
- delete h;
}
TEST(data_bus, subscribe)
UTestEvent event1(200);
DataBus::publish(pub_id, DbUtIds::EVENT, event1);
CHECK(200 == h->evt_msg);
-
- DataBus::unsubscribe(pub_key, DbUtIds::EVENT, h);
-
- UTestEvent event2(300);
- DataBus::publish(pub_id, DbUtIds::EVENT, event2);
- CHECK(200 == h->evt_msg); // unsubscribed!
-
- delete h;
}
TEST(data_bus, order1)
CHECK(1 == h1->seq);
CHECK(2 == h9->seq);
CHECK(3 == h0->seq);
-
- DataBus::unsubscribe(pub_key, DbUtIds::EVENT, h0);
- DataBus::unsubscribe(pub_key, DbUtIds::EVENT, h1);
- DataBus::unsubscribe(pub_key, DbUtIds::EVENT, h9);
-
- delete h0;
- delete h1;
- delete h9;
}
TEST(data_bus, order2)
CHECK(1 == h1->seq);
CHECK(2 == h9->seq);
CHECK(3 == h0->seq);
-
- DataBus::unsubscribe(pub_key, DbUtIds::EVENT, h0);
- DataBus::unsubscribe(pub_key, DbUtIds::EVENT, h1);
- DataBus::unsubscribe(pub_key, DbUtIds::EVENT, h9);
-
- delete h0;
- delete h1;
- delete h9;
}
//-------------------------------------------------------------------------
void LogXrefs(TextLog* log, const Event& e)
{
- const SigInfo& sig_info = e.get_sig_info();
+ unsigned idx = 0;
+ const char* name = nullptr;
+ const char* id = nullptr;
+ const char* url = nullptr;
- for ( const auto ref : sig_info.refs )
+ while ( e.get_reference(idx++, name, id, url) )
{
- if ( !ref->system )
- TextLog_Print(log, "[Xref => %s]", ref->id.c_str());
-
- else if ( !ref->system->url.empty() )
- TextLog_Print(log, "[Xref => %s%s]", ref->system->url.c_str(), ref->id.c_str());
-
+ if ( url and *url )
+ TextLog_Print(log, "[Xref => %s%s]", url, id);
else
- TextLog_Print(log, "[Xref => %s %s]", ref->system->name.c_str(), ref->id.c_str());
+ TextLog_Print(log, "[Xref => %s %s]", name, id);
}
}
add_subdirectory(smtp)
add_subdirectory(ssh)
add_subdirectory(ssl)
-add_subdirectory(tcp_pdu)
+add_subdirectory(tlv_pdu)
add_subdirectory(wizard)
if (STATIC_INSPECTORS)
$<TARGET_OBJECTS:smtp>
$<TARGET_OBJECTS:ssh>
$<TARGET_OBJECTS:ssl>
- $<TARGET_OBJECTS:tcp_pdu>
+ $<TARGET_OBJECTS:tlv_pdu>
$<TARGET_OBJECTS:wizard>
)
endif()
extern const BaseApi* sin_rpc_decode;
extern const BaseApi* sin_smtp;
extern const BaseApi* sin_ssh;
-extern const BaseApi* sin_tcp_pdu;
+extern const BaseApi* sin_tlv_pdu;
extern const BaseApi* sin_telnet;
extern const BaseApi* sin_wizard;
sin_rpc_decode,
sin_smtp,
sin_ssh,
- sin_tcp_pdu,
+ sin_tlv_pdu,
sin_telnet,
sin_wizard,
#endif
+++ /dev/null
-
-set( FILE_LIST
- tcp_pdu.cc
- tcp_pdu.h
- tcp_pdu_splitter.cc
-)
-
-if (STATIC_INSPECTORS)
- add_library( tcp_pdu OBJECT ${FILE_LIST})
-
-else (STATIC_INSPECTORS)
- add_dynamic_module(tcp_pdu inspectors ${FILE_LIST})
-
-endif (STATIC_INSPECTORS)
-
-add_subdirectory(test)
-
--- /dev/null
+
+set( FILE_LIST
+ tlv_pdu.cc
+ tlv_pdu.h
+ tlv_pdu_splitter.cc
+)
+
+if (STATIC_INSPECTORS)
+ add_library(tlv_pdu OBJECT ${FILE_LIST})
+
+else (STATIC_INSPECTORS)
+ add_dynamic_module(tlv_pdu inspectors ${FILE_LIST})
+
+endif (STATIC_INSPECTORS)
+
+add_subdirectory(test)
+
-The TcpPdu splitter provides a generic TCP stream flush function to support
+The TlvPdu splitter provides a generic TCP stream flush function to support
IPS. This works for PDUs that contain a length field at a fixed offset that
can be extracted and used to set a flush point.
So a PDU with a 4 byte length field in the middle of a 12 byte header would be
configured with offset = size = skip = 4.
-tcp_pdu is not service specific. An appropriate wizard pattern must direct the
-paylaod to a tcp_pdu instance configured for the flow.
+tlv_pdu is not service specific. An appropriate wizard pattern must direct the
+payload to a tlv_pdu instance configured for the flow.
The initial implementation supports these parameters:
-* int tcp_pdu.offset = 0: index to first byte of length field { 0:65535 }
-* int tcp_pdu.size = 4: number of bytes in length field { 1:4 }
-* int tcp_pdu.skip = 0: bytes after length field to end of header { 0:65535 }
-* bool tcp_pdu.relative = false: extracted length follows field (instead of whole PDU)
+* int tlv_pdu.offset = 0: index to first byte of length field { 0:65535 }
+* int tlv_pdu.size = 4: number of bytes in length field { 1:4 }
+* int tlv_pdu.skip = 0: bytes after length field to end of header { 0:65535 }
+* bool tlv_pdu.relative = false: extracted length follows field (instead of whole PDU)
Additional parameters that may be supported in the future if required:
-* int tcp_pdu.bitmask = 0xFFFFFFFF: applies as an AND to the extracted value to get length { 0x1:0xFFFFFFFF }
-* int tcp_pdu.multiplier = 1: scale extracted value by given amount after masking { 1:65535 }
+* int tlv_pdu.bitmask = 0xFFFFFFFF: applies as an AND to the extracted value to get length { 0x1:0xFFFFFFFF }
+* int tlv_pdu.multiplier = 1: scale extracted value by given amount after masking { 1:65535 }
Still other possibilities:
-* bool tcp_pdu.big = false: big endian
-* bool tcp_pdu.little = false: little endian
-* bool tcp_pdu.string = false: convert from string
-* bool tcp_pdu.hex = false: convert from hex string
-* bool tcp_pdu.oct = false: convert from octal string
-* bool tcp_pdu.dec = false: convert from decimal string
+* bool tlv_pdu.big = false: big endian
+* bool tlv_pdu.little = false: little endian
+* bool tlv_pdu.string = false: convert from string
+* bool tlv_pdu.hex = false: convert from hex string
+* bool tlv_pdu.oct = false: convert from octal string
+* bool tlv_pdu.dec = false: convert from decimal string
-add_cpputest( tcp_pdu_test
+add_cpputest( tlv_pdu_test
SOURCES
- ../tcp_pdu_splitter.cc
+ ../tlv_pdu_splitter.cc
../../../stream/stream_splitter.cc
)
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-// tcp_pdu_test.cc author Russ Combs <rucombs@cisco.com>
+// tlv_pdu_test.cc author Russ Combs <rucombs@cisco.com>
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "stream/flush_bucket.h"
#include "stream/stream.h"
-#include "../tcp_pdu.h"
+#include "../tlv_pdu.h"
// must appear after snort_config.h to avoid broken c++ map include
#include <CppUTest/CommandLineTestRunner.h>
void setup() override
{
- TcpPduConfig c = { 4, 0, 0, true };
- ss = new TcpPduSplitter(true, c); // cppcheck-suppress unreadVariable
+ TlvPduConfig c = { 4, 0, 0, true };
+ ss = new TlvPduSplitter(true, c); // cppcheck-suppress unreadVariable
}
void teardown() override
{ delete ss; }
void setup() override
{
- TcpPduConfig c = { 4, 3, 2, true };
- ss = new TcpPduSplitter(true, c); // cppcheck-suppress unreadVariable
+ TlvPduConfig c = { 4, 3, 2, true };
+ ss = new TlvPduSplitter(true, c); // cppcheck-suppress unreadVariable
}
void teardown() override
{ delete ss; }
TEST(various, absolute2)
{
- TcpPduConfig c = { 2, 3, 0, false };
- ss = new TcpPduSplitter(true, c);
+ TlvPduConfig c = { 2, 3, 0, false };
+ ss = new TlvPduSplitter(true, c);
uint32_t fp = 0;
StreamSplitter::Status result;
TEST(various, absolute3)
{
- TcpPduConfig c = { 3, 2, 0, false };
- ss = new TcpPduSplitter(true, c);
+ TlvPduConfig c = { 3, 2, 0, false };
+ ss = new TlvPduSplitter(true, c);
uint32_t fp = 0;
StreamSplitter::Status result;
TEST(various, abort)
{
- TcpPduConfig c = { 1, 2, 0, false };
- ss = new TcpPduSplitter(true, c);
+ TlvPduConfig c = { 1, 2, 0, false };
+ ss = new TlvPduSplitter(true, c);
uint32_t fp = 0;
StreamSplitter::Status result;
TEST(various, header_only)
{
- TcpPduConfig c = { 1, 2, 0, true };
- ss = new TcpPduSplitter(true, c);
+ TlvPduConfig c = { 1, 2, 0, true };
+ ss = new TlvPduSplitter(true, c);
uint32_t fp = 0;
StreamSplitter::Status result;
void setup() override
{
- TcpPduConfig c = { 1, 2, 0, true };
- ss = new TcpPduSplitter(true, c); // cppcheck-suppress unreadVariable
+ TlvPduConfig c = { 1, 2, 0, true };
+ ss = new TlvPduSplitter(true, c); // cppcheck-suppress unreadVariable
}
void teardown() override
{ delete ss; }
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-// tcp_pdu.cc author Russ Combs <rucombs@cisco.com>
+// tlv_pdu.cc author Russ Combs <rucombs@cisco.com>
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "framework/module.h"
#include "profiler/profiler.h"
-#include "tcp_pdu.h"
+#include "tlv_pdu.h"
using namespace snort;
using namespace std;
// common foo
//-------------------------------------------------------------------------
-#define s_name "tcp_pdu"
+#define s_name "tlv_pdu"
#define s_help "set TCP flush points based on PDU length field"
static const PegInfo pdu_pegs[] =
{ nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
};
-class TcpPduModule : public snort::Module
+class TlvPduModule : public snort::Module
{
public:
- TcpPduModule() : Module(s_name, s_help, s_params)
+ TlvPduModule() : Module(s_name, s_help, s_params)
{ }
const PegInfo* get_pegs() const override
bool set(const char*, Value&, SnortConfig*) override;
- TcpPduConfig& get_config()
+ TlvPduConfig& get_config()
{ return config; }
private:
- TcpPduConfig config;
+ TlvPduConfig config;
};
-bool TcpPduModule::set(const char*, Value& v, SnortConfig*)
+bool TlvPduModule::set(const char*, Value& v, SnortConfig*)
{
if (v.is("offset"))
config.offset = v.get_int32();
// inspector foo
//-------------------------------------------------------------------------
-class TcpPdu : public Inspector
+class TlvPdu : public Inspector
{
public:
- TcpPdu(TcpPduConfig& c) : config(c) { }
+ TlvPdu(TlvPduConfig& c) : config(c) { }
StreamSplitter* get_splitter(bool c2s) override
- { return new TcpPduSplitter(c2s, config); }
+ { return new TlvPduSplitter(c2s, config); }
private:
- TcpPduConfig config;
+ TlvPduConfig config;
};
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
static Module* mod_ctor()
-{ return new TcpPduModule; }
+{ return new TlvPduModule; }
static void mod_dtor(Module* m)
{ delete m; }
static Inspector* pdu_ctor(Module* m)
{
- TcpPduModule* tpm = (TcpPduModule*)m;
- return new TcpPdu(tpm->get_config());
+ TlvPduModule* tpm = (TlvPduModule*)m;
+ return new TlvPdu(tpm->get_config());
}
static void pdu_dtor(Inspector* p)
nullptr
};
#else
-const BaseApi* sin_tcp_pdu = &pdu_api.base;
+const BaseApi* sin_tlv_pdu = &pdu_api.base;
#endif
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-// tcp_pdu.h author Russ Combs <rucombs@cisco.com>
+// tlv_pdu.h author Russ Combs <rucombs@cisco.com>
// provides a simple flush mechanism for TCP PDUs with
// a fixed size header containing a length field
#include "main/snort_types.h"
#include "stream/stream_splitter.h"
-struct TcpPduConfig
+struct TlvPduConfig
{
unsigned size = 0;
unsigned offset = 0;
extern THREAD_LOCAL PduCounts pdu_counts;
-class TcpPduSplitter : public snort::StreamSplitter
+class TlvPduSplitter : public snort::StreamSplitter
{
public:
- TcpPduSplitter(bool b, TcpPduConfig& c) : snort::StreamSplitter(b), config(c) { }
+ TlvPduSplitter(bool b, TlvPduConfig& c) : snort::StreamSplitter(b), config(c) { }
bool is_paf() override { return true; }
Status scan(struct snort::Packet*, const uint8_t*, uint32_t, uint32_t, uint32_t*) override;
private:
- TcpPduConfig config;
+ TlvPduConfig config;
unsigned index = 0;
uint32_t value = 0;
};
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-// tcp_pdu_splitter.cc author Russ Combs <rucombs@cisco.com>
+// tlv_pdu_splitter.cc author Russ Combs <rucombs@cisco.com>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#include "tcp_pdu.h"
+#include "tlv_pdu.h"
using namespace snort;
// splitter foo
//-------------------------------------------------------------------------
-StreamSplitter::Status TcpPduSplitter::scan(Packet*, const uint8_t* data, uint32_t len, uint32_t, uint32_t* fp)
+StreamSplitter::Status TlvPduSplitter::scan(Packet*, const uint8_t* data, uint32_t len, uint32_t, uint32_t* fp)
{
++pdu_counts.scans;
unsigned prefix = config.offset + config.size;