]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
UNTESTED - Removing All ICMP embedded IP/TCP/UDP/ICMP data from Paket
authorJosh <jrosenba@cisco.com>
Wed, 6 Aug 2014 17:57:48 +0000 (13:57 -0400)
committerJosh <jrosenba@cisco.com>
Wed, 6 Aug 2014 21:11:47 +0000 (17:11 -0400)
49 files changed:
src/codecs/codec_api.cc
src/codecs/ip/cd_esp.cc
src/codecs/ip/cd_icmp4.cc
src/codecs/ip/cd_icmp6.cc
src/codecs/ip/cd_igmp.cc
src/codecs/ip/cd_ipv4.cc
src/codecs/ip/cd_ipv6.cc
src/codecs/ip/cd_tcp.cc
src/codecs/ip/cd_udp.cc
src/codecs/link/cd_pppencap.cc
src/codecs/misc/CMakeLists.txt
src/codecs/misc/cd_gtp.cc
src/codecs/misc/cd_ip4_embedded_in_icmp.cc [new file with mode: 0644]
src/codecs/misc/cd_ip6_embedded_in_icmp.cc [new file with mode: 0644]
src/codecs/misc/cd_prot_embedded_in_icmp.cc [new file with mode: 0644]
src/codecs/root/CMakeLists.txt
src/codecs/root/Makefile.am
src/codecs/root/cd_ppp.cc [new file with mode: 0644]
src/codecs/root/root_ppp.cc [deleted file]
src/codecs/root/root_ppp.h [deleted file]
src/detection/detect.cc
src/events/event_queue.cc
src/flow/flow_key.cc
src/framework/codec.h
src/log/log_text.cc
src/main/snort_config.cc
src/managers/packet_manager.cc
src/managers/packet_manager.h
src/network_inspectors/binder/binder.cc
src/network_inspectors/normalize/norm.cc
src/network_inspectors/port_scan/ps_detect.cc
src/protocols/CMakeLists.txt
src/protocols/Makefile.am
src/protocols/icmp4.h
src/protocols/ip.cc [new file with mode: 0644]
src/protocols/ip.h [new file with mode: 0644]
src/protocols/ipv4.h
src/protocols/ipv6.h
src/protocols/layer.cc
src/protocols/layer.h
src/protocols/packet.h
src/protocols/protocol_ids.h
src/protocols/tcp.h
src/sfip/ipv6_port.h
src/sfip/sf_iph.cc
src/sfip/sf_iph.h
src/stream/icmp/icmp_session.cc
src/stream/ip/ip_defrag.cc
src/stream/tcp/tcp_session.cc

index 8199cece6bbe750f48f99ca6064164f1be2bcdc3..f0066f0f7827affb8770ca1f4477ff457fba6b60 100644 (file)
@@ -56,6 +56,8 @@ extern const BaseApi* cd_frag;
 extern const BaseApi* cd_gre;
 extern const BaseApi* cd_gtp;
 extern const BaseApi* cd_hopopts;
+extern const BaseApi* cd_ip4_embedded_in_icmp;
+extern const BaseApi* cd_ip6_embedded_in_icmp;
 extern const BaseApi* cd_igmp;
 extern const BaseApi* cd_mobility;
 extern const BaseApi* cd_mpls;
@@ -74,6 +76,7 @@ extern const BaseApi* cd_vlan;
 #ifndef NO_NON_ETHER_DECODER
 extern const BaseApi* cd_eapol;
 extern const BaseApi* cd_linux_sll;
+extern const BaseApi* cd_ppp;
 extern const BaseApi* cd_wlan;
 
 #endif
@@ -109,6 +112,8 @@ const BaseApi* codecs[] =
     cd_gre,
     cd_gtp,
     cd_hopopts,
+    cd_ip4_embedded_in_icmp,
+    cd_ip6_embedded_in_icmp,
     cd_igmp,
     cd_mobility,
     cd_mpls,
@@ -127,6 +132,7 @@ const BaseApi* codecs[] =
 #ifndef NO_NON_ETHER_DECODER
     cd_eapol,
     cd_linux_sll,
+    cd_ppp,
     cd_wlan,
 #endif
 
index 1d39f360dbd51fafb6f7daffa42593aaf49a366c..11e8d04bc37597df021fbc6809a3dd5c3087512d 100644 (file)
@@ -138,8 +138,8 @@ bool EspCodec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
            different valid next_header. The DECODE__UNSURE_ENCAP flag tells the next
            decoder stage to silently ignore invalid headers. */
         p->decode_flags |= DECODE__UNSURE_ENCAP;
+        p->decode_flags |= DECODE__TRUST_ON_FAIL;
         const_cast<uint32_t&>(raw_len) -= (ESP_AUTH_DATA_LEN + ESP_TRAILER_LEN);
-        p->decode_flags |= DECODE__ESP;
     }
     else
     {
index ef69689c36d49fda4e995b88c7a3efd6f185814d..b8b24a9ba6db5a9c5c0644e0158d41679954862c 100644 (file)
 #include "config.h"
 #endif
 
-#ifdef HAVE_DUMBNET_H
-#include <dumbnet.h>
-#else
-#include <dnet.h>
-#endif
-
 #include "framework/codec.h"
 #include "snort.h"
 #include "protocols/icmp4.h"
@@ -57,9 +51,8 @@ public:
     virtual bool encode(EncState*, Buffer* out, const uint8_t* raw_in);
     virtual bool update(Packet*, Layer*, uint32_t* len);
     virtual void format(EncodeFlags, const Packet* p, Packet* c, Layer*);
-private:
 
-    void DecodeICMPEmbeddedIP(const uint8_t *pkt, const uint32_t len, Packet *p);
+private:
     void ICMP4AddrTests (Packet* );
     void ICMP4MiscTests (Packet *);
 
@@ -91,9 +84,9 @@ void Icmp4Codec::get_protocol_ids(std::vector<uint16_t> &v)
  * Returns: void function
  */
 bool Icmp4Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
-        Packet *p, uint16_t &lyr_len, uint16_t& /*next_prot_id*/)
+        Packet *p, uint16_t &lyr_len, uint16_t& next_prot_id)
 {
-    if(raw_len < icmp4::hdr_len())
+    if(raw_len < icmp::hdr_len())
     {
         DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
             "WARNING: Truncated ICMP4 header (%d bytes).\n", raw_len););
@@ -110,17 +103,17 @@ bool Icmp4Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
     switch (p->icmph->type)
     {
             // fall through ...
-        case icmp4::IcmpType::SOURCE_QUENCH:
-        case icmp4::IcmpType::DEST_UNREACH:
-        case icmp4::IcmpType::REDIRECT:
-        case icmp4::IcmpType::TIME_EXCEEDED:
-        case icmp4::IcmpType::PARAMETERPROB:
-        case icmp4::IcmpType::ECHOREPLY:
-        case icmp4::IcmpType::ECHO:
-        case icmp4::IcmpType::ROUTER_ADVERTISE:
-        case icmp4::IcmpType::ROUTER_SOLICIT:
-        case icmp4::IcmpType::INFO_REQUEST:
-        case icmp4::IcmpType::INFO_REPLY:
+        case icmp::IcmpType::SOURCE_QUENCH:
+        case icmp::IcmpType::DEST_UNREACH:
+        case icmp::IcmpType::REDIRECT:
+        case icmp::IcmpType::TIME_EXCEEDED:
+        case icmp::IcmpType::PARAMETERPROB:
+        case icmp::IcmpType::ECHOREPLY:
+        case icmp::IcmpType::ECHO:
+        case icmp::IcmpType::ROUTER_ADVERTISE:
+        case icmp::IcmpType::ROUTER_SOLICIT:
+        case icmp::IcmpType::INFO_REQUEST:
+        case icmp::IcmpType::INFO_REPLY:
             if (raw_len < 8)
             {
                 DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
@@ -133,8 +126,8 @@ bool Icmp4Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
             }
             break;
 
-        case icmp4::IcmpType::TIMESTAMP:
-        case icmp4::IcmpType::TIMESTAMPREPLY:
+        case icmp::IcmpType::TIMESTAMP:
+        case icmp::IcmpType::TIMESTAMPREPLY:
             if (raw_len < 20)
             {
                 DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
@@ -147,8 +140,8 @@ bool Icmp4Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
             }
             break;
 
-        case icmp4::IcmpType::ADDRESS:
-        case icmp4::IcmpType::ADDRESSREPLY:
+        case icmp::IcmpType::ADDRESS:
+        case icmp::IcmpType::ADDRESSREPLY:
             if (raw_len < 12)
             {
                 DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
@@ -182,26 +175,26 @@ bool Icmp4Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
         }
     }
 
-    lyr_len =  icmp4::hdr_len();
+    lyr_len =  icmp::hdr_len();
 
     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "ICMP type: %d   code: %d\n",
                 p->icmph->type, p->icmph->code););
 
     switch(p->icmph->type)
     {
-        case icmp4::IcmpType::ECHO:
+        case icmp::IcmpType::ECHO:
             ICMP4AddrTests(p);
         // fall through ...
 
-        case icmp4::IcmpType::ECHOREPLY:
+        case icmp::IcmpType::ECHOREPLY:
             /* setup the pkt id and seq numbers */
             /* add the size of the echo ext to the data
              * ptr and subtract it from the data size */
             lyr_len += sizeof(ICMPHdr::icmp_hun.idseq);
             break;
 
-        case icmp4::IcmpType::DEST_UNREACH:
-            if ((p->icmph->code == icmp4::IcmpCode::FRAG_NEEDED)
+        case icmp::IcmpType::DEST_UNREACH:
+            if ((p->icmph->code == icmp::IcmpCode::FRAG_NEEDED)
                     && (ntohs(p->icmph->s_icmp_nextmtu) < 576))
             {
                 codec_events::decoder_event(p, DECODE_ICMP_PATH_MTU_DOS);
@@ -209,13 +202,13 @@ bool Icmp4Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
 
             /* Fall through */
 
-        case icmp4::IcmpType::SOURCE_QUENCH:
-        case icmp4::IcmpType::REDIRECT:
-        case icmp4::IcmpType::TIME_EXCEEDED:
-        case icmp4::IcmpType::PARAMETERPROB:
+        case icmp::IcmpType::SOURCE_QUENCH:
+        case icmp::IcmpType::REDIRECT:
+        case icmp::IcmpType::TIME_EXCEEDED:
+        case icmp::IcmpType::PARAMETERPROB:
             /* account for extra 4 bytes in header */
             lyr_len += 4;
-            DecodeICMPEmbeddedIP(raw_pkt + lyr_len,  raw_len - lyr_len, p);
+            next_prot_id = IP_EMBEDDED_IN_ICMP4;
             break;
 
         default:
@@ -232,7 +225,8 @@ bool Icmp4Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
     return true;
 }
 
-
+// TODO: delete
+#if 0
 /*
  * Function: DecodeICMPEmbeddedIP(uint8_t *, const uint32_t, Packet *)
  *
@@ -252,7 +246,7 @@ void Icmp4Codec::DecodeICMPEmbeddedIP(const uint8_t *pkt, const uint32_t len, Pa
     uint16_t orig_frag_offset;
 
     /* do a little validation */
-    if(len < ipv4::hdr_len())
+    if(len < ip::hdr_len())
     {
         DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
             "ICMP: IP short header (%d bytes)\n", len););
@@ -367,7 +361,7 @@ void Icmp4Codec::DecodeICMPEmbeddedIP(const uint8_t *pkt, const uint32_t len, Pa
 
     return;
 }
-
+#endif
 
 void Icmp4Codec::ICMP4AddrTests (Packet* p)
 {
@@ -376,7 +370,7 @@ void Icmp4Codec::ICMP4AddrTests (Packet* p)
     uint32_t dst = GET_DST_IP(p)->ip32[0];
 
     // check all 32 bits; all set so byte order is irrelevant ...
-    if ( ipv4::is_broadcast(dst) )
+    if ( ip::is_broadcast(dst) )
         codec_events::decoder_event(p, DECODE_ICMP4_DST_BROADCAST);
 
     /* - don't use htonl for speed reasons -
@@ -390,7 +384,7 @@ void Icmp4Codec::ICMP4AddrTests (Packet* p)
     // check the 'msn' (most significant nibble) ...
     msb_dst >>= 4;
 
-    if( ipv4::is_multicast(msb_dst) )
+    if( ip::is_multicast(msb_dst) )
         codec_events::decoder_event(p, DECODE_ICMP4_DST_MULTICAST);
 }
 
@@ -398,51 +392,51 @@ void Icmp4Codec::ICMP4AddrTests (Packet* p)
 void Icmp4Codec::ICMP4MiscTests (Packet *p)
 {
     if ((p->dsize == 0) &&
-        (p->icmph->type == icmp4::IcmpType::ECHO))
+        (p->icmph->type == icmp::IcmpType::ECHO))
         codec_events::decoder_event(p, DECODE_ICMP_PING_NMAP);
 
     if ((p->dsize == 0) &&
         (p->icmph->s_icmp_seq == 666))
         codec_events::decoder_event(p, DECODE_ICMP_ICMPENUM);
 
-    if ((p->icmph->type == icmp4::IcmpType::REDIRECT) &&
-        (p->icmph->code == icmp4::IcmpCode::REDIR_HOST))
+    if ((p->icmph->type == icmp::IcmpType::REDIRECT) &&
+        (p->icmph->code == icmp::IcmpCode::REDIR_HOST))
         codec_events::decoder_event(p, DECODE_ICMP_REDIRECT_HOST);
 
-    if ((p->icmph->type == icmp4::IcmpType::REDIRECT) &&
-        (p->icmph->code == icmp4::IcmpCode::REDIR_NET))
+    if ((p->icmph->type == icmp::IcmpType::REDIRECT) &&
+        (p->icmph->code == icmp::IcmpCode::REDIR_NET))
         codec_events::decoder_event(p, DECODE_ICMP_REDIRECT_NET);
 
-    if (p->icmph->type == icmp4::IcmpType::ECHOREPLY)
+    if (p->icmph->type == icmp::IcmpType::ECHOREPLY)
     {
         int i;
         for (i = 0; i < p->ip_option_count; i++)
         {
-            if ( ipv4::is_opt_rr(p->ip_options[i].code) )
+            if (p->ip_options[i].is_opt_rr())
                 codec_events::decoder_event(p, DECODE_ICMP_TRACEROUTE_IPOPTS);
         }
     }
 
-    if ((p->icmph->type == icmp4::IcmpType::SOURCE_QUENCH) &&
-        (p->icmph->code == icmp4::IcmpCode::SOURCE_QUENCH_CODE))
+    if ((p->icmph->type == icmp::IcmpType::SOURCE_QUENCH) &&
+        (p->icmph->code == icmp::IcmpCode::SOURCE_QUENCH_CODE))
         codec_events::decoder_event(p, DECODE_ICMP_SOURCE_QUENCH);
 
     if ((p->dsize == 4) &&
-        (p->icmph->type == icmp4::IcmpType::ECHO) &&
+        (p->icmph->type == icmp::IcmpType::ECHO) &&
         (p->icmph->s_icmp_seq == 0) &&
-        (p->icmph->code == icmp4::IcmpCode::ECHO_CODE))
+        (p->icmph->code == icmp::IcmpCode::ECHO_CODE))
         codec_events::decoder_event(p, DECODE_ICMP_BROADSCAN_SMURF_SCANNER);
 
-    if ((p->icmph->type == icmp4::IcmpType::DEST_UNREACH) &&
-        (p->icmph->code == icmp4::IcmpCode::PKT_FILTERED))
+    if ((p->icmph->type == icmp::IcmpType::DEST_UNREACH) &&
+        (p->icmph->code == icmp::IcmpCode::PKT_FILTERED))
         codec_events::decoder_event(p, DECODE_ICMP_DST_UNREACH_ADMIN_PROHIBITED);
 
-    if ((p->icmph->type == icmp4::IcmpType::DEST_UNREACH) &&
-        (p->icmph->code == icmp4::IcmpCode::PKT_FILTERED_HOST))
+    if ((p->icmph->type == icmp::IcmpType::DEST_UNREACH) &&
+        (p->icmph->code == icmp::IcmpCode::PKT_FILTERED_HOST))
         codec_events::decoder_event(p, DECODE_ICMP_DST_UNREACH_DST_HOST_PROHIBITED);
 
-    if ((p->icmph->type == icmp4::IcmpType::DEST_UNREACH) &&
-        (p->icmph->code == icmp4::IcmpCode::PKT_FILTERED_NET))
+    if ((p->icmph->type == icmp::IcmpType::DEST_UNREACH) &&
+        (p->icmph->code == icmp::IcmpCode::PKT_FILTERED_NET))
         codec_events::decoder_event(p, DECODE_ICMP_DST_UNREACH_DST_NET_PROHIBITED);
 }
 
@@ -469,14 +463,14 @@ bool Icmp4Codec::encode(EncState* enc, Buffer* out, const uint8_t* raw_in)
     uint8_t* p;
     IcmpHdr* ho;
 
-    if (!update_buffer(out, sizeof(*ho) + enc->ip_len + icmp4::unreach_data()))
+    if (!update_buffer(out, sizeof(*ho) + enc->ip_len + icmp::unreach_data()))
         return false;
 
     const uint16_t *hi = reinterpret_cast<const uint16_t*>(raw_in);
     ho = reinterpret_cast<IcmpHdr*>(out->base);
 
     enc->proto = IPPROTO_ID_ICMPV4;
-    ho->type = icmp4::IcmpType::DEST_UNREACH;
+    ho->type = icmp::IcmpType::DEST_UNREACH;
     ho->code = get_icmp_code(enc->type);
     ho->cksum = 0;
     ho->unused = 0;
@@ -487,7 +481,7 @@ bool Icmp4Codec::encode(EncState* enc, Buffer* out, const uint8_t* raw_in)
 
     // copy first 8 octets of original ip data (ie udp header)
     p += enc->ip_len;
-    memcpy(p, hi, icmp4::unreach_data());
+    memcpy(p, hi, icmp::unreach_data());
 
     ho->cksum = checksum::icmp_cksum((uint16_t *)ho, buff_diff(out, (uint8_t *)ho));
 
index 54a7369fc844fd7caa24f6c59522a9c8ce03b190..7604af37fb5b36632dec1ca93cf2c409e7f64fb1 100644 (file)
@@ -53,8 +53,6 @@ public:
         Packet *, uint16_t &lyr_len, uint16_t &next_prot_id);
     virtual bool encode(EncState*, Buffer* out, const uint8_t* raw_in);
     virtual bool update(Packet*, Layer*, uint32_t* len);
-    virtual void format(EncodeFlags, const Packet* p, Packet* c, Layer*);
-    
 };
 
 
@@ -62,9 +60,6 @@ public:
 } // anonymous namespace
 
 
-static void DecodeICMPEmbeddedIP6(const uint8_t *pkt, const uint32_t len, Packet *p);
-
-
 void Icmp6Codec::get_protocol_ids(std::vector<uint16_t>& v)
 {
     v.push_back(IPPROTO_ICMPV6);
@@ -75,7 +70,7 @@ void Icmp6Codec::get_protocol_ids(std::vector<uint16_t>& v)
 //--------------------------------------------------------------------
 
 bool Icmp6Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
-    Packet* p, uint16_t &lyr_len, uint16_t & /* next_prot_id */)
+    Packet* p, uint16_t &lyr_len, uint16_t & next_prot_id )
 {
     if(raw_len < icmp6::hdr_min_len())
     {
@@ -86,7 +81,7 @@ bool Icmp6Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
         return false;
     }
 
-    p->icmp6h = reinterpret_cast<icmp6::ICMP6Hdr*>(const_cast<uint8_t*>(raw_pkt));
+    const icmp6::ICMP6Hdr* icmp6h = reinterpret_cast<const icmp6::ICMP6Hdr*>(raw_pkt);
     p->icmph = reinterpret_cast<const ICMPHdr*>(raw_pkt); /* This is needed for icmp rules */
 
 
@@ -97,7 +92,7 @@ bool Icmp6Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
 
         if(IS_IP4(p))
         {
-            csum = checksum::cksum_add((uint16_t *)(p->icmp6h), raw_len);
+            csum = checksum::cksum_add((uint16_t *)(icmp6h), raw_len);
         }
         /* IPv6 traffic */
         else
@@ -109,7 +104,7 @@ bool Icmp6Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
             ph6.protocol = GET_IPH_PROTO(p);
             ph6.len = htons((u_short)raw_len);
 
-            csum = checksum::icmp_cksum((uint16_t *)(p->icmp6h), raw_len, &ph6);
+            csum = checksum::icmp_cksum((uint16_t *)(icmp6h), raw_len, &ph6);
         }
         if(csum)
         {
@@ -127,9 +122,9 @@ bool Icmp6Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
     p->data = raw_pkt + icmp6::hdr_min_len();
 
     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "ICMP type: %d   code: %d\n",
-                p->icmp6h->type, p->icmp6h->code););
+                icmp6h->type, icmp6h->code););
 
