]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #947 in SNORT/snort3 from icmp6 to master
authorRuss Combs (rucombs) <rucombs@cisco.com>
Sun, 9 Jul 2017 19:33:28 +0000 (15:33 -0400)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Sun, 9 Jul 2017 19:33:28 +0000 (15:33 -0400)
Squashed commit of the following:

commit b44fab9650238404e622cd1dfeea84ffd3308e89
Author: Russ Combs <rucombs@cisco.com>
Date:   Fri Jul 7 14:23:53 2017 -0400

    icmp6: remove ip4 cruft from decoder

commit f3a75c0d7e46e7f9b6ca0a42f178c3e5190c5ba4
Author: Russ Combs <rucombs@cisco.com>
Date:   Thu Jul 6 18:56:55 2017 -0400

    icmp6: reject non-ip6, raise 116:474

src/codecs/codec_module.h
src/codecs/ip/cd_icmp6.cc

index bb45c9fd54a8493beab8030595bd4c6a31676694..f75a1db2946dc0da07f42718898d94de884d4e05 100644 (file)
@@ -209,6 +209,7 @@ enum CodecSid : uint32_t
     DECODE_CISCO_META_HDR_SGT,
     DECODE_TOO_MANY_LAYERS,
     DECODE_BAD_ETHER_TYPE,
+    DECODE_ICMP6_NOT_IP6,
     DECODE_INDEX_MAX
 };
 
index 6ec3a0dc8e48145786b5b29b55d877728349050e..537aa76e906f5dda5ca1a743c40cd12d51d48682 100644 (file)
@@ -39,14 +39,12 @@ namespace
 {
 const PegInfo pegs[]
 {
-    { "bad_icmp4_checksum", "nonzero ipcm4 checksums" },
-    { "bad_icmp6_checksum", "nonzero ipcm6 checksums" },
+    { "bad_icmp6_checksum", "nonzero icmp6 checksums" },
     { nullptr, nullptr }
 };
 
 struct Stats
 {
-    PegCount bad_ip4_cksum;
     PegCount bad_ip6_cksum;
 };
 
@@ -54,7 +52,7 @@ static THREAD_LOCAL Stats stats;
 
 static const RuleMap icmp6_rules[] =
 {
-    { DECODE_ICMP6_HDR_TRUNC, "truncated ICMP6 header" },
+    { DECODE_ICMP6_HDR_TRUNC, "truncated ICMPv6 header" },
     { DECODE_ICMP6_TYPE_OTHER, "ICMPv6 type not decoded" },
     { DECODE_ICMP6_DST_MULTICAST, "ICMPv6 packet to multicast address" },
     { DECODE_ICMPV6_TOO_BIG_BAD_MTU,
@@ -73,6 +71,7 @@ static const RuleMap icmp6_rules[] =
       "ICMPv6 packet of type 1 (destination unreachable) with non-RFC 4443 code" },
     { DECODE_ICMPV6_NODE_INFO_BAD_CODE,
       "ICMPv6 node info query/response packet with a code greater than 2" },
+    { DECODE_ICMP6_NOT_IP6, "ICMPv6 not encapsulated in IPv6" },
     { 0, nullptr }
 };
 
@@ -117,38 +116,28 @@ bool Icmp6Codec::decode(const RawData& raw, CodecData& codec, DecodeData& snort)
         return false;
     }
 
+    if ( !snort.ip_api.get_ip6h() /* FIXIT-L && verify prior layer == ip6 */ )
+    {
+        codec_event(codec, DECODE_ICMP6_NOT_IP6);
+        return false;
+    }
+
     const icmp::Icmp6Hdr* const icmp6h = reinterpret_cast<const icmp::Icmp6Hdr*>(raw.data);
 
-    /* Do checksums */
-    if (SnortConfig::icmp_checksums())
+    if ( SnortConfig::icmp_checksums() )
     {
-        uint16_t csum;
-        PegCount* bad_cksum_cnt;
+        checksum::Pseudoheader6 ph6;
+        COPY4(ph6.sip, snort.ip_api.get_src()->get_ip6_ptr());
+        COPY4(ph6.dip, snort.ip_api.get_dst()->get_ip6_ptr());
+        ph6.zero = 0;
+        ph6.protocol = codec.ip6_csum_proto;
+        ph6.len = htons((u_short)raw.len);
+
+        uint16_t csum = checksum::icmp_cksum((uint16_t*)(icmp6h), raw.len, &ph6);
 
-        if (snort.ip_api.is_ip4())
-        {
-            bad_cksum_cnt = &stats.bad_ip4_cksum;
-            csum = checksum::cksum_add((uint16_t*)(icmp6h), raw.len);
-        }
-        /* IPv6 traffic */
-        else
-        {
-            // make sure we have a valid header
-            assert(snort.ip_api.get_ip6h());
-
-            bad_cksum_cnt = &stats.bad_ip6_cksum;
-            checksum::Pseudoheader6 ph6;
-            COPY4(ph6.sip, snort.ip_api.get_src()->get_ip6_ptr());
-            COPY4(ph6.dip, snort.ip_api.get_dst()->get_ip6_ptr());
-            ph6.zero = 0;
-            ph6.protocol = codec.ip6_csum_proto;
-            ph6.len = htons((u_short)raw.len);
-
-            csum = checksum::icmp_cksum((uint16_t*)(icmp6h), raw.len, &ph6);
-        }
         if (csum && !codec.is_cooked())
         {
-            (*bad_cksum_cnt)++;
+            stats.bad_ip6_cksum++;
             snort.decode_flags |= DECODE_ERR_CKSUM_ICMP;
             return false;
         }