From: Josh Date: Sat, 20 Sep 2014 01:37:10 +0000 (-0400) Subject: adding Packet command line options X-Git-Tag: 3.0.0-233~1404^2~10^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=096f93bc2d95571e0ba511bd848d9919ee084a44;p=thirdparty%2Fsnort3.git adding Packet command line options --- diff --git a/src/codecs/ip/cd_dst_opts.cc b/src/codecs/ip/cd_dst_opts.cc index 66244e394..0f313e99f 100644 --- a/src/codecs/ip/cd_dst_opts.cc +++ b/src/codecs/ip/cd_dst_opts.cc @@ -72,7 +72,7 @@ bool Ipv6DSTOptsCodec::decode(const RawData& raw, CodecData& codec, SnortData&) 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; diff --git a/src/codecs/ip/cd_frag.cc b/src/codecs/ip/cd_frag.cc index 3313f873d..9e6beadac 100644 --- a/src/codecs/ip/cd_frag.cc +++ b/src/codecs/ip/cd_frag.cc @@ -71,7 +71,7 @@ bool Ipv6FragCodec::decode(const RawData& raw, CodecData& codec, SnortData& snor 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; diff --git a/src/codecs/ip/cd_hop_opts.cc b/src/codecs/ip/cd_hop_opts.cc index 66bfd290c..d9139576e 100644 --- a/src/codecs/ip/cd_hop_opts.cc +++ b/src/codecs/ip/cd_hop_opts.cc @@ -78,7 +78,7 @@ bool Ipv6HopOptsCodec::decode(const RawData& raw, CodecData& codec, SnortData&) 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; diff --git a/src/codecs/ip/cd_ipv4.cc b/src/codecs/ip/cd_ipv4.cc index 3bcf700ce..52f5a3817 100644 --- a/src/codecs/ip/cd_ipv4.cc +++ b/src/codecs/ip/cd_ipv4.cc @@ -151,10 +151,8 @@ bool Ipv4Codec::decode(const RawData& raw, CodecData& codec, SnortData& snort) 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 */ diff --git a/src/codecs/ip/cd_ipv6.cc b/src/codecs/ip/cd_ipv6.cc index 12efac1a3..4578d4b04 100644 --- a/src/codecs/ip/cd_ipv6.cc +++ b/src/codecs/ip/cd_ipv6.cc @@ -152,8 +152,7 @@ bool Ipv6Codec::decode(const RawData& raw, CodecData& codec, SnortData& snort) 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); diff --git a/src/codecs/ip/cd_routing.cc b/src/codecs/ip/cd_routing.cc index 294cf5f0c..a1085c810 100644 --- a/src/codecs/ip/cd_routing.cc +++ b/src/codecs/ip/cd_routing.cc @@ -89,7 +89,7 @@ bool Ipv6RoutingCodec::decode(const RawData& raw, CodecData& codec, SnortData&) 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; diff --git a/src/framework/codec.h b/src/framework/codec.h index 56cb349fd..05c07af3c 100644 --- a/src/framework/codec.h +++ b/src/framework/codec.h @@ -145,7 +145,7 @@ struct EncState // * 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 */ diff --git a/src/main/modules.cc b/src/main/modules.cc index 28be1c8a9..feab5d1bb 100644 --- a/src/main/modules.cc +++ b/src/main/modules.cc @@ -1028,6 +1028,17 @@ static const Parameter network_params[] = { "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 } }; @@ -1063,6 +1074,15 @@ bool NetworkModule::set(const char*, Value& v, SnortConfig* sc) 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; diff --git a/src/main/policy.h b/src/main/policy.h index 8ce58d51f..b82ded2a3 100644 --- a/src/main/policy.h +++ b/src/main/policy.h @@ -152,13 +152,13 @@ public: 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) diff --git a/src/main/snort.cc b/src/main/snort.cc index 07b391497..ac0cec037 100644 --- a/src/main/snort.cc +++ b/src/main/snort.cc @@ -117,6 +117,7 @@ using namespace std; //------------------------------------------------------------------------- +static THREAD_LOCAL Packet s_packet; // runtime variable. THREAD_LOCAL SnortConfig* snort_conf = nullptr; static SnortConfig* snort_cmd_line_conf = nullptr; @@ -690,7 +691,7 @@ SnortConfig* reload_config() //------------------------------------------------------------------------- // 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]; @@ -963,7 +964,7 @@ void snort_thread_init(const char* intf) DAQ_New(snort_conf, intf); DAQ_Start(); - CodecManager::thread_init(); + CodecManager::thread_init(snort_conf, s_packet); FileAPIPostInit(); // this depends on instantiated daq capabilities @@ -995,6 +996,7 @@ void snort_thread_term() ActionManager::thread_term(snort_conf); IpsManager::clear_options(); EventManager::close_outputs(); + CodecManager::thread_term(s_packet); if ( DAQ_WasStarted() ) DAQ_Stop(); @@ -1015,6 +1017,5 @@ void snort_thread_term() SnortEventqFree(); Active_Term(); - CodecManager::thread_term(); } diff --git a/src/main/snort_config.cc b/src/main/snort_config.cc index 995dbbc12..984634eb5 100644 --- a/src/main/snort_config.cc +++ b/src/main/snort_config.cc @@ -158,6 +158,9 @@ SnortConfig * SnortConfNew(void) 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*/ @@ -366,6 +369,11 @@ SnortConfig* MergeSnortConfs(SnortConfig *cmd_line, SnortConfig *config_file) 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)); diff --git a/src/main/snort_config.h b/src/main/snort_config.h index 5aeb058b8..71009394c 100644 --- a/src/main/snort_config.h +++ b/src/main/snort_config.h @@ -157,6 +157,9 @@ struct SnortConfig char *gtp_ports; uint8_t enable_esp; + uint8_t num_layers; + uint8_t max_ip6_options; + uint8_t max_ip_layers; int pkt_snaplen; //------------------------------------------------------ @@ -281,14 +284,23 @@ struct SnortConfig 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); diff --git a/src/managers/codec_manager.cc b/src/managers/codec_manager.cc index cf503f40a..310f8e918 100644 --- a/src/managers/codec_manager.cc +++ b/src/managers/codec_manager.cc @@ -46,6 +46,7 @@ std::vector CodecManager::s_codecs; std::array CodecManager::s_proto_map{{0}}; std::array 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++ @@ -196,8 +197,11 @@ void CodecManager::instantiate() 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(); @@ -247,7 +251,7 @@ void CodecManager::thread_init(void) #endif } -void CodecManager::thread_term() +void CodecManager::thread_term(Packet& p) { PacketManager::accumulate(); // statistics @@ -262,6 +266,12 @@ void CodecManager::thread_term() rand_close(s_rand); s_rand = NULL; } + + if (p.layers != nullptr) + { + free(p.layers); + p.layers = nullptr; + } } void CodecManager::dump_plugins() diff --git a/src/managers/codec_manager.h b/src/managers/codec_manager.h index a29467bda..deb10efc3 100644 --- a/src/managers/codec_manager.h +++ b/src/managers/codec_manager.h @@ -62,10 +62,10 @@ public: 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(); @@ -76,6 +76,7 @@ private: static std::array s_proto_map; static std::array s_protocols; static THREAD_LOCAL uint8_t grinder; + static THREAD_LOCAL uint8_t max_layers; /* * Private helper functions. These are all declared here diff --git a/src/protocols/packet.h b/src/protocols/packet.h index 0ee4f77e1..7b54bc764 100644 --- a/src/protocols/packet.h +++ b/src/protocols/packet.h @@ -139,10 +139,11 @@ enum PseudoPacketType{ 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 *********************************************/ @@ -176,7 +177,7 @@ struct Packet 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 diff --git a/src/protocols/packet_manager.cc b/src/protocols/packet_manager.cc index b4163273b..bd75a358c 100644 --- a/src/protocols/packet_manager.cc +++ b/src/protocols/packet_manager.cc @@ -101,29 +101,36 @@ static inline void push_layer(Packet *p, // 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); } } @@ -178,7 +185,7 @@ void PacketManager::decode( // 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; diff --git a/src/protocols/packet_manager.h b/src/protocols/packet_manager.h index bf1828096..c472bcd32 100644 --- a/src/protocols/packet_manager.h +++ b/src/protocols/packet_manager.h @@ -143,7 +143,7 @@ private: // 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); diff --git a/src/stream/ip/ip_defrag.cc b/src/stream/ip/ip_defrag.cc index 20458613f..e92440526 100644 --- a/src/stream/ip/ip_defrag.cc +++ b/src/stream/ip/ip_defrag.cc @@ -227,11 +227,8 @@ static THREAD_LOCAL unsigned long mem_in_use = 0; /* memory in use, used for sel 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 defrag_pkts{{0}}; +static THREAD_LOCAL Packet** defrag_pkts; // An array of Packet pointers /* enum for policy names */ static const char *frag_policy_names[] = @@ -1291,22 +1288,28 @@ int fragGetApplicationProtocolId(Packet *p) // 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) { @@ -1314,6 +1317,9 @@ void Defrag::tterm() defrag_pkts[i] = nullptr; } } + + delete defrag_pkts; + defrag_pkts = nullptr; } void Defrag::show(SnortConfig*) diff --git a/src/stream/ip/ip_defrag.h b/src/stream/ip/ip_defrag.h index 1b45e332a..d973d2b64 100644 --- a/src/stream/ip/ip_defrag.h +++ b/src/stream/ip/ip_defrag.h @@ -70,6 +70,7 @@ private: private: FragEngine& engine; + uint8_t layers; }; #endif