-    switch(p->icmp6h->type)
+    switch(icmp6h->type)
     {
         case icmp6::Icmp6Types::ECHO:
         case icmp6::Icmp6Types::REPLY:
@@ -152,7 +147,6 @@ bool Icmp6Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
                 codec_events::decoder_event(p, DECODE_ICMP_DGRAM_LT_ICMPHDR);
 
                 p->icmph = NULL;
-                p->icmp6h = NULL;
                 return false;
             }
             break;
@@ -170,7 +164,7 @@ bool Icmp6Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
                     codec_events::decoder_event(p, DECODE_ICMPV6_TOO_BIG_BAD_MTU);
                 }
                 lyr_len = icmp6::hdr_normal_len();
-                DecodeICMPEmbeddedIP6(p->data, p->dsize, p);
+                next_prot_id = IP_EMBEDDED_IN_ICMP6;
             }
             else
             {
@@ -180,7 +174,6 @@ bool Icmp6Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
                 codec_events::decoder_event(p, DECODE_ICMP_DGRAM_LT_ICMPHDR);
 
                 p->icmph = NULL;
-                p->icmp6h = NULL;
                 return false;
             }
             break;
@@ -194,19 +187,19 @@ bool Icmp6Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
                 p->data += 4;
                 p->dsize -= 4;
 
-                if (p->icmp6h->type == icmp6::Icmp6Types::UNREACH)
+                if (icmp6h->type == icmp6::Icmp6Types::UNREACH)
                 {
-                    if (p->icmp6h->code == 2)
+                    if (icmp6h->code == 2)
                     {
                         codec_events::decoder_event(p, DECODE_ICMPV6_UNREACHABLE_NON_RFC_2463_CODE);
                     }
-                    else if (p->icmp6h->code > 6)
+                    else if (icmp6h->code > 6)
                     {
                         codec_events::decoder_event(p, DECODE_ICMPV6_UNREACHABLE_NON_RFC_4443_CODE);
                     }
                 }
                 lyr_len = icmp6::hdr_normal_len();
-                DecodeICMPEmbeddedIP6(p->data, p->dsize, p);
+                next_prot_id = IP_EMBEDDED_IN_ICMP6;
             }
             else
             {
@@ -216,7 +209,6 @@ bool Icmp6Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
                 codec_events::decoder_event(p, DECODE_ICMP_DGRAM_LT_ICMPHDR);
 
                 p->icmph = NULL;
-                p->icmp6h = NULL;
                 return false;
             }
             break;
@@ -225,7 +217,7 @@ bool Icmp6Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
             if (p->dsize >= (sizeof(ICMP6RouterAdvertisement) - icmp6::hdr_min_len()))
             {
                 ICMP6RouterAdvertisement *ra = (ICMP6RouterAdvertisement *)raw_pkt;
-                if (p->icmp6h->code != 0)
+                if (icmp6h->code != 0)
                 {
                     codec_events::decoder_event(p, DECODE_ICMPV6_ADVERT_BAD_CODE);
                 }
@@ -243,7 +235,6 @@ bool Icmp6Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
                 codec_events::decoder_event(p, DECODE_ICMP_DGRAM_LT_ICMPHDR);
 
                 p->icmph = NULL;
-                p->icmp6h = NULL;
                 return false;
             }
             break;
@@ -270,7 +261,6 @@ bool Icmp6Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
                 codec_events::decoder_event(p, DECODE_ICMP_DGRAM_LT_ICMPHDR);
 
                 p->icmph = NULL;
-                p->icmp6h = NULL;
                 return false;
             }
             break;
@@ -297,14 +287,13 @@ bool Icmp6Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
                 codec_events::decoder_event(p, DECODE_ICMP_DGRAM_LT_ICMPHDR);
 
                 p->icmph = NULL;
-                p->icmp6h = NULL;
                 return false;
             }
             break;
 
         default:
                 DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
-                    "WARNING: ICMP6_TYPE (type %d).\n", p->icmp6h->type););
+                    "WARNING: ICMP6_TYPE (type %d).\n", icmp6h->type););
             codec_events::decoder_event(p, DECODE_ICMP6_TYPE_OTHER);
 
             lyr_len = icmp6::hdr_min_len();
@@ -317,6 +306,9 @@ bool Icmp6Codec::decode(const uint8_t* raw_pkt, const uint32_t& raw_len,
 }
 
 
+// TODO:  delete (along with any mention of this function)
+
+#if 0
 
 /*
  * Function: DecodeICMPEmbeddedIP6(uint8_t *, const uint32_t, Packet *)
@@ -414,6 +406,8 @@ static void DecodeICMPEmbeddedIP6(const uint8_t *pkt, const uint32_t len, Packet
     return;
 }
 
+#endif
+
 
 /******************************************************************
  ******************** E N C O D E R  ******************************
@@ -444,9 +438,9 @@ bool Icmp6Codec::encode (EncState* enc, Buffer* out, const uint8_t *raw_in)
 
     // copy first 8 octets of original ip data (ie udp header)
     // TBD: copy up to minimum MTU worth of data
-    if (!update_buffer(out, icmp4::unreach_data()))
+    if (!update_buffer(out, icmp::unreach_data()))
         return false;
-    memcpy(out->base, raw_in, icmp4::unreach_data());
+    memcpy(out->base, raw_in, icmp::unreach_data());
 
 
     // copy original ip header
@@ -502,12 +496,6 @@ bool Icmp6Codec::update (Packet* p, Layer* lyr, uint32_t* len)
     return true;
 }
 
-void Icmp6Codec::format (EncodeFlags, const Packet*, Packet* c, Layer* lyr)
-{
-    // TBD handle nested icmp6 layers
-    c->icmp6h = (ICMP6Hdr*)lyr->start;
-}
-
 //-------------------------------------------------------------------------
 // api
 //-------------------------------------------------------------------------
index 1d2b2ccbd44baaf4d4f25e96deb3a4cb7182a4df..9a3670651285f11e0755a94099a8073a74748a6c 100644 (file)
@@ -74,7 +74,7 @@ bool IgmpCodec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
         for(i=0; i< (int) p->ip_option_count; i++) {
             /* All IGMPv2 packets contain IP option code 148 (router alert).
                This vulnerability only applies to IGMPv3, so return early. */
-            if (ipv4::is_opt_rtralt(p->ip_options[i].code)) {
+            if (p->ip_options[i].is_opt_rtralt()) {
                 return true; /* No alert. */
             }
 
index c22d34212225ee52705affab7af6845751505c7b..d992ad4d867ae5e8bcaf849ec2195d025cf200ac 100644 (file)
@@ -167,7 +167,7 @@ bool Ipv4Codec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
     uint16_t hlen;  /* ip header length */
 
     /* do a little validation */
-    if(raw_len < ipv4::hdr_len())
+    if(raw_len < ip::IP4_HEADER_LEN)
     {
         DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
             "WARNING: Truncated IP4 header (%d bytes).\n", raw_len););
@@ -195,13 +195,14 @@ bool Ipv4Codec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
     }
 
     /* lay the IP struct over the raw data */
-    p->inner_iph = p->iph = reinterpret_cast<IPHdr*>(const_cast<uint8_t *>(raw_pkt));
+    IPHdr* iph = reinterpret_cast<IPHdr*>(const_cast<uint8_t *>(raw_pkt));
+    p->inner_iph = p->iph = iph;
 
     /*
      * with datalink DLT_RAW it's impossible to differ ARP datagrams from IP.
      * So we are just ignoring non IP datagrams
      */
-    if(ipv4::get_version((IPHdr*)raw_pkt) != 4)
+    if (iph->get_ver() != 4)
     {
         if ((p->decode_flags & DECODE__UNSURE_ENCAP) == 0)
             codec_events::decoder_event(p, DECODE_NOT_IPV4_DGRAM);
@@ -215,10 +216,10 @@ bool Ipv4Codec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
 
     /* get the IP datagram length */
     ip_len = ntohs(p->iph->ip_len);
-    hlen = ipv4::get_pkt_len(p->iph);
+    hlen = iph->get_hlen() << 2;
 
     /* header length sanity check */
-    if(hlen < ipv4::hdr_len())
+    if(hlen < ip::IP4_HEADER_LEN)
     {
         DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
             "Bogus IP header length of %i bytes\n", hlen););
@@ -292,12 +293,12 @@ bool Ipv4Codec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
     }
 
     /* test for IP options */
-    p->ip_options_len = (uint16_t)(hlen - ipv4::hdr_len());
+    p->ip_options_len = (uint16_t)(hlen - ip::IP4_HEADER_LEN);
 
     if(p->ip_options_len > 0)
     {
-        p->ip_options_data = raw_pkt + ipv4::hdr_len();
-        DecodeIPOptions((raw_pkt + ipv4::hdr_len()), p->ip_options_len, p);
+        p->ip_options_data = raw_pkt + ip::IP4_HEADER_LEN;
+        DecodeIPOptions((raw_pkt + ip::IP4_HEADER_LEN), p->ip_options_len, p);
     }
     else
     {
@@ -425,10 +426,10 @@ static inline void IP4AddrTests (Packet* p)
     }
 
     // check all 32 bits ...
-    if ( ipv4::is_broadcast(p->iph->ip_src.s_addr)  )
+    if ( ip::is_broadcast(p->iph->ip_src.s_addr)  )
         codec_events::decoder_event(p, DECODE_IP4_SRC_BROADCAST);
 
-    if ( ipv4::is_broadcast(p->iph->ip_dst.s_addr)  )
+    if ( ip::is_broadcast(p->iph->ip_dst.s_addr)  )
         codec_events::decoder_event(p, DECODE_IP4_DST_BROADCAST);
 
     /* Loopback traffic  - don't use htonl for speed reasons -
@@ -441,28 +442,28 @@ static inline void IP4AddrTests (Packet* p)
     msb_dst = (uint8_t)(p->iph->ip_dst.s_addr & 0xff);
 #endif
     // check the msb ...
-    if ( ipv4::is_loopback(msb_src) || ipv4::is_loopback(msb_dst) )
+    if ( ip::is_loopback(msb_src) || ip::is_loopback(msb_dst) )
     {
         codec_events::decoder_event(p, DECODE_BAD_TRAFFIC_LOOPBACK);
     }
     // check the msb ...
-    if ( ipv4::is_this_net(msb_src) )
+    if ( ip::is_this_net(msb_src) )
         codec_events::decoder_event(p, DECODE_IP4_SRC_THIS_NET);
 
-    if ( ipv4::is_this_net(msb_dst) )
+    if ( ip::is_this_net(msb_dst) )
         codec_events::decoder_event(p, DECODE_IP4_DST_THIS_NET);
 
     // check the 'msn' (most significant nibble) ...
     msb_src >>= 4;
     msb_dst >>= 4;
 
-    if ( ipv4::is_multicast(msb_src) )
+    if ( ip::is_multicast(msb_src) )
         codec_events::decoder_event(p, DECODE_IP4_SRC_MULTICAST);
 
-    if ( ipv4::is_reserved(msb_src) )
+    if ( ip::is_reserved(msb_src) )
         codec_events::decoder_event(p, DECODE_IP4_SRC_RESERVED);
 
-    if ( ipv4::is_reserved(msb_dst))
+    if ( ip::is_reserved(msb_dst))
         codec_events::decoder_event(p, DECODE_IP4_DST_RESERVED);
 }
 
@@ -481,7 +482,7 @@ static inline void IPMiscTests(Packet *p)
         if (p->ip_options[i].data == NULL)
             continue;
 
-        if (ipv4::is_opt_rr(p->ip_options[i].code))
+        if (p->ip_options[i].is_opt_rr())
         {
             length = p->ip_options[i].len;
             if (length < 1)
@@ -498,7 +499,7 @@ static inline void IPMiscTests(Packet *p)
             if (((length + 3) - pointer) % 4)
                 codec_events::decoder_event(p, DECODE_ICMP_DOS_ATTEMPT);
         }
-        else if (ipv4::is_opt_ts(p->ip_options[i].code))
+        else if (p->ip_options[i].is_opt_ts())
         {
             length = p->ip_options[i].len;
             if (length < 2)
@@ -571,13 +572,13 @@ static void DecodeIPOptions(const uint8_t *start, uint32_t o_len, Packet *p)
             len_ptr = NULL;
         }
 
-        switch(static_cast<ipv4::IPOptionCodes>(*option_ptr))
+        switch(static_cast<ip::IPOptionCodes>(*option_ptr))
         {
-        case ipv4::IPOptionCodes::EOL:
+        case ip::IPOptionCodes::EOL:
             done = 1;
             // fall through
         
-        case ipv4::IPOptionCodes::NOP:
+        case ip::IPOptionCodes::NOP:
             /* if we hit an EOL, we're done */
 
             p->ip_options[opt_count].len = 0;
@@ -682,7 +683,7 @@ bool Ipv4Codec::encode(EncState* enc, Buffer* out, const uint8_t* raw_in)
 
     /* IPv4 encoded header is hardcoded 20 bytes, we save some
      * cycles and use the literal header size for checksum */
-    ho->ip_csum = checksum::ip_cksum((uint16_t *)ho, ipv4::hdr_len());
+    ho->ip_csum = checksum::ip_cksum((uint16_t *)ho, ip::IP4_HEADER_LEN);
     return true;
 }
 
