93
-- updated example inspector dpx.cc api
-- misc tweaks
+-- changed binder to inspector with designated type
+-- added prototype wizard inspector for service selection magic
+-- fixed plugin instantiation when top level table is a list
92
-- fixed fast_pattern only auto configuration
src/stream/udp/Makefile \
src/network_inspectors/Makefile \
src/network_inspectors/arp_spoof/Makefile \
+src/network_inspectors/binder/Makefile \
src/network_inspectors/normalize/Makefile \
src/network_inspectors/perf_monitor/Makefile \
src/network_inspectors/port_scan/Makefile \
src/service_inspectors/http_inspect/Makefile \
src/service_inspectors/nhttp_inspect/Makefile \
src/service_inspectors/rpc_decode/Makefile \
+src/service_inspectors/wizard/Makefile \
src/protocols/Makefile \
src/search_engines/Makefile \
src/sfip/Makefile \
if STATIC_INSPECTORS
lib_list = \
network_inspectors/arp_spoof/libarp_spoof.a \
+network_inspectors/binder/libbinder.a \
network_inspectors/port_scan/libport_scan.a \
service_inspectors/back_orifice/libback_orifice.a \
service_inspectors/ftp_telnet/libftp_telnet.a \
+service_inspectors/nhttp_inspect/libnhttp_inspect.a \
service_inspectors/rpc_decode/librpc_decode.a \
-service_inspectors/nhttp_inspect/libnhttp_inspect.a
+service_inspectors/wizard/libwizard.a
endif
# order libs to avoid undefined symbols
#include "flow/session.h"
#include "packet_io/active.h"
#include "packet_io/sfdaq.h"
-#include "main/binder.h"
#include "utils/stats.h"
#include "protocols/layer.h"
#include "protocols/vlan.h"
+#include "managers/inspector_manager.h"
-FlowControl::FlowControl()
+FlowControl::FlowControl(Inspector* pi)
{
ip_cache = nullptr;
icmp_cache = nullptr;
tcp_cache = nullptr;
udp_cache = nullptr;
exp_cache = nullptr;
+ binder = pi;
}
FlowControl::~FlowControl()
if ( !flow )
return 0;
+ p->flow = flow;
+
if ( !flow->ssn_client )
{
- Binder::init_flow(flow);
+ binder->eval(p);
if ( !flow->session->setup(p) )
return 0;
news = 1;
}
- p->flow = flow;
flow->session->process(p);
if ( news )
- Binder::init_flow(flow, p);
+ binder->eval(p);
if ( flow->next && is_bidirectional(flow) )
cache->unlink_uni(flow);
class FlowControl
{
public:
- FlowControl();
+ FlowControl(class Inspector*);
~FlowControl();
public:
FlowCache* udp_cache;
FlowCache* icmp_cache;
FlowCache* ip_cache;
+
class ExpectCache* exp_cache;
+ class Inspector* binder;
};
#endif
void set_api(const InspectApi* p)
{ api = p; };
+ const InspectApi* get_api()
+ { return api; };
+
public:
static unsigned max_slots;
static THREAD_LOCAL unsigned slot;
enum InspectorType
{
+ IT_BINDER,
+ IT_WIZARD,
IT_PACKET,
IT_PROTOCOL,
IT_STREAM,
add_library (main STATIC
analyzer.h
analyzer.cc
- binder.cc
- binder.h
build.h
modules.cc
modules.h
libmain_a_SOURCES = \
analyzer.cc \
analyzer.h \
-binder.cc \
-binder.h \
build.h \
modules.cc \
modules.h \
#include "framework/module.h"
#include "managers/module_manager.h"
-#include "main/binder.h"
#include "main.h"
#include "snort.h"
#include "snort_config.h"
-#include "binder.h"
#include "parser/parser.h"
#include "parser/parse_conf.h"
#include "parser/config_file.h"
bool set(const char*, Value&, SnortConfig*) { return false; };
};
-//-------------------------------------------------------------------------
-// binder module
-//-------------------------------------------------------------------------
-
-static const Parameter binder_when_params[] =
-{
- { "policy_id", Parameter::PT_STRING, nullptr, nullptr,
- "unique ID for selection of this config by external logic" },
-
- { "vlans", Parameter::PT_BIT_LIST, "4095", nullptr,
- "list of VLAN IDs" },
-
- { "nets", Parameter::PT_ADDR_LIST, nullptr, nullptr,
- "list of networks" },
-
- { "proto", Parameter::PT_ENUM, "any | ip | icmp | tcp | udp", nullptr,
- "protocol" },
-
- { "ports", Parameter::PT_BIT_LIST, "65535", nullptr,
- "list of ports" },
-
- { "role", Parameter::PT_ENUM, "client | server | any", "any",
- "use the given configuration on one or any end of a session" },
-
- { "service", Parameter::PT_STRING, nullptr, nullptr,
- "override default configuration" },
-
- { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
-};
-
-static const Parameter binder_use_params[] =
-{
- { "action", Parameter::PT_ENUM, "inspect | allow | block", "inspect",
- "what to do with matching traffic" },
-
- { "file", Parameter::PT_STRING, nullptr, nullptr,
- "use configuration in given file" },
-
- { "policy_id", Parameter::PT_STRING, nullptr, nullptr,
- "use configuration in given policy" },
-
- { "service", Parameter::PT_STRING, nullptr, nullptr,
- "override automatic service identification" },
-
- { "type", Parameter::PT_STRING, nullptr, nullptr,
- "select module for binding" },
-
- { "name", Parameter::PT_STRING, nullptr, "defaults to type",
- "symbol name" },
-
- { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
-};
-
-static const Parameter binder_params[] =
-{
- { "when", Parameter::PT_TABLE, binder_when_params, nullptr,
- "match criteria" },
-
- { "use", Parameter::PT_TABLE, binder_use_params, nullptr,
- "target configuration" },
-
- { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
-};
-
-class BinderModule : public Module
-{
-public:
- BinderModule() : Module("binder", binder_params) { work = nullptr; };
- bool set(const char*, Value&, SnortConfig*);
- bool begin(const char*, int, SnortConfig*);
- bool end(const char*, int, SnortConfig*);
-
-private:
- Binding* work;
-};
-
-bool BinderModule::set(const char* fqn, Value& v, SnortConfig*)
-{
- // both
- if ( !strcmp(fqn, "binder.when.policy_id") )
- work->when_id = v.get_string();
-
- else if ( !strcmp(fqn, "binder.use.policy_id") )
- work->use_id = v.get_string();
-
- else if ( !strcmp(fqn, "binder.when.service") )
- work->when_svc = v.get_string();
-
- else if ( !strcmp(fqn, "binder.use.service") )
- work->use_svc = v.get_string();
-
- // when
- else if ( v.is("nets") )
- work->nets = v.get_string();
-
- else if ( v.is("proto") )
- work->proto = (BindProto)v.get_long();
-
- else if ( v.is("ports") )
- v.get_bits(work->ports);
-
- else if ( v.is("role") )
- work->role = (BindRole)v.get_long();
-
- else if ( v.is("vlans") )
- v.get_bits(work->vlans);
-
- // use
- else if ( v.is("action") )
- work->action = (BindAction)v.get_long();
-
- else if ( v.is("file") )
- work->file = v.get_string();
-
- else if ( v.is("name") )
- work->name = v.get_string();
-
- else if ( v.is("type") )
- work->type = v.get_string();
-
- else
- return false;
-
- return true;
-}
-
-bool BinderModule::begin(const char* fqn, int idx, SnortConfig*)
-{
- if ( idx && !strcmp(fqn, "binder") )
- work = new Binding;
-
- return true;
-}
-
-bool BinderModule::end(const char* fqn, int idx, SnortConfig*)
-{
- if ( idx && !strcmp(fqn, "binder") )
- {
- Binder::add(work);
- work = nullptr;
- }
- return true;
-}
-
//-------------------------------------------------------------------------
// hosts module
//-------------------------------------------------------------------------
// these modules replace config and hosts.xml
ModuleManager::add_module(new AttributeTableModule);
ModuleManager::add_module(new HostsModule);
-
- // and this one ties it all together
- ModuleManager::add_module(new BinderModule);
}
#include "file_api/file_service.h"
#include "flow/flow_control.h"
#include "main/analyzer.h"
-#include "main/binder.h"
#include "log/sf_textlog.h"
#include "log/log_text.h"
#include "time/periodic.h"
/* Need to do this after dynamic detection stuff is initialized, too */
IpsManager::verify();
- Binder::init();
if (snort_conf->file_mask != 0)
umask(snort_conf->file_mask);
#include <mutex>
#include "module_manager.h"
-#include "main/binder.h"
#include "flow/flow.h"
#include "framework/inspector.h"
#include "detection/detection_util.h"
for ( auto* p : ph_list )
{
- if ( p->pp_class.api.ssn )
- continue;
-
- else if ( p->pp_class.api.type == IT_STREAM )
- session.add(p);
+ switch ( p->pp_class.api.type )
+ {
+ case IT_STREAM:
+ if ( !p->pp_class.api.ssn )
+ session.add(p);
+ break;
- else if ( p->pp_class.api.type < IT_STREAM )
+ case IT_PACKET:
+ case IT_PROTOCOL:
network.add(p);
+ break;
- else if ( p->pp_class.api.type < IT_SERVICE )
+ case IT_SESSION:
generic.add(p);
+ break;
- else
+ case IT_SERVICE:
service.add(p);
+ break;
+
+ case IT_BINDER:
+ case IT_WIZARD:
+ case IT_MAX:
+ break;
+ }
}
};
};
{
if ( !p->init && p->api.term )
p->api.term();
+
delete p;
}
}
if ( !p->is_inactive() )
return;
-#if 0
- // FIXIT add name to Inspector to enable proper call to dtor
- InspectApi* api = (InspectApi*)get_api(PT_INSPECTOR, p->get_name());
-
- if ( api )
- api->dtor(p);
-#else
- delete p;
-#endif
+ free_inspector(p);
s_trash.pop_front();
}
}
return p->handler;
}
+void InspectorManager::free_inspector(Inspector* p)
+{
+ p->get_api()->dtor(p);
+}
+
InspectSsnFunc InspectorManager::get_session(const char* key)
{
const InspectApi* api = get_plugin(key);
static void instantiate(const InspectApi*, Module*, SnortConfig*);
static Inspector* get_inspector(const char* key);
+ static void free_inspector(Inspector*);
static InspectSsnFunc get_session(const char* key);
static bool configure(SnortConfig*);
{
h->mod->end(s, idx, s_config);
- if ( h->api && (key == s) )
+ if ( !idx && h->api && (key == s) )
PluginManager::instantiate(h->api, h->mod, s_config);
}
}
# FIXIT LIBADD here causes undefineds
#libnetwork_inspectors_a_LIBADD = \
#arp_spoof/libarp_spoof.a \
+#binder/libbinder.a \
#normalize/libnormalize.a \
#perf_monitor/libperf_monitor.a \
#port_scan/libport_scan.a
SUBDIRS = \
arp_spoof \
+binder \
normalize \
perf_monitor \
port_scan
--- /dev/null
+AUTOMAKE_OPTIONS=foreign no-dependencies
+
+file_list = \
+binder.cc binder.h \
+bind_module.cc bind_module.h
+
+#if STATIC_INSPECTORS
+noinst_LIBRARIES = libbinder.a
+libbinder_a_SOURCES = $(file_list)
+#else
+# need to fix undefineds first :(
+#shlibdir = $(pkglibdir)/inspectors
+#shlib_LTLIBRARIES = libbinder.la
+#libbinder_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
+#libbinder_la_LDFLAGS = -export-dynamic -shared
+#libbinder_la_SOURCES = $(file_list)
+#endif
+
+AM_CXXFLAGS = @AM_CXXFLAGS@
+
--- /dev/null
+/*
+** Copyright (C) 2014 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.
+*/
+
+// bind_module.cc author Russ Combs <rucombs@cisco.com>
+
+#include "bind_module.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include <string>
+using namespace std;
+
+#include "binder.h"
+
+//-------------------------------------------------------------------------
+// binder module
+//-------------------------------------------------------------------------
+
+static const Parameter binder_when_params[] =
+{
+ { "policy_id", Parameter::PT_STRING, nullptr, nullptr,
+ "unique ID for selection of this config by external logic" },
+
+ { "vlans", Parameter::PT_BIT_LIST, "4095", nullptr,
+ "list of VLAN IDs" },
+
+ { "nets", Parameter::PT_ADDR_LIST, nullptr, nullptr,
+ "list of networks" },
+
+ { "proto", Parameter::PT_ENUM, "any | ip | icmp | tcp | udp", nullptr,
+ "protocol" },
+
+ { "ports", Parameter::PT_BIT_LIST, "65535", nullptr,
+ "list of ports" },
+
+ { "role", Parameter::PT_ENUM, "client | server | any", "any",
+ "use the given configuration on one or any end of a session" },
+
+ { "service", Parameter::PT_STRING, nullptr, nullptr,
+ "override default configuration" },
+
+ { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
+};
+
+static const Parameter binder_use_params[] =
+{
+ { "action", Parameter::PT_ENUM, "inspect | allow | block", "inspect",
+ "what to do with matching traffic" },
+
+ { "file", Parameter::PT_STRING, nullptr, nullptr,
+ "use configuration in given file" },
+
+ { "policy_id", Parameter::PT_STRING, nullptr, nullptr,
+ "use configuration in given policy" },
+
+ { "service", Parameter::PT_STRING, nullptr, nullptr,
+ "override automatic service identification" },
+
+ { "type", Parameter::PT_STRING, nullptr, nullptr,
+ "select module for binding" },
+
+ { "name", Parameter::PT_STRING, nullptr, "defaults to type",
+ "symbol name" },
+
+ { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
+};
+
+static const Parameter binder_params[] =
+{
+ { "when", Parameter::PT_TABLE, binder_when_params, nullptr,
+ "match criteria" },
+
+ { "use", Parameter::PT_TABLE, binder_use_params, nullptr,
+ "target configuration" },
+
+ { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
+};
+
+BinderModule::BinderModule() : Module("binder", binder_params)
+{ work = nullptr; }
+
+BinderModule::~BinderModule()
+{
+ if ( work )
+ delete work;
+}
+
+bool BinderModule::set(const char* fqn, Value& v, SnortConfig*)
+{
+ // both
+ if ( !strcmp(fqn, "binder.when.policy_id") )
+ work->when_id = v.get_string();
+
+ else if ( !strcmp(fqn, "binder.use.policy_id") )
+ work->use_id = v.get_string();
+
+ else if ( !strcmp(fqn, "binder.when.service") )
+ work->when_svc = v.get_string();
+
+ else if ( !strcmp(fqn, "binder.use.service") )
+ work->use_svc = v.get_string();
+
+ // when
+ else if ( v.is("nets") )
+ work->nets = v.get_string();
+
+ else if ( v.is("proto") )
+ work->proto = (BindProto)v.get_long();
+
+ else if ( v.is("ports") )
+ v.get_bits(work->ports);
+
+ else if ( v.is("role") )
+ work->role = (BindRole)v.get_long();
+
+ else if ( v.is("vlans") )
+ v.get_bits(work->vlans);
+
+ // use
+ else if ( v.is("action") )
+ work->action = (BindAction)v.get_long();
+
+ else if ( v.is("file") )
+ work->file = v.get_string();
+
+ else if ( v.is("name") )
+ work->name = v.get_string();
+
+ else if ( v.is("type") )
+ work->type = v.get_string();
+
+ else
+ return false;
+
+ return true;
+}
+
+bool BinderModule::begin(const char* fqn, int idx, SnortConfig*)
+{
+ if ( idx && !strcmp(fqn, "binder") )
+ work = new Binding;
+
+ return true;
+}
+
+bool BinderModule::end(const char* fqn, int idx, SnortConfig*)
+{
+ if ( idx && !strcmp(fqn, "binder") )
+ {
+ bindings.push_back(work);
+ work = nullptr;
+ }
+ return true;
+}
+
+vector<Binding*> BinderModule::get_data()
+{
+ return bindings; // move semantics
+}
+
--- /dev/null
+/*
+** Copyright (C) 2014 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.
+*/
+
+// bind_module.cc author Russ Combs <rucombs@cisco.com>
+
+#ifndef BIND_MODULE_H
+#define BIND_MODULE_H
+
+#include <vector>
+
+#include "framework/module.h"
+
+struct Binding;
+
+class BinderModule : public Module
+{
+public:
+ BinderModule();
+ ~BinderModule();
+
+ bool set(const char*, Value&, SnortConfig*);
+ bool begin(const char*, int, SnortConfig*);
+ bool end(const char*, int, SnortConfig*);
+
+ std::vector<Binding*> get_data();
+private:
+ Binding* work;
+ std::vector<Binding*> bindings;
+};
+
+#endif
+
// binder.cc author Russ Combs <rucombs@cisco.com>
#include "binder.h"
-using namespace std;
#include <vector>
+using namespace std;
+
+#include "bind_module.h"
#include "flow/flow.h"
#include "framework/inspector.h"
#include "stream/stream_splitter.h"
#include "managers/inspector_manager.h"
#include "protocols/packet.h"
#include "stream/stream_api.h"
+#include "time/profiler.h"
+#include "utils/stats.h"
+#include "log/messages.h"
-static vector<Binding*> bindings;
+static const char* mod_name = "binder";
-void Binder::init()
-{
-}
+#ifdef PERF_PROFILING
+static THREAD_LOCAL PreprocStats bindPerfStats;
-void Binder::term()
+static PreprocStats* bind_get_profile(const char* key)
{
- for ( auto* p : bindings )
- delete p;
-}
+ if ( !strcmp(key, mod_name) )
+ return &bindPerfStats;
-void Binder::add(Binding* b)
-{
- bindings.push_back(b);
+ return nullptr;
}
+#endif
+
+static THREAD_LOCAL SimpleStats tstats;
+static SimpleStats gstats;
+
+//-------------------------------------------------------------------------
+// helpers
+//-------------------------------------------------------------------------
// FIXIT bind this is a temporary hack. note that both ends must be set
// independently and that we must ref count inspectors.
return false;
}
+//-------------------------------------------------------------------------
+// class stuff
+//-------------------------------------------------------------------------
+
+class Binder : public Inspector {
+public:
+ Binder(vector<Binding*>);
+ ~Binder();
+
+ void show(SnortConfig*)
+ { LogMessage("Binder\n"); };
+
+ void eval(Packet*);
+
+ void add(Binding* b)
+ { bindings.push_back(b); };
+
+private:
+ Inspector* get_clouseau(Flow*, Packet*);
+
+ void init_flow(Flow*);
+ void init_flow(Flow*, Packet*);
+
+private:
+ vector<Binding*> bindings;
+};
+
+Binder::Binder(vector<Binding*> v)
+{
+ bindings = v;
+}
+
+Binder::~Binder()
+{
+ for ( auto* p : bindings )
+ delete p;
+}
+
+void Binder::eval(Packet* p)
+{
+ Flow* flow = p->flow;
+
+ if ( !flow->ssn_client )
+ init_flow(p->flow);
+
+ else if ( !flow->clouseau )
+ init_flow(p->flow, p);
+
+ ++tstats.total_packets;
+}
+
// FIXIT bind services - this is a temporary hack that just looks at ports,
// need to examine all key fields for matching. ultimately need a routing
// table, scapegoat tree, magic wand, etc.
-static Inspector* get_clouseau(Flow* flow, Packet* p)
+Inspector* Binder::get_clouseau(Flow* flow, Packet* p)
{
Binding* pb;
unsigned i, sz = bindings.size();
if ( pb->ports.test(port) )
break;
}
+ Inspector* ins;
+
if ( i == sz || !pb->type.size() )
- return nullptr;
+ ins = InspectorManager::get_inspector("wizard");
+
+ else
+ ins = InspectorManager::get_inspector(pb->type.c_str());
- Inspector* ins = InspectorManager::get_inspector(pb->type.c_str());
return ins;
}
flow->set_clouseau(ins);
}
+//-------------------------------------------------------------------------
+// api stuff
+//-------------------------------------------------------------------------
+
+static Module* mod_ctor()
+{ return new BinderModule; }
+
+static void mod_dtor(Module* m)
+{ delete m; }
+
+void bind_init()
+{
+#ifdef PERF_PROFILING
+ RegisterPreprocessorProfile(
+ mod_name, &bindPerfStats, 0, &totalPerfStats, bind_get_profile);
+#endif
+}
+
+static Inspector* bind_ctor(Module* m)
+{
+ BinderModule* mod = (BinderModule*)m;
+ vector<Binding*> pb = mod->get_data();
+ return new Binder(pb);
+}
+
+static void bind_dtor(Inspector* p)
+{
+ delete p;
+}
+
+static void bind_sum()
+{
+ sum_stats(&gstats, &tstats);
+}
+
+static void bind_stats()
+{
+ show_stats(&gstats, mod_name);
+}
+
+static void bind_reset()
+{
+ memset(&gstats, 0, sizeof(gstats));
+}
+
+static const InspectApi bind_api =
+{
+ {
+ PT_INSPECTOR,
+ mod_name,
+ INSAPI_PLUGIN_V0,
+ 0,
+ mod_ctor,
+ mod_dtor
+ },
+ IT_BINDER,
+ PROTO_BIT__ALL,
+ nullptr, // buffers
+ nullptr, // service
+ bind_init,
+ nullptr, // term
+ bind_ctor,
+ bind_dtor,
+ nullptr, // pinit
+ nullptr, // pterm
+ nullptr, // ssn
+ bind_sum,
+ bind_stats,
+ bind_reset
+};
+
+#ifdef BUILDING_SO
+SO_PUBLIC const BaseApi* snort_plugins[] =
+{
+ &bind_api.base,
+ nullptr
+};
+#else
+const BaseApi* nin_binder = &bind_api.base;
+#endif
+
{ role = BR_EITHER; action = BA_INSPECT; };
};
-class Binder
-{
-public:
- static void init();
- static void term();
- static void add(Binding*);
- static void init_flow(class Flow*);
- static void init_flow(class Flow*, struct Packet*);
-};
-
#endif
#endif
#include "framework/inspector.h"
+extern const BaseApi* nin_binder;
extern const BaseApi* nin_normalize;
extern const BaseApi* nin_perf_monitor;
extern const BaseApi* nin_stream_ip;
const BaseApi* network_inspectors[] =
{
+ nin_binder,
nin_normalize,
nin_perf_monitor,
nin_stream_ip,
#back_orifice/libback_orifice.a \
#ftp_telnet/libftp_telnet.a \
#http_inspect/libhttp_inspect.a \
+#nhttp_inspect/libnhttp_inspect.a \
#rpc_decode/librpc_decode.a
+#wizard/libwizard.a
SUBDIRS = \
back_orifice \
ftp_telnet \
http_inspect \
nhttp_inspect \
-rpc_decode
+rpc_decode \
+wizard
AM_CXXFLAGS = @AM_CXXFLAGS@
extern const BaseApi* sin_bo;
extern const BaseApi* sin_ftp_client;
extern const BaseApi* sin_ftp_server;
+extern const BaseApi* sin_nhttp;
extern const BaseApi* sin_rpc_decode;
extern const BaseApi* sin_telnet;
-extern const BaseApi* sin_nhttp;
+extern const BaseApi* sin_wizard;
#endif
const BaseApi* service_inspectors[] =
sin_bo,
sin_ftp_client,
sin_ftp_server,
+ sin_nhttp,
sin_rpc_decode,
sin_telnet,
- sin_nhttp,
+ sin_wizard,
#endif
nullptr,
};
--- /dev/null
+AUTOMAKE_OPTIONS=foreign no-dependencies
+
+file_list = \
+wizard.cc wizard.h \
+wiz_module.cc wiz_module.h
+
+#if STATIC_INSPECTORS
+noinst_LIBRARIES = libwizard.a
+libwizard_a_SOURCES = $(file_list)
+#else
+# need to fix undefineds first :(
+#shlibdir = $(pkglibdir)/inspectors
+#shlib_LTLIBRARIES = libwizard.la
+#libwizard_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
+#libwizard_la_LDFLAGS = -export-dynamic -shared
+#libwizard_la_SOURCES = $(file_list)
+#endif
+
+AM_CXXFLAGS = @AM_CXXFLAGS@
+
--- /dev/null
+/*
+** Copyright (C) 2014 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.
+*/
+
+// wiz_module.cc author Russ Combs <rucombs@cisco.com>
+
+#include "wiz_module.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include <string>
+using namespace std;
+
+#include "wizard.h"
+
+static const char* s_name = "wizard";
+
+//-------------------------------------------------------------------------
+// wizard module
+//-------------------------------------------------------------------------
+
+static const Parameter wizard_params[] =
+{
+ { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
+};
+
+WizardModule::WizardModule() : Module(s_name, wizard_params)
+{ }
+
+WizardModule::~WizardModule()
+{ }
+
+bool WizardModule::set(const char*, Value&, SnortConfig*)
+{
+ //if ( v.is("type") )
+ // work->type = v.get_string();
+
+ //else
+ // return false;
+
+ return true;
+}
+
+bool WizardModule::begin(const char*, int, SnortConfig*)
+{
+ return true;
+}
+
+bool WizardModule::end(const char*, int, SnortConfig*)
+{
+ return true;
+}
+
--- /dev/null
+/*
+** Copyright (C) 2014 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.
+*/
+
+// wiz_module.cc author Russ Combs <rucombs@cisco.com>
+
+#ifndef WIZ_MODULE_H
+#define WIZ_MODULE_H
+
+#include "framework/module.h"
+
+class WizardModule : public Module
+{
+public:
+ WizardModule();
+ ~WizardModule();
+
+ bool set(const char*, Value&, SnortConfig*);
+ bool begin(const char*, int, SnortConfig*);
+ bool end(const char*, int, SnortConfig*);
+
+private:
+};
+
+#endif
+
--- /dev/null
+/*
+** Copyright (C) 2014 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.
+*/
+// wizard.cc author Russ Combs <rucombs@cisco.com>
+
+#include "wizard.h"
+
+#include <vector>
+using namespace std;
+
+#include "wiz_module.h"
+#include "flow/flow.h"
+#include "framework/inspector.h"
+#include "stream/stream_splitter.h"
+#include "managers/inspector_manager.h"
+#include "protocols/packet.h"
+#include "stream/stream_api.h"
+#include "stream/stream_splitter.h"
+#include "time/profiler.h"
+#include "utils/stats.h"
+#include "log/messages.h"
+
+static const char* mod_name = "wizard";
+
+#ifdef PERF_PROFILING
+static THREAD_LOCAL PreprocStats wizPerfStats;
+
+static PreprocStats* wiz_get_profile(const char* key)
+{
+ if ( !strcmp(key, mod_name) )
+ return &wizPerfStats;
+
+ return nullptr;
+}
+#endif
+
+static THREAD_LOCAL SimpleStats tstats;
+static SimpleStats gstats;
+
+//-------------------------------------------------------------------------
+// splitter - this doesn't actually split the stream but it applies
+// basic magic type logic to determine the appropriate inspector that
+// will split the stream.
+//-------------------------------------------------------------------------
+
+class MagicSplitter : public StreamSplitter
+{
+public:
+ MagicSplitter(bool c2s) : StreamSplitter(c2s) { };
+ ~MagicSplitter() { };
+
+ PAF_Status scan(Flow*, const uint8_t* data, uint32_t len,
+ uint32_t flags, uint32_t* fp);
+};
+
+PAF_Status MagicSplitter::scan (
+ Flow*, const uint8_t* data, uint32_t len,
+ uint32_t, uint32_t* fp)
+{
+ // this is a basic hack to find http requests so that the overall
+ // processing flow can be determined at which point the real magic
+ // can begin.
+ if ( len >= 3 && !strncmp((const char*)data, "GET", 3) )
+ {
+ // FIXIT here we have determined that the inspector should
+ // be http and must somehow tell the binder so it can set
+ // inspector gadget.
+
+ // the real magic must check direction and protocol
+ // (and should be called from eval() for udp and from
+ // here for tcp).
+
+ // len + 1 means go back to the last flush point
+ *fp = len + 1;
+
+ // the reset status ensures that all the
+ // data scanned so far is delivered to the new inspector's
+ // splitter.
+ return PAF_RESET;
+ }
+
+ return PAF_SEARCH;
+}
+
+//-------------------------------------------------------------------------
+// class stuff
+//-------------------------------------------------------------------------
+
+class Wizard : public Inspector {
+public:
+ Wizard();
+ ~Wizard();
+
+ void show(SnortConfig*)
+ { LogMessage("Wizard\n"); };
+
+ void eval(Packet*);
+
+ StreamSplitter* get_splitter(bool);
+
+private:
+
+private:
+};
+
+Wizard::Wizard()
+{
+}
+
+Wizard::~Wizard()
+{
+}
+
+void Wizard::eval(Packet*)
+{
+ if ( !IsUDP(p) )
+ return;
+
+ // FIXIT do udp scanning here
+ ++tstats.total_packets;
+}
+
+StreamSplitter* Wizard::get_splitter(bool c2s)
+{
+ return new MagicSplitter(c2s);
+}
+
+//-------------------------------------------------------------------------
+// api stuff
+//-------------------------------------------------------------------------
+
+static Module* mod_ctor()
+{ return new WizardModule; }
+
+static void mod_dtor(Module* m)
+{ delete m; }
+
+void wiz_init()
+{
+#ifdef PERF_PROFILING
+ RegisterPreprocessorProfile(
+ mod_name, &wizPerfStats, 0, &totalPerfStats, wiz_get_profile);
+#endif
+}
+
+static Inspector* wiz_ctor(Module* m)
+{
+ WizardModule* mod = (WizardModule*)m;
+ assert(mod);
+ return new Wizard;
+}
+
+static void wiz_dtor(Inspector* p)
+{
+ delete p;
+}
+
+static void wiz_sum()
+{
+ sum_stats(&gstats, &tstats);
+}
+
+static void wiz_stats()
+{
+ show_stats(&gstats, mod_name);
+}
+
+static void wiz_reset()
+{
+ memset(&gstats, 0, sizeof(gstats));
+}
+
+static const InspectApi wiz_api =
+{
+ {
+ PT_INSPECTOR,
+ mod_name,
+ INSAPI_PLUGIN_V0,
+ 0,
+ mod_ctor,
+ mod_dtor
+ },
+ IT_WIZARD,
+ PROTO_BIT__TCP | PROTO_BIT__UDP,
+ nullptr, // buffers
+ nullptr, // service
+ wiz_init,
+ nullptr, // term
+ wiz_ctor,
+ wiz_dtor,
+ nullptr, // pinit
+ nullptr, // pterm
+ nullptr, // ssn
+ wiz_sum,
+ wiz_stats,
+ wiz_reset
+};
+
+#ifdef BUILDING_SO
+SO_PUBLIC const BaseApi* snort_plugins[] =
+{
+ &wiz_api.base,
+ nullptr
+};
+#else
+const BaseApi* sin_wizard = &wiz_api.base;
+#endif
+
--- /dev/null
+/*
+** Copyright (C) 2014 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.
+*/
+// wizard.cc author Russ Combs <rucombs@cisco.com>
+
+#ifndef WIZARD_H
+#define WIZARD_H
+
+#include <string>
+
+#endif
+
void StreamBase::pinit()
{
assert(!flow_con);
- flow_con = new FlowControl();
+ Inspector* pi = InspectorManager::get_inspector("binder");
+ flow_con = new FlowControl(pi);
InspectSsnFunc f;
if ( config->tcp_cfg.max_sessions )
PAF_START, // internal use only
PAF_SEARCH, // searching for next flush point
PAF_FLUSH, // flush at given offset
- PAF_SKIP // skip ahead to given offset
+ PAF_SKIP, // skip ahead to given offset
+ PAF_RESET // rewind to the prior flush point
};
//-------------------------------------------------------------------------
void ResetRuleProfiling(void);
/* Preprocessor stats info */
-typedef struct _PreprocStats
+struct PreprocStats
{
uint64_t ticks, ticks_start;
uint64_t checks;
uint64_t exits;
-} PreprocStats;
+};
typedef struct _ProfileConfig
{