return false;
}
- if ( codec.ip6_extension_count >= IP6_EXTMAX )
+ if ( codec.ip6_extension_count >= snort_conf->get_ip6_maxopts() )
{
codec_events::decoder_event(codec, DECODE_IP6_EXCESS_EXT_HDR);
return false;
return false;
}
- if ( codec.ip6_extension_count >= IP6_EXTMAX )
+ if ( codec.ip6_extension_count >= snort_conf->get_ip6_maxopts() )
{
codec_events::decoder_event(codec, DECODE_IP6_EXCESS_EXT_HDR);
return false;
return false;
}
- if ( codec.ip6_extension_count >= IP6_EXTMAX )
+ if ( codec.ip6_extension_count >= snort_conf->get_ip6_maxopts() )
{
codec_events::decoder_event(codec, DECODE_IP6_EXCESS_EXT_HDR);
return false;
return false;
}
- // comparable to snort
- codec.ip_layer_cnt++;
- // FIXIT-H -j allow configure IP and IP6 encapsulation limits
- if (codec.ip_layer_cnt > 1)
+
+ if (++codec.ip_layer_cnt > snort_conf->get_ip_maxlayers())
codec_events::decoder_event(codec, DECODE_IP_MULTIPLE_ENCAPSULATION);
/* lay the IP struct over the raw data */
goto decodeipv6_fail;
}
- // FIXIT-H -J alert on user configured encapsulated
- if (codec.ip_layer_cnt++ > 1)
+ if (++codec.ip_layer_cnt > snort_conf->get_ip_maxlayers())
codec_events::decoder_event(codec, DECODE_IP_MULTIPLE_ENCAPSULATION);
return false;
}
- if ( codec.ip6_extension_count >= IP6_EXTMAX)
+ if ( codec.ip6_extension_count >= snort_conf->get_ip6_maxopts())
{
codec_events::decoder_event(codec, DECODE_IP6_EXCESS_EXT_HDR);
return false;
// * base+size-1 is last byte of packet (in) / buffer (out)
struct Buffer
{
- uint8_t* base; /* start of data */
+ uint8_t* base; /* start of data */ /* FIXIT-L J - make this private. Ppl should be to access, not manipulate */
uint32_t off; /* offset into data */
private:
uint32_t end; /* end of data */
{ "new_ttl", Parameter::PT_INT, "1:255", "1",
"use this value for responses and when normalizing" },
+ { "layers", Parameter::PT_INT, "3:255", "40",
+ "The maximum number of protocols that Snort can correctly decode" },
+
+ { "max_ip6_options", Parameter::PT_INT, "1:255", "8",
+ "The number of IP6 options following an IPv6 layer Snort must see "
+ "before alerting *gid 119: sid XXX" }, //FIXIT-H J --fIll in SID
+
+ { "max_ip_layers", Parameter::PT_INT, "1:255", "2",
+ "The number of IPv4 and IPv6 layer Snort must see "
+ "before alerting (gid 119: sid XXX" }, //FIXIT-H J --fIll in SID
+
{ nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
};
else if ( v.is("new_ttl") )
p->new_ttl = (uint8_t)v.get_long();
+ else if (v.is("layers"))
+ sc->num_layers = (uint8_t)v.get_long();
+
+ else if (v.is("max_ip6_options"))
+ sc->max_ip6_options = (uint8_t)v.get_long();
+
+ else if (v.is("max_ip_layers"))
+ sc->max_ip_layers = (uint8_t)v.get_long();
+
else
return false;
PolicyMap();
~PolicyMap();
- InspectionPolicy* get_inspection_policy()
+ InspectionPolicy* get_inspection_policy() const
{ return inspection_policy[0]; };
- IpsPolicy* get_ips_policy()
+ IpsPolicy* get_ips_policy() const
{ return ips_policy[0]; };
- NetworkPolicy* get_network_policy()
+ NetworkPolicy* get_network_policy() const
{ return network_policy[0]; };
unsigned add_shell(Shell* sh)
//-------------------------------------------------------------------------
+static THREAD_LOCAL Packet s_packet; // runtime variable.
THREAD_LOCAL SnortConfig* snort_conf = nullptr;
static SnortConfig* snort_cmd_line_conf = nullptr;
//-------------------------------------------------------------------------
// non-local for easy access from core
-static THREAD_LOCAL Packet s_packet;
+//static THREAD_LOCAL Packet s_packet; declared above due to initalization in CodecManager
static THREAD_LOCAL DAQ_PktHdr_t s_pkth;
static THREAD_LOCAL uint8_t s_data[65536];
DAQ_New(snort_conf, intf);
DAQ_Start();
- CodecManager::thread_init();
+ CodecManager::thread_init(snort_conf, s_packet);
FileAPIPostInit();
// this depends on instantiated daq capabilities
ActionManager::thread_term(snort_conf);
IpsManager::clear_options();
EventManager::close_outputs();
+ CodecManager::thread_term(s_packet);
if ( DAQ_WasStarted() )
DAQ_Stop();
SnortEventqFree();
Active_Term();
- CodecManager::thread_term();
}
sc->pkt_skip = 0;
sc->pkt_snaplen = -1;
sc->output_flags = 0;
+ sc->num_layers = DEFAULT_LAYERMAX;
+ sc->max_ip6_options = DEFAULT_IP6_EXTMAX;
+ sc->max_ip_layers = DEFAULT_IPMAX;
/*user_id and group_id should be initialized to -1 by default, because
* chown() use this later, -1 means no change to user_id/group_id*/
p->checksum_eval = cl_drop;
}
+ /* FIXIT-L J do these belong in network policy? */
+ config_file->num_layers = cmd_line->num_layers;
+ config_file->max_ip6_options = cmd_line->max_ip6_options;
+ config_file->max_ip_layers = cmd_line->max_ip_layers;
+
if (cmd_line->obfuscation_net.family != 0)
memcpy(&config_file->obfuscation_net, &cmd_line->obfuscation_net, sizeof(sfip_t));
char *gtp_ports;
uint8_t enable_esp;
+ uint8_t num_layers;
+ uint8_t max_ip6_options;
+ uint8_t max_ip_layers;
int pkt_snaplen;
//------------------------------------------------------
bool unit_test;
#endif
- InspectionPolicy* get_inspection_policy()
+ InspectionPolicy* get_inspection_policy() const
{ return policy_map->get_inspection_policy(); };
- IpsPolicy* get_ips_policy()
+ IpsPolicy* get_ips_policy() const
{ return policy_map->get_ips_policy(); };
- NetworkPolicy* get_network_policy()
+ NetworkPolicy* get_network_policy() const
{ return policy_map->get_network_policy(); };
+
+ inline uint8_t get_num_layers() const
+ { return num_layers; }
+
+ inline uint8_t get_ip6_maxopts() const
+ { return max_ip6_options; }
+
+ inline uint8_t get_ip_maxlayers() const
+ { return max_ip_layers; }
};
SnortConfig* SnortConfNew(void);
std::array<uint8_t, max_protocol_id> CodecManager::s_proto_map{{0}};
std::array<Codec*, UINT8_MAX> CodecManager::s_protocols{{0}};
THREAD_LOCAL uint8_t CodecManager::grinder = 0;
+THREAD_LOCAL uint8_t CodecManager::max_layers = DEFAULT_LAYERMAX;
// This is hardcoded into Snort++
instantiate(wrap, nullptr, nullptr);
}
-void CodecManager::thread_init(void)
+void CodecManager::thread_init(const SnortConfig* const sc, Packet& p)
{
+ max_layers = sc->get_num_layers();
+ p.layers = new Layer[max_layers];
+
for ( CodecApiWrapper& wrap : s_codecs )
if (wrap.api->tinit)
wrap.api->tinit();
#endif
}
-void CodecManager::thread_term()
+void CodecManager::thread_term(Packet& p)
{
PacketManager::accumulate(); // statistics
rand_close(s_rand);
s_rand = NULL;
}
+
+ if (p.layers != nullptr)
+ {
+ free(p.layers);
+ p.layers = nullptr;
+ }
}
void CodecManager::dump_plugins()
static void instantiate();
// destroy all global codec related information
static void release_plugins();
- // initialize the current threads codecs
- static void thread_init();
+ // initialize the current threads DLT and Packet struct
+ static void thread_init(const SnortConfig* const, Packet&);
// destroy thread_local data
- static void thread_term();
+ static void thread_term(Packet&);
// print all of the codec plugins
static void dump_plugins();
static std::array<uint8_t, max_protocol_id> s_proto_map;
static std::array<Codec*, UINT8_MAX> s_protocols;
static THREAD_LOCAL uint8_t grinder;
+ static THREAD_LOCAL uint8_t max_layers;
/*
* Private helper functions. These are all declared here
constexpr int32_t MAX_PORTS = 65536;
constexpr uint16_t NUM_IP_PROTOS = 256;
constexpr int16_t SFTARGET_UNKNOWN_PROTOCOL = -1;
-constexpr uint8_t IP_OPTMAX = 40;
constexpr uint8_t TCP_OPTLENMAX = 40; /* (((2^4) - 1) * 4 - TCP_HEADER_LEN) */
-constexpr uint8_t IP6_EXTMAX = 8;
-constexpr uint8_t LAYER_MAX = 32;
+constexpr uint8_t DEFAULT_IPMAX = 2;
+constexpr uint8_t DEFAULT_IP6_EXTMAX = 8;
+constexpr uint8_t DEFAULT_LAYERMAX = 40;
+
/* D A T A S T R U C T U R E S *********************************************/
uint16_t dsize; /* packet payload size */
SnortData ptrs; // convenience pointers used throughout Snort++
- Layer layers[LAYER_MAX]; /* decoded encapsulations */
+ Layer* layers; /* decoded encapsulations */
PseudoPacketType pseudo_type; // valid only when PKT_PSEUDO is set
// Initialization and setup
//-------------------------------------------------------------------------
-Packet* PacketManager::encode_new ()
+Packet* PacketManager::encode_new()
{
Packet* p = (Packet*)SnortAlloc(sizeof(*p));
uint8_t* b = (uint8_t*)SnortAlloc(sizeof(*p->pkth) + Codec::PKT_MAX + SPARC_TWIDDLE);
+ Layer* lyr = (Layer*)SnortAlloc(sizeof(Layer) * CodecManager::max_layers);
- if ( !p || !b )
+ if ( !p || !b || !lyr)
FatalError("encode_new() => Failed to allocate packet\n");
p->pkth = (DAQ_PktHdr_t*)b;
b += sizeof(*p->pkth);
b += SPARC_TWIDDLE;
p->pkt = b;
+ p->layers = lyr;
return p;
}
-void PacketManager::encode_delete (Packet* p)
+void PacketManager::encode_delete(Packet* p)
{
if (p)
{
- if (p->pkth)
+ if(p->pkth)
free((void*)p->pkth); // cast away const!
+ if(p->layers)
+ free(p->layers);
+
+ p->pkth = nullptr;
+ p->layers = nullptr;
free(p);
}
}
// must be done here after decode and before push for case layer
// LAYER_MAX+1 is invalid or the default codec
- if ( p->num_layers == LAYER_MAX )
+ if ( p->num_layers == CodecManager::max_layers )
{
SnortEventqAdd(GID_DECODE, DECODE_TOO_MANY_LAYERS);
p->data = raw.data;
// STATISTICS!!
// The only time we should accumulate is when CodecManager tells us too
- friend void CodecManager::thread_term();
+ friend void CodecManager::thread_term(Packet&);
static void accumulate();
static bool encode(const Packet* p, EncodeFlags,
uint8_t lyr_start, uint8_t next_prot, Buffer& buf);
static THREAD_LOCAL FragStats t_stats;
static FragStats g_stats;
-//static THREAD_LOCAL Packet* defrag_pkt = NULL;
-//static THREAD_LOCAL Packet* encap_defrag_pkt = NULL;
-
static THREAD_LOCAL uint32_t pkt_snaplen = 0;
-static THREAD_LOCAL std::array<Packet*, LAYER_MAX> defrag_pkts{{0}};
+static THREAD_LOCAL Packet** defrag_pkts; // An array of Packet pointers
/* enum for policy names */
static const char *frag_policy_names[] =
// Defrag methods
//-------------------------------------------------------------------------
-Defrag::Defrag(FragEngine& e) : engine(e) { }
+Defrag::Defrag(FragEngine& e) : engine(e), layers(DEFAULT_LAYERMAX) { }
-bool Defrag::configure(SnortConfig*)
+bool Defrag::configure(SnortConfig* sc)
{
+ layers = sc->get_num_layers();
return true;
}
void Defrag::tinit()
{
+ defrag_pkts = new Packet*[layers];
+
+ for (int i = 1; i < layers; i++)
+ defrag_pkts[i] = nullptr;
+
defrag_pkts[0] = PacketManager::encode_new();
pkt_snaplen = DAQ_GetSnapLen();
}
void Defrag::tterm()
{
- for (std::size_t i = 0; i < defrag_pkts.size(); i++)
+ for (int i = 0; i < layers; i++)
{
if (defrag_pkts[i] != nullptr)
{
defrag_pkts[i] = nullptr;
}
}
+
+ delete defrag_pkts;
+ defrag_pkts = nullptr;
}
void Defrag::show(SnortConfig*)
private:
FragEngine& engine;
+ uint8_t layers;
};
#endif