@@ -691,7 +692,7 @@ bool Ipv4Codec::update(Packet* p, Layer* lyr, uint32_t* len)
     IPHdr* h = (IPHdr*)(lyr->start);
     int i = lyr - p->layers;
 
-    *len += ipv4::get_pkt_len(h);
+    *len += ip::get_pkt_len(h);
 
     if ( i + 1 == p->num_layers )
     {
@@ -702,7 +703,7 @@ bool Ipv4Codec::update(Packet* p, Layer* lyr, uint32_t* len)
     if ( !PacketWasCooked(p) || (p->packet_flags & PKT_REBUILT_FRAG) )
     {
         h->ip_csum = 0;
-        h->ip_csum = checksum::ip_cksum((uint16_t *)h, ipv4::get_pkt_len(h));
+        h->ip_csum = checksum::ip_cksum((uint16_t *)h, ip::get_pkt_len(h));
     }
 
     return true;
@@ -729,7 +730,7 @@ void Ipv4Codec::format(EncodeFlags f, const Packet* p, Packet* c, Layer* lyr)
         {
             lyr->length = sizeof(*ch);
             ch->ip_len = htons(lyr->length);
-            ipv4::set_hlen(ch, lyr->length >> 2);
+            ip::set_hlen(ch, lyr->length >> 2);
         }
     }
     sfiph_build(c, c->iph, AF_INET);
index de0cc0484690b7b5d37798612e2ba962d13f5700..f1c5a608472b572cf88c8ea745a40a72901889eb 100644 (file)
@@ -36,6 +36,7 @@
 #include "packet_io/active.h"
 #include "codecs/ip/cd_ipv6_module.h"
 #include "codecs/sf_protocols.h"
+#include "protocols/protocol_ids.h"
 
 namespace
 {
@@ -125,8 +126,8 @@ uint8_t Ipv6Codec::RevTTL (const EncState* enc, uint8_t ttl)
 
 void Ipv6Codec::get_protocol_ids(std::vector<uint16_t>& v)
 {
-    v.push_back(ipv6::ethertype());
-    v.push_back(ipv6::prot_id());
+    v.push_back(ETHERTYPE_IPV6);
+    v.push_back(IPPROTO_ID_IPV6);
 }
 
 
index 8bbf1c80c1084f70d4d12c64c9c4bb308838c5e6..b347aeeb94780211cd9f493d2db3c2fa15bd447a 100644 (file)
@@ -123,7 +123,7 @@ bool TcpCodec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
     }
 
     /* lay TCP on top of the data cause there is enough of it! */
-    p->tcph = reinterpret_cast<TCPHdr*>(const_cast<uint8_t*>(raw_pkt));
+    p->tcph = reinterpret_cast<tcp::TCPHdr*>(const_cast<uint8_t*>(raw_pkt));
 
     /* multiply the payload offset value by 4 */
     lyr_len = TCP_OFFSET(p->tcph) << 2;
