# 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
/* 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,
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)
{
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:
{ "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, },