]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
updating packet. Still minor updates
authorJosh <jrosenba@cisco.com>
Fri, 1 Aug 2014 17:30:05 +0000 (13:30 -0400)
committerJosh <jrosenba@cisco.com>
Fri, 1 Aug 2014 17:30:05 +0000 (13:30 -0400)
27 files changed:
doc/differences.txt
src/codecs/decode_module.h
src/codecs/ip/cd_dstopts.cc
src/codecs/ip/cd_gre.cc
src/codecs/ip/cd_hopopts.cc
src/codecs/ip/cd_icmp6.cc
src/codecs/ip/cd_ipv4.cc
src/codecs/ip/cd_ipv6.cc
src/codecs/link/cd_erspan2.cc
src/codecs/link/cd_erspan3.cc
src/codecs/link/cd_vlan.cc
src/codecs/misc/cd_gtp.cc
src/codecs/root/root_ppp.cc
src/events/event_queue.cc
src/log/log_text.cc
src/main/modules.cc
src/main/snort.h
src/main/snort_config.h
src/managers/packet_manager.cc
src/network_inspectors/binder/binder.cc
src/network_inspectors/normalize/norm.cc
src/packet_io/active.cc
src/protocols/layer.cc
src/protocols/layer.h
src/protocols/packet.h
src/sfip/sf_iph.cc
src/stream/ip/ip_defrag.cc

index 2803f498724e2e3407b36de75279635a35613ccb..09a0db63e5c9536dac8689e817eaad236870c661 100644 (file)
@@ -93,7 +93,7 @@ Snort++ differs from Snort in the following ways:
   uricontent:"foo" -->  http_uri; content:"foo"
 * deleted urilen raw and norm; must use http_raw_uri and http_uri instead
 * deleted unused http_encode option
-* content suboption http_* are no full option and should be place before content
+* content suboption http_* are not full option and should be place before content
 * the following pcre options have been deleted: use sticky buffers instead
     B, U, P, H, M, C, I, D, K, S, Y
 
index 06eedd508e8a73683a28f1800612f39c5b095b8c..d1eddc94e33fb1c94be17cab99e1520d78c12552 100644 (file)
@@ -201,6 +201,7 @@ enum CodecSid {
     DECODE_ERSPAN3_DGRAM_LT_HDR,
     DECODE_AUTH_HDR_TRUNC,
     DECODE_AUTH_HDR_BAD_LEN,
+    DECODE_TOO_MANY_LAYERS,
     DECODE_INDEX_MAX
 };
 
index 2a80b2e10455d604e8443ce330c23f2c24d894fc..9053e5d2d13405354961cb57abed295faf8de1bc 100644 (file)
@@ -117,7 +117,7 @@ void Ipv6DSTOptsCodec::get_protocol_ids(std::vector<uint16_t>& v)
 
 bool Ipv6DSTOptsCodec::update(Packet* p, Layer* lyr, uint32_t* len)
 {
-    if ( lyr == (p->layers + p->next_layer - 1) )
+    if ( lyr == (p->layers + p->num_layers - 1) )
         *len += p->dsize;
 
     *len += lyr->length;
index 0eb04559d3a20e061c751cba0bb73f83ec06763a..ba803b90e331aa1cb15924859e0116b4ddfcd0b1 100644 (file)
@@ -103,14 +103,7 @@ bool GreCodec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
         return false;
     }
 
-    if (p->encapsulated)
-    {
-        /* discard packet - multiple GRE encapsulation */
-        /* not sure if this is ever used but I am assuming it is not */
-        codec_events::decoder_alert_encapsulated(p, DECODE_IP_MULTIPLE_ENCAPSULATION,
-                        raw_pkt, raw_len);
-        return false;
-    }
+    p->encapsulations++;
 
     /* Note: Since GRE doesn't have a field to indicate header length and
      * can contain a few options, we need to walk through the header to
index c99eb46f683fbe844c84f33827a1e219909de9d1..d2f5d877d335a2c01e64dfa769f0d996ba7090b6 100644 (file)
@@ -115,7 +115,7 @@ void Ipv6HopOptsCodec::get_protocol_ids(std::vector<uint16_t>& v)
 
 bool Ipv6HopOptsCodec::update(Packet* p, Layer* lyr, uint32_t* len)
 {
-    if ( lyr == (p->layers + p->next_layer - 1) )
+    if ( lyr == (p->layers + p->num_layers - 1) )
         *len += p->dsize;
 
     *len += lyr->length;
index ed13f121ecdb69599e3827f2fc9b59fe94725ca3..54a7369fc844fd7caa24f6c59522a9c8ce03b190 100644 (file)
@@ -334,7 +334,7 @@ static void DecodeICMPEmbeddedIP6(const uint8_t *pkt, const uint32_t len, Packet
 //    uint16_t orig_frag_offset;
 
     /* lay the IP struct over the raw data */