@@ -587,7 +587,7 @@ static inline void TCPMiscTests(Packet *p)
 bool TcpCodec::encode (EncState* enc, Buffer* out, const uint8_t* raw_in)
 {
     int ctl;
-    const TCPHdr* hi = reinterpret_cast<const TCPHdr*>(raw_in);
+    const tcp::TCPHdr* hi = reinterpret_cast<const tcp::TCPHdr*>(raw_in);
     bool attach_payload = (enc->type == EncodeType::ENC_TCP_FIN || 
         enc->type == EncodeType::ENC_TCP_PUSH);
 
@@ -602,7 +602,7 @@ bool TcpCodec::encode (EncState* enc, Buffer* out, const uint8_t* raw_in)
     if (!update_buffer(out, tcp::get_tcp_hdr_len(hi)))
         return false;
 
-    TCPHdr* ho = reinterpret_cast<TCPHdr*>(out->base);
+    tcp::TCPHdr* ho = reinterpret_cast<tcp::TCPHdr*>(out->base);
     ctl = (hi->th_flags & TH_SYN) ? 1 : 0;
 
     if ( forward(enc) )
@@ -661,7 +661,7 @@ bool TcpCodec::encode (EncState* enc, Buffer* out, const uint8_t* raw_in)
 
     ho->th_sum = 0;
 
-    if (ipv4::get_version((IPHdr *)enc->ip_hdr) == 4) {
+    if (ip::get_version((IPHdr *)enc->ip_hdr) == 4) {
         checksum::Pseudoheader ps;
         int len = buff_diff(out, (uint8_t*)ho);
 
@@ -688,7 +688,7 @@ bool TcpCodec::encode (EncState* enc, Buffer* out, const uint8_t* raw_in)
 
 bool TcpCodec::update(Packet* p, Layer* lyr, uint32_t* len)
 {
-    TCPHdr* h = (TCPHdr*)(lyr->start);
+    tcp::TCPHdr* h = reinterpret_cast<tcp::TCPHdr*>(lyr->start);
 
     *len += tcp::get_tcp_hdr_len(h) + p->dsize;
 
@@ -719,13 +719,13 @@ bool TcpCodec::update(Packet* p, Layer* lyr, uint32_t* len)
 
 void TcpCodec::format(EncodeFlags f, const Packet* p, Packet* c, Layer* lyr)
 {
-    TCPHdr* ch = (TCPHdr*)lyr->start;
+    tcp::TCPHdr* ch = (tcp::TCPHdr*)lyr->start;
     c->tcph = ch;
 
     if ( reverse(f) )
     {
         int i = lyr - c->layers;
-        TCPHdr* ph = (TCPHdr*)p->layers[i].start;
+        tcp::TCPHdr* ph = (tcp::TCPHdr*)p->layers[i].start;
 
         ch->th_sport = ph->th_dport;
         ch->th_dport = ph->th_sport;
index 4e80b3f196f26bf9138aed7b16b818bc9583b467..d4bb941b099f3d0af20fb46870ed9474ec861ffe 100644 (file)
@@ -36,7 +36,6 @@
 #include "protocols/teredo.h"
 #include "protocols/protocol_ids.h"
 #include "protocols/icmp4.h"
-#include "protocols/icmp6.h"
 #include "protocols/ipv4.h"
 #include "protocols/protocol_ids.h"
 #include "codecs/checksum.h"
@@ -341,7 +340,7 @@ bool UdpCodec::encode (EncState* enc, Buffer* out, const uint8_t* raw_in)
         ho->uh_len = htons((uint16_t)len);
         ho->uh_chk = 0;
 
-        if (ipv4::is_ipv4((ipv4::IPHdr*)enc->ip_hdr)) {
+        if (ip::is_ipv4(*(enc->ip_hdr))) {
             checksum::Pseudoheader ps;
             ps.sip = ((IPHdr *)enc->ip_hdr)->ip_src.s_addr;
             ps.dip = ((IPHdr *)enc->ip_hdr)->ip_dst.s_addr;
@@ -364,20 +363,20 @@ bool UdpCodec::encode (EncState* enc, Buffer* out, const uint8_t* raw_in)
     }
 
     // if this is not GTP, we want to return an ICMP unreachable packet
-    else if ( ipv4::is_ipv4((ipv4::IPHdr*)enc->ip_hdr))
+    else if ( ip::is_ipv4(*(enc->ip_hdr)))
     {
         // copied directly from Icmp4Codec::encode()
         uint8_t* p;
         IcmpHdr* ho;
 
-        if (!update_buffer(out, sizeof(*ho) + enc->ip_len + icmp4::unreach_data()))
+        if (!update_buffer(out, sizeof(*ho) + enc->ip_len + icmp::unreach_data()))
             return false;
 
         const uint16_t *hi = reinterpret_cast<const uint16_t*>(raw_in);
         ho = reinterpret_cast<IcmpHdr*>(out->base);
 
         enc->proto = IPPROTO_ID_ICMPV4;
-        ho->type = icmp4::IcmpType::DEST_UNREACH;
+        ho->type = icmp::IcmpType::DEST_UNREACH;
         ho->code = get_icmp_code(enc->type);
         ho->cksum = 0;
         ho->unused = 0;
@@ -388,7 +387,7 @@ bool UdpCodec::encode (EncState* enc, Buffer* out, const uint8_t* raw_in)
 
         // copy first 8 octets of original ip data (ie udp header)
         p += enc->ip_len;
-        memcpy(p, hi, icmp4::unreach_data());
+        memcpy(p, hi, icmp::unreach_data());
 
         ho->cksum = checksum::icmp_cksum((uint16_t *)ho, buff_diff(out, (uint8_t *)ho));
     }
@@ -403,9 +402,9 @@ bool UdpCodec::encode (EncState* enc, Buffer* out, const uint8_t* raw_in)
 
         // copy first 8 octets of original ip data (ie udp header)
         // TBD: copy up to minimum MTU worth of data
-        if (!update_buffer(out, icmp4::unreach_data()))
+        if (!update_buffer(out, icmp::unreach_data()))
             return false;
-        memcpy(out->base, raw_in, icmp4::unreach_data());
+        memcpy(out->base, raw_in, icmp::unreach_data());
 
         // copy original ip header
         if (!update_buffer(out, enc->ip_len))
index 01fc7948d0bfe866bb49981040c2725e5ceaaeb0..89c36c6c668618c110c04037beb52aa21151bc48 100644 (file)
@@ -140,7 +140,7 @@ bool PppEncap::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
         case PPP_VJ_UCOMP:
             /* VJ compression modifies the protocol field. It must be set
              * to tcp (only TCP packets can be VJ compressed) */
-            if(raw_len < (lyr_len + ipv4::hdr_len()))
+            if(raw_len < (lyr_len + ip::IP4_HEADER_LEN))
             {
                 if (ScLogVerbose())
                     ErrorMessage("PPP VJ min packet length > captured len! "
index b61902a149859e3db8420211152afd5bc4c03402..f4ffb17b9d752d462b2bbfd87ad041e729a48d45 100644 (file)
@@ -2,6 +2,9 @@
 
 if(STATIC_CODECS)
     set(PLUGIN_LIST
+        cd_ip4_embedded_in_icmp.cc
+        cd_ip6_embedded_in_icmp.cc
+        cd_prot_embedded_in_icmp.cc
         cd_gtp.cc
         cd_gtp_module.h
         cd_gtp_module.cc
@@ -12,6 +15,9 @@ else(STATIC_CODECS)
     add_shared_library(cd_gtp codecs cd_gtp.cc cd_gtp_module.h cd_gtp_module.cc)
     add_shared_library(cd_teredo codecs cd_teredo.cc)
 
+    #  When static codecs NOT enabled, the icmp files will be included in the
+    #  ICMP libraries in the other file.
+
 endif(STATIC_CODECS)
 
 add_library( misc_codecs STATIC
index a40f008028b48c11e529d66bd0a3bc9a194417c6..d8b8025aa69cad022902d937e53785f8c0fdc161 100644 (file)
@@ -215,9 +215,9 @@ bool GtpCodec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
 
         ip_ver = *(raw_pkt + GTP_MIN_LEN) & 0xF0;
         if (ip_ver == 0x40)
-            next_prot_id = ipv4::prot_id(); 
+            next_prot_id = IPPROTO_ID_IPIP;
         else if (ip_ver == 0x60)
-            next_prot_id = ipv6::prot_id();
+            next_prot_id = IPPROTO_ID_IPV6;
     }
     
     return true;
diff --git a/src/codecs/misc/cd_ip4_embedded_in_icmp.cc b/src/codecs/misc/cd_ip4_embedded_in_icmp.cc
new file mode 100644 (file)
index 0000000..3cb3a47
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+** Copyright (C) 2002-2013 Sourcefire, Inc.
+** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
+**
+** 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.
+*/
+// cd_ip4_embedded_in_icmp.cc author Josh Rosenbaum <jrosenba@cisco.com>
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "framework/codec.h"
+#include "protocols/ipv4.h"
+#include "codecs/decode_module.h"
+#include "codecs/codec_events.h"
+
+
+namespace
+{
+
+// yes, macros are necessary. The API and class constructor require different strings.
+//
+// this macros is defined in the module to ensure identical names. However,
+// if you don't want a module, define the name here.
+#ifndef IP4_EMBEDDED_IN_ICMP
+#define IP4_EMBEDDED_IN_ICMP "ip4_embedded_in_icmp"
+#endif
+
+class Ip4EmbeddedInIcmpCodec : public Codec
+{
+public:
+    Ip4EmbeddedInIcmpCodec() : Codec(IP4_EMBEDDED_IN_ICMP){};
+    ~Ip4EmbeddedInIcmpCodec() {};
+
+
+    virtual bool decode(const uint8_t *raw_pkt, const uint32_t &raw_len,
+        Packet *, uint16_t &lyr_len, uint16_t &next_prot_id);
+
+    virtual void get_protocol_ids(std::vector<uint16_t>&);
+
+};
+
+} // namespace
+
+// TODO: delete
+#include <iostream>
+
+void Ip4EmbeddedInIcmpCodec::get_protocol_ids(std::vector<uint16_t>& v)
+{
+    v.push_back(IP_EMBEDDED_IN_ICMP4);
+}
+
+bool Ip4EmbeddedInIcmpCodec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
+        Packet* p, uint16_t& lyr_len, uint16_t& next_prot_id)
+{
+    uint32_t ip_len;       /* length from the start of the ip hdr to the
+                             * pkt end */
+    uint32_t hlen;          /* ip header length */
+
+    /* do a little validation */
+    if(raw_len < ip::IP4_HEADER_LEN)
+    {
+        DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
+            "ICMP: IP short header (%d bytes)\n", raw_len););
+
+        codec_events::decoder_event(p, DECODE_ICMP_ORIG_IP_TRUNCATED);
+
+        return false;
+    }
+
+    /* lay the IP struct over the raw data */
+    const IPHdr *ip4h = reinterpret_cast<const IPHdr *>(raw_pkt);
+
+    /*
+     * with datalink DLT_RAW it's impossible to differ ARP datagrams from IP.
+     * So we are just ignoring non IP datagrams
+     */
+    if((ip4h->get_ver() != 4) && !IS_IP6(p))
+    {
+        DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
+            "ICMP: not IPv4 datagram ([ver: 0x%x][len: 0x%x])\n",
+            ip4h->get_ver(), ntohs(ip4h->get_len())););
+
+        codec_events::decoder_event(p, DECODE_ICMP_ORIG_IP_VER_MISMATCH);
+
+        return false;
+    }
+
+    ip_len = ntohs(ip4h->get_len());/* set the IP datagram length */
+    hlen = ip4h->get_len() << 2;    /* set the IP header length */
+
+    if(raw_len < hlen)
+    {
+        DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
+            "ICMP: IP len (%d bytes) < IP hdr len (%d bytes), packet discarded\n",
+            ip_len, hlen););
+
+        codec_events::decoder_event(p, DECODE_ICMP_ORIG_DGRAM_LT_ORIG_IP);
+        return false;
+    }
+
+    /* set the remaining packet length */
+    ip_len = raw_len - hlen;
+
+    uint16_t orig_frag_offset = ntohs(ip4h->get_off());
+    orig_frag_offset &= 0x1FFF;
+
+    if (orig_frag_offset == 0)
+    {
+        /* Original IP payload should be 64 bits */
+        if (ip_len < 8)
+        {
+            codec_events::decoder_event(p, DECODE_ICMP_ORIG_PAYLOAD_LT_64);
+
+            return false;
+        }
+        /* ICMP error packets could contain as much of original payload
+         * as possible, but not exceed 576 bytes
+         */
+        else if (ntohs(GET_IPH_LEN(p)) > 576)
+        {
+            codec_events::decoder_event(p, DECODE_ICMP_ORIG_PAYLOAD_GT_576);
+        }
+    }
+    else
+    {
+        /* RFC states that only first frag will get an ICMP response */
+        codec_events::decoder_event(p, DECODE_ICMP_ORIG_IP_WITH_FRAGOFFSET);
+        return false;
+    }
+
+    DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "ICMP Unreachable IP header length: "
+                            "%lu\n", (unsigned long)hlen););
+
+    // since we know the protocol ID in this layer (and NOT the
+    // next layer), set the correct protocol here.  Normally,
+    // I would just set the next_protocol_id and let the packet_manger
+    // decode the next layer. However, I  can't set the next_prot_id in
+    // this case because I don't want this going to the TCP, UDP, or
+    // ICMP codec. Therefore, doing a minor decode here.
+    switch(ip4h->get_proto())
+    {
+        case IPPROTO_TCP: /* decode the interesting part of the header */
+            p->proto_bits |= PROTO_BIT__TCP_EMBED_ICMP;
+            next_prot_id = PROT_EMBEDDED_IN_ICMP;
+            break;
+
+        case IPPROTO_UDP:
+            p->proto_bits |= PROTO_BIT__UDP_EMBED_ICMP;
+            next_prot_id = PROT_EMBEDDED_IN_ICMP;
+            break;
+
+        case IPPROTO_ICMP:
+            p->proto_bits |= PROTO_BIT__ICMP_EMBED_ICMP;
+            next_prot_id = PROT_EMBEDDED_IN_ICMP;
+            break;
+    }
+
+    return true;
+}
+
+//-------------------------------------------------------------------------
+// api
+//-------------------------------------------------------------------------
+
+
+static Codec* ctor(Module*)
+{
+    return new Ip4EmbeddedInIcmpCodec();
+}
+
+static void dtor(Codec *cd)
+{
+    delete cd;
+}
+
+
+static const CodecApi ip4_embedded_in_icmp_api =
+{
+    {
+        PT_CODEC,
+        IP4_EMBEDDED_IN_ICMP,
+        CDAPI_PLUGIN_V0,
+        0,
+        nullptr, // module constructor
+        nullptr  // module destructor
+    },
+    nullptr, // g_ctor
+    nullptr, // g_dtor
+    nullptr, // t_ctor
+    nullptr, // t_dtor
+    ctor,
+    dtor,
+};
+
+
+#ifdef BUILDING_SO
+SO_PUBLIC const BaseApi* snort_plugins[] =
+{
+    &name_api.base,
+    nullptr
+};
+#else
+const BaseApi* cd_ip4_embedded_in_icmp = &ip4_embedded_in_icmp_api.base;
+#endif
diff --git a/src/codecs/misc/cd_ip6_embedded_in_icmp.cc b/src/codecs/misc/cd_ip6_embedded_in_icmp.cc
new file mode 100644 (file)
index 0000000..27cbc34
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+** Copyright (C) 2002-2013 Sourcefire, Inc.
+** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
+**
+** 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.
+*/
+// cd_ip6_embedded_in_icmp.cc author Josh Rosenbaum <jrosenba@cisco.com>
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "framework/codec.h"
+#include "protocols/ipv4.h"
+#include "codecs/decode_module.h"
+#include "codecs/codec_events.h"
+
+
+namespace
+{
+
+// yes, macros are necessary. The API and class constructor require different strings.
+//
+// this macros is defined in the module to ensure identical names. However,
+// if you don't want a module, define the name here.
+#ifndef IP6_EMBEDDED_IN_ICMP
+#define IP6_EMBEDDED_IN_ICMP "ip6_embedded_in_icmp"
+#endif
+
+class Ip6EmbeddedInIcmpCodec : public Codec
+{
+public:
+    Ip6EmbeddedInIcmpCodec() : Codec(IP6_EMBEDDED_IN_ICMP){};
+    ~Ip6EmbeddedInIcmpCodec() {};
+
+
+    virtual void get_protocol_ids(std::vector<uint16_t>&);
+    virtual bool decode(const uint8_t *raw_pkt, const uint32_t &raw_len,
+        Packet *, uint16_t &lyr_len, uint16_t &next_prot_id);
+};
+
+} // namespace
+
+// TODO: delete
+#include <iostream>
+
+void Ip6EmbeddedInIcmpCodec::get_protocol_ids(std::vector<uint16_t>& v)
+{
+    v.push_back(IP_EMBEDDED_IN_ICMP6);
+}
+
+bool Ip6EmbeddedInIcmpCodec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
+        Packet* p, uint16_t& lyr_len, uint16_t& next_prot_id)
+{
+//    uint16_t orig_frag_offset;
+
+    /* lay the IP struct over the raw data */
+    const ipv6::IP6RawHdr* ip6h = reinterpret_cast<const ipv6::IP6RawHdr*>(raw_pkt);
+
+    DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "DecodeICMPEmbeddedIP6: ip header"
+                    " starts at: %p, length is %lu\n", ip6h,
+                    (unsigned long) raw_len););
+
+    /* do a little validation */
+    if ( raw_len < ipv6::hdr_len() )
+    {
+        DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
+            "ICMP6: IP short header (%d bytes)\n", raw_len););
+
+        codec_events::decoder_event(p, DECODE_ICMP_ORIG_IP_TRUNCATED);
+
+        return false;
+    }
+
+    /*
+     * with datalink DLT_RAW it's impossible to differ ARP datagrams from IP.
+     * So we are just ignoring non IP datagrams
+     */
+    if(ip6h->get_ver() != 6)
+    {
+        DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
+            "ICMP: not IPv6 datagram ([ver: 0x%x][len: 0x%x])\n",
+            ip6h->get_ver(), raw_len););
+
+        codec_events::decoder_event(p, DECODE_ICMP_ORIG_IP_VER_MISMATCH);
+
+        return false;
+    }
+
+    if ( raw_len < ipv6::hdr_len() )
+    {
+        DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
+            "ICMP6: IP6 len (%d bytes) < IP6 hdr len (%d bytes), packet discarded\n",
+            raw_len, ipv6::hdr_len()););
+
+        codec_events::decoder_event(p, DECODE_ICMP_ORIG_DGRAM_LT_ORIG_IP);
+
+        return false;
+    }
+
+//    orig_frag_offset = ntohs(GET_ORIG_IPH_OFF(p));
+//    orig_frag_offset &= 0x1FFF;
+
+    // XXX NOT YET IMPLEMENTED - fragments inside ICMP payload
+
+    DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "ICMP6 Unreachable IP6 header length: "
+                            "%lu\n", (unsigned long)ipv6::hdr_len()););
+
+    // since we know the protocol ID in this layer (and NOT the
+    // next layer), set the correct protocol here.  Normally,
+    // I would just set the next_protocol_id and let the packet_manger
+    // decode the next layer. However, I  can't set the next_prot_id in
+    // this case because I don't want this going to the TCP, UDP, or
+    // ICMP codec. Therefore, doing a minor decode here.
+    switch(ip6h->get_next())
+    {
+        case IPPROTO_TCP: /* decode the interesting part of the header */
+            p->proto_bits |= PROTO_BIT__TCP_EMBED_ICMP;
+            next_prot_id = PROT_EMBEDDED_IN_ICMP;
+            break;
+
+        case IPPROTO_UDP:
+            p->proto_bits |= PROTO_BIT__UDP_EMBED_ICMP;
+            next_prot_id = PROT_EMBEDDED_IN_ICMP;
+            break;
+
+        case IPPROTO_ICMP:
+            p->proto_bits |= PROTO_BIT__ICMP_EMBED_ICMP;
+            next_prot_id = PROT_EMBEDDED_IN_ICMP;
+            break;
+    }
+
+    return true;
+}
+
+//-------------------------------------------------------------------------
+// api
+//-------------------------------------------------------------------------
+
+static Codec* ctor(Module*)
+{
+    return new Ip6EmbeddedInIcmpCodec();
+}
+
+static void dtor(Codec *cd)
+{
+    delete cd;
+}
+
+
+static const CodecApi ip6_embedded_in_icmp_api =
+{
+    {
+        PT_CODEC,
+        IP6_EMBEDDED_IN_ICMP,
+        CDAPI_PLUGIN_V0,
+        0,
+        nullptr, // module constructor
+        nullptr  // module destructor
+    },
+    nullptr, // g_ctor
+    nullptr, // g_dtor
+    nullptr, // t_ctor
+    nullptr, // t_dtor
+    ctor,
+    dtor,
+};
+
+
+#ifdef BUILDING_SO
+SO_PUBLIC const BaseApi* snort_plugins[] =
+{
+    &name_api.base,
+    nullptr
+};
+#else
+const BaseApi* cd_ip6_embedded_in_icmp = &ip6_embedded_in_icmp_api.base;
+#endif
diff --git a/src/codecs/misc/cd_prot_embedded_in_icmp.cc b/src/codecs/misc/cd_prot_embedded_in_icmp.cc
new file mode 100644 (file)
index 0000000..c818636
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+** Copyright (C) 2002-2013 Sourcefire, Inc.
+** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
+**
+** 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.
+*/
+// cd_prot_embedded_in_icmp.cc author Josh Rosenbaum <jrosenba@cisco.com>
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "framework/codec.h"
+
+
+namespace
+{
+
+// yes, macros are necessary. The API and class constructor require different strings.
+//
+// this macros is defined in the module to ensure identical names. However,
+// if you don't want a module, define the name here.
+#ifndef ProtEmbeddedInIcmp_NAME
+#define ProtEmbeddedInIcmp_NAME "prot_embedded_in_icmp"
+#endif
+
+class ProtEmbeddedInIcmp : public Codec
+{
+public:
+    ProtEmbeddedInIcmp() : Codec(ProtEmbeddedInIcmp_NAME){};
+    ~ProtEmbeddedInIcmp() {};
+
+
+    virtual bool decode(const uint8_t *raw_pkt, const uint32_t &raw_len,
+        Packet *, uint16_t &lyr_len, uint16_t &next_prot_id);
+
+    virtual void get_protocol_ids(std::vector<uint16_t>&);
+};
+
+} // namespace
+
+
+void ProtEmbeddedInIcmp::get_protocol_ids(std::vector<uint16_t>& v)
+{
+    v.push_back(PROT_EMBEDDED_IN_ICMP);
+}
+
+bool ProtEmbeddedInIcmp::decode(const uint8_t* /*raw_pkt*/, const uint32_t& /*raw_len*/,
+        Packet* /*p*/, uint16_t& /*lyr_len*/, uint16_t& /*next_prot_id*/)
+{
+
+    // Since the previous layer already set the correct p->proto_bits,
+    // there is really nothing to do here.  This layer is actually
+    // a placeholder so I can easily find this layer's data at some
+    // other point in Snort++.
+    return true;
+}
+
+
+
+
+//-------------------------------------------------------------------------
+// api
+//-------------------------------------------------------------------------
+
+
+static Codec* ctor(Module*)
+{
+    return new ProtEmbeddedInIcmp();
+}
+
+static void dtor(Codec *cd)
+{
+    delete cd;
+}
+
+
+static const CodecApi prot_embedded_in_icmp_api =
+{
+    {
+        PT_CODEC,
+        ProtEmbeddedInIcmp_NAME,
+        CDAPI_PLUGIN_V0,
+        0,
+        nullptr,
+        nullptr
+    },
+    nullptr, // ginit
+    nullptr, // gterm
+    nullptr, // tinit
+    nullptr, // tterm
+    ctor,
+    dtor,
+};
+
+
+#ifdef BUILDING_SO
+SO_PUBLIC const BaseApi* snort_plugins[] =
+{
+    &prot_embedded_in_icmp_api.base,
+    nullptr
+};
+#else
+const BaseApi* cd_prot_embedded_in_icmp = &prot_embedded_in_icmp_api.base;
+#endif
index 1c9936c6066cb5c907d99c9944e7c041eb44de81..c37f8579872d331b63c22b7de702e715f972509f 100644 (file)
@@ -7,6 +7,7 @@ if (STATIC_CODECS)
     if (ENABLE_NON_ETHER_DECODERS)
             set(NON_ETHER_PLUGINS
                 cd_linux_sll.cc
+                cd_ppp.cc
                 cd_wlan.cc
                 cd_wlan_module.h
                 cd_wlan_module.cc
@@ -15,7 +16,6 @@ if (STATIC_CODECS)
         #        root_i4lrawip.cc
         #        root_oldpflog.cc
         #        root_enc.cc
-        #        root_ppp.cc
         #        root_pflog.cc
         #        root_pppserial.cc
         #        root_chdlc.cc
@@ -30,6 +30,7 @@ else(STATIC_CODECS)
     if (ENABLE_NON_ETHER_DECODERS)
         add_shared_library(cd_wlan codecs cd_wlan.cc cd_wlan_module.h cd_wlan_module.cc)
         add_shared_library(cd_linux_sll codecs cd_linux_sll.cc)
+        add_shared_library(cd_ppp codecs cd_ppp.cc)
     endif(ENABLE_NON_ETHER_DECODERS)
 endif(STATIC_CODECS)
 
index 90e484b1152a2671f5ac4cd65493244384ea81e4..3b396979afb183e582988cb19b303fe9e6518dd0 100644 (file)
@@ -15,6 +15,7 @@ if ENABLE_NON_ETHER_DECODER
 if STATIC_CODECS
 libroot_codecs_a_SOURCES += \
 cd_linux_sll.cc \
+cd_ppp.cc \
 cd_wlan.cc \
 cd_wlan_module.h \
 cd_wlan_module.cc
@@ -34,16 +35,21 @@ cd_wlan_module.cc
 else
 ehlibdir = $(pkglibdir)/codecs
 
-ehlib_LTLIBRARIES = libcd_wlan.la
-libcd_wlan_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
-libcd_wlan_la_LDFLAGS = -export-dynamic -shared
-libcd_wlan_la_SOURCES =  cd_wlan.cc cd_wlan_module.h cd_wlan_module.cc
-
-ehlib_LTLIBRARIES += libcd_linux_sll.la
+ehlib_LTLIBRARIES = libcd_linux_sll.la
 libcd_linux_sll_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
 libcd_linux_sll_la_LDFLAGS = -export-dynamic -shared
 libcd_linux_sll_la_SOURCES =  cd_linux_sll.cc
 
+ehlib_LTLIBRARIES += libcd_ppp.la
+libcd_ppp_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
+libcd_ppp_la_LDFLAGS = -export-dynamic -shared
+libcd_ppp_la_SOURCES =  cd_ppp.cc cd_ppp.h
+
+ehlib_LTLIBRARIES += libcd_wlan.la
+libcd_wlan_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
+libcd_wlan_la_LDFLAGS = -export-dynamic -shared
+libcd_wlan_la_SOURCES =  cd_wlan.cc cd_wlan_module.h cd_wlan_module.cc
+
 endif
 endif
 
diff --git a/src/codecs/root/cd_ppp.cc b/src/codecs/root/cd_ppp.cc
new file mode 100644 (file)
index 0000000..b4ea96b
--- /dev/null
@@ -0,0 +1,144 @@
+/* $Id: decode.c,v 1.285 2013-06-29 03:03:00 rcombs Exp $ */
+
+/*
+** Copyright (C) 2002-2013 Sourcefire, Inc.
+** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
+**
+** 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cstdint>
+#include "framework/codec.h"
+#include "main/snort.h"
+
+
+
+namespace
+{
+
+// yes, macros are necessary. The API and class constructor require different strings.
+//
+// this macros is defined in the module to ensure identical names. However,
+// if you don't want a module, define the name here.
+#ifndef PPP_NAME
+#define PPP_NAME "point_to_point"
+#endif
+
+class PPPCodec : public Codec
+{
+public:
+    PPPCodec() : Codec(PPP_NAME){}
+    ~PPPCodec() {}
+
+
+    virtual bool decode(const uint8_t *raw_pkt, const uint32_t &raw_len,
+        Packet *, uint16_t &lyr_len, uint16_t &next_prot_id);
+    virtual void get_data_link_type(std::vector<int>&);
+};
+
+} // namespace
+
+
+#ifndef DLT_PPP
+static constexpr int DLT_PPP = 51;
+#endif
+
+static constexpr uint8_t CHDLC_ADDR_BROADCAST = 0xff;
+static constexpr uint8_t CHDLC_CTRL_UNNUMBERED = 0x03;
+
+
+void PPPCodec::get_data_link_type(std::vector<int>& v)
+{
+    v.push_back(DLT_PPP);
+}
+
+
+bool PPPCodec::decode(const uint8_t *raw_pkt, const uint32_t& raw_len,
+        Packet* /*p*/, uint16_t& lyr_len, uint16_t& next_prot_id)
+{
+    if(raw_len < 2)
+    {
+        if (ScLogVerbose())
+        {
+            ErrorMessage("Length not big enough for even a single "
+                         "header or a one byte payload\n");
+        }
+        return false;
+    }
+
+    if(raw_pkt[0] == CHDLC_ADDR_BROADCAST && raw_pkt[1] == CHDLC_CTRL_UNNUMBERED)
+    {
+        /*
+         * Check for full HDLC header (rfc1662 section 3.2)
+         */
+        lyr_len = 2;
+    }
+
+    next_prot_id = ETHERTYPE_PPP;
+    return true;
+}
+
+
+
+//-------------------------------------------------------------------------
+// api
+//-------------------------------------------------------------------------
+
+
+static Codec* ctor(Module*)
+{
+    return new PPPCodec();
+}
+
+static void dtor(Codec *cd)
+{
+    delete cd;
+}
+
+
+static const CodecApi ppp_api =
+{
+    {
+        PT_CODEC,
+        PPP_NAME,
+        CDAPI_PLUGIN_V0,
+        0,
+        nullptr, // mod_ctor
+        nullptr, // mod_dtor
+    },
+    nullptr, // pinit
+    nullptr, // pterm
+    nullptr, // tinit
+    nullptr, // tterm
+    ctor,
+    dtor,
+};
+
+
+#ifdef BUILDING_SO
+SO_PUBLIC const BaseApi* snort_plugins[] =
+{
+    &ppp_api.base,
+    nullptr
+};
+#else
+const BaseApi* cd_ppp = &ppp_api.base;
+#endif
+
diff --git a/src/codecs/root/root_ppp.cc b/src/codecs/root/root_ppp.cc
deleted file mode 100644 (file)
index 4056440..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/* $Id: decode.c,v 1.285 2013-06-29 03:03:00 rcombs Exp $ */
-
-/*
-** Copyright (C) 2002-2013 Sourcefire, Inc.
-** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
-**
-** 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.
-*/
-
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-
-#include "framework/codec.h"
-
-
-static int DLT_PPP = 51;
-
-
-/*
- * Function: DecodePppPkt(Packet *, char *, DAQ_PktHdr_t*, uint8_t*)
- *
- * Purpose: Decode PPP traffic (either RFC1661 or RFC1662 framing).
- *          This really is intended to handle IPCP
- *
- * Arguments: p => pointer to decoded packet struct
- *            user => Utility pointer, unused
- *            pkthdr => ptr to the packet header
- *            pkt => pointer to the real live packet data
- *
- * Returns: void function
- */
-// DecodePppPkt() and DecodePppSerialPkt() may be incorrect ...
-// both skip past 2 byte protocol and then call DecodePppPktEncapsulated()
-// which does the same thing.  That one works inside DecodePPPoEPkt();
-void DecodePppPkt(Packet * p, const DAQ_PktHdr_t * pkthdr, const uint8_t * pkt)
-{
-    uint32_t cap_len = pkthdr->caplen;
-    int hlen = 0;
-
-    if(cap_len < 2)
-    {
-        if (ScLogVerbose())
-        {
-            ErrorMessage("Length not big enough for even a single "
-                         "header or a one byte payload\n");
-        }
-        MODULE_PROFILE_END(decodePerfStats);
-        return;
-    }
-
-    if(pkt[0] == CHDLC_ADDR_BROADCAST && pkt[1] == CHDLC_CTRL_UNNUMBERED)
-    {
-        /*
-         * Check for full HDLC header (rfc1662 section 3.2)
-         */
-        hlen = 2;
-    }
-
-    DecodePppPktEncapsulated(p->pkt + hlen, cap_len - hlen, p);
-
-    MODULE_PROFILE_END(decodePerfStats);
-    return;
-}
-
-
diff --git a/src/codecs/root/root_ppp.h b/src/codecs/root/root_ppp.h
deleted file mode 100644 (file)
index a68caeb..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
-** Copyright (C) 2002-2013 Sourcefire, Inc.
-** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
-**
-** 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.
-*/
-
-
-#ifndef ROOT_PPP_H
-#define ROOT_PPP_H
-
-
-void DecodePppPkt(Packet *, const DAQ_PktHdr_t*, const uint8_t *);
-
-#endif /* ROOT_PPP_H */
-
index 62c2345cfaca0f19d731c1779a36db17fe131150..0cfeb5b3a7605373f161939056a216b69d64a813 100644 (file)
@@ -308,7 +308,8 @@ int Detect(Packet * p)
         return 0;
     }
 
