#include "packet_io/sfdaq_config.h"
#include "packet_io/sfdaq_instance.h"
#include "packet_io/trough.h"
-#include "target_based/sftarget_reader.h"
+#include "target_based/host_attributes.h"
#include "time/periodic.h"
#include "utils/util.h"
#include "utils/safec.h"
assert(!athread);
LogMessage("++ [%u] %s\n", idx, analyzer->get_source());
- Swapper* ps = new Swapper(SnortConfig::get_conf(), SFAT_GetConfig());
+ Swapper* ps = new Swapper(SnortConfig::get_conf(), HostAttributes::get_host_attributes_table());
athread = new std::thread(std::ref(*analyzer), ps, ++run_num);
}
return 0;
}
- tTargetBasedConfig* old_tc = SFAT_GetConfig();
- tTargetBasedConfig* tc = SFAT_Swap();
+ if ( !sc->attribute_hosts_file.empty() )
+ HostAttributes::load_hosts_file(sc, sc->attribute_hosts_file.c_str());
+
+ HostAttributesTable* old_tc = HostAttributes::get_host_attributes_table();
+ HostAttributesTable* tc = HostAttributes::activate();
- if ( !tc )
- {
- // FIXIT-L it does not seem a valid check, delete old config if come to it
- current_request->respond("== reload failed - bad config\n");
- SnortConfig::set_parser_conf(nullptr);
- return 0;
- }
PluginManager::reload_so_plugins_cleanup(sc);
SnortConfig::set_conf(sc);
proc_stats.conf_reloads++;
return 0;
}
- Shell sh = Shell(fname);
- sh.configure(SnortConfig::get_conf(), false, true);
+ proc_stats.attribute_table_overflow = 0;
+ HostAttributes::load_hosts_file(SnortConfig::get_conf(), fname);
- tTargetBasedConfig* old = SFAT_GetConfig();
- tTargetBasedConfig* tc = SFAT_Swap();
+ HostAttributesTable* old = HostAttributes::get_host_attributes_table();
+ HostAttributesTable* tc = HostAttributes::activate();
if ( !tc )
{
return 0;
}
+ proc_stats.attribute_table_reloads++;
+ LogMessage(STDu64 " hosts loaded\n", proc_stats.attribute_table_hosts);
+
bool from_shell = ( L != nullptr );
current_request->respond(".. swapping hosts table\n", from_shell);
main_broadcast_command(new ACSwap(new Swapper(old, tc), current_request, from_shell), from_shell);
#include "side_channel/side_channel_module.h"
#include "sfip/sf_ipvar.h"
#include "stream/stream.h"
-#include "target_based/sftarget_data.h"
+#include "target_based/host_attributes.h"
#include "target_based/snort_protocols.h"
#include "trace/trace_module.h"
static const Parameter attribute_table_params[] =
{
+ { "hosts_file", Parameter::PT_STRING, nullptr, nullptr,
+ "filename to load attribute host table from" },
+
{ "max_hosts", Parameter::PT_INT, "32:max53", "1024",
"maximum number of hosts in attribute table" },
bool AttributeTableModule::set(const char*, Value& v, SnortConfig* sc)
{
- if ( v.is("max_hosts") )
+ if ( v.is("hosts_file") )
+ sc->attribute_hosts_file = std::string(v.get_string());
+
+ else if ( v.is("max_hosts") )
sc->max_attribute_hosts = v.get_uint32();
else if ( v.is("max_services_per_host") )
bool HostsModule::begin(const char* fqn, int idx, SnortConfig*)
{
if ( idx && !strcmp(fqn, "hosts.services") )
- app = SFAT_CreateApplicationEntry();
-
+ app = new ApplicationEntry;
else if ( idx && !strcmp(fqn, "hosts") )
- host = SFAT_CreateHostEntry();
+ host = new HostAttributeEntry;
return true;
}
-bool HostsModule::end(const char* fqn, int idx, SnortConfig*)
+bool HostsModule::end(const char* fqn, int idx, SnortConfig* sc)
{
if ( idx && !strcmp(fqn, "hosts.services") )
{
- SFAT_AddService(host, app);
+ host->add_service(app);
app = nullptr;
}
else if ( idx && !strcmp(fqn, "hosts") )
{
- SFAT_AddHost(host);
+ if ( !HostAttributes::add_host(host, sc) )
+ delete host;
host = nullptr;
}
#include "service_inspectors/service_inspectors.h"
#include "side_channel/side_channel.h"
#include "stream/stream_inspectors.h"
-#include "target_based/sftarget_reader.h"
+#include "target_based/host_attributes.h"
#include "time/periodic.h"
#include "trace/trace_log_api.h"
#include "utils/util.h"
#endif
InitProtoNames();
- SFAT_Init();
load_actions();
load_codecs();
sc->setup();
+ if ( !sc->attribute_hosts_file.empty() )
+ HostAttributes::load_hosts_file(sc, sc->attribute_hosts_file.c_str());
+
// Must be after CodecManager::instantiate()
if ( !InspectorManager::configure(sc) )
ParseError("can't initialize inspectors");
if ((offload_search_api != nullptr) and (offload_search_api != search_api))
MpseManager::activate_search_engine(offload_search_api, sc);
- SFAT_Start();
+ HostAttributes::activate();
#ifdef PIGLET
if ( !Piglet::piglet_mode() )
term_signals();
IpsManager::global_term(SnortConfig::get_conf());
- SFAT_Cleanup();
+ HostAttributes::cleanup();
#ifdef PIGLET
if ( !Piglet::piglet_mode() )
#include "profiler/profiler.h"
#include "protocols/packet.h"
#include "sfip/sf_ip.h"
-#include "target_based/sftarget_reader.h"
+#include "target_based/host_attributes.h"
#include "target_based/snort_protocols.h"
#include "trace/trace_config.h"
#include "utils/dnet_header.h"
class ProtocolReference;
class XHash;
struct ProfilerConfig;
-struct SnortConfig;
class ReloadResourceTuner
{
//------------------------------------------------------
// attribute tables stuff
+ std::string attribute_hosts_file;
uint32_t max_attribute_hosts = 0;
uint32_t max_attribute_services_per_host = 0;
uint32_t max_metadata_services = 0;
#include "swapper.h"
-#include "target_based/sftarget_reader.h"
+#include "target_based/host_attributes.h"
#include "analyzer.h"
#include "snort.h"
bool Swapper::reload_in_progress = false;
-Swapper::Swapper(SnortConfig* s, tTargetBasedConfig* t)
+Swapper::Swapper(SnortConfig* s, HostAttributesTable* t)
{
old_conf = nullptr;
new_conf = s;
new_attribs = nullptr;
}
-Swapper::Swapper(SnortConfig* sold, SnortConfig* snew, tTargetBasedConfig* told, tTargetBasedConfig* tnew)
+Swapper::Swapper(SnortConfig* sold, SnortConfig* snew, HostAttributesTable* told, HostAttributesTable* tnew)
{
old_conf = sold;
new_conf = snew;
new_attribs = tnew;
}
-Swapper::Swapper(tTargetBasedConfig* told, tTargetBasedConfig* tnew)
+Swapper::Swapper(HostAttributesTable* told, HostAttributesTable* tnew)
{
old_conf = nullptr;
new_conf = nullptr;
delete old_conf;
if ( old_attribs )
- SFAT_Free(old_attribs);
+ delete old_attribs;
}
void Swapper::apply(Analyzer& analyzer)
const bool reload = (SnortConfig::get_conf() != nullptr);
SnortConfig::set_conf(new_conf);
// FIXIT-M Determine whether we really want to do this before or after the set_conf
- if (reload)
+ if ( reload )
analyzer.reinit(new_conf);
}
if ( new_attribs )
- SFAT_SetConfig(new_attribs);
+ HostAttributes::set_host_attributes_table(new_attribs);
}
}
class Analyzer;
-struct tTargetBasedConfig;
+struct HostAttributesTable;
class Swapper
{
public:
- Swapper(snort::SnortConfig*, tTargetBasedConfig*);
+ Swapper(snort::SnortConfig*, HostAttributesTable*);
Swapper(snort::SnortConfig*, snort::SnortConfig*);
- Swapper(snort::SnortConfig*, snort::SnortConfig*, tTargetBasedConfig*, tTargetBasedConfig*);
- Swapper(tTargetBasedConfig*, tTargetBasedConfig*);
+ Swapper(snort::SnortConfig*, snort::SnortConfig*, HostAttributesTable*, HostAttributesTable*);
+ Swapper(HostAttributesTable*, HostAttributesTable*);
~Swapper();
void apply(Analyzer&);
snort::SnortConfig* old_conf;
snort::SnortConfig* new_conf;
- tTargetBasedConfig* old_attribs;
- tTargetBasedConfig* new_attribs;
+ HostAttributesTable* old_attribs;
+ HostAttributesTable* new_attribs;
static bool reload_in_progress;
};
#include "pub_sub/assistant_gadget_event.h"
#include "stream/stream.h"
#include "stream/stream_splitter.h"
-#include "target_based/sftarget_reader.h"
+#include "target_based/host_attributes.h"
#include "target_based/snort_protocols.h"
#include "bind_module.h"
if ( !stuff.apply_action(flow) )
return;
- const HostAttributeEntry* host = SFAT_LookupHostEntryByIP(&flow->server_ip);
+ const HostAttributeEntry* host = HostAttributes::find_host(&flow->server_ip);
// setup session
stuff.apply_session(flow, host);
#include "packet_io/active.h"
#include "protocols/vlan.h"
#include "stream/base/stream_module.h"
-#include "target_based/sftarget_hostentry.h"
+#include "target_based/host_attributes.h"
#include "target_based/snort_protocols.h"
#include "utils/util.h"
set_ip_protocol(flow);
}
- snort_protocol_id = get_snort_protocol_id_from_host_table(
- host_entry, flow->ssn_state.ipprotocol,
- flow->server_port, SFAT_SERVICE);
+ snort_protocol_id = host_entry->get_snort_protocol_id
+ (flow->ssn_state.ipprotocol, flow->server_port);
#if 0
// FIXIT-M from client doesn't imply need to swap
set_ip_protocol(flow);
}
- if ( HostAttributeEntry* host_entry = SFAT_LookupHostEntryByIP(&flow->server_ip) )
+ if ( HostAttributeEntry* host_entry = HostAttributes::find_host(&flow->server_ip) )
{
set_snort_protocol_id(flow, host_entry, FROM_SERVER);
return flow->ssn_state.snort_protocol_id;
}
- if ( HostAttributeEntry* host_entry = SFAT_LookupHostEntryByIP(&flow->client_ip) )
+ if ( HostAttributeEntry* host_entry = HostAttributes::find_host(&flow->client_ip) )
{
set_snort_protocol_id(flow, host_entry, FROM_CLIENT);
if ( !flow->is_proxied() )
{
- SFAT_UpdateApplicationProtocol(
- &flow->server_ip, flow->server_port,
- flow->ssn_state.ipprotocol, id);
+ HostAttributes::update_service
+ (&flow->server_ip, flow->server_port, flow->ssn_state.ipprotocol, id);
}
return id;
}
{ flushed = 2; }
}
-
uint16_t FlushBucket::get_size()
{ return 1; }
-
//--------------------------------------------------------------------------
// atom splitter tests
//--------------------------------------------------------------------------
add_library( target_based OBJECT
- sftarget_reader.cc
- sftarget_reader.h
- sftarget_hostentry.cc
- sftarget_hostentry.h
- sftarget_data.h
+ host_attributes.cc
+ host_attributes.h
snort_protocols.cc
)
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
+// Copyright (C) 2006-2013 Sourcefire, Inc.
+//
+// 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.
+//--------------------------------------------------------------------------
+
+// host_attributes.cc Author: davis mcpherson
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "host_attributes.h"
+
+#include "log/messages.h"
+#include "main/shell.h"
+#include "main/snort_config.h"
+#include "protocols/packet.h"
+#include "sfrt/sfrt.h"
+#include "utils/stats.h"
+#include "utils/util.h"
+
+using namespace snort;
+
+static THREAD_LOCAL HostAttributesTable* curr_cfg = nullptr;
+static HostAttributesTable* next_cfg = nullptr;
+
+void HostAttributesTable::free_host_entry(void* host)
+{ delete (HostAttributeEntry*)host; }
+
+HostAttributesTable::HostAttributesTable(uint32_t max_hosts)
+ : max_hosts(max_hosts)
+{
+ // Add 1 to max for table purposes
+ // We use max_hosts to limit memcap, assume 16k per entry costs
+ // FIXIT-M 16k per host is no longer true
+ host_table = sfrt_new(DIR_8x16, IPv6, max_hosts + 1, (max_hosts >> 6) + 1);
+}
+
+HostAttributesTable::~HostAttributesTable()
+{
+ sfrt_cleanup(host_table, HostAttributesTable::free_host_entry);
+ sfrt_free(host_table);
+}
+
+bool HostAttributesTable::add_host(HostAttributeEntry* host)
+{
+ SfCidr* ipAddr = &host->ipAddr;
+ int ret = sfrt_insert(ipAddr, (unsigned char)ipAddr->get_bits(), host,
+ RT_FAVOR_SPECIFIC, host_table);
+
+ if ( ret == RT_SUCCESS )
+ {
+ ++num_hosts;
+ return true;
+ }
+
+ if ( ret == RT_POLICY_TABLE_EXCEEDED )
+ {
+ if ( !sfat_insufficient_space_logged )
+ {
+ ParseWarning(WARN_HOSTS, "Attribute table insertion failed: %d Insufficient "
+ "space in attribute table, only configured to store %u hosts\n",
+ ret, max_hosts);
+ sfat_insufficient_space_logged = true;
+ }
+
+ proc_stats.attribute_table_overflow++;
+ }
+ else if ( !sfat_grammar_error_printed )
+ {
+ ParseWarning(WARN_HOSTS, "Attribute table insertion failed: %d '%s'\n",
+ ret, rt_error_messages[ret]);
+ sfat_grammar_error_printed = true;
+ }
+
+ return false;
+}
+
+HostAttributeEntry* HostAttributesTable::get_host(SfIp* ipAddr)
+{
+ HostAttributeEntry* host = (HostAttributeEntry*)sfrt_lookup(ipAddr, host_table);
+ if ( !host && !is_host_attribute_table_full() )
+ {
+ host = new HostAttributeEntry;
+ host->ipAddr.set(*ipAddr);
+ if ( !curr_cfg->add_host(host) )
+ {
+ delete host;
+ host = nullptr;
+ }
+ }
+
+ return host;
+}
+
+HostAttributeEntry* HostAttributesTable::find_host(const SfIp* ipAddr)
+{ return (HostAttributeEntry*)sfrt_lookup(ipAddr, host_table); }
+
+HostAttributeEntry::~HostAttributeEntry()
+{
+ for ( auto app : services )
+ delete app;
+}
+
+void HostAttributeEntry::add_service(ApplicationEntry* app)
+{ services.push_back(app); }
+
+void HostAttributeEntry::update_service
+ (HostAttributeEntry* host, uint16_t port, uint16_t protocol, SnortProtocolId snort_protocol_id)
+{
+ unsigned service_count = 0;
+
+ for ( auto app : services)
+ {
+ if ( app->ipproto == protocol && (uint16_t)app->port == port )
+ {
+ app->snort_protocol_id = snort_protocol_id;
+ return;
+ }
+
+ service_count++;
+ }
+
+ // application service not found, add it
+ if ( service_count >= SnortConfig::get_max_services_per_host() )
+ return;
+
+ ApplicationEntry* app = new ApplicationEntry(port, protocol, snort_protocol_id);
+ host->add_service(app);
+}
+SnortProtocolId HostAttributeEntry::get_snort_protocol_id(int ipprotocol, uint16_t port) const
+{
+ for ( auto app : services )
+ {
+ if ( (app->ipproto == ipprotocol) && (app->port == port) )
+ return app->snort_protocol_id;
+ }
+
+ return 0;
+}
+
+void HostAttributes::load_hosts_file(SnortConfig* sc, const char* fname)
+{
+ delete next_cfg;
+ next_cfg = new HostAttributesTable(sc->max_attribute_hosts);
+
+ Shell sh = Shell(fname);
+ if ( !sh.configure(sc, false, true) )
+ {
+ delete next_cfg;
+ next_cfg = nullptr;
+ }
+}
+
+HostAttributesTable* HostAttributes::activate()
+{
+ curr_cfg = next_cfg;
+ next_cfg = nullptr;
+
+ if ( curr_cfg )
+ proc_stats.attribute_table_hosts = curr_cfg->get_num_hosts();
+ else
+ proc_stats.attribute_table_hosts = 0;
+
+ return curr_cfg;
+}
+
+void HostAttributes::set_host_attributes_table(HostAttributesTable* p)
+{ curr_cfg = p; }
+
+HostAttributesTable* HostAttributes::get_host_attributes_table()
+{ return curr_cfg; }
+
+bool HostAttributes::add_host(HostAttributeEntry* host, snort::SnortConfig* sc)
+{
+ if ( !next_cfg )
+ next_cfg = new HostAttributesTable(sc->max_attribute_hosts);
+
+ return next_cfg->add_host(host);
+}
+
+HostAttributeEntry* HostAttributes::find_host(const SfIp* ipAddr)
+{
+ if ( !curr_cfg )
+ return nullptr;
+
+ return curr_cfg->find_host(ipAddr);
+}
+
+void HostAttributes::update_service(SfIp* ipAddr, uint16_t port, uint16_t protocol, SnortProtocolId snort_protocol_id)
+{
+ if ( curr_cfg )
+ {
+ HostAttributeEntry* host = curr_cfg->get_host(ipAddr);
+ if ( host )
+ host->update_service(host, port, protocol, snort_protocol_id);
+ }
+}
+
+void HostAttributes::cleanup()
+{ delete curr_cfg; }
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
+// Copyright (C) 2006-2013 Sourcefire, Inc.
+//
+// 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.
+//--------------------------------------------------------------------------
+
+// host_attributes.h author davis mcpherson
+
+#ifndef HOST_ATTRIBUTES_H
+#define HOST_ATTRIBUTES_H
+
+// Provides attribute table initialization, lookup, swap, and releasing.
+
+#include <vector>
+
+#include "sfip/sf_cidr.h"
+#include "sfrt/sfrt.h"
+#include "target_based/snort_protocols.h"
+
+struct ApplicationEntry
+{
+ ApplicationEntry() = default;
+ ApplicationEntry(uint16_t port, uint16_t protocol, SnortProtocolId spi)
+ : port(port), ipproto(protocol), snort_protocol_id(spi)
+ { }
+ ~ApplicationEntry() = default;
+
+ uint16_t port = 0;
+ uint16_t ipproto = 0;
+ SnortProtocolId snort_protocol_id = 0;
+};
+
+struct HostInfo
+{
+ uint8_t streamPolicy = 0;
+ uint8_t fragPolicy = 0;
+};
+
+struct HostAttributeEntry
+{
+ HostAttributeEntry() = default;
+ ~HostAttributeEntry();
+
+ void add_service(ApplicationEntry*);
+ void update_service(HostAttributeEntry*, uint16_t port, uint16_t protocol, SnortProtocolId);
+ SnortProtocolId get_snort_protocol_id(int ipprotocol, uint16_t port) const;
+
+ snort::SfCidr ipAddr;
+ HostInfo hostInfo;
+ std::vector<ApplicationEntry*> services;
+};
+
+#define DEFAULT_MAX_ATTRIBUTE_HOSTS 10000
+#define DEFAULT_MAX_ATTRIBUTE_SERVICES_PER_HOST 100
+#define DEFAULT_MAX_METADATA_SERVICES 9
+
+namespace snort
+{
+struct SfIp;
+struct SnortConfig;
+}
+
+struct HostAttributesTable
+{
+ HostAttributesTable(uint32_t max_hosts);
+ ~HostAttributesTable();
+
+ bool add_host(HostAttributeEntry*);
+ HostAttributeEntry* get_host(snort::SfIp*);
+ HostAttributeEntry* find_host(const snort::SfIp*);
+ void add_service(HostAttributeEntry*, ApplicationEntry*);
+
+ bool is_host_attribute_table_full()
+ { return num_hosts >= max_hosts; }
+
+ uint32_t get_num_hosts () const
+ { return num_hosts; }
+
+private:
+ table_t* host_table;
+ uint32_t max_hosts;
+ uint32_t num_hosts = 0;
+
+ bool sfat_grammar_error_printed = false;
+ bool sfat_insufficient_space_logged = false;
+
+ static void free_host_entry(void* host);
+};
+
+class HostAttributes
+{
+public:
+ static void load_hosts_file(snort::SnortConfig*, const char* fname);
+ static HostAttributesTable* activate();
+ static HostAttributesTable* get_host_attributes_table();
+ static void set_host_attributes_table(HostAttributesTable*);
+ static bool add_host(HostAttributeEntry*, snort::SnortConfig*);
+ static HostAttributeEntry* find_host(const snort::SfIp* ipAddr);
+ static void update_service(snort::SfIp*, uint16_t port, uint16_t protocol, uint16_t id);
+ static void cleanup();
+};
+
+
+#endif
+
+++ /dev/null
-//--------------------------------------------------------------------------
-// Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
-// Copyright (C) 2006-2013 Sourcefire, Inc.
-//
-// 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.
-//--------------------------------------------------------------------------
-
-// sftarget_data.c author Steven Sturges
-
-#ifndef SFTARGET_DATA_H
-#define SFTARGET_DATA_H
-
-#include "sfip/sf_cidr.h"
-#include "target_based/snort_protocols.h"
-
-#define SFAT_OK 0
-#define SFAT_ERROR (-1)
-#define SFAT_BUFSZ 1024
-
-enum ServiceClient
-{
- ATTRIBUTE_SERVICE,
- ATTRIBUTE_CLIENT
-};
-
-#define APPLICATION_ENTRY_PORT 0x01
-#define APPLICATION_ENTRY_IPPROTO 0x02
-#define APPLICATION_ENTRY_PROTO 0x04
-#define APPLICATION_ENTRY_APPLICATION 0x08
-#define APPLICATION_ENTRY_VERSION 0x10
-
-struct ApplicationEntry
-{
- ApplicationEntry* next;
-
- uint16_t port;
- uint16_t ipproto;
- SnortProtocolId snort_protocol_id;
-
- uint8_t fields;
-};
-
-#define HOST_INFO_OS 1
-#define HOST_INFO_VENDOR 2
-#define HOST_INFO_VERSION 3
-#define HOST_INFO_FRAG_POLICY 4
-#define HOST_INFO_STREAM_POLICY 5
-
-struct HostInfo
-{
- uint8_t streamPolicy;
- uint8_t fragPolicy;
-};
-
-#define SFAT_SERVICE 1
-#define SFAT_CLIENT 2
-
-struct HostAttributeEntry
-{
- snort::SfCidr ipAddr;
- HostInfo hostInfo;
- ApplicationEntry* services;
- ApplicationEntry* clients;
-};
-
-int SFAT_AddHost(HostAttributeEntry*);
-int SFAT_AddService(HostAttributeEntry*, ApplicationEntry*);
-int SFAT_AddHostEntryToMap(HostAttributeEntry*);
-
-HostAttributeEntry* SFAT_CreateHostEntry();
-ApplicationEntry* SFAT_CreateApplicationEntry();
-
-#endif
-
+++ /dev/null
-//--------------------------------------------------------------------------
-// Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
-// Copyright (C) 2006-2013 Sourcefire, Inc.
-//
-// 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.
-//--------------------------------------------------------------------------
-
-// sftarget_hostentry.c author Steven Sturges
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "sftarget_hostentry.h"
-
-#if 0
-static bool hasService(const HostAttributeEntry* host_entry,
- int ipprotocol, int protocol, int application)
-{
- ApplicationEntry* service;
-
- if (!host_entry)
- return false;
-
- for (service = host_entry->services; service; service = service->next)
- {
- if (ipprotocol && (service->ipproto == ipprotocol))
- {
- if (protocol && (service->protocol == protocol))
- {
- if (!application)
- {
- /* match of ipproto, proto. application not specified */
- return true;
- }
- }
- else if (!protocol)
- {
- /* match of ipproto. protocol not specified */
- return true;
- }
- }
- /* No ipprotocol specified, huh? */
- }
-
- return false;
-}
-
-static bool hasClient(const HostAttributeEntry* host_entry,
- int ipprotocol, int protocol, int application)
-{
- ApplicationEntry* client;
-
- if (!host_entry)
- return false;
-
- for (client = host_entry->clients; client; client = client->next)
- {
- if (ipprotocol && (client->ipproto == ipprotocol))
- {
- if (protocol && (client->protocol == protocol))
- {
- if (!application)
- {
- /* match of ipproto, proto. application not specified */
- return true;
- }
- }
- else if (!protocol)
- {
- /* match of ipproto. protocol not specified */
- return true;
- }
- }
- /* No ipprotocol specified, huh? */
- }
-
- return false;
-}
-
-bool hasProtocol(const HostAttributeEntry* host_entry,
- int ipprotocol, int protocol, int application)
-{
- if ( hasService(host_entry, ipprotocol, protocol, application) )
- return true;
-
- if ( hasClient(host_entry, ipprotocol, protocol, application) )
- return true;
-
- return false;
-}
-#endif
-
-SnortProtocolId get_snort_protocol_id_from_host_table(const HostAttributeEntry* host_entry,
- int ipprotocol,
- uint16_t port,
- char direction)
-{
- ApplicationEntry* application;
-
- if (!host_entry)
- return 0;
-
- if (direction == SFAT_SERVICE)
- {
- for (application = host_entry->services; application; application = application->next)
- {
- if (application->ipproto == ipprotocol)
- {
- if ((uint16_t)application->port == port)
- {
- return application->snort_protocol_id;
- }
- }
- }
- }
-
- return 0;
-}
-
+++ /dev/null
-//--------------------------------------------------------------------------
-// Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
-// Copyright (C) 2006-2013 Sourcefire, Inc.
-//
-// 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.
-//--------------------------------------------------------------------------
-
-// sftarget_hostentry.h author Steven Sturges
-
-#ifndef SFTARGET_HOSTENTRY_H
-#define SFTARGET_HOSTENTRY_H
-
-#include "target_based/sftarget_reader.h"
-
-/* API for HostAttributeEntry 'class' */
-
-#if 0
-bool hasProtocol(const HostAttributeEntry*, int ipprotocol, int protocol, int application);
-#endif
-
-SnortProtocolId get_snort_protocol_id_from_host_table(
- const HostAttributeEntry*, int ipprotocol, uint16_t port, char direction);
-
-#endif
-
+++ /dev/null
-//--------------------------------------------------------------------------
-// Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
-// Copyright (C) 2006-2013 Sourcefire, Inc.
-//
-// 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.
-//--------------------------------------------------------------------------
-
-/*
- * Author: Steven Sturges
- * sftarget_reader.c
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "sftarget_reader.h"
-
-#include "log/messages.h"
-#include "main/snort_config.h"
-#include "protocols/packet.h"
-#include "sfrt/sfrt.h"
-#include "utils/stats.h"
-#include "utils/util.h"
-
-using namespace snort;
-
-#define ATTRIBUTE_MAP_MAX_ROWS 1024
-
-struct tTargetBasedConfig
-{
- table_t* lookupTable;
-
- tTargetBasedConfig();
- ~tTargetBasedConfig();
-};
-
-static void SFAT_CleanupCallback(void* host_attr_ent)
-{
- HostAttributeEntry* host_entry = (HostAttributeEntry*)host_attr_ent;
- FreeHostEntry(host_entry);
-}
-
-tTargetBasedConfig::tTargetBasedConfig()
-{
- /* Add 1 to max for table purposes
- * We use max_hosts to limit memcap, assume 16k per entry costs*/
- // FIXIT-M 16k per host is no longer true
- // FIXIT-M init before snort_conf; move to filename and load separately
- // this is a hack to get it going
- uint32_t max = SnortConfig::get_conf() ?
- SnortConfig::get_max_attribute_hosts() : DEFAULT_MAX_ATTRIBUTE_HOSTS;
- lookupTable = sfrt_new(DIR_8x16, IPv6, max + 1, (max>>6) + 1);
-}
-
-tTargetBasedConfig::~tTargetBasedConfig()
-{
- sfrt_cleanup(lookupTable, SFAT_CleanupCallback);
- sfrt_free(lookupTable);
-}
-
-static THREAD_LOCAL tTargetBasedConfig* curr_cfg = nullptr;
-static tTargetBasedConfig* next_cfg = nullptr;
-
-static bool sfat_grammar_error_printed = false;
-static bool sfat_insufficient_space_logged = false;
-
-/*****TODO: cleanup to use config directive *******/
-uint32_t SFAT_NumberOfHosts()
-{
- if ( curr_cfg && curr_cfg->lookupTable )
- {
- return sfrt_num_entries(curr_cfg->lookupTable);
- }
-
- return 0;
-}
-
-static void FreeApplicationEntry(ApplicationEntry* app)
-{
- snort_free(app);
-}
-
-ApplicationEntry* SFAT_CreateApplicationEntry()
-{
- return (ApplicationEntry*)snort_calloc(sizeof(ApplicationEntry));
-}
-
-HostAttributeEntry* SFAT_CreateHostEntry()
-{
- return (HostAttributeEntry*)snort_calloc(sizeof(HostAttributeEntry));
-}
-
-void FreeHostEntry(HostAttributeEntry* host)
-{
- ApplicationEntry* app = nullptr, * tmp_app;
-
- if (!host)
- return;
-
-
- /* Free the service list */
- if (host->services)
- {
- do
- {
- tmp_app = host->services;
- app = tmp_app->next;
- FreeApplicationEntry(tmp_app);
- host->services = app;
- }
- while (app);
- }
-
- /* Free the client list */
- if (host->clients)
- {
- do
- {
- tmp_app = host->clients;
- app = tmp_app->next;
- FreeApplicationEntry(tmp_app);
- host->clients = app;
- }
- while (app);
- }
-
- snort_free(host);
-}
-
-static void AppendApplicationData(ApplicationEntry** list, ApplicationEntry* app)
-{
- if (!list)
- return;
-
- if (*list)
- {
- app->next = *list;
- }
- *list = app;
-}
-
-int SFAT_AddService(HostAttributeEntry* host, ApplicationEntry* app)
-{
- AppendApplicationData(&host->services, app);
- return SFAT_OK;
-}
-
-#if 0
-int SFAT_AddApplicationData(HostAttributeEntry* host, ApplicationEntry* app)
-{
- uint8_t required_fields =
- (APPLICATION_ENTRY_PORT |
- APPLICATION_ENTRY_IPPROTO |
- APPLICATION_ENTRY_PROTO);
-
- if ((app->fields & required_fields) != required_fields)
- {
- ParseError("Missing required field in Service attribute table for host %s",
- host->ipAddr.ntoa());
- }
- AppendApplicationData(&host->services, app);
-
- return SFAT_OK;
-}
-
-#endif
-
-
-int SFAT_AddHost(HostAttributeEntry* host)
-{
- return SFAT_AddHostEntryToMap(host);
-}
-
-int SFAT_AddHostEntryToMap(HostAttributeEntry* host)
-{
- int ret;
- SfCidr* ipAddr;
-
- ipAddr = &host->ipAddr;
- assert(ipAddr);
-
- ret = sfrt_insert(ipAddr, (unsigned char)ipAddr->get_bits(), host,
- RT_FAVOR_SPECIFIC, next_cfg->lookupTable);
-
- if (ret != RT_SUCCESS)
- {
- if (ret == RT_POLICY_TABLE_EXCEEDED)
- {
- if ( !sfat_insufficient_space_logged )
- {
- ParseWarning(WARN_HOSTS,
- "AttributeTable insertion failed: %d Insufficient "
- "space in attribute table, only configured to store %u hosts\n",
- ret, SnortConfig::get_max_attribute_hosts());
- sfat_insufficient_space_logged = true;
- }
- /* Reset return value and continue w/ only SnortConfig::get_conf()->max_attribute_hosts */
- ret = RT_SUCCESS;
- }
- else if ( !sfat_grammar_error_printed )
- {
- ParseWarning(WARN_HOSTS,
- "AttributeTable insertion failed: %d '%s'\n",
- ret, rt_error_messages[ret]);
- sfat_grammar_error_printed = true;
- }
-
- FreeHostEntry(host);
- }
-
- return ret == RT_SUCCESS ? SFAT_OK : SFAT_ERROR;
-}
-
-HostAttributeEntry* SFAT_LookupHostEntryByIP(const SfIp* ipAddr)
-{
- if ( !curr_cfg )
- return nullptr;
-
- return (HostAttributeEntry*)sfrt_lookup((const SfIp*)ipAddr, curr_cfg->lookupTable);
-}
-
-HostAttributeEntry* SFAT_LookupHostEntryBySrc(Packet* p)
-{
- if (!p || !p->ptrs.ip_api.is_ip())
- return nullptr;
-
- return SFAT_LookupHostEntryByIP(p->ptrs.ip_api.get_src());
-}
-
-HostAttributeEntry* SFAT_LookupHostEntryByDst(Packet* p)
-{
- if (!p || !p->ptrs.ip_api.is_ip())
- return nullptr;
-
- return SFAT_LookupHostEntryByIP(p->ptrs.ip_api.get_dst());
-}
-
-void SFAT_Cleanup()
-{
- delete curr_cfg;
- delete next_cfg;
-}
-
-void SFAT_SetConfig(tTargetBasedConfig* p)
-{
- curr_cfg = p;
-}
-
-tTargetBasedConfig* SFAT_GetConfig()
-{
- return curr_cfg;
-}
-
-void SFAT_Free(tTargetBasedConfig* p)
-{
- delete p;
-}
-
-void SFAT_Init()
-{
- curr_cfg = nullptr;
- next_cfg = new tTargetBasedConfig;
-}
-
-void SFAT_Start()
-{
- curr_cfg = next_cfg;
- next_cfg = new tTargetBasedConfig;
- proc_stats.attribute_table_hosts = SFAT_NumberOfHosts();
-}
-
-tTargetBasedConfig* SFAT_Swap()
-{
- curr_cfg = next_cfg;
- next_cfg = new tTargetBasedConfig;
-
- proc_stats.attribute_table_hosts = SFAT_NumberOfHosts();
- proc_stats.attribute_table_reloads++;
-
- LogMessage(STDu64 " hosts loaded\n", proc_stats.attribute_table_hosts);
- return curr_cfg;
-}
-
-void SFAT_UpdateApplicationProtocol(SfIp* ipAddr, uint16_t port, uint16_t protocol, SnortProtocolId snort_protocol_id)
-{
- HostAttributeEntry* host_entry;
- ApplicationEntry* service;
- unsigned service_count = 0;
-
- host_entry = (HostAttributeEntry*)sfrt_lookup(ipAddr, curr_cfg->lookupTable);
-
- if (!host_entry)
- {
- if (sfrt_num_entries(curr_cfg->lookupTable) >= SnortConfig::get_max_attribute_hosts())
- return;
-
- host_entry = (HostAttributeEntry*)snort_calloc(sizeof(*host_entry));
- host_entry->ipAddr.set(*ipAddr);
-
- int rval = sfrt_insert(&host_entry->ipAddr, (unsigned char)host_entry->ipAddr.get_bits(),
- host_entry, RT_FAVOR_SPECIFIC, curr_cfg->lookupTable);
-
- if ( rval != RT_SUCCESS)
- {
- FreeHostEntry(host_entry);
- return;
- }
- service = nullptr;
- }
- else
- {
- for (service = host_entry->services; service; service = service->next)
- {
- if (service->ipproto == protocol && (uint16_t)service->port == port)
- {
- break;
- }
- service_count++;
- }
- }
- if (!service)
- {
- if ( service_count >= SnortConfig::get_max_services_per_host() )
- return;
-
- service = (ApplicationEntry*)snort_calloc(sizeof(*service));
- service->port = port;
- service->ipproto = protocol;
- service->next = host_entry->services;
- host_entry->services = service;
- service->snort_protocol_id = snort_protocol_id;
- }
- else if (service->snort_protocol_id != snort_protocol_id)
- {
- service->snort_protocol_id = snort_protocol_id;
- }
-}
-
+++ /dev/null
-//--------------------------------------------------------------------------
-// Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
-// Copyright (C) 2006-2013 Sourcefire, Inc.
-//
-// 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.
-//--------------------------------------------------------------------------
-
-// sftarget_reader.h author Steven Sturges
-
-#ifndef SFTARGET_READER_H
-#define SFTARGET_READER_H
-
-// Provides attribute table initialization, lookup, swap, and releasing.
-
-#include "target_based/sftarget_data.h"
-
-#define DEFAULT_MAX_ATTRIBUTE_HOSTS 10000
-#define DEFAULT_MAX_ATTRIBUTE_SERVICES_PER_HOST 100
-#define DEFAULT_MAX_METADATA_SERVICES 9
-
-#define MAX_MAX_ATTRIBUTE_HOSTS (512 * 1024)
-#define MIN_MAX_ATTRIBUTE_HOSTS 32
-#define MAX_MAX_ATTRIBUTE_SERVICES_PER_HOST 65535
-#define MIN_MAX_ATTRIBUTE_SERVICES_PER_HOST 1
-#define MAX_MAX_METADATA_SERVICES 256
-#define MIN_MAX_METADATA_SERVICES 1
-
-namespace snort
-{
-struct Packet;
-}
-
-/* main Functions, called by Snort shutdown */
-void SFAT_Init();
-void SFAT_Start();
-void SFAT_Cleanup();
-void FreeHostEntry(HostAttributeEntry* host);
-
-/* status functions */
-uint32_t SFAT_NumberOfHosts();
-
-/* API Lookup functions, to be called by Stream & Frag */
-HostAttributeEntry* SFAT_LookupHostEntryByIP(const snort::SfIp* ipAddr);
-HostAttributeEntry* SFAT_LookupHostEntryBySrc(snort::Packet* p);
-HostAttributeEntry* SFAT_LookupHostEntryByDst(snort::Packet* p);
-
-#if 0
-int SFAT_AddApplicationData(HostAttributeEntry*, struct ApplicationEntry*);
-#endif
-void SFAT_UpdateApplicationProtocol(snort::SfIp*, uint16_t port, uint16_t protocol, uint16_t id);
-
-// reload functions
-struct tTargetBasedConfig;
-tTargetBasedConfig* SFAT_Swap();
-tTargetBasedConfig* SFAT_GetConfig();
-void SFAT_SetConfig(tTargetBasedConfig*);
-void SFAT_Free(tTargetBasedConfig*);
-
-#endif
-
#include "utils/util.h"
#include "utils/util_cstring.h"
-#include "sftarget_data.h"
-
using namespace snort;
using namespace std;
{ CountType::SUM, "policy_reloads", "number of times policies were reloaded" },
{ CountType::SUM, "inspector_deletions", "number of times inspectors were deleted" },
{ CountType::SUM, "daq_reloads", "number of times daq configuration was reloaded" },
- { CountType::SUM, "attribute_table_reloads", "number of times hosts table was reloaded" },
- { CountType::SUM, "attribute_table_hosts", "total number of hosts in table" },
+ { CountType::SUM, "attribute_table_reloads", "number of times hosts attribute table was reloaded" },
+ { CountType::SUM, "attribute_table_hosts", "number of hosts added to the attribute table" },
+ { CountType::SUM, "attribute_table_overflow", "number of host additions that failed due to attribute table full" },
{ CountType::END, nullptr, nullptr }
};
PegCount daq_reloads;
PegCount attribute_table_reloads;
PegCount attribute_table_hosts;
+ PegCount attribute_table_overflow;
};
extern ProcessCount proc_stats;