Skip past Shim6, HIP and Mobility header.
Detect data after 'none' header.
decode-event:ipv6.data_after_none_header;
alert ipv6 any any -> any any (msg:"SURICATA zero length padN option"; decode-event:ipv6.zero_len_padn; sid:2200094; rev:1;)
# Frag Header 'length' field is reserved and should be 0
alert ipv6 any any -> any any (msg:"SURICATA reserved field in Frag Header not zero"; decode-event:ipv6.fh_non_zero_reserved_field; sid:2200095; rev:1;)
+# Data after the 'none' header (59) is suspicious.
+alert ipv6 any any -> any any (msg:"SURICATA data after none (59) header"; decode-event:ipv6.data_after_none_header; sid:2200096; rev:1;)
alert ipv6 any any -> any any (msg:"SURICATA IPv6 with ICMPv4 header"; decode-event:ipv6.icmpv4; sid:2200090; rev:1;)
alert pkthdr any any -> any any (msg:"SURICATA ICMPv4 packet too small"; decode-event:icmpv4.pkt_too_small; sid:2200023; rev:1;)
alert pkthdr any any -> any any (msg:"SURICATA ICMPv4 unknown type"; decode-event:icmpv4.unknown_type; sid:2200024; rev:1;)
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 2200096
+# next sid is 2200097
IPV6_EXTHDR_RH_TYPE_0, /**< RH 0 is deprecated as per rfc5095 */
IPV6_EXTHDR_ZERO_LEN_PADN, /**< padN w/o data (0 len) */
IPV6_FH_NON_ZERO_RES_FIELD, /**< reserved field not zero */
+ IPV6_DATA_AFTER_NONE_HEADER, /**< data after 'none' (59) header */
IPV6_WITH_ICMPV4, /**< IPv6 packet with ICMPv4 header */
SCEnter();
uint8_t *orig_pkt = pkt;
- uint8_t nh;
+ uint8_t nh = 0; /* careful, 0 is actually a real type */
uint16_t hdrextlen;
uint16_t plen;
char dstopts = 0;
while(1)
{
+ /* No upper layer, but we do have data. Suspicious. */
+ if (nh == IPPROTO_NONE && plen > 0) {
+ ENGINE_SET_EVENT(p, IPV6_DATA_AFTER_NONE_HEADER);
+ SCReturn;
+ }
+
if (plen < 2) { /* minimal needed in a hdr */
SCReturn;
}
IPV6_SET_L4PROTO(p,nh);
DecodeIPv4inIPv6(tv, dtv, p, pkt, plen, pq);
SCReturn;
+ /* none, last header */
case IPPROTO_NONE:
IPV6_SET_L4PROTO(p,nh);
SCReturn;
case IPPROTO_ICMP:
ENGINE_SET_EVENT(p,IPV6_WITH_ICMPV4);
SCReturn;
+ /* no parsing yet, just skip it */
+ case IPPROTO_MH:
+ case IPPROTO_HIP:
+ case IPPROTO_SHIM6:
+ hdrextlen = 8 + (*(pkt+1) * 8); /* 8 bytes + length in 8 octet units */
+ if (hdrextlen > plen) {
+ ENGINE_SET_EVENT(p, IPV6_TRUNC_EXTHDR);
+ SCReturn;
+ }
+ nh = *pkt;
+ pkt += hdrextlen;
+ plen -= hdrextlen;
+ break;
default:
IPV6_SET_L4PROTO(p,nh);
SCReturn;
case IPPROTO_DSTOPTS:
case IPPROTO_AH:
case IPPROTO_ESP:
+ case IPPROTO_MH:
+ case IPPROTO_HIP:
+ case IPPROTO_SHIM6:
DecodeIPV6ExtHdrs(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
break;
case IPPROTO_ICMP:
#define IPPROTO_SCTP 132
#endif
+#ifndef IPPROTO_MH
+#define IPPROTO_MH 135
+#endif
+
+/* Host Identity Protocol (rfc 5201) */
+#ifndef IPPROTO_HIP
+#define IPPROTO_HIP 139
+#endif
+
+#ifndef IPPROTO_SHIM6
+#define IPPROTO_SHIM6 140
+#endif
+
/* pcap provides this, but we don't want to depend on libpcap */
#ifndef DLT_EN10MB
#define DLT_EN10MB 1
{ "ipv6.rh_type_0", IPV6_EXTHDR_RH_TYPE_0, },
{ "ipv6.zero_len_padn", IPV6_EXTHDR_ZERO_LEN_PADN, },
{ "ipv6.fh_non_zero_reserved_field", IPV6_FH_NON_ZERO_RES_FIELD, },
+ { "ipv6.data_after_none_header", IPV6_DATA_AFTER_NONE_HEADER, },
{ "ipv6.icmpv4", IPV6_WITH_ICMPV4, },
/* TCP EVENTS */