-
+    // FIXIT:  Bug??  Do we want to check inner IP protocol tpe,
+    //          when indexing outer ip array??
     if (!snort_conf->ip_proto_array[GET_IPH_PROTO(p)])
     {
         switch (p->outer_family)
index 719ef1d87078b43fe9a7f753808615ec03a7c68c..949957aca5bce8bff4c7de88b7919cff1c99b170 100644 (file)
@@ -157,7 +157,7 @@ int SnortEventqAdd(uint32_t gid, uint32_t sid, RuleType type)
 
     EventNode* en = (EventNode*)sfeventq_event_alloc(event_queue[qIndex]);
 
-    if ( en )
+    if ( !en )
         return -1;
 
     en->otn = otn;
index bf38ca746c61e0be1a7760b8d9ac9a8f8832729e..464b0e907efa323b06316992495c318207f09dd7 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
 ** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
 ** Copyright (C) 2005-2013 Sourcefire, Inc.
@@ -89,7 +88,7 @@ inline void FlowKey::init4(
         port_h = srcPort;
     }
     if (ScMplsOverlappingIp() &&
-        ipv4::isPrivateIP(*src) && ipv4::isPrivateIP(*dst))
+        ip::isPrivateIP(*src) && ip::isPrivateIP(*dst))
         mplsLabel = mplsId;
     else
        mplsLabel = 0;
index 21f46a5faf615a71d9529853f65479a78944551e..2332cae550d3de71f20c86bc4dd6c3b28a359cd7 100644 (file)
@@ -96,6 +96,7 @@ static inline bool update_buffer(Buffer* buf, size_t n)
 }
 
 
+
 class Codec
 {
 public:
@@ -115,8 +116,6 @@ public:
 
     // Get the codec's name
     inline const char* get_name(){return name; };
-    // Several codecs are for convenience. So, tell Snort++ not to print any info
-    virtual bool dump_at_startup(){ return true; };
     // used for backwards compatability.
     virtual PROTO_ID get_proto_id() { return PROTO_AH; };
     // Registers this Codec's data link type (as defined by libpcap)
@@ -173,14 +172,14 @@ protected:
         return (((uint8_t*)(buf->base+buf->end))-(uint8_t*)ho);
     }
 
-    static inline icmp4::IcmpCode get_icmp_code (EncodeType et)
+    static inline icmp::IcmpCode get_icmp_code (EncodeType et)
     {
         switch ( et ) {
-            case EncodeType::ENC_UNR_NET:  return icmp4::IcmpCode::NET_UNREACH;
-            case EncodeType::ENC_UNR_HOST: return icmp4::IcmpCode::HOST_UNREACH;
-            case EncodeType::ENC_UNR_PORT: return icmp4::IcmpCode::PORT_UNREACH;
-            case EncodeType::ENC_UNR_FW:   return icmp4::IcmpCode::PKT_FILTERED;
-            default: return icmp4::IcmpCode::PORT_UNREACH;
+            case EncodeType::ENC_UNR_NET:  return icmp::IcmpCode::NET_UNREACH;
+            case EncodeType::ENC_UNR_HOST: return icmp::IcmpCode::HOST_UNREACH;
+            case EncodeType::ENC_UNR_PORT: return icmp::IcmpCode::PORT_UNREACH;
+            case EncodeType::ENC_UNR_FW:   return icmp::IcmpCode::PKT_FILTERED;
+            default: return icmp::IcmpCode::PORT_UNREACH;
         }
     }
 
index 5f810d06c14a0a50b158325c3ec550240b607e47..8febed432b7e205573e7d069344e49d0ce5d9df9 100644 (file)
@@ -1004,7 +1004,6 @@ static void LogICMPEmbeddedIP(TextLog* log, Packet *p)
 {
     Packet op;
     Packet *orig_p;
-    uint32_t orig_ip_hlen;
 
     if (log == NULL || p == NULL)
         return;
@@ -1012,50 +1011,73 @@ static void LogICMPEmbeddedIP(TextLog* log, Packet *p)
     memset((char*)&op, 0, sizeof(op));
     orig_p = &op;
 
-    orig_p->iph = p->orig_iph;
-    orig_p->tcph = p->orig_tcph;
-    orig_p->udph = p->orig_udph;
-    orig_p->sp = p->orig_sp;
-    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->family = p->orig_family;
-
-    if(orig_p->iph != NULL)
+    if (!layer::set_api_ip_embed_icmp(p, op.ip_api))
     {
-        TextLog_Print(log, "\n** ORIGINAL DATAGRAM DUMP:\n");
-        LogIPHeader(log, orig_p);
-        orig_ip_hlen = ipv4::get_pkt_len(p->orig_iph) << 2;
-
-        switch(GET_IPH_PROTO(orig_p))
+        switch(orig_p->ip_api.proto())
         {
             case IPPROTO_TCP:
-                if(orig_p->tcph != NULL)
+            {
+                const tcp::TCPHdr* tcph = layer::get_tcp_embed_icmp(p);
+                if (tcph)
+                {
+                    orig_p->sp = ntohs(tcph->th_sport);
+                    orig_p->dp = ntohs(tcph->th_dport);
+                    orig_p->tcph = tcph;
+                }
+
+                TextLog_Print(log, "\n** ORIGINAL DATAGRAM DUMP:\n");
+                LogIPHeader(log, orig_p);
+
+                if(tcph != NULL)
+                {
                     TextLog_Print(log, "Seq: 0x%lX\n",
                             (u_long)ntohl(orig_p->tcph->th_seq));
+                }
                 break;
+            }
 
             case IPPROTO_UDP:
-                if(orig_p->udph != NULL)
+            {
+                const udp::UDPHdr* udph = layer::get_udp_embed_icmp(p);
+                if (udph)
+                {
+                    orig_p->sp = ntohs(p->udph->uh_sport);
+                    orig_p->dp = ntohs(p->udph->uh_dport);
+                    orig_p->udph = udph;
+                }
+
+                TextLog_Print(log, "\n** ORIGINAL DATAGRAM DUMP:\n");
+                LogIPHeader(log, orig_p);
+
+                if(udph != NULL)
                     TextLog_Print(log, "Len: %d  Csum: %d\n",
                             ntohs(orig_p->udph->uh_len) - UDP_HEADER_LEN,
                             ntohs(orig_p->udph->uh_chk));
                 break;
+            }
 
             case IPPROTO_ICMP:
-                if(orig_p->icmph != NULL)
-                    LogEmbeddedICMPHeader(log, orig_p->icmph);
+            {
+                TextLog_Print(log, "\n** ORIGINAL DATAGRAM DUMP:\n");
+                LogIPHeader(log, orig_p);
+
+                const icmp::ICMPHdr* icmph = layer::get_icmp_embed_icmp(p);
+                if(icmph != NULL)
+                    LogEmbeddedICMPHeader(log, icmph);
                 break;
+            }
 
             default:
+                TextLog_Print(log, "\n** ORIGINAL DATAGRAM DUMP:\n");
+                LogIPHeader(log, orig_p);
+
                 TextLog_Print(log, "Protocol: 0x%X (unknown or "
                         "header truncated)", GET_IPH_PROTO(orig_p));
                 break;
         }       /* switch */
 
         /* if more than 8 bytes of original IP payload sent */
+        uint32_t orig_ip_hlen = p->ip_api.hlen() << 2;
         if (p->dsize - orig_ip_hlen > 8)
         {
             TextLog_Print(log, "(%d more bytes of original packet)\n",
index ff73f936b16a413978b41027d8436871f93fac29..4ad8fbe60eeca177787306a2b778f2a8ca81a85b 100644 (file)
@@ -195,6 +195,8 @@ SnortConfig * SnortConfNew(void)
     set_ips_policy(sc->get_ips_policy());
     set_network_policy(sc->get_network_policy());
 
+    sc->max_encapsulations = -1;
+
     return sc;
 }
 
@@ -465,6 +467,9 @@ SnortConfig * MergeSnortConfs(SnortConfig *cmd_line, SnortConfig *config_file)
     if ( cmd_line->remote_control )
         config_file->remote_control = cmd_line->remote_control;
 
+    if ( cmd_line->max_encapsulations )
+        config_file->max_encapsulations = cmd_line->max_encapsulations;
+
     // config file vars are stored differently
     // FIXIT should config_file and cmd_line use the same var list / table?
     config_file->var_list = NULL;
index 6c0e7cfe0ae2317e7f42e7de3c6be99d9f64dba2..5187c02e7655cb9a164941aad1c7252d741926ca 100644 (file)
@@ -160,8 +160,8 @@ static const uint8_t* encode_packet(
     enc->p = 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);
+    if ( ip::is_ipv4(*(enc->ip_hdr)))
+        enc->ip_len = ip::get_pkt_len((IPHdr*) enc->ip_hdr);
     else if ( ipv6::is_ip6_hdr_ver((ipv6::IP6RawHdr*)(enc->ip_hdr)))
         enc->ip_len = sizeof(ipv6::IP6RawHdr);
     else
@@ -207,7 +207,7 @@ static bool api_instantiated(const CodecApi* cd_api)
         std::find(s_codecs.begin(), s_codecs.end(), cd_api);
 
     if (p == s_codecs.end())
-        FatalError("PacketManager:: should never reach this code!!" \
+        FatalError("PacketManager:: should never reach this code!!"
                     "Cannot find Codec %s's api", cd_api->base.name);
 
     int pos = p - s_codecs.begin();
@@ -409,6 +409,8 @@ void PacketManager::decode(
 
     // initialize all of the relevent data to decode this packet
     memset(p, 0, PKT_ZERO_LEN);
+    p->ip_api.reset();
+
     p->pkth = pkthdr;
     p->pkt = pkt;
     len = pkthdr->caplen;
@@ -418,6 +420,11 @@ 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))
     {
+        DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Codec %s (protocol_id: %u:"
+                "ip header starts at: %p, length is %lu\n",
+                s_protocols[mapped_prot]->get_name(), prot_id, pkt,
+                (unsigned long) len););
+
         // 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 )
@@ -440,6 +447,12 @@ void PacketManager::decode(
         lyr_len = 0;
     }
 
+    DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Codec %s (protocol_id: %hu: ip header"
+                    " starts at: %p, length is %lu\n",
+                     s_protocols[mapped_prot]->get_name(),
+                     prot_id, pkt, (unsigned long) len););
+
+
     // if the final protocol ID is not the default codec, a Codec failed
     if (prev_prot_id != FINISHED_DECODE)
     {
@@ -452,7 +465,7 @@ void PacketManager::decode(
                 s_stats[other_codecs]++;
         }
 
-        if (p->decode_flags & DECODE__ESP)
+        if (p->decode_flags & DECODE__TRUST_ON_FAIL)
             p->packet_flags |= PKT_TRUST;
     }
 
index 70df31d13e16aa054d4030ee386b653b8bd82e9e..3dcda9011bfbf92f20b657106d30834f283d4c30 100644 (file)
@@ -126,8 +126,6 @@ public:
     {
         encode_set_pkt(NULL);
     }
-
 };
 
 #endif
-
index 60a3ebfdcf98f00c991c072d0991b62c5489b435..0124cf41793abc6b9fb861297935c8460b85bac7 100644 (file)
@@ -176,7 +176,9 @@ 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));
+
+    if (p->proto_bits & PROTO_BIT__VLAN)
+        uint16_t vlan = vlan::vth_vlan(layer::get_vlan_layer(p));
 
     for ( i = 0; i < sz; i++ )
     {
index 4bd82f73195daf4fe36b6f37e82ec17be0e40159..f2c4ebb8ed5cc3dc5b4ec0df1a762e45a0699582 100644 (file)
@@ -1,6 +1,6 @@
 /****************************************************************************
  *
-** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+ * Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
  * Copyright (C) 2005-2013 Sourcefire, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
@@ -220,10 +220,10 @@ static int Norm_IP4 (
             changes++;
         }
     }
-    if ( p->layers[layer].length > IP_HEADER_LEN )
+    if ( p->layers[layer].length > ip::IP4_HEADER_LEN )
     {
-        uint8_t* opts = p->layers[layer].start + IP_HEADER_LEN;
-        uint8_t len = p->layers[layer].length - IP_HEADER_LEN;
+        uint8_t* opts = p->layers[layer].start + ip::IP4_HEADER_LEN;
+        uint8_t len = p->layers[layer].length - ip::IP4_HEADER_LEN;
         // expect len > 0 because IHL yields a multiple of 4
         memset(opts, IPOPT_NOP, len);
         normStats[PC_IP4_OPTS]++;
@@ -241,9 +241,9 @@ static int Norm_ICMP4 (
     ICMPHdr* h = (ICMPHdr*)(p->layers[layer].start);
 
     if ( (h->type == ICMP_ECHO || h->type == ICMP_ECHOREPLY) &&
-         (h->code != icmp4::IcmpCode::ECHO_CODE) )
+         (h->code != icmp::IcmpCode::ECHO_CODE) )
     {
-        h->code =  icmp4::IcmpCode::ECHO_CODE;
+        h->code =  icmp::IcmpCode::ECHO_CODE;
         normStats[PC_ICMP4_ECHO]++;
         sfBase.iPegs[PERF_COUNT_ICMP4_ECHO]++;
         changes++;
@@ -283,7 +283,7 @@ static int Norm_ICMP6 (
           (uint16_t)h->type == icmp6::Icmp6Types::REPLY) &&
          (h->code != 0) )
     {
-        h->code = static_cast<icmp4::IcmpCode>(0);
+        h->code = static_cast<icmp::IcmpCode>(0);
         normStats[PC_ICMP6_ECHO]++;
         sfBase.iPegs[PERF_COUNT_ICMP6_ECHO]++;
         changes++;
@@ -344,7 +344,7 @@ static inline void NopDaOpt (uint8_t* opt, uint8_t len)
 
 static inline int Norm_TCPOptions (
     NormalizerConfig* config,
-    uint8_t* opts, size_t len, const TCPHdr* h, uint8_t numOpts, int changes)
+    uint8_t* opts, size_t len, const tcp::TCPHdr* h, uint8_t numOpts, int changes)
 {
     size_t i = 0;
     uint8_t c = 0;
@@ -433,7 +433,7 @@ static inline int Norm_TCPPadding (
 static int Norm_TCP (
     NormalizerConfig* c, Packet * p, uint8_t layer, int changes)
 {
-    TCPHdr* h = (TCPHdr*)(p->layers[layer].start);
+    tcp::TCPHdr* h = (tcp::TCPHdr*)(p->layers[layer].start);
 
     if ( h->th_offx2 & TH_RSV )
     {
index a59ed8a14a75fdd2549fa6e6d727d2d2e8169994..249f641ed76aedebd524aa8b073fb78f19f890e4 100644 (file)
@@ -575,7 +575,7 @@ int PortScan::ps_get_proto(PS_PKT *ps_pkt, int *proto)
                 || ((p->icmph != NULL) && (p->icmph->type == ICMP_DEST_UNREACH)
                     && ((p->icmph->code == ICMP_PORT_UNREACH)
                         || (p->icmph->code == ICMP_PKT_FILTERED))
-                    && (p->orig_tcph != NULL)))
+                    && (p->proto_bits & PROTO_BIT__TCP_EMBED_ICMP)))
         {
             *proto = PS_PROTO_TCP;
             return 0;
@@ -588,7 +588,7 @@ int PortScan::ps_get_proto(PS_PKT *ps_pkt, int *proto)
                 || ((p->icmph != NULL) && (p->icmph->type == ICMP_DEST_UNREACH)
                     && ((p->icmph->code == ICMP_PORT_UNREACH)
                         || (p->icmph->code == ICMP_PKT_FILTERED))
-                    && (p->orig_udph != NULL)))
+                    && (p->proto_bits & PROTO_BIT__UDP_EMBED_ICMP)))
         {
             *proto = PS_PROTO_UDP;
             return 0;
index 22f1afc78e624a66972e18655d3f365d33b1a386..6b4229c2a67dcd2b66c28dbf361e15dfc797be7b 100644 (file)
@@ -5,6 +5,8 @@ set (PROTOCOL_HEADERS
     eth.h
     icmp4.h
     icmp6.h
+    ip.cc
+    ip.h
     ipv4.h
     ipv6.h
     gre.h
index 76180e5e2ff87cb5e888c9b23cb73532e87e8613..9991874a9f0e909bde9e211543e14e7a89153806 100644 (file)
@@ -10,6 +10,8 @@ eapol.h \
 eth.h \
 icmp4.h \
 icmp6.h \
+ip.h \
+ip.cc \
 ipv4.h \
 ipv6.h \
 gre.h \
index 171afcb90cb799a316c14753cb9532cae1e0bc3c..0c48700b2abebad3d41e08f01b87921c43481b2f 100644 (file)
@@ -26,7 +26,7 @@
 #include "main/snort_types.h"
 #include "protocols/ipv4.h"
 
-namespace icmp4
+namespace icmp
 {
 
 namespace detail
@@ -176,7 +176,7 @@ struct ICMPHdr
         /* IP header for unreach */
         struct ih_ip
         {
-            ipv4::IPHdr *ip;
+            ip::IPHdr *ip;
             /* options and then 64 bits of data */
         } ip;
 
@@ -224,12 +224,12 @@ static inline uint8_t unreach_data()
     return detail::ICMP_UNREACH_DATA;
 }
 
