]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
adding Packet command line options
authorJosh <jrosenba@cisco.com>
Sat, 20 Sep 2014 01:37:10 +0000 (21:37 -0400)
committerJosh <jrosenba@cisco.com>
Sat, 20 Sep 2014 01:37:10 +0000 (21:37 -0400)
19 files changed:
src/codecs/ip/cd_dst_opts.cc
src/codecs/ip/cd_frag.cc
src/codecs/ip/cd_hop_opts.cc
src/codecs/ip/cd_ipv4.cc
src/codecs/ip/cd_ipv6.cc
src/codecs/ip/cd_routing.cc
src/framework/codec.h
src/main/modules.cc
src/main/policy.h
src/main/snort.cc
src/main/snort_config.cc
src/main/snort_config.h
src/managers/codec_manager.cc
src/managers/codec_manager.h
src/protocols/packet.h
src/protocols/packet_manager.cc
src/protocols/packet_manager.h
src/stream/ip/ip_defrag.cc
src/stream/ip/ip_defrag.h

index 66244e39480091599e3131a303fe15f10331f4b3..0f313e99f45ffb72fd0c5adaf207a52f97f77cb1 100644 (file)
@@ -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;
index 3313f873dc7eaa4882cd1b38e6dfafb5555c23cc..9e6beadac64fd506e7d3b5c119b02fb1b073c0cf 100644 (file)
@@ -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;
index 66bfd290c33d5e4d6a52736abecb23696f998f72..d9139576e6ebbb0a4cfdf3eb2b3ceccdd931b28f 100644 (file)
@@ -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;
index 3bcf700ce865d05120fffa6225b925cef9103f2f..52f5a3817112d7c8aa30f69cbe6a5fa9dda04ee7 100644 (file)
@@ -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 */
index 12efac1a307b45d4140da1ab2fac55387354f54b..4578d4b04035ce28281bd7e9998e5aaa6c338c35 100644 (file)
@@ -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);
 
 
index 294cf5f0c68937c50f19c6a8b55b2990ede98969..a1085c810ba6f9b33921f7258a92d5264ea2ca13 100644 (file)
@@ -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;
index 56cb349fdfa7993100d7399b871994c8ad5328e0..05c07af3ccf1c3858df7ead0ed192e8c6e1aebb8 100644 (file)
@@ -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 */
index 28be1c8a900835e902726ce4964019631908b4f1..feab5d1bb67f18db1de8295adfa4d053611179f7 100644 (file)
@@ -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;
 
index 8ce58d51f56e755c1fea464dd5acad42de371a05..b82ded2a36ef116a1a13cec9b1d9f6dd7da73106 100644 (file)
@@ -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)
index 07b3914975325a70186b67e643263071d972cc80..ac0cec03738f0898aaa6a08dd099fac7e60af299 100644 (file)
@@ -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();
 }
 
index 995dbbc1201557db278150753b0eccbecdce1325..984634eb5252b66631da77300c8e0717fc5d9ff7 100644 (file)
@@ -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));
 
index 5aeb058b8daa457560fa8eddbda724f77455371e..71009394cf42829241c4e6273cc64fef09bbf3dd 100644 (file)
@@ -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);
index cf503f40a8d53234ad2c6aa9eb73d476d580fc40..310f8e91832569ebc65a5f91308b2d9d618f09e9 100644 (file)
@@ -46,6 +46,7 @@ std::vector<CodecManager::CodecApiWrapper> CodecManager::s_codecs;
 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++
@@ -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()
index a29467bda1151d33a8f3773fdcee4a52157dab81..deb10efc35c2a04f0901ec8026ef56e3fc950881 100644 (file)
@@ -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<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
index 0ee4f77e10f90b415dbd2fb1e4b559079f32d1ac..7b54bc7640ec3ec1c56ea98d58597244fcd7c7f6 100644 (file)
@@ -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
index b4163273b35233bf2e50ba2a7e9b5363391a9159..bd75a358c7959fbe339628720ad46f40ecf90e8d 100644 (file)
@@ -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;
index bf18280964d00f833d826b5f0adb30c3612055a0..c472bcd323801dcbf468313e0a90995d5c459a6d 100644 (file)
@@ -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);
index 20458613f3dbcd1793e8c78e6466912f282d606b..e9244052603005f635e6d341a3f2c2d2cfce1862 100644 (file)
@@ -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<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[] =
@@ -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*)
index 1b45e332ad3c6e8a5948873c413f5b17e2c1a414..d973d2b6404b2c814514c861c9492fc92b6f0363 100644 (file)
@@ -70,6 +70,7 @@ private:
 
 private:
     FragEngine& engine;
+    uint8_t layers;
 };
 
 #endif