-    ipv6::IP6RawHdr* hdr = (ipv6::IP6RawHdr*)pkt;
+    const ipv6::IP6RawHdr* hdr = reinterpret_cast<const ipv6::IP6RawHdr*>(pkt);
 
     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "DecodeICMPEmbeddedIP6: ip header"
                     " starts at: %p, length is %lu\n", hdr,
index 03122f1eb90ec32f1ecd7bb1679f42db67038cc7..e5e26b4466c1af9c8d8d332d7ba4abeb9b490acc 100644 (file)
@@ -180,22 +180,18 @@ bool Ipv4Codec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
         return false;
     }
 
-    if (p->family != NO_IP)
+    if (p->encapsulations)
     {
-        if (p->encapsulated)
-        {
+        if (p->encapsulations)
             codec_events::decoder_alert_encapsulated(p, DECODE_IP_MULTIPLE_ENCAPSULATION,
                 raw_pkt, raw_len);
 
-            return false;
-        }
-        else
-        {
-            p->encapsulated = 1;
-            p->outer_iph = p->iph;
-            p->outer_ip_data = p->ip_data;
-            p->outer_ip_dsize = p->ip_dsize;
-        }
+
+        p->encapsulations++;
+        p->outer_iph = p->iph;
+        p->outer_ip_data = p->ip_data;
+        p->outer_ip_dsize = p->ip_dsize;
+
     }
 
     /* lay the IP struct over the raw data */
@@ -311,7 +307,7 @@ bool Ipv4Codec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
          * Zero these options so they aren't associated with this inner IP
          * since p->iph will be pointing to this inner IP
          */
