From 516ca7ead5606d76ed457d5421ba676377ebbbb2 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Sun, 26 Jul 2009 21:19:27 +0200 Subject: [PATCH] Fix IPv4 and IPv6 decoders not being able to deal with ethernet packets with trailing bytes. --- src/decode-ipv4.c | 10 +++++----- src/decode-ipv4.h | 12 ++++++------ src/decode-ipv6.c | 13 +++++++++---- src/decode-ipv6.h | 14 +++++++------- 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/decode-ipv4.c b/src/decode-ipv4.c index 83f3a2353b..812ad16a2d 100644 --- a/src/decode-ipv4.c +++ b/src/decode-ipv4.c @@ -87,19 +87,19 @@ void DecodeIPV4(ThreadVars *t, Packet *p, u_int8_t *pkt, u_int16_t len, PacketQu /* check PPP VJ uncompressed packets and decode tcp dummy */ if(p->ppph != NULL && ntohs(p->ppph->protocol) == PPP_VJ_UCOMP) { - return(DecodeTCP(t, p, pkt + IPV4_GET_HLEN(p), len - IPV4_GET_HLEN(p))); + return(DecodeTCP(t, p, pkt + IPV4_GET_HLEN(p), IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p))); } break; case IPPROTO_TCP: - return(DecodeTCP(t, p, pkt + IPV4_GET_HLEN(p), len - IPV4_GET_HLEN(p))); + return(DecodeTCP(t, p, pkt + IPV4_GET_HLEN(p), IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p))); break; case IPPROTO_UDP: //printf("DecodeIPV4: next layer is UDP\n"); - return(DecodeUDP(t, p, pkt + IPV4_GET_HLEN(p), len - IPV4_GET_HLEN(p))); + return(DecodeUDP(t, p, pkt + IPV4_GET_HLEN(p), IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p))); break; case IPPROTO_ICMP: //printf("DecodeIPV4: next layer is ICMP\n"); - return(DecodeICMPV4(t, p, pkt + IPV4_GET_HLEN(p), len - IPV4_GET_HLEN(p))); + return(DecodeICMPV4(t, p, pkt + IPV4_GET_HLEN(p), IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p))); break; case IPPROTO_IPV6: { @@ -108,7 +108,7 @@ void DecodeIPV4(ThreadVars *t, Packet *p, u_int8_t *pkt, u_int16_t len, PacketQu //printf("DecodeIPV4: we are p %p\n", p); /* spawn off tunnel packet */ - Packet *tp = TunnelPktSetup(t, p, pkt + IPV4_GET_HLEN(p), len - IPV4_GET_HLEN(p), IPV4_GET_IPPROTO(p)); + Packet *tp = TunnelPktSetup(t, p, pkt + IPV4_GET_HLEN(p), IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), IPV4_GET_IPPROTO(p)); //printf("DecodeIPV4: tunnel is tp %p\n", tp); /* send that to the Tunnel decoder */ diff --git a/src/decode-ipv4.h b/src/decode-ipv4.h index b3ece1b124..d767174d00 100644 --- a/src/decode-ipv4.h +++ b/src/decode-ipv4.h @@ -69,11 +69,11 @@ typedef struct _IPV4Hdr #define IPV4_GET_IPTOS(p) \ IPV4_GET_RAW_IPTOS(p) #define IPV4_GET_IPLEN(p) \ - (p)->ip4c.flags & IPV4_CACHE_IPLEN ? \ - (p)->ip4c.ip_len : ((p)->ip4c.flags |= IPV4_CACHE_IPLEN, (p)->ip4c.ip_len = ntohs(IPV4_GET_RAW_IPLEN((p)->ip4h))) + ((p)->ip4c.flags & IPV4_CACHE_IPLEN ? \ + (p)->ip4c.ip_len : ((p)->ip4c.flags |= IPV4_CACHE_IPLEN, (p)->ip4c.ip_len = ntohs(IPV4_GET_RAW_IPLEN((p)->ip4h)))) #define IPV4_GET_IPID(p) \ - (p)->ip4c.flags & IPV4_CACHE_IPID ? \ - (p)->ip4c.ip_id : ((p)->ip4c.flags |= IPV4_CACHE_IPID, (p)->ip4c.ip_id = ntohs(IPV4_GET_RAW_IPID((p)->ip4h))) + ((p)->ip4c.flags & IPV4_CACHE_IPID ? \ + (p)->ip4c.ip_id : ((p)->ip4c.flags |= IPV4_CACHE_IPID, (p)->ip4c.ip_id = ntohs(IPV4_GET_RAW_IPID((p)->ip4h)))) /* _IPV4_GET_IPOFFSET: get the content of the offset header field in host order */ #define _IPV4_GET_IPOFFSET(p) \ ((p)->ip4c.flags & IPV4_CACHE__IPOFF ? \ @@ -97,8 +97,8 @@ typedef struct _IPV4Hdr #define IPV4_GET_IPTTL(p) \ IPV4_GET_RAW_IPTTL(p) #define IPV4_GET_IPPROTO(p) \ - (p)->ip4c.flags & IPV4_CACHE_IPPROTO ? \ - (p)->ip4c.ip_proto : ((p)->ip4c.flags |= IPV4_CACHE_IPPROTO, (p)->ip4c.ip_proto = IPV4_GET_RAW_IPPROTO((p)->ip4h)) + ((p)->ip4c.flags & IPV4_CACHE_IPPROTO ? \ + (p)->ip4c.ip_proto : ((p)->ip4c.flags |= IPV4_CACHE_IPPROTO, (p)->ip4c.ip_proto = IPV4_GET_RAW_IPPROTO((p)->ip4h))) #define IPV4_CACHE_VER 0x0001 /* 1 */ #define IPV4_CACHE_HLEN 0x0002 /* 2 */ diff --git a/src/decode-ipv6.c b/src/decode-ipv6.c index 2ea1fb5486..f8b150882c 100644 --- a/src/decode-ipv6.c +++ b/src/decode-ipv6.c @@ -347,6 +347,11 @@ static int DecodeIPV6Packet (ThreadVars *t, Packet *p, u_int8_t *pkt, u_int16_t return -1; } + if (len < (IPV6_HEADER_LEN + IPV6_GET_PLEN(p))) + { + return -1; + } + SET_IPV6_SRC_ADDR(p,&p->src); SET_IPV6_DST_ADDR(p,&p->dst); @@ -377,13 +382,13 @@ void DecodeIPV6(ThreadVars *t, Packet *p, u_int8_t *pkt, u_int16_t len) /* now process the Ext headers and/or the L4 Layer */ switch(IPV6_GET_NH(p)) { case IPPROTO_TCP: - return(DecodeTCP(t, p, pkt + IPV6_HEADER_LEN, len - IPV6_HEADER_LEN)); + return(DecodeTCP(t, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p))); break; case IPPROTO_UDP: - return(DecodeUDP(t, p, pkt + IPV6_HEADER_LEN, len - IPV6_HEADER_LEN)); + return(DecodeUDP(t, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p))); break; case IPPROTO_ICMPV6: - return(DecodeICMPV6(t, p, pkt + IPV6_HEADER_LEN, len - IPV6_HEADER_LEN)); + return(DecodeICMPV6(t, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p))); break; case IPPROTO_FRAGMENT: case IPPROTO_HOPOPTS: @@ -392,7 +397,7 @@ void DecodeIPV6(ThreadVars *t, Packet *p, u_int8_t *pkt, u_int16_t len) case IPPROTO_DSTOPTS: case IPPROTO_AH: case IPPROTO_ESP: - DecodeIPV6ExtHdrs(t, p, pkt + IPV6_HEADER_LEN, len - IPV6_HEADER_LEN); + DecodeIPV6ExtHdrs(t, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p)); break; } diff --git a/src/decode-ipv6.h b/src/decode-ipv6.h index c74823e8af..653a26dd31 100644 --- a/src/decode-ipv6.h +++ b/src/decode-ipv6.h @@ -62,18 +62,18 @@ typedef struct _IPV6Hdr ((p)->ip6c.flags & IPV6_CACHE_CLASS ? \ (p)->ip6c.cl : ((p)->ip6c.flags |= IPV6_CACHE_CLASS, (p)->ip6c.cl = IPV6_GET_RAW_CLASS((p)->ip6h))) #define IPV6_GET_FLOW(p) \ - (p)->ip6c.flags & IPV6_CACHE_FLOW ? \ - (p)->ip6c.flow : ((p)->ip6c.flags |= IPV6_CACHE_FLOW, (p)->ip6c.flow = IPV6_GET_RAW_FLOW((p)->ip6h)) + ((p)->ip6c.flags & IPV6_CACHE_FLOW ? \ + (p)->ip6c.flow : ((p)->ip6c.flags |= IPV6_CACHE_FLOW, (p)->ip6c.flow = IPV6_GET_RAW_FLOW((p)->ip6h))) #define IPV6_GET_NH(p) \ - IPV6_GET_RAW_NH((p)->ip6h) + (IPV6_GET_RAW_NH((p)->ip6h)) #define IPV6_GET_PLEN(p) \ - (p)->ip6c.flags & IPV6_CACHE_PLEN ? \ - (p)->ip6c.plen : ((p)->ip6c.flags |= IPV6_CACHE_PLEN, (p)->ip6c.plen = IPV6_GET_RAW_PLEN((p)->ip6h)) + ((p)->ip6c.flags & IPV6_CACHE_PLEN ? \ + (p)->ip6c.plen : ((p)->ip6c.flags |= IPV6_CACHE_PLEN, (p)->ip6c.plen = IPV6_GET_RAW_PLEN((p)->ip6h))) #define IPV6_GET_HLIM(p) \ - IPV6_GET_RAW_HLIM((p)->ip6h) + (IPV6_GET_RAW_HLIM((p)->ip6h)) /* XXX */ #define IPV6_GET_L4PROTO(p) \ - (p)->ip6vars.l4proto + ((p)->ip6vars.l4proto) #define IPV6_CACHE_VER 0x0001 /* 1 */ #define IPV6_CACHE_CLASS 0x0002 /* 2 */