-} //namespace icmp4
+} //namespace icmp
 
 
 
-typedef icmp4::ICMPbaseHdr ICMPbaseHdr;
-typedef icmp4::ICMPHdr ICMPHdr;
+typedef icmp::ICMPbaseHdr ICMPbaseHdr;
+typedef icmp::ICMPHdr ICMPHdr;
 
 #ifndef ICMP_ECHOREPLY
 const uint8_t ICMP_ECHOREPLY = 0;    /* Echo Reply                   */
diff --git a/src/protocols/ip.cc b/src/protocols/ip.cc
new file mode 100644 (file)
index 0000000..74e69be
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+** Copyright (C) 2007-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.
+*/
+// ip.cc author Josh Rosenbaum <jrosenba@cisco.com>
+
+#include "protocols/ip.h"
+#include "protocols/packet.h"
+
+namespace ip
+{
+
+void IpApi::reset()
+{
+    ip4h = nullptr;
+    ip6h = nullptr;
+    src_p = nullptr;
+    dst_p = nullptr;
+}
+
+void IpApi::set(const IPHdr* h4)
+{
+    ip4h = h4;
+    ip6h = nullptr;
+    src_p = nullptr;
+    dst_p = nullptr;
+}
+
+void IpApi::set(const ipv6::IP6RawHdr* h6)
+{
+    ip6h = h6;
+    ip4h = nullptr;
+    src_p = nullptr;
+    dst_p = nullptr;
+}
+
+bool IpApi::set(const uint8_t* raw_ip_data)
+{
+    const IPHdr* h4 = reinterpret_cast<const IPHdr*>(raw_ip_data);
+    if (h4->get_ver() == 4)
+    {
+        set(h4);
+        return true;
+    }
+
+    const ipv6::IP6RawHdr* h6 =
+        reinterpret_cast<const ipv6::IP6RawHdr*>(raw_ip_data);
+
+    if (h6->get_ver() != 6)
+        return false;
+
+    set(h6);
+    return true;
+}
+
+const sfip_t* IpApi::get_src()
+{
+    if (src_p)
+        return src_p;
+
+    if(ip4h)
+    {
+        src.family = AF_INET;
+        src.bits = 32;
+
+        // TODO:  Make this a pointer rather than copying
+        //          will likely need to change Snort++
+        src.ip32[0] = *(uint32_t*)(&ip4h->ip_src);
+        std::memset(&(src.ip32[1]), 0, 12);
+    }
+    else if (ip6h)
+    {
+        src.family = AF_INET6;
+        src.bits = 128;
+
+        std::memcpy(&(src.ip8), &(ip6h->ip6_src), 16);
+    }
+    else
+    {
+        return nullptr;
+    }
+
+    src_p = &src;
+    return src_p;
+}
+
+
+const sfip_t* IpApi::get_dst()
+{
+    if (dst_p)
+        return dst_p;
+
+    if(ip4h)
+    {
+        dst.family = AF_INET;
+        dst.bits = 32;
+
+        // TODO:  Make this a pointer rather than copying
+        //          will likely need to change Snort++
+        dst.ip32[0] = *(uint32_t*)(&ip4h->ip_dst);
+        std::memset(&(dst.ip32[1]), 0, 12);
+    }
+    else if (ip6h)
+    {
+        dst.family = AF_INET6;
+        dst.bits = 128;
+        std::memcpy(&(dst.ip8), &(ip6h->ip6_dst), 16);
+    }
+    else
+    {
+        return nullptr;
+    }
+
+    dst_p = &dst;
+    return dst_p;
+
+}
+
+uint32_t IpApi::id(const Packet* const p)
+{
+    if (ip4h)
+        return ip4h->get_id();
+
+    // ensure we have an ipv6 frag
+    if (p->ip6_extension_count == 0 || p->ip_frag_start == 0)
+        return 0;
+
+    const IP6Frag* const frag_hdr = reinterpret_cast<const IP6Frag* const>(
+            p->ip6_extensions[p->ip6_frag_index].data);
+
+    return frag_hdr->get_id();
+}
+
+uint16_t IpApi::off(const Packet* const p)
+{
+    if (ip4h)
+        return ip4h->get_id();
+
+    // ensure we have an ipv6 frag
+    if (p->ip6_extension_count == 0 || p->ip_frag_start == 0)
+        return 0;
+
+    const IP6Frag* const frag_hdr = reinterpret_cast<const IP6Frag* const>(
+            p->ip6_extensions[p->ip6_frag_index].data);
+
+    return frag_hdr->get_off();
+}
+
+
+} // namespace protocols
diff --git a/src/protocols/ip.h b/src/protocols/ip.h
new file mode 100644 (file)
index 0000000..e032f0b
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+**
+** 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.
+*/
+
+// ip.h author Josh Rosenbaum <jrosenba@cisco.com>
+
+#ifndef WIN32
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#else /* !WIN32 */
+#include <netinet/in_systm.h>
+#ifndef IFNAMSIZ
+#define IFNAMESIZ MAX_ADAPTER_NAME
+#endif /* !IFNAMSIZ */
+#endif /* !WIN32 */
+
+#include <cstring>
+
+#include "protocols/ipv4.h"
+#include "protocols/ipv6.h"
+#include "sfip/sfip_t.h"
+
+#ifndef IP_H
+#define IP_H
+
+class Packet;
+
+namespace ip
+{
+
+// keeping this as a class to avoid confusion.
+class IpApi
+{
+public:
+//    IpApi();   constructor and destructor MUST remain a trivial. Adding
+//    ~IpApi();  any non-trivial code will cause a compilation failure.
+
+    void set(const IPHdr* h4);
+    void set(const ipv6::IP6RawHdr* h6);
+    bool set(const uint8_t* raw_ip_data);
+    void reset();
+    const sfip_t* get_src();
+    const sfip_t* get_dst();
+    uint32_t id(const Packet* const p);
+    uint16_t off(const Packet* const p);
+
+
+    inline uint16_t tos()
+    { return ip4h ? ip4h->get_tos() : ip6h ? ip6h->get_tos() : 0; }
+
+    inline uint8_t ttl()
+    { return ip4h ? ip4h->get_ttl() : ip6h ? ip6h->get_hop_lim() : 0; }
+
+    inline uint8_t proto()
+    { return ip4h ? ip4h->get_proto() : ip6h ? ip6h->get_next() : 0; }
+
+    inline uint16_t len()
+    { return ip4h ? ip4h->get_len() : ip6h ? ip6h->get_len() : 0; }
+
+    inline uint8_t hlen()
+    { return ip4h ? ip4h->get_hlen() : ip6h ? ip6h->get_hlen() : 0; }
+
+    inline uint8_t ver()
+    { return ip4h ? ip4h->get_ver() : ip6h ? ip6h->get_ver() : 0; }
+
+
+private:
+    sfip_t src;
+    sfip_t dst;
+    const sfip_t* src_p;
+    const sfip_t* dst_p;
+    const IPHdr* ip4h;
+    const ipv6::IP6RawHdr* ip6h;
+};
+
+} // namespace ip
+
+#endif
index d015401c9be274685cbe961c6f37beda5c47aaef..04474d20561a5b49a9dd02d8988e1f4ddc411cf0 100644 (file)
@@ -19,9 +19,6 @@
 */
 
 
-#ifndef IPV4_H
-#define IPV4_H
-
 #include <cstdint>
 
 
 #include "sfip/sfip_t.h"
 #include "protocols/protocol_ids.h" // include ipv4 protocol numbers
 
+
+
+#ifndef IPV4_H
+#define IPV4_H
+
 #define ETHERNET_TYPE_IP 0x0800
 
 #ifndef IP_MAXPACKET
 #endif /* IP_MAXPACKET */
 
 
-namespace ipv4
+namespace ip
 {
 
 namespace detail
 {
 /* ip option type codes */
-const uint32_t IP4_THIS_NET  = 0x00;  // msb
-const uint32_t IP4_MULTICAST = 0x0E;  // ms nibble
-const uint32_t IP4_RESERVED = 0x0F;  // ms nibble
-const uint32_t IP4_LOOPBACK = 0x7F;  // msb
-const uint32_t IP4_BROADCAST = 0xffffffff;
-const uint8_t IP_HEADER_LEN = 20;
+constexpr uint32_t IP4_THIS_NET  = 0x00;  // msb
+constexpr uint32_t IP4_MULTICAST = 0x0E;  // ms nibble
+constexpr uint32_t IP4_RESERVED = 0x0F;  // ms nibble
+constexpr uint32_t IP4_LOOPBACK = 0x7F;  // msb
+constexpr uint32_t IP4_BROADCAST = 0xffffffff;
 } // namespace detail
 
+// not included in details since this should not be hidden
+constexpr uint8_t IP4_HEADER_LEN = 20;
 
 
 enum class IPOptionCodes : std::uint8_t {
@@ -83,6 +86,15 @@ struct IpOptions
     uint8_t code;
     uint8_t len; /* length of the data section */
     const uint8_t *data;
+
+    inline bool is_opt_rtralt() const
+    { return code == static_cast<uint8_t>(IPOptionCodes::RTRALT); }
+
+    inline bool is_opt_ts() const
+    { return code == static_cast<uint8_t>(IPOptionCodes::TS); }
+
+    inline bool is_opt_rr() const
+    { return code == static_cast<uint8_t>(IPOptionCodes::RR); }
 };
 
 // This must be a standard layour struct!
@@ -96,8 +108,41 @@ struct IPHdr
     uint8_t ip_ttl;        /* time to live field */
     uint8_t ip_proto;      /* datagram protocol */
     uint16_t ip_csum;      /* checksum */
-    struct in_addr ip_src;  /* source IP */
-    struct in_addr ip_dst;  /* dest IP */
+    in_addr ip_src;        /* source IP */
+    in_addr ip_dst;        /* dest IP */
+
+    inline uint8_t get_hlen() const
+    { return ip_verhl & 0x0f; }
+
+    inline uint8_t get_ver() const
+    { return ((ip_verhl & 0xf0) >> 4); }
+
+    inline uint8_t get_tos() const
+    { return ip_tos; };
+
+    inline uint16_t get_len() const
+    { return ip_len; }
+
+    inline uint32_t get_id() const
+    { return (uint32_t)ip_id; }
+
+    inline uint16_t get_off() const
+    { return ip_off; }
+
+    inline uint8_t get_ttl() const
+    { return ip_ttl; }
+
+    inline uint8_t get_proto() const
+    { return ip_proto; }
+
+    inline uint16_t get_csum() const
+    { return ip_csum; }
+
+    inline const in_addr* get_src() const
+    { return &ip_src; }
+
+    inline const in_addr* get_dst() const
+    { return &ip_dst; }
 } ;
 
 
@@ -138,17 +183,6 @@ static inline bool isPrivateIP(uint32_t addr)
     return false;
 }
 
-
-static inline uint16_t prot_id()
-{
-    return IPPROTO_ID_IPIP;
-}
-
-static inline int ethertype_ip()
-{
-    return ETHERTYPE_IPV4;
-}
-
 static inline bool is_broadcast(uint32_t addr)
 { 
     return (addr == detail::IP4_BROADCAST);
@@ -159,51 +193,6 @@ static inline bool is_multicast(uint8_t addr)
     return (addr == detail::IP4_MULTICAST);
 }
 
-static inline bool is_opt_rr(IPOptionCodes code)
-{
-    return (code == IPOptionCodes::RR);
-}
-
-static inline bool is_opt_rr(uint8_t code)
-{
-    return (static_cast<IPOptionCodes>(code) == IPOptionCodes::RR);
-}
-
-static inline bool is_opt_rtralt(IPOptionCodes code)
-{
-    return (code == IPOptionCodes::RTRALT);
-}
-
-static inline bool is_opt_rtralt(uint8_t code)
-{
-    return (static_cast<IPOptionCodes>(code) == IPOptionCodes::RTRALT);
-}
-
-static inline bool is_opt_ts(IPOptionCodes code)
-{
-    return (code == IPOptionCodes::TS);
-}
-
-static inline bool is_opt_ts(uint8_t code)
-{
-    return (static_cast<IPOptionCodes>(code) == IPOptionCodes::TS);
-}
-
-static inline bool is_ethertype_ip(int proto)
-{
-    return (proto == ETHERTYPE_IPV4);
-}
-
-static inline bool is_ipv4(IPHdr* p)
-{
-    return (p->ip_verhl >> 4) == 4;
-}
-
-static inline bool is_ipv4(const IP4Hdr* p)
-{
-    return (p->ip_verhl >> 4)  == 4;
-}
-
 static inline bool is_ipv4(uint8_t ch)
 {
     return (ch >> 4)  == 4;
@@ -229,11 +218,6 @@ static inline uint8_t get_version(IP4Hdr* p)
     return (p->ip_verhl & 0xf0) >> 4;
 }
 
-static inline uint8_t hdr_len()
-{
-    return detail::IP_HEADER_LEN;
-}
-
 static inline bool is_loopback(uint8_t addr)
 {
     return addr == detail::IP4_LOOPBACK;
@@ -269,31 +253,31 @@ static inline void set_hlen(IP4Hdr* p, uint8_t value)
     p->ip_verhl = (unsigned char)(((p)->ip_verhl & 0xf0) | (value & 0x0f));
 }
 
-} /* namespace ipv4 */
+} /* namespace ip */
 
 /* tcpdump shows us the way to cross platform compatibility */
 
 /* we need to change them as well as get them */
 // TYPEDEF WHICH NEED TO BE DELETED
 
