Add support for IPv4-in-IPv6

This patch adds support for IPv4-in-IPv6 and should fix #462.
pull/23/head
Eric Leblond 13 years ago
parent 2c57275921
commit 09fa0b9542

@ -86,5 +86,9 @@ alert tcp any any -> any any (msg:"SURICATA TCPv6 invalid checksum"; tcpv6-csum:
alert udp any any -> any any (msg:"SURICATA UDPv6 invalid checksum"; udpv6-csum:invalid; sid:2200078; rev:1;)
alert icmp any any -> any any (msg:"SURICATA ICMPv6 invalid checksum"; icmpv6-csum:invalid; sid:2200079; rev:1;)
# next sid is 2200082
# 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;)
# next sid is 2200084

@ -192,6 +192,10 @@ enum {
IPV6_FRAG_PKT_TOO_LARGE,
IPV6_FRAG_OVERLAP,
/* IPv4 in IPv6 events */
IPV4_IN_IPV6_PKT_TOO_SMALL,
IPV4_IN_IPV6_WRONG_IP_VER,
/* should always be last! */
DECODE_EVENT_MAX,
};

@ -45,6 +45,32 @@
#define IPV6_EXTHDRS ip6eh.ip6_exthdrs
#define IPV6_EH_CNT ip6eh.ip6_exthdrs_cnt
/**
* \brief Function to decode IPv4 in IPv6 packets
*
*/
static void DecodeIPv4inIPv6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t plen, PacketQueue *pq)
{
if (unlikely(plen < IPV4_HEADER_LEN)) {
ENGINE_SET_EVENT(p, IPV4_IN_IPV6_PKT_TOO_SMALL);
return;
}
if (IP_GET_RAW_VER(pkt) == 4) {
if (pq != NULL) {
Packet *tp = PacketPseudoPktSetup(p, pkt, plen, IPPROTO_IP);
if (tp != NULL) {
DecodeTunnel(tv, dtv, tp, pkt, plen, pq, IPPROTO_IP);
PacketEnqueue(pq,tp);
return;
}
}
} else {
ENGINE_SET_EVENT(p, IPV4_IN_IPV6_WRONG_IP_VER);
}
return;
}
static void
DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
{
@ -403,6 +429,10 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
plen -= hdrextlen;
break;
}
case IPPROTO_IPIP:
IPV6_SET_L4PROTO(p,nh);
DecodeIPv4inIPv6(tv, dtv, p, pkt, plen, pq);
SCReturn;
case IPPROTO_NONE:
IPV6_SET_L4PROTO(p,nh);
SCReturn;
@ -482,6 +512,9 @@ void DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
case IPPROTO_SCTP:
IPV6_SET_L4PROTO (p, IPPROTO_SCTP);
return DecodeSCTP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), 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_FRAGMENT:
case IPPROTO_HOPOPTS:
case IPPROTO_ROUTING:
@ -491,6 +524,7 @@ void DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
case IPPROTO_ESP:
DecodeIPV6ExtHdrs(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
break;
default:
p->proto = IPV6_GET_NH(p);
break;

@ -116,6 +116,8 @@ struct DetectEngineEvents_ {
{ "ipv4.frag_overlap", IPV4_FRAG_OVERLAP, },
{ "ipv6.frag_too_large", IPV6_FRAG_PKT_TOO_LARGE, },
{ "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, },
{ "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, },

Loading…
Cancel
Save