]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
decode: decode IPv6-in-IPv6
authorEric Leblond <eric@regit.org>
Wed, 8 Aug 2012 14:21:27 +0000 (16:21 +0200)
committerVictor Julien <victor@inliniac.net>
Thu, 23 Aug 2012 07:13:04 +0000 (09:13 +0200)
This patch adds decoding of IPv6-in-IPv6. It also adds some events
for invalid packets.

This patch should fix #514.

rules/decoder-events.rules
src/decode-events.h
src/decode-ipv6.c
src/detect-engine-event.h

index 1299e41a30523ac260fee3907b85aee3c7c6f2d6..6ced87942f39d7ba5ba941dda4b88496fb4eb966 100644 (file)
@@ -89,6 +89,9 @@ alert icmp any any -> any any (msg:"SURICATA ICMPv6 invalid checksum"; icmpv6-cs
 # IPv4 in IPv6 rules
 alert pkthdr any any -> any any (msg:"SURICATA IPv4-in-IPv6 packet too short"; decode-event:ipv6.ipv4_in_ipv6_too_small; sid:2200082; rev:1;)
 alert pkthdr any any -> any any (msg:"SURICATA IPv4-in-IPv6 invalid protocol"; decode-event:ipv6.ipv4_in_ipv6_wrong_version; sid:2200083; rev:1;)
+# IPv6 in IPv6 rules
+alert pkthdr any any -> any any (msg:"SURICATA IPv6-in-IPv6 packet too short"; decode-event:ipv6.ipv6_in_ipv6_too_small; sid:2200084; rev:1;)
+alert pkthdr any any -> any any (msg:"SURICATA IPv6-in-IPv6 invalid protocol"; decode-event:ipv6.ipv6_in_ipv6_wrong_version; sid:2200085; rev:1;)
 
-# next sid is 2200084
+# next sid is 2200086
 
index 0c7983d501f3781b4e0ceb69ed2a775b0265fbc6..89f8422444dc12d4597529e67cd43a5fd203788c 100644 (file)
@@ -200,6 +200,9 @@ enum {
     /* IPv4 in IPv6 events */
     IPV4_IN_IPV6_PKT_TOO_SMALL,
     IPV4_IN_IPV6_WRONG_IP_VER,
+    /* IPv6 in IPv6 events */
+    IPV6_IN_IPV6_PKT_TOO_SMALL,
+    IPV6_IN_IPV6_WRONG_IP_VER,
 
     /* should always be last! */
     DECODE_EVENT_MAX,
index 826dba5e230c5e79d0dc4b9b32c1e9eca4bb9b28..be003afc110f371ea267a71dcfa49bf085585705 100644 (file)
@@ -71,6 +71,32 @@ static void DecodeIPv4inIPv6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, u
     return;
 }
 
+/**
+ * \brief Function to decode IPv4 in IPv6 packets
+ *
+ */
+static void DecodeIP6inIP6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t plen, PacketQueue *pq)
+{
+
+    if (unlikely(plen < IPV6_HEADER_LEN)) {
+        ENGINE_SET_EVENT(p, IPV6_IN_IPV6_PKT_TOO_SMALL);
+        return;
+    }
+    if (IP_GET_RAW_VER(pkt) == 6) {
+        if (pq != NULL) {
+            Packet *tp = PacketPseudoPktSetup(p, pkt, plen, IPPROTO_IPV6);
+            if (tp != NULL) {
+                DecodeTunnel(tv, dtv, tp, pkt, plen, pq, IPPROTO_IPV6);
+                PacketEnqueue(pq,tp);
+                return;
+            }
+        }
+    } else {
+        ENGINE_SET_EVENT(p, IPV6_IN_IPV6_WRONG_IP_VER);
+    }
+    return;
+}
+
 static void
 DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
 {
@@ -515,6 +541,8 @@ void DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
         case IPPROTO_IPIP:
             IPV6_SET_L4PROTO(p, IPPROTO_IPIP);
             return DecodeIPv4inIPv6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
+        case IPPROTO_IPV6:
+            return DecodeIP6inIP6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
         case IPPROTO_FRAGMENT:
         case IPPROTO_HOPOPTS:
         case IPPROTO_ROUTING:
index 9d719b84bda8f9fdad2d436da5d434c121fcd4c9..f8034f96f099500209c76c26c075cf74b8b7c999 100644 (file)
@@ -118,6 +118,8 @@ struct DetectEngineEvents_ {
     { "ipv6.frag_overlap", IPV6_FRAG_OVERLAP, },
     { "ipv6.ipv4_in_ipv6_too_small", IPV4_IN_IPV6_PKT_TOO_SMALL, },
     { "ipv6.ipv4_in_ipv6_wrong_version", IPV4_IN_IPV6_WRONG_IP_VER, },
+    { "ipv6.ipv6_in_ipv6_too_small", IPV6_IN_IPV6_PKT_TOO_SMALL, },
+    { "ipv6.ipv6_in_ipv6_wrong_version", IPV6_IN_IPV6_WRONG_IP_VER, },
     { "stream.3whs_ack_in_wrong_dir", STREAM_3WHS_ACK_IN_WRONG_DIR, },
     { "stream.3whs_async_wrong_seq", STREAM_3WHS_ASYNC_WRONG_SEQ, },
     { "stream.3whs_right_seq_wrong_ack_evasion", STREAM_3WHS_RIGHT_SEQ_WRONG_ACK_EVASION, },