-typedef ipv4::IPHdr IPHdr;
-typedef ipv4::IP4Hdr IP4Hdr;
+typedef ip::IPHdr IPHdr;
+typedef ip::IP4Hdr IP4Hdr;
 
 
-const uint8_t IPOPT_EOL = 0x00;
-const uint8_t IPOPT_NOP = 0x01;
-const uint8_t IPOPT_RR = 0x07;
-const uint8_t IPOPT_TS = 0x44;
-const uint8_t IPOPT_SECURITY = 0x82;
-const uint8_t IPOPT_LSRR = 0x83;
-const uint8_t IPOPT_LSRR_E = 0x84;
-const uint8_t IPOPT_ESEC = 0x85;
-const uint8_t IPOPT_SATID = 0x88;
-const uint8_t IPOPT_SSRR = 0x89;
-const uint8_t IPOPT_RTRALT = 0x94;
-const uint8_t IPOPT_ANY = 0xff;
+constexpr uint8_t IPOPT_EOL = 0x00;
+constexpr uint8_t IPOPT_NOP = 0x01;
+constexpr uint8_t IPOPT_RR = 0x07;
+constexpr uint8_t IPOPT_TS = 0x44;
+constexpr uint8_t IPOPT_SECURITY = 0x82;
+constexpr uint8_t IPOPT_LSRR = 0x83;
+constexpr uint8_t IPOPT_LSRR_E = 0x84;
+constexpr uint8_t IPOPT_ESEC = 0x85;
+constexpr uint8_t IPOPT_SATID = 0x88;
+constexpr uint8_t IPOPT_SSRR = 0x89;
+constexpr uint8_t IPOPT_RTRALT = 0x94;
+constexpr uint8_t IPOPT_ANY = 0xff;
 
-#define IP_HEADER_LEN ipv4::hdr_len()
+/* #define IP_HEADER_LEN ip::ip4_hdr_len() */
 
 
 #endif
index ff2ea5e767abe4fdd739528c80a9cf75202e1188..d431836943bfac40fc5734bfa2a6d929223575c0 100644 (file)
@@ -43,11 +43,9 @@ namespace ipv6
 
 namespace detail
 {
-const uint16_t ETHERNET_TYPE_IPV6 = 0x86dd;
-const uint16_t IPV6_PROT_ID = 41;
-const uint8_t IP6_HEADER_LEN = 40;
-const uint8_t IP6_MULTICAST = 0xFF;  // first/most significant octet
-const uint32_t MIN_EXT_LEN = 8;
+constexpr uint8_t IP6_HEADER_LEN = 40;
+constexpr uint8_t IP6_MULTICAST = 0xFF;  // first/most significant octet
+constexpr uint32_t MIN_EXT_LEN = 8;
 } // namespace
 
 
@@ -108,7 +106,13 @@ struct IP6Frag
     uint8_t   ip6f_reserved;    /* reserved field */
     uint16_t  ip6f_offlg;   /* offset, reserved, and flag */
     uint32_t  ip6f_ident;   /* identification */
-} ;
+
+    inline uint32_t get_id() const
+    { return ip6f_ident; }
+
+    inline uint16_t get_off() const
+    { return ip6f_offlg; }
+};
 
 
 struct IP6RawHdr
@@ -119,10 +123,40 @@ struct IP6RawHdr
     uint8_t  ip6_next;                /* next header */
     uint8_t  ip6_hoplim;               /* hop limit */
 
-    struct in6_addr ip6_src;      /* source address */
-    struct in6_addr ip6_dst;      /* destination address */
+    in6_addr ip6_src;      /* source address */
+    in6_addr ip6_dst;      /* destination address */
+
+    inline const in6_addr* get_src() const
+    { return &ip6_src; }
+
+    inline const in6_addr* get_dst() const
+    { return &ip6_dst; }
+
+    inline uint16_t get_tos() const
+    { return (uint16_t)((ntohl(ip6_vtf) & 0x0FF00000) >> 20); }
+
+    inline uint8_t get_hop_lim() const
+    { return ip6_hoplim; }
+
+    inline uint16_t get_len() const
+    { return ip6_payload_len; }
+
+    inline uint8_t get_next() const
+    { return ip6_next; }
+
+    inline uint8_t get_ver() const
+    { return (uint8_t)(ntohl(ip6_vtf) >> 28); }
+
+    inline uint8_t get_hdr_len() const
+    { return (uint8_t) detail::IP6_HEADER_LEN; }
+
+    // becaise Snort expects this in terms of 32 bit words.
+    inline uint8_t get_hlen() const
+    { return detail::IP6_HEADER_LEN / 4; }
+
 };
 
+
 struct IP6Hdr
 {
     uint32_t vcl;      /* version, class, and label */
@@ -166,16 +200,6 @@ inline uint8_t hdr_len()
     return detail::IP6_HEADER_LEN;
 }
 
-inline uint16_t ethertype()
-{
-    return detail::ETHERNET_TYPE_IPV6;
-}
-
-inline uint16_t prot_id()
-{
-    return detail::IPV6_PROT_ID;
-}
-
 inline bool is_multicast(uint8_t addr)
 {
     return addr == detail::IP6_MULTICAST;
index fd7ff92069c14d8e79066cc8a7b43b0aee4b4785..973657b0d60a76c390f6ec8ac6f3096875eb0337 100644 (file)
 
 
 #include "protocols/packet.h"
+#include "protocols/layer.h"
 #include "protocols/ipv4.h"
 #include "protocols/ipv6.h"
+#include "protocols/ip.h"
 
 namespace layer
 {
 
-static inline const uint8_t *find_layer(const Layer *lyr,
+static inline const uint8_t* find_outer_layer(const Layer* lyr,
                                 uint8_t num_layers,
                                 uint16_t prot_id)
 {
-    for(int i = num_layers - 1; i >= 0 ; i--)
+    for(int i = 0; i < num_layers ; i++)
     {
         if (lyr->prot_id == prot_id)
             return lyr->start;
@@ -40,28 +42,55 @@ static inline const uint8_t *find_layer(const Layer *lyr,
     return nullptr;
 }
 
-static inline const uint8_t *find_layer(const Layer *lyr,
+static inline const uint8_t* find_inner_layer(const Layer* lyr,
+                                uint8_t num_layers,
+                                uint16_t prot_id)
+{
+    int tmp = num_layers-1;
+    lyr = &lyr[tmp];
+
+    for(int i = tmp; i >= 0 ; i--)
+    {
+        if (lyr->prot_id == prot_id)
+            return lyr->start;
+        lyr--;
+    }
+    return nullptr;
+}
+
+static inline const uint8_t* find_inner_layer(const Layer* lyr,
                                 uint8_t num_layers,
                                 uint16_t prot_id1,
                                 uint16_t prot_id2)
 {
+    int tmp = num_layers-1;
+    lyr = &lyr[tmp];
+
     for(int i = num_layers - 1; i >= 0; i--)
     {
         if (lyr->prot_id == prot_id1 ||
             lyr->prot_id == prot_id2)
             return lyr->start;
-        lyr++;
+        lyr--;
     }
     return nullptr;
 }
 
+
+const uint8_t* get_inner_layer(const Packet* p, uint16_t proto)
+{ return find_inner_layer(p->layers, p->num_layers, proto); }
+
+const uint8_t* get_outer_layer(const Packet* p, uint16_t proto)
+{ return find_outer_layer(p->layers, p->num_layers, proto); }
+
+
 const arp::EtherARP* get_arp_layer(const Packet* const p)
 {
     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));
+        find_inner_layer(lyr, num_layers, ETHERTYPE_ARP, ETHERTYPE_REVARP));
 }
 
 const gre::GREHdr* get_gre_layer(const Packet* const p)
@@ -70,7 +99,7 @@ const gre::GREHdr* get_gre_layer(const Packet* const p)
     const Layer *lyr = p->layers;
 
     return reinterpret_cast<const gre::GREHdr*>(
-        find_layer(lyr, num_layers, IPPROTO_ID_GRE));
+        find_inner_layer(lyr, num_layers, IPPROTO_ID_GRE));
 }
 
 const eapol::EtherEapol* get_eapol_layer(const Packet* const p)
@@ -79,7 +108,7 @@ const eapol::EtherEapol* get_eapol_layer(const Packet* const p)
     const Layer *lyr = p->layers;
 
     return reinterpret_cast<const eapol::EtherEapol*>(
-            find_layer(lyr, num_layers, ETHERTYPE_EAPOL));
+        find_inner_layer(lyr, num_layers, ETHERTYPE_EAPOL));
 }
 
 const vlan::VlanTagHdr* get_vlan_layer(const Packet* const p)
@@ -88,7 +117,7 @@ const vlan::VlanTagHdr* get_vlan_layer(const Packet* const p)
     const Layer *lyr = p->layers;
 
     return reinterpret_cast<const vlan::VlanTagHdr*>(
-        find_layer(lyr, num_layers, ETHERTYPE_8021Q));
+        find_inner_layer(lyr, num_layers, ETHERTYPE_8021Q));
 }
 
 const eth::EtherHdr* get_eth_layer(const Packet* const p)
@@ -98,7 +127,7 @@ const eth::EtherHdr* get_eth_layer(const Packet* const p)
 
     // First, search for the inner eth layer (transbridging)
     const eth::EtherHdr* eh = reinterpret_cast<const eth::EtherHdr*>(
-        find_layer(lyr, num_layers, ETHERTYPE_TRANS_ETHER_BRIDGING));
+        find_inner_layer(lyr, num_layers, ETHERTYPE_TRANS_ETHER_BRIDGING));
 
     // if no inner eth layer, assume root layer is eth (callers job to confirm)
     return eh ? eh : reinterpret_cast<const eth::EtherHdr*>(get_root_layer(p));
@@ -155,4 +184,62 @@ int get_inner_ip_lyr(const Packet* const p)
     return -1;
 }
 
+bool set_api_ip_embed_icmp(Packet* const p)
+{ return set_api_ip_embed_icmp(p, p->ip_api); }
+
+bool set_api_ip_embed_icmp(const Packet* p, ip::IpApi& api)
+{
+    int num_layers = p->num_layers - 1;
+    const Layer* lyr = &p->layers[num_layers];
+
+    for(int i = num_layers; i >= 0; i--)
+    {
+        if (lyr->prot_id == IP_EMBEDDED_IN_ICMP4)
+        {
+            const ip::IPHdr* ip4h =
+                reinterpret_cast<const ip::IPHdr*>(lyr->start);
+            api.set(ip4h);
+            return true;
+        }
+        else if (lyr->prot_id == IP_EMBEDDED_IN_ICMP6)
+        {
+            const ipv6::IP6RawHdr* ip6h =
+                reinterpret_cast<const ipv6::IP6RawHdr*>(lyr->start);
+            api.set(ip6h);
+            return true;
+        }
+
+        lyr--;
+    }
+
+    api.reset();
+    return false;
+}
+
+const uint8_t* get_prot_embed_icmp(const Packet* const p)
+{
+    return find_inner_layer(p->layers,
+                            p->num_layers,
+                            PROT_EMBEDDED_IN_ICMP);
+}
+
+const tcp::TCPHdr* get_tcp_embed_icmp(const Packet* const p)
+{
+    return reinterpret_cast<const tcp::TCPHdr*>(
+        get_prot_embed_icmp(p));
+}
+
+const udp::UDPHdr* get_udp_embed_icmp(const Packet* const p)
+{
+    return reinterpret_cast<const udp::UDPHdr*>(
+        get_prot_embed_icmp(p));
+}
+
+const icmp::ICMPHdr* get_icmp_embed_icmp(const Packet* const p)
+{
+    return reinterpret_cast<const icmp::ICMPHdr*>(
+        get_prot_embed_icmp(p));
+}
+
+
 } // namespace layer
index e76a0b6efbbae75453a49116c094170c7cb056ae..120c5b00f9943362d95046dbb7bbb95c951e40c7 100644 (file)
@@ -26,7 +26,6 @@
 #include "codecs/sf_protocols.h"
 
 
-
 struct Layer {
     uint16_t prot_id;
     PROTO_ID proto;
@@ -63,12 +62,33 @@ namespace eth
 struct EtherHdr;
 }
 
+namespace ip
+{
+class IpApi;
+}
+
+namespace tcp
+{
+struct TCPHdr;
+}
+
+namespace udp
+{
+struct UDPHdr;
+}
+
+namespace icmp
+{
+struct ICMPHdr;
+}
 
 namespace layer
 {
 
 // all of these functions will begin search from layer 0,
 // and will return the first function they find.
+const uint8_t* get_inner_layer(const Packet*, uint16_t proto);
+const uint8_t* get_outer_layer(const Packet*, uint16_t proto);
 
 
 const arp::EtherARP* get_arp_layer(const Packet*);
@@ -78,6 +98,27 @@ 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);
 
+
+// ICMP with Embedded IP layer
+
+
+// Sets the Packet's api to be the IP layer which is
+// embedded inside an ICMP layer.
+// RETURN:
+//          true - ip layer found and api set
+//          false - ip layer NOT found, api reset
+bool set_api_ip_embed_icmp(const Packet*);
+bool set_api_ip_embed_icmp(const Packet*, ip::IpApi& api);
+
+// When a protocol is embedded in ICMP, this function
+// will return a pointer to the layer.  Use the
+// proto_bits to determine what this layer is!
+const uint8_t* get_prot_embed_icmp(const Packet* const);
+const tcp::TCPHdr* get_tcp_embed_icmp(const Packet* const);
+const udp::UDPHdr* get_udp_embed_icmp(const Packet* const);
+const icmp::ICMPHdr* get_icmp_embed_icmp(const Packet* const);
+
+
 int get_inner_ip_lyr(const Packet* const p);
 uint16_t get_outer_ip_next_proto(const Packet* const);
 