-        if (p->encapsulated)
+        if (p->encapsulations)
         {
             p->ip_options_data = NULL;
             p->ip_options_len = 0;
@@ -692,7 +688,7 @@ bool Ipv4Codec::update(Packet* p, Layer* lyr, uint32_t* len)
 
     *len += ipv4::get_pkt_len(h);
 
-    if ( i + 1 == p->next_layer )
+    if ( i + 1 == p->num_layers )
     {
         *len += p->dsize;
     }
@@ -724,7 +720,7 @@ void Ipv4Codec::format(EncodeFlags f, const Packet* p, Packet* c, Layer* lyr)
     if ( f & ENC_FLAG_DEF )
     {
         int i = lyr - c->layers;
-        if ( i + 1 == p->next_layer )
+        if ( i + 1 == p->num_layers )
         {
             lyr->length = sizeof(*ch);
             ch->ip_len = htons(lyr->length);
index 47404c104f7c817639f916fa9bec4da99a844316..d0748462b4bbbe5fdd80782473675eb7313461f1 100644 (file)
@@ -162,22 +162,13 @@ bool Ipv6Codec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
     // This will need to go
     if (p->family != NO_IP)
     {
-        /* Snort currently supports only 2 IP layers. Any more will fail to be
-           decoded. */
-        if (p->encapsulated)
-        {
-
+        if (p->encapsulations)
             codec_events::decoder_alert_encapsulated(p, DECODE_IP_MULTIPLE_ENCAPSULATION,
                             raw_pkt, raw_len);
-            goto decodeipv6_fail;
-        }
-        else
-        {
-            p->encapsulated = 1;
-            p->outer_iph = p->iph;
-            p->outer_ip_data = p->ip_data;
-            p->outer_ip_dsize = p->ip_dsize;
-        }
+
+        p->outer_iph = p->iph;
+        p->outer_ip_data = p->ip_data;
+        p->outer_ip_dsize = p->ip_dsize;
     }
 
     payload_len = ntohs(hdr->ip6plen) + ipv6::hdr_len();
@@ -216,7 +207,7 @@ bool Ipv6Codec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
     sfiph_build(p, hdr, AF_INET6);
 
     /* Remove outer IP options */
-    if (p->encapsulated)
+    if (p->encapsulations)
     {
         p->ip_options_data = NULL;
         p->ip_options_len = 0;
@@ -624,7 +615,7 @@ bool Ipv6Codec::update (Packet* p, Layer* lyr, uint32_t* len)
     }
     else
     {
-        if ( i + 1 == p->next_layer )
+        if ( i + 1 == p->num_layers )
             *len += lyr->length + p->dsize;
 
         // w/o all extension headers, can't use just the
@@ -654,7 +645,7 @@ void Ipv6Codec::format(EncodeFlags f, const Packet* p, Packet* c, Layer* lyr)
     if ( f & ENC_FLAG_DEF )
     {
         int i = lyr - c->layers;
-        if ( i + 1 == p->next_layer )
+        if ( i + 1 == p->num_layers )
         {
             uint8_t* b = (uint8_t*)p->ip6_extensions[p->ip6_frag_index].data;
             if ( b ) lyr->length = b - p->layers[i].start;
index 1acea62bac692af445776adc6100cf8cbb3b0938..cdd00e7f1e7813c8d2439944eb7c5160ad7e816d 100644 (file)
@@ -91,14 +91,8 @@ bool Erspan2Codec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
         return false;
     }
 
-    if (p->encapsulated)
-    {
-        /* discard packet - multiple encapsulation */
-        /* not sure if this is ever used but I am assuming it is not */
-        codec_events::decoder_alert_encapsulated(p, DECODE_IP_MULTIPLE_ENCAPSULATION,
-                        raw_pkt, raw_len);
-        return false;
-    }
+    p->encapsulations++;
+
 
     /* Check that this is in fact ERSpan Type 2.
      */
index 369ca523b80cbfb0ca7b8409b433a0ee525cc967..0466d48d9215d523c0b3520bdc0f6d075bc5603d 100644 (file)
@@ -115,14 +115,7 @@ bool Erspan3Codec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
         return false;
     }
 
-    if (p->encapsulated)
-    {
-        /* discard packet - multiple encapsulation */
-        /* not sure if this is ever used but I am assuming it is not */
-        codec_events::decoder_alert_encapsulated(p, DECODE_IP_MULTIPLE_ENCAPSULATION,
-                        raw_pkt, raw_len);
-        return false;
-    }
+    p->encapsulations++;
 
     /* Check that this is in fact ERSpan Type 3.
      */
index 6a5ca791a7ba4f8b2a3b16ebd1e859a1d7afaeaa..f6db4fe052eeaa14cd548206cf1cbefc803198a1 100644 (file)
@@ -157,9 +157,22 @@ bool VlanCodec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
     }
     else
     {
+        uint16_t vid = vlan::vth_vlan(vh);
+
+        // Vlan IDs 0 and 4095 are reserved.
+        if (vid == 0 || vid == 4095)
+        {
+            codec_events::decoder_event(p, DECODE_BAD_VLAN);
+
+            // TBD add decoder drop event for VLAN hdr len issue
+            p->iph = NULL;
+            p->family = NO_IP;
+            return false;
+        }
+
+
         lyr_len = sizeof(vlan::VlanTagHdr);
         next_prot_id = ntohs(vh->vth_proto);
-
     }
 
     p->proto_bits |= PROTO_BIT__VLAN;
index c458fe0f499026fbe4c0629f6ec24b355c4b3427..f8ee9a41a1d8d9e52fa71e65f1d6f4d2b0653345 100644 (file)
@@ -90,22 +90,16 @@ bool GtpCodec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
     uint8_t  next_hdr_type;
     uint8_t  version;
     uint8_t  ip_ver;
-    GTPHdr *hdr;
+    const GTPHdr *hdr;
 
     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Start GTP decoding.\n"););
 
-    hdr = (GTPHdr *) raw_pkt;
+    p->encapsulations++;
+
+    hdr = reinterpret_cast<const GTPHdr *>(raw_pkt);
+
+
 
-    if (p->GTPencapsulated)
-    {
-        codec_events::decoder_alert_encapsulated(p, DECODE_GTP_MULTIPLE_ENCAPSULATION,
-                raw_pkt, raw_len);
-        return false;
-    }
-    else
-    {
-        p->GTPencapsulated = 1;
-    }
     /*Check the length*/
     if (raw_len < GTP_MIN_LEN)
        return false;
index ad93a5d2c9c29c4356b7359f5123768249f1afe2..dc33f4959b2ca67f097b23819a52dd6c0dc619ea 100644 (file)
 #include "config.h"
 #endif
 
-#include "generators.h"
-#include "protocols/packet.h"  
-#include "static_include.h"
 
-#include "root_ppp.h"
-#include "../decoder_includes.h"
-#include "protocols/root/root_chdlc.h"
+#include "framework/codec.h"
+
+
+static int DLT_PPP = 51;
 
 
 /*
@@ -55,18 +53,6 @@ void DecodePppPkt(Packet * p, const DAQ_PktHdr_t * pkthdr, const uint8_t * pkt)
 {
     uint32_t cap_len = pkthdr->caplen;
     int hlen = 0;
-    PROFILE_VARS;
-
-    PREPROC_PROFILE_START(decodePerfStats);
-
-    dc.total_processed++;
-
-    memset(p, 0, PKT_ZERO_LEN);
-
-    p->pkth = pkthdr;
-    p->pkt = pkt;
-
-    DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"););
 
     if(cap_len < 2)
     {
@@ -89,7 +75,6 @@ void DecodePppPkt(Packet * p, const DAQ_PktHdr_t * pkthdr, const uint8_t * pkt)
 
     DecodePppPktEncapsulated(p->pkt + hlen, cap_len - hlen, p);
 
-    PREPROC_PROFILE_END(decodePerfStats);
     return;
 }
 
index 5058858b350de29aa3287e8be8a8cdc734faa221..949957aca5bce8bff4c7de88b7919cff1c99b170 100644 (file)
@@ -133,7 +133,7 @@ int SnortEventqAdd(OptTreeNode* otn)
 
     EventNode* en = (EventNode*)sfeventq_event_alloc(event_queue[qIndex]);
 
-    if ( !en )
+    if ( en )
         return -1;
 
     en->otn = otn;
index 66306f73e6c8667e51f252f1b0565451065cca3f..6063caa6a6e93887e0ccdf51fced238e51887504 100644 (file)
@@ -408,23 +408,23 @@ void Log2ndHeader(TextLog* log, Packet* p)
     switch(DAQ_GetBaseProtocol())
     {
         case DLT_EN10MB:        /* Ethernet */
-            if(p && (p->next_layer > 0))
+            if(p && (p->num_layers > 0))
                 LogEthHeader(log, p);
             break;
 #ifndef NO_NON_ETHER_DECODER
 #ifdef DLT_IEEE802_11
         case DLT_IEEE802_11:
-            if(p && (p->next_layer > 0))
+            if(p && (p->num_layers > 0))
                 LogWifiHeader(log, p);
             break;
 #endif
         case DLT_IEEE802:                /* Token Ring */
-            if(p && (p->next_layer > 0))
+            if(p && (p->num_layers > 0))
                 LogTrHeader(log, p);
             break;
 #ifdef DLT_LINUX_SLL
         case DLT_LINUX_SLL:
-            if (p && (p->next_layer > 0))
+            if (p && (p->num_layers > 0))
                 LogSLLHeader(log, p);  /* Linux cooked sockets */
             break;
 #endif
@@ -1019,8 +1019,8 @@ static void LogICMPEmbeddedIP(TextLog* log, Packet *p)
     orig_p->dp = p->orig_dp;
     orig_p->icmph = p->orig_icmph;
     orig_p->iph_api = p->orig_iph_api;
-    orig_p->ip4h = p->orig_ip4h;
-    orig_p->ip6h = p->orig_ip6h;
+//    orig_p->ip4h = p->orig_ip4h;
+//    orig_p->ip6h = p->orig_ip6h;
     orig_p->family = p->orig_family;
 
     if(orig_p->iph != NULL)
@@ -1494,8 +1494,8 @@ void LogNetData (TextLog* log, const uint8_t* data, const int len, Packet *p)
 
     if(p && ScObfuscate() )
     {
-        int next_layer =  p->next_layer;
-        for ( i = 0; i < next_layer; i++ )
+        int num_layers =  p->num_layers;
+        for ( i = 0; i < num_layers; i++ )
         {
             if ( p->layers[i].proto == PROTO_IP4
                   || p->layers[i].proto == PROTO_IP6
index d2eaefc3e0f5c5dcc1f1c09af95bc49b56baa7a3..1fc35dd40c1724e83d3a678c66b10ebc457f1406 100644 (file)
@@ -815,6 +815,9 @@ bool ActiveModule::set(const char*, Value& v, SnortConfig* sc)
     else if ( v.is("react") )
         sc->react_page = SnortStrdup(v.get_string());
 
+    else
+        return false;
+
     return true;
 }
 
@@ -1022,6 +1025,9 @@ static const Parameter network_params[] =
     { "new_ttl", Parameter::PT_INT, "1:255", "1",
       "use this value for responses and when normalizing" },
 
+    { "max_encapsulations", Parameter::PT_INT, "-1:32", "-1",
+      "maximum number of encapsulations per packet" },
+
     { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
 };
 
@@ -1054,6 +1060,9 @@ 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("max_encapsulations") )
+        sc->max_encapsulations = v.get_long();
+
     else
         return false;
 
index 9bce3a96bbb2c6081831f343b358a0888094f389..8c00f59c6d4b9decc274f78b94de7251215bd95a 100644 (file)
@@ -548,10 +548,15 @@ static inline uint32_t ScSoRuleMemcap(void)
     return snort_conf->so_rule_memcap;
 }
 
-static inline bool ScTunnelBypassEnabled (uint8_t proto)
+static inline bool ScTunnelBypassEnabled(uint8_t proto)
 {
     return !(snort_conf->tunnel_mask & proto);
 }
 
+static inline int8_t ScMaxEncapsulations(void)
+{
+    return snort_conf->max_encapsulations;
+}
+
 #endif
 
index 85e49dd65ae84a9fd0fc76b5b9ea5860e50f8bc6..7437b60b158208cba7c58b37f96c9b0d67ee8cc3 100644 (file)
@@ -137,6 +137,7 @@ struct SnortConfig
     uint8_t enable_gtp;
     char *gtp_ports;
     uint8_t enable_esp;
+    int8_t max_encapsulations;
 
     int pkt_snaplen;
 
index f20352f5f62e0dfd385fe869e9694d9d1774d083..2a97f349819ee9027ef719615a0c7913dc7fa478 100644 (file)
@@ -38,6 +38,8 @@
 #include "protocols/ipv4.h"
 #include "protocols/ipv6.h"
 #include "codecs/ip/ipv6_util.h"
+#include "codecs/codec_events.h"
+#include "codecs/decode_module.h"
 
 // Encoder FOO
 #ifdef HAVE_DUMBNET_H
@@ -106,9 +108,9 @@ static inline void push_layer(Packet *p,
                                 uint32_t len,
                                 Codec *const cd)
 {
-    if ( p->next_layer < LAYER_MAX )
+    if ( p->num_layers < LAYER_MAX )
     {
-        Layer& lyr = p->layers[p->next_layer++];
+        Layer& lyr = p->layers[p->num_layers++];
         lyr.proto = cd->get_proto_id();
         lyr.prot_id = prot_id;
         lyr.start = (uint8_t*)hdr_start;
@@ -121,45 +123,6 @@ static inline void push_layer(Packet *p,
     }
 }
 
-static inline uint8_t* get_inner_ip_hdr(const Packet *p)
-{
-    const Layer *layers = p->layers;
-
-    for (int i = p->next_layer-1; i >= 0; i--)
-    {
-        switch(layers[i].prot_id)
-        {
-            case ETHERTYPE_IPV4:
-            case ETHERTYPE_IPV6:
-            case IPPROTO_ID_IPIP:
-            case IPPROTO_ID_IPV6:
-                return layers[i].start;
-            default:
-                break;
-        }
-    }
-    return nullptr;
-}
-
-static inline int get_inner_ip_lyr(const Packet *p)
-{
-    const Layer *layers = p->layers;
-
-    for (int i = p->next_layer-1; i >= 0; i--)
-    {
-        switch(layers[i].prot_id)
-        {
-            case ETHERTYPE_IPV4:
-            case ETHERTYPE_IPV6:
-            case IPPROTO_ID_IPIP:
-            case IPPROTO_ID_IPV6:
-                return i;
-            default:
-                break;
-        }
-    }
-    return -1;
-}
 
 /*
  * Begin search from index 1.  0 is a special case in that it is the default
@@ -193,9 +156,9 @@ static const uint8_t* encode_packet(
     obuf.size = sizeof(s_pkt);
 
     // setting convenience pointers
-    enc->layer = p->next_layer;
+    enc->layer = p->num_layers;
     enc->p = p;
-    enc->ip_hdr = get_inner_ip_hdr(p);
+    enc->ip_hdr = p->layers[layer::get_inner_ip_lyr(p)].start;
 
     if ( ipv4::is_ipv4(*(enc->ip_hdr)))
         enc->ip_len = ipv4::get_pkt_len((IPHdr*) enc->ip_hdr);
@@ -206,7 +169,7 @@ static const uint8_t* encode_packet(
 
 
     const Layer *lyrs = p->layers;
-    for(int i = p->next_layer-1; i >= 0; i--)
+    for(int i = p->num_layers-1; i >= 0; i--)
     {
         // lots of room for improvement
         const Layer *l = &lyrs[i];
@@ -455,6 +418,15 @@ void PacketManager::decode(
     // loop until the protocol id is no longer valid
     while(s_protocols[mapped_prot]->decode(pkt, len, p, lyr_len, prot_id))
     {
+        // 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 )
+        {
+            codec_events::decoder_event(p, DECODE_TOO_MANY_LAYERS);
+            PREPROC_PROFILE_END(decodePerfStats);
+            return false;
+        }
+
         // internal statistics and record keeping
         push_layer(p, prev_prot_id, pkt, lyr_len, s_protocols[mapped_prot]);
         s_stats[mapped_prot + stat_offset]++;
@@ -484,6 +456,12 @@ void PacketManager::decode(
             p->packet_flags |= PKT_TRUST;
     }
 
+    if (ScMaxEncapsulations() != -1 &&
+        p->encapsulations > ScMaxEncapsulations())
+    {
+        codec_events::decoder_event(p, DECODE_IP_MULTIPLE_ENCAPSULATION);
+    }
+
     if (p->ip6_extension_count > 0)
         ipv6_util::CheckIPv6ExtensionOrder(p);
 
@@ -570,7 +548,7 @@ SO_PUBLIC int PacketManager::encode_format_with_daq_info (
     int i;
     Layer* lyr;
     int len;
-    int num_layers = p->next_layer;
+    int num_layers = p->num_layers;
     DAQ_PktHdr_t* pkth = (DAQ_PktHdr_t*)c->pkth;
     uint8_t* pkt = (uint8_t*)c->pkt;
 
@@ -601,7 +579,7 @@ SO_PUBLIC int PacketManager::encode_format_with_daq_info (
 
     if ( f & ENC_FLAG_NET )
     {
-        num_layers = get_inner_ip_lyr(p) + 1;
+        num_layers = layer::get_inner_ip_lyr(p) + 1;
 
         // TBD:  is this an extraneous check?
         if (num_layers == 0)
@@ -629,7 +607,7 @@ SO_PUBLIC int PacketManager::encode_format_with_daq_info (
     }
 
     // setup payload info
-    c->next_layer = num_layers;
+    c->num_layers = num_layers;
     c->data = lyr->start + lyr->length;
     len = c->data - c->pkt;
 
@@ -696,7 +674,7 @@ SO_PUBLIC void PacketManager::encode_update (Packet* p)
     p->actual_ip_len = 0;
     Layer *lyr = p->layers;
 
-    for ( i = p->next_layer - 1; i >= 0; i-- )
+    for ( i = p->num_layers - 1; i >= 0; i-- )
     {
         Layer *l = lyr + i;
 
index 358ad8a835e2308e087318c1d4db8bbe638e36ee..ad3de6c06c5f8b23732127c855689116897790db 100644 (file)
@@ -29,6 +29,8 @@ using namespace std;
 #include "stream/stream_splitter.h"
 #include "managers/inspector_manager.h"
 #include "protocols/packet.h"
+#include "protocols/vlan.h"
+#include "protocols/layer.h"
 #include "stream/stream_api.h"
 #include "time/profiler.h"
 #include "utils/stats.h"
@@ -174,6 +176,7 @@ int Binder::check_rules(Flow* flow, Packet* p)
     unsigned i, sz = bindings.size();
 
     Port port = (p->packet_flags & PKT_FROM_CLIENT) ? p->dp : p->sp;
+    uint16_t vlan = vlan::vth_vlan(layer::get_vlan_layer(p));
 
     for ( i = 0; i < sz; i++ )
     {
index 52fd8713f8c1e0e91744624659a4df25ab8eaa4c..4bd82f73195daf4fe36b6f37e82ec17be0e40159 100644 (file)
@@ -99,7 +99,7 @@ static const uint8_t MAX_EOL_PAD[TCP_OPTLENMAX] = {
 // go from inner to outer
 int Norm_Packet (NormalizerConfig* c, Packet* p)
 {
-    uint8_t lyr = p->next_layer;
+    uint8_t lyr = p->num_layers;
     int changes = 0;
 
     while ( lyr > 0 )
index 76d86afaa3d0613fd2e495be0ffc8b80947b2e68..e6677fc549e56be2102880d07a902a08d637df91 100644 (file)
@@ -79,8 +79,8 @@ static int s_enabled = 0;
 
 static inline PROTO_ID GetInnerProto (const Packet* p)
 {
-    if ( !p->next_layer ) return PROTO_MAX;
-    return ( p->layers[p->next_layer-1].proto );
+    if ( !p->num_layers ) return PROTO_MAX;
+    return ( p->layers[p->num_layers-1].proto );
 }
 
 //--------------------------------------------------------------------
index c01fb7d0bf404b5dd75e4bf555f4f290921f7029..1441fda5125879a1c1cfd132e1afdff686bb32b1 100644 (file)
@@ -21,6 +21,8 @@
 
 
 #include "protocols/packet.h"
+#include "protocols/ipv4.h"
+#include "protocols/ipv6.h"
 
 namespace layer
 {
@@ -53,45 +55,45 @@ static inline const uint8_t *find_layer(const Layer *lyr,
     return nullptr;
 }
 
-const arp::EtherARP* get_arp_layer(const Packet* p)
+const arp::EtherARP* get_arp_layer(const Packet* const p)
 {
-    uint8_t num_layers = p->next_layer;
+    uint8_t num_layers = p->num_layers;
     const Layer *lyr = p->layers;
 
     return reinterpret_cast<const arp::EtherARP*>(
         find_layer(lyr, num_layers, ETHERTYPE_ARP, ETHERTYPE_REVARP));
 }
 
-const gre::GREHdr* get_gre_layer(const Packet* p)
+const gre::GREHdr* get_gre_layer(const Packet* const p)
 {
-    uint8_t num_layers = p->next_layer;
+    uint8_t num_layers = p->num_layers;
     const Layer *lyr = p->layers;
 
     return reinterpret_cast<const gre::GREHdr*>(
         find_layer(lyr, num_layers, IPPROTO_ID_GRE));
 }
 
-const eapol::EtherEapol* get_eapol_layer(const Packet* p)
+const eapol::EtherEapol* get_eapol_layer(const Packet* const p)
 {
-    uint8_t num_layers = p->next_layer;
+    uint8_t num_layers = p->num_layers;
     const Layer *lyr = p->layers;
 
     return reinterpret_cast<const eapol::EtherEapol*>(
             find_layer(lyr, num_layers, ETHERTYPE_EAPOL));
 }
 
-const vlan::VlanTagHdr* get_vlan_layer(const Packet* p)
+const vlan::VlanTagHdr* get_vlan_layer(const Packet* const p)
 {
-    uint8_t num_layers = p->next_layer;
+    uint8_t num_layers = p->num_layers;
     const Layer *lyr = p->layers;
 
     return reinterpret_cast<const vlan::VlanTagHdr*>(
         find_layer(lyr, num_layers, ETHERTYPE_8021Q));
 }
 
-const eth::EtherHdr* get_eth_layer(const Packet* p)
+const eth::EtherHdr* get_eth_layer(const Packet* const p)
 {
-    uint8_t num_layers = p->next_layer;
+    uint8_t num_layers = p->num_layers;
     const Layer *lyr = p->layers;
 
     // First, search for the inner eth layer (transbridging)
@@ -102,12 +104,54 @@ const eth::EtherHdr* get_eth_layer(const Packet* p)
     return eh ? eh : reinterpret_cast<const eth::EtherHdr*>(get_root_layer(p));
 }
 
-const uint8_t* get_root_layer(const Packet* p)
+const uint8_t* get_root_layer(const Packet* const p)
 {
     // since token ring is the grinder, its the begining of the packet.
-    if (p->next_layer > 0)
+    if (p->num_layers > 0)
         return p->layers[0].start;
     return nullptr;
 }
 
+
+uint8_t get_outer_ip_next_pro(const Packet* const p)
+{
+    const Layer* layers = p->layers;
+    const int max_layers = p->num_layers;
+
+    for (int i = 0; i < max_layers; i++)
+    {
+        switch(layers[i].prot_id)
+        {
+            case ETHERTYPE_IPV4:
+            case IPPROTO_ID_IPIP:
+                return reinterpret_cast<IP4Hdr*>(layers[i].start)->ip_proto;
+            case ETHERTYPE_IPV6:
+            case IPPROTO_ID_IPV6:
+                return reinterpret_cast<IP6Hdr*>(layers[i].start)->next;
+            default:
+                break;
+        }
+    }
+}
+
+int get_inner_ip_lyr(const Packet* const p)
+{
+    const Layer* layers = p->layers;
+
+    for (int i = p->num_layers-1; i >= 0; i--)
+    {
+        switch(layers[i].prot_id)
+        {
+            case ETHERTYPE_IPV4:
+            case ETHERTYPE_IPV6:
+            case IPPROTO_ID_IPIP:
+            case IPPROTO_ID_IPV6:
+                return i;
+            default:
+                break;
+        }
+    }
+    return -1;
+}
+
 } // namespace layer
index 5bf3e4f6a2ae717e04fc8153df993548a90a56c5..e76a0b6efbbae75453a49116c094170c7cb056ae 100644 (file)
@@ -64,19 +64,22 @@ struct EtherHdr;
 }
 
 
-// code maintained in header to ensure files to not depend on this library
 namespace layer
 {
 
+// all of these functions will begin search from layer 0,
+// and will return the first function they find.
+
 
-// signatures. No need to go searching for the correct function
 const arp::EtherARP* get_arp_layer(const Packet*);
 const vlan::VlanTagHdr* get_vlan_layer(const Packet*);
 const gre::GREHdr* get_gre_layer(const Packet*);
 const eapol::EtherEapol* get_eapol_layer(const Packet*);
 const eth::EtherHdr* get_eth_layer(const Packet*);
-const uint8_t* get_root_layer(const Packet*);
+const uint8_t* get_root_layer(const Packet* const);
 
+int get_inner_ip_lyr(const Packet* const p);
+uint16_t get_outer_ip_next_proto(const Packet* const);
 
 } // namespace layer
 
index cf400c8ea610dd900d94a5f6c3a48d09829c3764..ac93f401d1bae137d91df52e56d9fb76bee19e2f 100644 (file)
@@ -109,6 +109,7 @@ extern "C" {
 
 #define PKT_FILE_EVENT_SET   0x04000000
 #define PKT_ESP_LYR_PRESENT  0x08000000
+#define PKT_UNUSED_FLAGS     0xF0000000
 
 // 0x40000000 are available
 #define PKT_PDU_FULL (PKT_PDU_HEAD | PKT_PDU_TAIL)
@@ -205,12 +206,11 @@ struct Packet
     //vvv-----------------------------
     ipv4::IP4Hdr *ip4h, *orig_ip4h;
     ipv6::IP6Hdr *ip6h, *orig_ip6h;
-    icmp6::ICMP6Hdr *icmp6h, *orig_icmp6h;
+    icmp6::ICMP6Hdr *icmp6h;
 
     IPH_API* iph_api;
     IPH_API* orig_iph_api;
     IPH_API* outer_iph_api;
-    IPH_API* outer_orig_iph_api;
 
     int family;
     int orig_family;
@@ -256,9 +256,9 @@ struct Packet
     uint8_t ip6_frag_index;
 
     uint8_t error_flags;        /* flags indicate checksum errors, bad TTLs, etc. */
-    uint8_t encapsulated;
-    uint8_t GTPencapsulated;
-    uint8_t next_layer;         /* index into layers for next encap */
+    uint8_t num_layers;         /* index into layers for next encap */
+    uint8_t decode_flags;       /* flags used while decoding */
+    uint8_t encapsulations;     /* thh curent number of encapsulations */
 
     // nothing after this point is zeroed ...
     ipv4::IpOptions ip_options[IP_OPTMAX];         /* ip options decode structure */
index 323b61813df78f33fd85c2889e0018d9110823c0..c2d1f62c339bda555906f99cce3d75cd681390d1 100644 (file)
@@ -463,15 +463,11 @@ void sfiph_orig_build(Packet *p, const void *hdr, int family)
     /* If iph_api is already set, we've been here before.
      * That means this is a nested IP.  */
     if (p->orig_iph_api && (p->orig_iph_api->ver == IPH_API_V4))
-    {
         memcpy(&p->outer_orig_ip4h, &p->inner_orig_ip4h, sizeof(IP4Hdr));
-        p->outer_orig_iph_api = p->orig_iph_api;
-    }
+
     else if (p->orig_iph_api && (p->orig_iph_api->ver == IPH_API_V6))
-    {
         memcpy(&p->outer_orig_ip6h, &p->inner_orig_ip6h, sizeof(IP6Hdr));
-        p->outer_orig_iph_api = p->orig_iph_api;
-    }
+
 
     _set_callbacks(p, family, CALLBACK_ICMP_ORIG);
 
index c2d2271c35eb096b1fec0c37f11e8b1b65eb5d80..147a37071d9c0fb7874524b5132a6ae7a07f7ec1 100644 (file)
@@ -889,7 +889,7 @@ static void FragRebuild(FragTracker *ft, Packet *p)
 
     PREPROC_PROFILE_START(fragRebuildPerfStats);
 
-    if ( p->encapsulated )
+    if ( p->encapsulations )
         dpkt = encap_defrag_pkt;
     else
         dpkt = defrag_pkt;