index 18658da004fe78c1eda7d7024b6e358d223b00df..9b61517dd17e7afaec7a37bdd07f942494989f00 100644 (file)
@@ -62,6 +62,7 @@ extern "C" {
 #include "protocols/icmp4.h"
 #include "protocols/icmp6.h"
 #include "protocols/mpls.h"
+#include "protocols/ip.h"
 
 /*  D E F I N E S  ************************************************************/
 
@@ -147,15 +148,15 @@ enum PseudoPacketType{
 #define DEFAULT_MPLS_PAYLOADTYPE      MPLS_PAYLOADTYPE_IPV4
 #define DEFAULT_LABELCHAIN_LENGTH    -1
 
-const int32_t MAX_PORTS = 65536;
-const uint16_t NUM_IP_PROTOS = 256;
-const int16_t SFTARGET_UNKNOWN_PROTOCOL = -1;
-const uint8_t IP_OPTMAX = 40;
-const uint8_t TCP_OPTLENMAX = 40; /* (((2^4) - 1) * 4  - TCP_HEADER_LEN) */
-const uint8_t IP6_EXTMAX = 8;
-const uint8_t MIN_TTL = 64;
-const uint8_t MAX_TTL = 255;
-const uint8_t LAYER_MAX = 32;
+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 MIN_TTL = 64;
+constexpr uint8_t MAX_TTL = 255;
+constexpr uint8_t LAYER_MAX = 32;
 
 
 
@@ -181,13 +182,13 @@ struct Packet
 
     //vvv-----------------------------
 
-    const IPHdr *iph, *orig_iph;/* and orig. headers for ICMP_*_UNREACH family */
+    const IPHdr *iph;
     const IPHdr *inner_iph;     /* if IP-in-IP, this will be the inner IP header */
     const IPHdr *outer_iph;     /* if IP-in-IP, this will be the outer IP header */
-    const TCPHdr *tcph, *orig_tcph;
-    const udp::UDPHdr *udph, *orig_udph;
+    const tcp::TCPHdr *tcph;
+    const udp::UDPHdr *udph;
     const udp::UDPHdr *outer_udph;   /* if Teredo + UDP, this will be the outer UDP header */
-    const ICMPHdr *icmph, *orig_icmph;
+    const ICMPHdr *icmph;
 
     const uint8_t *data;        /* packet payload pointer */
     const uint8_t *ip_data;     /* IP payload pointer */
@@ -197,16 +198,13 @@ struct Packet
     Flow* flow;   /* for session tracking */
 
     //vvv-----------------------------
-    ipv4::IP4Hdr *ip4h;
+    ip::IP4Hdr *ip4h;
     ipv6::IP6Hdr *ip6h;
-    icmp6::ICMP6Hdr *icmp6h;
 
     IPH_API* iph_api;
-    IPH_API* orig_iph_api;
     IPH_API* outer_iph_api;
 
     int family;
-    int orig_family;
     int outer_family;
     //^^^-----------------------------
 
@@ -231,8 +229,6 @@ struct Packet
     //vvv-----------------------------
     uint16_t sp;                /* source port (TCP/UDP) */
     uint16_t dp;                /* dest port (TCP/UDP) */
-    uint16_t orig_sp;           /* source port (TCP/UDP) of original datagram */
-    uint16_t orig_dp;           /* dest port (TCP/UDP) of original datagram */
     //^^^-----------------------------
     // and so on ...
 
@@ -252,7 +248,7 @@ struct Packet
     const DAQ_PktHdr_t *pkth;    // packet meta data
     const uint8_t *pkt;         // raw packet data
 
-    ipv4::IpOptions ip_options[IP_OPTMAX];         /* ip options decode structure */
+    ip::IpOptions ip_options[IP_OPTMAX];         /* ip options decode structure */
     Options tcp_options[TCP_OPTLENMAX];    /* tcp options decode struct */
     IP6Option ip6_extensions[IP6_EXTMAX];  /* IPv6 Extension References */
 
@@ -265,10 +261,11 @@ struct Packet
     const ipv6::IP6RawHdr* raw_ip6h;  // innermost raw ip6 header
     Layer layers[LAYER_MAX];    /* decoded encapsulations */
 
-    ipv4::IP4Hdr inner_ip4h;
+    ip::IP4Hdr inner_ip4h;
     ipv6::IP6Hdr inner_ip6h;
-    ipv4::IP4Hdr outer_ip4h;
+    ip::IP4Hdr outer_ip4h;
     ipv6::IP6Hdr outer_ip6h;
+    ip::IpApi ip_api;
 
     MplsHdr mplsHdr;
 
@@ -300,7 +297,10 @@ struct Packet
 #define PROTO_BIT__MPLS     0x0080
 #define PROTO_BIT__VLAN     0x0100
 #define PROTO_BIT__ETH      0x0200
-#define PROTO_BIT__FREE     0x7c00
+#define PROTO_BIT__TCP_EMBED_ICMP  0x0400
+#define PROTO_BIT__UDP_EMBED_ICMP  0x0800
+#define PROTO_BIT__ICMP_EMBED_ICMP 0x1000
+#define PROTO_BIT__FREE     0x6000
 #define PROTO_BIT__OTHER    0x8000
 #define PROTO_BIT__ALL      0xffff
 
@@ -309,9 +309,9 @@ struct Packet
 #define DECODE__MF      0x02  /* more fragments flag */
 #define DECODE__DF      0x04  /* don't fragment flag */
 #define DECODE__RF      0x08  /* IP reserved bit */
-#define DECODE__ESP     0x10  /* flag to indicate an ESP layer has been seen */
-#define DECODE__UNSURE_ENCAP 0x20 /* packet may have incorrect encapsulation layer. */
-                                  /* don't alert if "next layer" is invalid. */
+#define DECODE__TRUST_ON_FAIL 0x10  /* if decode fails, set the PKT_TRUST flag */
+#define DECODE__UNSURE_ENCAP  0x20  /* packet may have incorrect encapsulation layer. */
+                                    /* don't alert if "next layer" is invalid. */
 #define DECODE__FREE    0xC0
 
 #define IsIP(p) (IPH_IS_VALID(p))
index 03dce3d0ef9927e2e1c58029187ed29ee436d9ef..da795f386f87882063a565787b060694b566771f 100644 (file)
  * http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
  */
 
-const uint16_t IPPROTO_ID_HOPOPTS = 0;
-const uint16_t IPPROTO_ID_ICMPV4 = 1;
-const uint16_t IPPROTO_ID_IPIP = 4;
-const uint16_t IPPROTO_ID_IPV6 = 41;
-const uint16_t IPPROTO_ID_ROUTING = 43;
-const uint16_t IPPROTO_ID_FRAGMENT = 44;
-const uint16_t IPPROTO_ID_GRE = 47;
-const uint16_t IPPROTO_ID_ESP = 50;
-const uint16_t IPPROTO_ID_AH = 51; // RFC 4302
-const uint16_t IPPROTO_ID_ICMPV6 = 58;
-const uint16_t IPPROTO_ID_NONEXT = 59;
-const uint16_t IPPROTO_ID_DSTOPTS = 60;
+constexpr uint16_t IPPROTO_ID_HOPOPTS = 0;
+constexpr uint16_t IPPROTO_ID_ICMPV4 = 1;
+constexpr uint16_t IPPROTO_ID_IPIP = 4;
+constexpr uint16_t IPPROTO_ID_IPV6 = 41;
+constexpr uint16_t IPPROTO_ID_ROUTING = 43;
+constexpr uint16_t IPPROTO_ID_FRAGMENT = 44;
+constexpr uint16_t IPPROTO_ID_GRE = 47;
+constexpr uint16_t IPPROTO_ID_ESP = 50;
+constexpr uint16_t IPPROTO_ID_AH = 51; // RFC 4302
+constexpr uint16_t IPPROTO_ID_ICMPV6 = 58;
+constexpr uint16_t IPPROTO_ID_NONEXT = 59;
+constexpr uint16_t IPPROTO_ID_DSTOPTS = 60;
 
 
 /*
  *  Undefined Protocol!
  */
 
-const uint16_t FINISHED_DECODE = 0x0100;  // Indicates Codecs have succesfully decoded packet
-const uint16_t PROTOCOL_TEREDO = 0x0101;
-const uint16_t PROTOCOL_GTP = 0x0102;
+constexpr uint16_t FINISHED_DECODE = 0x0100;  // Indicates Codecs have succesfully decoded packet
+constexpr uint16_t PROTOCOL_TEREDO = 0x0101;
+constexpr uint16_t PROTOCOL_GTP = 0x0102;
+constexpr uint16_t IP_EMBEDDED_IN_ICMP4 = 0x0103;
+constexpr uint16_t IP_EMBEDDED_IN_ICMP6 = 0x0104;
+constexpr uint16_t PROT_EMBEDDED_IN_ICMP = 0x0105;
 
 
 
@@ -81,17 +84,15 @@ const uint16_t PROTOCOL_GTP = 0x0102;
  */
 
 
-const uint16_t ETHERTYPE_TRANS_ETHER_BRIDGING = 0x6558;
-const uint16_t ETHERTYPE_IPV4 = 0x0800;
-const uint16_t ETHERTYPE_REVARP = 0x8035;
-const uint16_t ETHERTYPE_ARP = 0x0806;
-const uint16_t ETHERTYPE_8021Q = 0x8100;
-const uint16_t ETHERTYPE_IPX = 0x8137;
-const uint16_t ETHERTYPE_IPV6 = 0x86dd;
-const uint16_t ETHERTYPE_PPP = 0x880B;
-const uint16_t ETHERTYPE_EAPOL = 0x888e;
+constexpr uint16_t ETHERTYPE_TRANS_ETHER_BRIDGING = 0x6558;
+constexpr uint16_t ETHERTYPE_IPV4 = 0x0800;
+constexpr uint16_t ETHERTYPE_REVARP = 0x8035;
+constexpr uint16_t ETHERTYPE_ARP = 0x0806;
+constexpr uint16_t ETHERTYPE_8021Q = 0x8100;
+constexpr uint16_t ETHERTYPE_IPX = 0x8137;
+constexpr uint16_t ETHERTYPE_IPV6 = 0x86dd;
+constexpr uint16_t ETHERTYPE_PPP = 0x880B;
+constexpr uint16_t ETHERTYPE_EAPOL = 0x888e;
 
 
 #endif
-
-
index 300b85a826ea94625017b046ddfe5d3e6264cdb5..48a5e845a33a38b9583b0444cc911ebdf3f52b0a 100644 (file)
@@ -79,7 +79,7 @@ namespace tcp
 namespace detail
 {
 
-const uint8_t TCP_HEADER_LEN = 20;
+constexpr uint8_t TCP_HEADER_LEN = 20;
 
 } // namespace detail
 
@@ -261,7 +261,5 @@ inline void set_tcp_x2(TCPHdr* tcph, uint8_t value)
 
 #define TCP_HEADER_LEN tcp::hdr_len()
 
-#define TCPHdr tcp::TCPHdr
-
 
 #endif /* TCP_H */
index 85f67cb62ac4c46103a91bbc2ad22b39d8800d07..a9d78b971d74d46b9d529226b38eb8fc788945d5 100644 (file)
@@ -42,9 +42,6 @@ typedef sfip_t *snort_ip_p;
 #define GET_SRC_IP(p) ((p)->iph_api->iph_ret_src(p))
 #define GET_DST_IP(p) ((p)->iph_api->iph_ret_dst(p))
 
-#define GET_ORIG_SRC(p) ((p)->orig_iph_api->orig_iph_ret_src(p))
-#define GET_ORIG_DST(p) ((p)->orig_iph_api->orig_iph_ret_dst(p))
-
 /* These are here for backwards compatibility */
 #define GET_SRC_ADDR(x) GET_SRC_IP(x)
 #define GET_DST_ADDR(x) GET_DST_IP(x)
@@ -68,12 +65,19 @@ typedef sfip_t *snort_ip_p;
 #define GET_IPH_VER(p)   (p)->iph_api->iph_ret_ver(p)
 #define GET_IPH_PROTO(p) ((uint8_t)(IS_IP6(p) ? ((p)->ip6h->next) : ((p)->iph_api->iph_ret_proto(p))))
 
+
+#if 0
+
+#define GET_ORIG_SRC(p) ((p)->orig_iph_api->orig_iph_ret_src(p))
+#define GET_ORIG_DST(p) ((p)->orig_iph_api->orig_iph_ret_dst(p))
 #define GET_ORIG_IPH_PROTO(p)   (p)->orig_iph_api->orig_iph_ret_proto(p)
 #define GET_ORIG_IPH_VER(p)     (p)->orig_iph_api->orig_iph_ret_ver(p)
 #define GET_ORIG_IPH_LEN(p)     (p)->orig_iph_api->orig_iph_ret_len(p)
 #define GET_ORIG_IPH_OFF(p)     (p)->orig_iph_api->orig_iph_ret_off(p)
 #define GET_ORIG_IPH_PROTO(p)   (p)->orig_iph_api->orig_iph_ret_proto(p)
 
+#endif
+
 /* XXX make sure these aren't getting confused with sfip_is_valid within the code */
 #define IPH_IS_VALID(p) iph_is_valid(p)
 
index 2591bdb532e19b0a3fd0029c34ee02f888de2ae4..1ed500092dde1098e35a916a86ea9406fd5c3a94 100644 (file)
@@ -308,10 +308,12 @@ uint8_t ip4_ret_ver(const Packet *p)
     return (p->iph->ip_verhl & 0xf0) >> 4;
 }
 
+#if 0
 uint8_t orig_ip4_ret_ver(const Packet *p)
 {
     return (p->orig_iph->ip_verhl & 0xf0) >> 4;
 }
+#endif
 
 uint8_t ip4_ret_hlen(const Packet *p)
 {
@@ -320,7 +322,8 @@ uint8_t ip4_ret_hlen(const Packet *p)
 
 uint8_t orig_ip4_ret_hlen(const Packet *p)
 {
-    return p->orig_iph->ip_verhl & 0x0f;
+    return 0;
+//    return p->orig_iph->ip_verhl & 0x0f;
 }
 
 uint8_t ip6_ret_hlen(const Packet*)
@@ -346,7 +349,7 @@ IPH_API ip4 =
    ip4_ret_off,
    ip4_ret_ver,
    ip4_ret_hlen,
-
+#if 0
    orig_ip4_ret_src,
    orig_ip4_ret_dst,
    orig_ip4_ret_tos,
@@ -357,7 +360,7 @@ IPH_API ip4 =
    orig_ip4_ret_off,
    orig_ip4_ret_ver,
    orig_ip4_ret_hlen,
-
+#endif
    IPH_API_V4
 };
 
@@ -373,7 +376,7 @@ IPH_API ip6 =
    ip6_ret_off,
    ip6_ret_ver,
    ip6_ret_hlen,
-
+#if 0
    orig_ip6_ret_src,
    orig_ip6_ret_dst,
    orig_ip6_ret_toc,
@@ -384,7 +387,7 @@ IPH_API ip6 =
    orig_ip6_ret_off,
    orig_ip6_ret_ver,
    orig_ip6_ret_hlen,
-
+#endif
    IPH_API_V6
 };
 
@@ -399,15 +402,6 @@ static inline void _set_callbacks(Packet* p, int family, char orig)
 
         p->family = family;
     }
-    else
-    {
-        if(family == AF_INET)
-            p->orig_iph_api = &ip4;
-        else
-            p->orig_iph_api = &ip6;
-
-        p->orig_family = family;
-    }
 }
 
 void set_callbacks(Packet* p, int family, char orig)
index 23e3f191a0178c703ea884ea6c247004ecdf8034..62bfa3653807d58df7d17f27412df4e5e83f160f 100644 (file)
@@ -39,6 +39,7 @@ typedef struct _IPH_API
     uint8_t    (*iph_ret_ver)(const Packet*);
     uint8_t    (*iph_ret_hlen)(const Packet*);
 
+#if 0
     sfip_t *   (*orig_iph_ret_src)(const Packet*);
     sfip_t *   (*orig_iph_ret_dst)(const Packet*);
     uint16_t   (*orig_iph_ret_tos)(const Packet*);
@@ -49,7 +50,7 @@ typedef struct _IPH_API
     uint16_t   (*orig_iph_ret_off)(const Packet*);
     uint8_t    (*orig_iph_ret_ver)(const Packet*);
     uint8_t    (*orig_iph_ret_hlen)(const Packet*);
-
+#endif
     char ver;
 } IPH_API;
 
@@ -63,7 +64,6 @@ extern IPH_API ip6;
 #define NO_IP 0
 
 void sfiph_build(Packet*, const void *hdr, int family);
-void sfiph_orig_build(Packet*, const void *hdr, int family);
 
 /* Sets the callbacks to point at the family selected by
  *  * "family".  "family" is either AF_INET or AF_INET6 */
index c36177ee340e37f71367e53b9e4bd7b5807e6b39..8017150f0009043c863079d3b49c2c04a841498b 100644 (file)
@@ -42,6 +42,7 @@
 #include "profiler.h"
 #include "protocols/layer.h"
 #include "protocols/vlan.h"
+#include "protocols/ip.h"
 
 THREAD_LOCAL SessionStats icmpStats;
 THREAD_LOCAL ProfileStats icmp_perf_stats;
@@ -74,26 +75,45 @@ static int ProcessIcmpUnreach(Packet *p)
 {
     /* Handle ICMP unreachable */
     FlowKey skey;
-    Flow *ssn = NULL;
+    Flowssn = NULL;
     uint16_t sport;
     uint16_t dport;
-    sfip_t *src;
-    sfip_t *dst;
+    const sfip_t* src;
+    const sfip_t* dst;
+    ip::IpApi iph;
 
-    /* No "orig" IP Header */
-    if (!p->orig_iph)
+    /* Set the Ip API to the embedded IP Header. */
+    if (!layer::set_api_ip_embed_icmp(p, iph))
         return 0;
 
-    /* Get TCP/UDP/ICMP session from original protocol/port info
-     * embedded in the ICMP Unreach message.  This is already decoded
-     * in p->orig_foo.  TCP/UDP ports are decoded as p->orig_sp/dp.
+    /* Get IP/TCP/UDP/ICMP session from original protocol/port info
+     * embedded in the ICMP Unreach message.
      */
-    skey.protocol = GET_ORIG_IPH_PROTO(p);
-    sport = p->orig_sp;
-    dport = p->orig_dp;
+    skey.protocol = iph.proto();
+    src = iph.get_src();
+    dst = iph.get_dst();
+
+
+    if (p->proto_bits & PROTO_BIT__TCP_EMBED_ICMP)
+    {
+        const tcp::TCPHdr* tcph = layer::get_tcp_embed_icmp(p);
+        sport = ntohs(tcph->th_sport);
+        dport = ntohs(tcph->th_dport);
+    }
+    else if (p->proto_bits & PROTO_BIT__UDP_EMBED_ICMP)
+    {
+        const udp::UDPHdr* udph = layer::get_udp_embed_icmp(p);
+
+        sport = ntohs(udph->uh_sport);
+        dport = ntohs(udph->uh_dport);
+    }
+    else
+    {
+        sport = 0;
+        dport = 0;
+    }
+
 
-    src = GET_ORIG_SRC(p);
-    dst = GET_ORIG_DST(p);
 
     if (sfip_fast_lt6(src, dst))
     {
@@ -102,7 +122,7 @@ static int ProcessIcmpUnreach(Packet *p)
         COPY4(skey.ip_h, dst->ip32);
         skey.port_h = dport;
     }
-    else if (IP_EQUALITY(GET_ORIG_SRC(p), GET_ORIG_DST(p)))
+    else if (IP_EQUALITY(iph.get_src(), iph.get_dst()))
     {
         COPY4(skey.ip_l, src->ip32);
         COPY4(skey.ip_h, skey.ip_l);
index b71e5a4b78a890137aa987fb194b42dcf95cb30e..0ecea051b36bdecbe1ce9dca071c3b9b9bd12c81 100644 (file)
@@ -916,7 +916,7 @@ static void FragRebuild(FragTracker *ft, Packet *p)
             DEBUG_WRAP(DebugMessage(DEBUG_FRAG,
                     "Adjusting IP Header to %d bytes\n",
                     new_ip_hlen););
-            ipv4::set_hlen((IPHdr *)dpkt->iph, new_ip_hlen>>2);
+            ip::set_hlen((IPHdr *)dpkt->iph, new_ip_hlen>>2);
 
             ret = SafeMemcpy(rebuild_ptr, ft->ip_options_data,
                 ft->ip_options_len, rebuild_ptr, rebuild_end);
index 70cf2e631d6fabf4c38f8e91556c73f2aeb977d6..9d6ce60222a17044a60dd351b722318b81170991 100644 (file)
@@ -85,6 +85,8 @@
 #include "tcp_module.h"
 #include "stream/stream_splitter.h"
 
+using namespace tcp;
+
 THREAD_LOCAL ProfileStats s5TcpPerfStats;
 THREAD_LOCAL ProfileStats s5TcpNewSessPerfStats;
 THREAD_LOCAL ProfileStats s5TcpStatePerfStats;