From: Victor Julien Date: Tue, 26 Mar 2024 09:21:57 +0000 (+0100) Subject: decode/ipv6: prep for turning ip4h/ip6h into union X-Git-Tag: suricata-8.0.0-beta1~1402 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a40d6f5c4ffeea3354e3bd70aca1d237039ead13;p=thirdparty%2Fsuricata.git decode/ipv6: prep for turning ip4h/ip6h into union Store IPv6 decoder vars in a new Packet::l3 section in the packet. Use inline functions instead of the often multi-layer macro's for various IPv6 header getters. Ticket: #6938. --- diff --git a/src/decode-icmpv6.c b/src/decode-icmpv6.c index 5d287d0bf8..f165e030a6 100644 --- a/src/decode-icmpv6.c +++ b/src/decode-icmpv6.c @@ -178,6 +178,7 @@ int ICMPv6GetCounterpart(uint8_t type) int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len) { + const IPV6Hdr *ip6h = PacketGetIPv6(p); int full_hdr = 0; StatsIncr(tv, dtv->counter_icmpv6); @@ -327,7 +328,7 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, if (ICMPV6_GET_CODE(p) != 0) { ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); } - if (IPV6_GET_HLIM(p) != 1) { + if (IPV6_GET_RAW_HLIM(ip6h) != 1) { ENGINE_SET_EVENT(p, ICMPV6_MLD_MESSAGE_WITH_INVALID_HL); } break; @@ -336,7 +337,7 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, if (ICMPV6_GET_CODE(p) != 0) { ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); } - if (IPV6_GET_HLIM(p) != 1) { + if (IPV6_GET_RAW_HLIM(ip6h) != 1) { ENGINE_SET_EVENT(p, ICMPV6_MLD_MESSAGE_WITH_INVALID_HL); } break; @@ -345,7 +346,7 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, if (ICMPV6_GET_CODE(p) != 0) { ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); } - if (IPV6_GET_HLIM(p) != 1) { + if (IPV6_GET_RAW_HLIM(ip6h) != 1) { ENGINE_SET_EVENT(p, ICMPV6_MLD_MESSAGE_WITH_INVALID_HL); } break; @@ -1532,11 +1533,11 @@ static int ICMPV6CalculateValidChecksumWithFCS(void) DecodeIPV6(&tv, &dtv, p, raw_ipv6 + 14, sizeof(raw_ipv6) - 14); FAIL_IF_NULL(p->icmpv6h); - uint16_t icmpv6_len = IPV6_GET_RAW_PLEN(p->ip6h) - - ((uint8_t *)p->icmpv6h - (uint8_t *)p->ip6h - IPV6_HEADER_LEN); + const IPV6Hdr *ip6h = PacketGetIPv6(p); + uint16_t icmpv6_len = IPV6_GET_RAW_PLEN(ip6h) - + ((const uint8_t *)p->icmpv6h - (const uint8_t *)ip6h - IPV6_HEADER_LEN); FAIL_IF(icmpv6_len != 28); - FAIL_IF(ICMPV6CalculateChecksum(p->ip6h->s_ip6_addrs, - (uint16_t *)p->icmpv6h, icmpv6_len) != csum); + FAIL_IF(ICMPV6CalculateChecksum(ip6h->s_ip6_addrs, (uint16_t *)p->icmpv6h, icmpv6_len) != csum); PacketRecycle(p); FlowShutdown(); diff --git a/src/decode-ipv6.c b/src/decode-ipv6.c index 754dec9439..dfc2448389 100644 --- a/src/decode-ipv6.c +++ b/src/decode-ipv6.c @@ -97,47 +97,44 @@ void DecodeIPV6FragHeader(Packet *p, const uint8_t *pkt, uint16_t frag_offset = (*(pkt + 2) << 8 | *(pkt + 3)) & 0xFFF8; int frag_morefrags = (*(pkt + 2) << 8 | *(pkt + 3)) & 0x0001; - p->ip6eh.fh_offset = frag_offset; - p->ip6eh.fh_more_frags_set = frag_morefrags ? true : false; - p->ip6eh.fh_nh = *pkt; + p->l3.vars.ip6.eh.fh_offset = frag_offset; + p->l3.vars.ip6.eh.fh_more_frags_set = frag_morefrags ? true : false; + p->l3.vars.ip6.eh.fh_nh = *pkt; uint32_t fh_id; memcpy(&fh_id, pkt+4, 4); - p->ip6eh.fh_id = SCNtohl(fh_id); + p->l3.vars.ip6.eh.fh_id = SCNtohl(fh_id); - SCLogDebug("IPV6 FH: offset %u, mf %s, nh %u, id %u/%x", - p->ip6eh.fh_offset, - p->ip6eh.fh_more_frags_set ? "true" : "false", - p->ip6eh.fh_nh, - p->ip6eh.fh_id, p->ip6eh.fh_id); + SCLogDebug("IPV6 FH: offset %u, mf %s, nh %u, id %u/%x", p->l3.vars.ip6.eh.fh_offset, + p->l3.vars.ip6.eh.fh_more_frags_set ? "true" : "false", p->l3.vars.ip6.eh.fh_nh, + p->l3.vars.ip6.eh.fh_id, p->l3.vars.ip6.eh.fh_id); // store header offset, data offset uint16_t frag_hdr_offset = (uint16_t)(pkt - GET_PKT_DATA(p)); uint16_t data_offset = (uint16_t)(frag_hdr_offset + hdrextlen); uint16_t data_len = plen - hdrextlen; - p->ip6eh.fh_header_offset = frag_hdr_offset; - p->ip6eh.fh_data_offset = data_offset; - p->ip6eh.fh_data_len = data_len; + p->l3.vars.ip6.eh.fh_header_offset = frag_hdr_offset; + p->l3.vars.ip6.eh.fh_data_offset = data_offset; + p->l3.vars.ip6.eh.fh_data_len = data_len; /* if we have a prev hdr, store the type and offset of it */ if (prev_hdrextlen) { - p->ip6eh.fh_prev_hdr_offset = frag_hdr_offset - prev_hdrextlen; + p->l3.vars.ip6.eh.fh_prev_hdr_offset = frag_hdr_offset - prev_hdrextlen; } SCLogDebug("IPV6 FH: frag_hdr_offset %u, data_offset %u, data_len %u", - p->ip6eh.fh_header_offset, p->ip6eh.fh_data_offset, - p->ip6eh.fh_data_len); + p->l3.vars.ip6.eh.fh_header_offset, p->l3.vars.ip6.eh.fh_data_offset, + p->l3.vars.ip6.eh.fh_data_len); } -static void -DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, +static void DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const IPV6Hdr *ip6h, const uint8_t *pkt, uint16_t len) { SCEnter(); const uint8_t *orig_pkt = pkt; - uint8_t nh = IPV6_GET_NH(p); /* careful, 0 is actually a real type */ + uint8_t nh = IPV6_GET_RAW_NH(ip6h); /* careful, 0 is actually a real type */ uint16_t hdrextlen = 0; uint16_t plen = len; char dstopts = 0; @@ -213,7 +210,7 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, if (ip6rh_type == 0) { ENGINE_SET_EVENT(p, IPV6_EXTHDR_RH_TYPE_0); } - p->ip6eh.rh_type = ip6rh_type; + p->l3.vars.ip6.eh.rh_type = ip6rh_type; nh = *pkt; pkt += hdrextlen; @@ -404,7 +401,7 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, * a defragmented packet without the frag header */ if (exthdr_fh_done == 0) { DEBUG_VALIDATE_BUG_ON(pkt - orig_pkt > UINT16_MAX); - p->ip6eh.fh_offset = (uint16_t)(pkt - orig_pkt); + p->l3.vars.ip6.eh.fh_offset = (uint16_t)(pkt - orig_pkt); exthdr_fh_done = 1; } @@ -439,7 +436,7 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, * parse this packet further right away, no defrag will be * needed. It is a useless FH then though, so we do set an * decoder event. */ - if (p->ip6eh.fh_more_frags_set == 0 && p->ip6eh.fh_offset == 0) { + if (p->l3.vars.ip6.eh.fh_more_frags_set == 0 && p->l3.vars.ip6.eh.fh_offset == 0) { ENGINE_SET_EVENT(p, IPV6_EXTHDR_USELESS_FH); nh = *pkt; @@ -447,7 +444,7 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, plen -= hdrextlen; break; } - if (p->ip6eh.fh_more_frags_set != 0 && plen % 8 != 0) { + if (p->l3.vars.ip6.eh.fh_more_frags_set != 0 && plen % 8 != 0) { // cf https://datatracker.ietf.org/doc/html/rfc2460#section-4.5 // each, except possibly the last ("rightmost") one, // being an integer multiple of 8 octets long. @@ -535,30 +532,30 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, SCReturn; } -static int DecodeIPV6Packet (ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len) +static const IPV6Hdr *DecodeIPV6Packet( + ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len) { if (unlikely(len < IPV6_HEADER_LEN)) { - return -1; + return NULL; } if (unlikely(IP_GET_RAW_VER(pkt) != 6)) { SCLogDebug("wrong ip version %d",IP_GET_RAW_VER(pkt)); ENGINE_SET_INVALID_EVENT(p, IPV6_WRONG_IP_VER); - return -1; + return NULL; } - p->ip6h = (IPV6Hdr *)pkt; + const IPV6Hdr *ip6h = PacketSetIPV6(p, pkt); - if (unlikely(len < (IPV6_HEADER_LEN + IPV6_GET_PLEN(p)))) - { + if (unlikely(len < (IPV6_HEADER_LEN + IPV6_GET_RAW_PLEN(ip6h)))) { ENGINE_SET_INVALID_EVENT(p, IPV6_TRUNC_PKT); - return -1; + return NULL; } - SET_IPV6_SRC_ADDR(p,&p->src); - SET_IPV6_DST_ADDR(p,&p->dst); + SET_IPV6_SRC_ADDR(ip6h, &p->src); + SET_IPV6_DST_ADDR(ip6h, &p->dst); - return 0; + return ip6h; } int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len) @@ -569,12 +566,12 @@ int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t * return TM_ECODE_FAILED; } /* do the actual decoding */ - int ret = DecodeIPV6Packet (tv, dtv, p, pkt, len); - if (unlikely(ret < 0)) { - CLEAR_IPV6_PACKET(p); + const IPV6Hdr *ip6h = DecodeIPV6Packet(tv, dtv, p, pkt, len); + if (unlikely(ip6h == NULL)) { + PacketClearL3(p); return TM_ECODE_FAILED; } - p->proto = IPV6_GET_NH(p); + p->proto = IPV6_GET_RAW_NH(ip6h); #ifdef DEBUG if (SCLogDebugEnabled()) { /* only convert the addresses if debug is really enabled */ @@ -582,17 +579,17 @@ int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t * char s[46], d[46]; PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), s, sizeof(s)); PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), d, sizeof(d)); - SCLogDebug("IPV6 %s->%s - CLASS: %" PRIu32 " FLOW: %" PRIu32 " NH: %" PRIu32 " PLEN: %" PRIu32 " HLIM: %" PRIu32 "", s,d, - IPV6_GET_CLASS(p), IPV6_GET_FLOW(p), IPV6_GET_NH(p), IPV6_GET_PLEN(p), - IPV6_GET_HLIM(p)); + SCLogDebug("IPV6 %s->%s - CLASS: %" PRIu32 " FLOW: %" PRIu32 " NH: %" PRIu32 + " PLEN: %" PRIu32 " HLIM: %" PRIu32 "", + s, d, IPV6_GET_RAW_CLASS(ip6h), IPV6_GET_RAW_FLOW(ip6h), IPV6_GET_RAW_NH(ip6h), + IPV6_GET_RAW_PLEN(ip6h), IPV6_GET_RAW_HLIM(ip6h)); } #endif /* DEBUG */ - const uint8_t *data = pkt + IPV6_HEADER_LEN; - const uint16_t data_len = IPV6_GET_PLEN(p); + const uint16_t data_len = IPV6_GET_RAW_PLEN(ip6h); /* now process the Ext headers and/or the L4 Layer */ - switch(IPV6_GET_NH(p)) { + switch (IPV6_GET_RAW_NH(ip6h)) { case IPPROTO_TCP: IPV6_SET_L4PROTO (p, IPPROTO_TCP); DecodeTCP(tv, dtv, p, data, data_len); @@ -630,14 +627,14 @@ int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t * case IPPROTO_MH: case IPPROTO_HIP: case IPPROTO_SHIM6: - DecodeIPV6ExtHdrs(tv, dtv, p, data, data_len); + DecodeIPV6ExtHdrs(tv, dtv, p, ip6h, data, data_len); break; case IPPROTO_ICMP: ENGINE_SET_EVENT(p,IPV6_WITH_ICMPV4); break; default: ENGINE_SET_EVENT(p, IPV6_UNKNOWN_NEXT_HEADER); - IPV6_SET_L4PROTO (p, IPV6_GET_NH(p)); + IPV6_SET_L4PROTO(p, IPV6_GET_RAW_NH(ip6h)); break; } p->proto = IPV6_GET_L4PROTO (p); @@ -855,7 +852,7 @@ static int DecodeIPV6RouteTest01 (void) DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1)); FAIL_IF (!(IPV6_EXTHDR_ISSET_RH(p1))); - FAIL_IF (p1->ip6eh.rh_type != 0); + FAIL_IF(p1->l3.vars.ip6.eh.rh_type != 0); PacketRecycle(p1); SCFree(p1); FlowShutdown(); diff --git a/src/decode-ipv6.h b/src/decode-ipv6.h index a2b833c4cc..4b3be53779 100644 --- a/src/decode-ipv6.h +++ b/src/decode-ipv6.h @@ -69,31 +69,11 @@ typedef struct IPV6Hdr_ #define IPV6_SET_RAW_VER(ip6h, value) ((ip6h)->s_ip6_vfc = (((ip6h)->s_ip6_vfc & 0x0f) | (value << 4))) #define IPV6_SET_RAW_NH(ip6h, value) ((ip6h)->s_ip6_nxt = (value)) -#define IPV6_SET_L4PROTO(p,proto) (p)->ip6vars.l4proto = (proto) -#define IPV6_SET_EXTHDRS_LEN(p,len) (p)->ip6vars.exthdrs_len = (len) +#define IPV6_SET_L4PROTO(p, proto) (p)->l3.vars.ip6.v.l4proto = (proto) +#define IPV6_SET_EXTHDRS_LEN(p, len) (p)->l3.vars.ip6.v.exthdrs_len = (len) - -/* ONLY call these functions after making sure that: - * 1. p->ip6h is set - * 2. p->ip6h is valid (len is correct) - */ -#define IPV6_GET_VER(p) \ - IPV6_GET_RAW_VER((p)->ip6h) -#define IPV6_GET_CLASS(p) \ - IPV6_GET_RAW_CLASS((p)->ip6h) -#define IPV6_GET_FLOW(p) \ - IPV6_GET_RAW_FLOW((p)->ip6h) -#define IPV6_GET_NH(p) \ - (IPV6_GET_RAW_NH((p)->ip6h)) -#define IPV6_GET_PLEN(p) \ - IPV6_GET_RAW_PLEN((p)->ip6h) -#define IPV6_GET_HLIM(p) \ - (IPV6_GET_RAW_HLIM((p)->ip6h)) - -#define IPV6_GET_L4PROTO(p) \ - ((p)->ip6vars.l4proto) -#define IPV6_GET_EXTHDRS_LEN(p) \ - ((p)->ip6vars.exthdrs_len) +#define IPV6_GET_L4PROTO(p) ((p)->l3.vars.ip6.v.l4proto) +#define IPV6_GET_EXTHDRS_LEN(p) ((p)->l3.vars.ip6.v.exthdrs_len) /** \brief get the highest proto/next header field we know */ //#define IPV6_GET_UPPER_PROTO(p) (p)->ip6eh.ip6_exthdrs_cnt ? @@ -108,13 +88,6 @@ typedef struct IPV6Vars_ uint16_t exthdrs_len; /**< length of the exthdrs */ } IPV6Vars; -#define CLEAR_IPV6_PACKET(p) do { \ - (p)->ip6h = NULL; \ - (p)->ip6vars.l4proto = 0; \ - (p)->ip6vars.exthdrs_len = 0; \ - memset(&(p)->ip6eh, 0x00, sizeof((p)->ip6eh)); \ -} while (0) - /* Fragment header */ typedef struct IPV6FragHdr_ { @@ -124,10 +97,10 @@ typedef struct IPV6FragHdr_ uint32_t ip6fh_ident; /* identification */ } __attribute__((__packed__)) IPV6FragHdr; -#define IPV6_EXTHDR_GET_FH_NH(p) (p)->ip6eh.fh_nh -#define IPV6_EXTHDR_GET_FH_OFFSET(p) (p)->ip6eh.fh_offset -#define IPV6_EXTHDR_GET_FH_FLAG(p) (p)->ip6eh.fh_more_frags_set -#define IPV6_EXTHDR_GET_FH_ID(p) (p)->ip6eh.fh_id +#define IPV6_EXTHDR_GET_FH_NH(p) (p)->l3.vars.ip6.eh.fh_nh +#define IPV6_EXTHDR_GET_FH_OFFSET(p) (p)->l3.vars.ip6.eh.fh_offset +#define IPV6_EXTHDR_GET_FH_FLAG(p) (p)->l3.vars.ip6.eh.fh_more_frags_set +#define IPV6_EXTHDR_GET_FH_ID(p) (p)->l3.vars.ip6.eh.fh_id /* rfc 1826 */ typedef struct IPV6AuthHdr_ @@ -235,10 +208,10 @@ typedef struct IPV6ExtHdrs_ } IPV6ExtHdrs; -#define IPV6_EXTHDR_SET_FH(p) (p)->ip6eh.fh_set = true -#define IPV6_EXTHDR_ISSET_FH(p) (p)->ip6eh.fh_set -#define IPV6_EXTHDR_SET_RH(p) (p)->ip6eh.rh_set = true -#define IPV6_EXTHDR_ISSET_RH(p) (p)->ip6eh.rh_set +#define IPV6_EXTHDR_SET_FH(p) (p)->l3.vars.ip6.eh.fh_set = true +#define IPV6_EXTHDR_ISSET_FH(p) (p)->l3.vars.ip6.eh.fh_set +#define IPV6_EXTHDR_SET_RH(p) (p)->l3.vars.ip6.eh.rh_set = true +#define IPV6_EXTHDR_ISSET_RH(p) (p)->l3.vars.ip6.eh.rh_set void DecodeIPV6RegisterTests(void); diff --git a/src/decode.h b/src/decode.h index 0662471832..417600b450 100644 --- a/src/decode.h +++ b/src/decode.h @@ -160,22 +160,23 @@ typedef struct Address_ { (a)->addr_data32[3] = 0; \ } while (0) -/* Set the IPv6 addresses into the Addrs of the Packet. - * Make sure p->ip6h is initialized and validated. */ -#define SET_IPV6_SRC_ADDR(p, a) do { \ - (a)->family = AF_INET6; \ - (a)->addr_data32[0] = (p)->ip6h->s_ip6_src[0]; \ - (a)->addr_data32[1] = (p)->ip6h->s_ip6_src[1]; \ - (a)->addr_data32[2] = (p)->ip6h->s_ip6_src[2]; \ - (a)->addr_data32[3] = (p)->ip6h->s_ip6_src[3]; \ +/* Set the IPv6 addresses into the Addrs of the Packet. */ +#define SET_IPV6_SRC_ADDR(ip6h, a) \ + do { \ + (a)->family = AF_INET6; \ + (a)->addr_data32[0] = (ip6h)->s_ip6_src[0]; \ + (a)->addr_data32[1] = (ip6h)->s_ip6_src[1]; \ + (a)->addr_data32[2] = (ip6h)->s_ip6_src[2]; \ + (a)->addr_data32[3] = (ip6h)->s_ip6_src[3]; \ } while (0) -#define SET_IPV6_DST_ADDR(p, a) do { \ - (a)->family = AF_INET6; \ - (a)->addr_data32[0] = (p)->ip6h->s_ip6_dst[0]; \ - (a)->addr_data32[1] = (p)->ip6h->s_ip6_dst[1]; \ - (a)->addr_data32[2] = (p)->ip6h->s_ip6_dst[2]; \ - (a)->addr_data32[3] = (p)->ip6h->s_ip6_dst[3]; \ +#define SET_IPV6_DST_ADDR(ip6h, a) \ + do { \ + (a)->family = AF_INET6; \ + (a)->addr_data32[0] = (ip6h)->s_ip6_dst[0]; \ + (a)->addr_data32[1] = (ip6h)->s_ip6_dst[1]; \ + (a)->addr_data32[2] = (ip6h)->s_ip6_dst[2]; \ + (a)->addr_data32[3] = (ip6h)->s_ip6_dst[3]; \ } while (0) /* Set the TCP ports into the Ports of the Packet. @@ -246,7 +247,6 @@ typedef uint16_t Port; *We determine the ip version. */ #define IP_GET_RAW_VER(pkt) ((((pkt)[0] & 0xf0) >> 4)) -#define PKT_IS_IPV6(p) (((p)->ip6h != NULL)) #define PKT_IS_TCP(p) (((p)->tcph != NULL)) #define PKT_IS_UDP(p) (((p)->udph != NULL)) #define PKT_IS_ICMPV4(p) (((p)->icmpv4h != NULL)) @@ -415,6 +415,7 @@ struct PacketQueue_; enum PacketL3Types { PACKET_L3_UNKNOWN = 0, PACKET_L3_IPV4, + PACKET_L3_IPV6, }; struct PacketL3 { @@ -423,10 +424,15 @@ struct PacketL3 { int32_t comp_csum; union Hdrs { IPV4Hdr *ip4h; + IPV6Hdr *ip6h; } hdrs; /* IPv4 and IPv6 are mutually exclusive */ union { IPV4Vars ip4; + struct { + IPV6Vars v; + IPV6ExtHdrs eh; + } ip6; } vars; }; @@ -554,11 +560,6 @@ typedef struct Packet_ int32_t level4_comp_csum; struct PacketL3 l3; - IPV6Hdr *ip6h; - struct { - IPV6Vars ip6vars; - IPV6ExtHdrs ip6eh; - }; /* Can only be one of TCP, UDP, ICMP at any given time */ union { @@ -670,6 +671,7 @@ typedef struct Packet_ } Packet; static inline bool PacketIsIPv4(const Packet *p); +static inline bool PacketIsIPv6(const Packet *p); /** highest mtu of the interfaces we monitor */ #define DEFAULT_MTU 1500 @@ -709,7 +711,7 @@ static inline uint8_t PacketGetIPProto(const Packet *p) if (PacketIsIPv4(p)) { const IPV4Hdr *hdr = PacketGetIPv4(p); return IPV4_GET_RAW_IPPROTO(hdr); - } else if (PKT_IS_IPV6(p)) { + } else if (PacketIsIPv6(p)) { return IPV6_GET_L4PROTO(p); } return 0; @@ -724,14 +726,28 @@ static inline uint8_t PacketGetIPv4IPProto(const Packet *p) return 0; } -static inline void PacketClearL3(Packet *p) +static inline const IPV6Hdr *PacketGetIPv6(const Packet *p) { - memset(&p->l3, 0, sizeof(p->l3)); + DEBUG_VALIDATE_BUG_ON(!PacketIsIPv6(p)); + return p->l3.hdrs.ip6h; +} + +static inline IPV6Hdr *PacketSetIPV6(Packet *p, const uint8_t *buf) +{ + DEBUG_VALIDATE_BUG_ON(p->l3.type != PACKET_L3_UNKNOWN); + p->l3.type = PACKET_L3_IPV6; + p->l3.hdrs.ip6h = (IPV6Hdr *)buf; + return p->l3.hdrs.ip6h; } static inline bool PacketIsIPv6(const Packet *p) { - return PKT_IS_IPV6(p); + return p->l3.type == PACKET_L3_IPV6; +} + +static inline void PacketClearL3(Packet *p) +{ + memset(&p->l3, 0, sizeof(p->l3)); } /** \brief Structure to hold thread specific data for all decode modules */ diff --git a/src/defrag.c b/src/defrag.c index d52dd87802..1e0213d127 100644 --- a/src/defrag.c +++ b/src/defrag.c @@ -421,10 +421,12 @@ Defrag6Reassemble(ThreadVars *tv, DefragTracker *tracker, Packet *p) } } + const IPV6Hdr *oip6h = PacketGetIPv6(p); + /* Allocate a Packet for the reassembled packet. On failure we * SCFree all the resources held by this tracker. */ - rp = PacketDefragPktSetup(p, (uint8_t *)p->ip6h, - IPV6_GET_PLEN(p) + sizeof(IPV6Hdr), 0); + rp = PacketDefragPktSetup( + p, (const uint8_t *)oip6h, IPV6_GET_RAW_PLEN(oip6h) + sizeof(IPV6Hdr), 0); if (rp == NULL) { goto error_remove_tracker; } @@ -502,15 +504,15 @@ Defrag6Reassemble(ThreadVars *tv, DefragTracker *tracker, Packet *p) prev_offset = frag->offset; } - rp->ip6h = (IPV6Hdr *)(GET_PKT_DATA(rp) + tracker->ip_hdr_offset); + IPV6Hdr *ip6h = (IPV6Hdr *)(GET_PKT_DATA(rp) + tracker->ip_hdr_offset); DEBUG_VALIDATE_BUG_ON(unfragmentable_len > UINT16_MAX - fragmentable_len); - rp->ip6h->s_ip6_plen = htons(fragmentable_len + unfragmentable_len); + ip6h->s_ip6_plen = htons(fragmentable_len + unfragmentable_len); /* if we have no unfragmentable part, so no ext hdrs before the frag * header, we need to update the ipv6 headers next header field. This * points to the frag header, and we will make it point to the layer * directly after the frag header. */ if (unfragmentable_len == 0) - rp->ip6h->s_ip6_nxt = next_hdr; + ip6h->s_ip6_nxt = next_hdr; SET_PKT_LEN(rp, ip_hdr_offset + sizeof(IPV6Hdr) + unfragmentable_len + fragmentable_len); @@ -552,7 +554,7 @@ DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragTracker *tracker, Packet *r = NULL; uint16_t ltrim = 0; - uint8_t more_frags; + bool more_frags; uint16_t frag_offset; /* IPv4 header length - IPv4 only. */ @@ -605,13 +607,14 @@ DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragTracker *tracker, } } else if (tracker->af == AF_INET6) { + const IPV6Hdr *ip6h = PacketGetIPv6(p); more_frags = IPV6_EXTHDR_GET_FH_FLAG(p); frag_offset = IPV6_EXTHDR_GET_FH_OFFSET(p); - data_offset = p->ip6eh.fh_data_offset; - data_len = p->ip6eh.fh_data_len; + data_offset = p->l3.vars.ip6.eh.fh_data_offset; + data_len = p->l3.vars.ip6.eh.fh_data_len; frag_end = frag_offset + data_len; - ip_hdr_offset = (uint16_t)((uint8_t *)p->ip6h - GET_PKT_DATA(p)); - frag_hdr_offset = p->ip6eh.fh_header_offset; + ip_hdr_offset = (uint16_t)((uint8_t *)ip6h - GET_PKT_DATA(p)); + frag_hdr_offset = p->l3.vars.ip6.eh.fh_header_offset; SCLogDebug("mf %s frag_offset %u data_offset %u, data_len %u, " "frag_end %u, ip_hdr_offset %u, frag_hdr_offset %u", @@ -627,7 +630,7 @@ DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragTracker *tracker, * relative to the buffer start */ /* store offset and FH 'next' value for updating frag buffer below */ - ip6_nh_set_offset = p->ip6eh.fh_prev_hdr_offset; + ip6_nh_set_offset = p->l3.vars.ip6.eh.fh_prev_hdr_offset; ip6_nh_set_value = IPV6_EXTHDR_GET_FH_NH(p); SCLogDebug("offset %d, value %u", ip6_nh_set_offset, ip6_nh_set_value); } @@ -938,8 +941,10 @@ DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragTracker *tracker, r = Defrag6Reassemble(tv, tracker, p); if (r != NULL && tv != NULL && dtv != NULL) { StatsIncr(tv, dtv->counter_defrag_ipv6_reassembled); - if (DecodeIPV6(tv, dtv, r, (uint8_t *)r->ip6h, - IPV6_GET_PLEN(r) + IPV6_HEADER_LEN) != TM_ECODE_OK) { + const uint32_t len = GET_PKT_LEN(r) - (uint32_t)tracker->ip_hdr_offset; + DEBUG_VALIDATE_BUG_ON(len > UINT16_MAX); + if (DecodeIPV6(tv, dtv, r, GET_PKT_DATA(r) + tracker->ip_hdr_offset, + (uint16_t)len) != TM_ECODE_OK) { r->root = NULL; TmqhOutputPacketpool(tv, r); r = NULL; @@ -1291,8 +1296,8 @@ static Packet *BuildIpv6TestPacket( /* copy content_len crap, we need full length */ PacketCopyData(p, (uint8_t *)&ip6h, sizeof(IPV6Hdr)); - p->ip6h = (IPV6Hdr *)GET_PKT_DATA(p); - IPV6_SET_RAW_VER(p->ip6h, 6); + IPV6Hdr *ip6p = PacketSetIPV6(p, GET_PKT_DATA(p)); + IPV6_SET_RAW_VER(ip6p, 6); /* Fragmentation header. */ IPV6FragHdr *fh = (IPV6FragHdr *)(GET_PKT_DATA(p) + sizeof(IPV6Hdr)); fh->ip6fh_nxt = proto; @@ -1309,17 +1314,17 @@ static Packet *BuildIpv6TestPacket( SET_PKT_LEN(p, sizeof(IPV6Hdr) + sizeof(IPV6FragHdr) + content_len); SCFree(pcontent); - p->ip6h->s_ip6_plen = htons(sizeof(IPV6FragHdr) + content_len); + ip6p->s_ip6_plen = htons(sizeof(IPV6FragHdr) + content_len); - SET_IPV6_SRC_ADDR(p, &p->src); - SET_IPV6_DST_ADDR(p, &p->dst); + SET_IPV6_SRC_ADDR(ip6p, &p->src); + SET_IPV6_DST_ADDR(ip6p, &p->dst); /* Self test. */ - if (IPV6_GET_VER(p) != 6) + if (IPV6_GET_RAW_VER(ip6p) != 6) goto error; - if (IPV6_GET_NH(p) != 44) + if (IPV6_GET_RAW_NH(ip6p) != 44) goto error; - if (IPV6_GET_PLEN(p) != sizeof(IPV6FragHdr) + content_len) + if (IPV6_GET_RAW_PLEN(ip6p) != sizeof(IPV6FragHdr) + content_len) goto error; return p; @@ -1361,8 +1366,8 @@ static Packet *BuildIpv6TestPacketWithContent( /* copy content_len crap, we need full length */ PacketCopyData(p, (uint8_t *)&ip6h, sizeof(IPV6Hdr)); - p->ip6h = (IPV6Hdr *)GET_PKT_DATA(p); - IPV6_SET_RAW_VER(p->ip6h, 6); + IPV6Hdr *ip6p = PacketSetIPV6(p, GET_PKT_DATA(p)); + IPV6_SET_RAW_VER(ip6p, 6); /* Fragmentation header. */ IPV6FragHdr *fh = (IPV6FragHdr *)(GET_PKT_DATA(p) + sizeof(IPV6Hdr)); fh->ip6fh_nxt = proto; @@ -1374,17 +1379,17 @@ static Packet *BuildIpv6TestPacketWithContent( PacketCopyDataOffset(p, sizeof(IPV6Hdr) + sizeof(IPV6FragHdr), content, content_len); SET_PKT_LEN(p, sizeof(IPV6Hdr) + sizeof(IPV6FragHdr) + content_len); - p->ip6h->s_ip6_plen = htons(sizeof(IPV6FragHdr) + content_len); + ip6p->s_ip6_plen = htons(sizeof(IPV6FragHdr) + content_len); - SET_IPV6_SRC_ADDR(p, &p->src); - SET_IPV6_DST_ADDR(p, &p->dst); + SET_IPV6_SRC_ADDR(ip6p, &p->src); + SET_IPV6_DST_ADDR(ip6p, &p->dst); /* Self test. */ - if (IPV6_GET_VER(p) != 6) + if (IPV6_GET_RAW_VER(ip6p) != 6) goto error; - if (IPV6_GET_NH(p) != 44) + if (IPV6_GET_RAW_NH(ip6p) != 44) goto error; - if (IPV6_GET_PLEN(p) != sizeof(IPV6FragHdr) + content_len) + if (IPV6_GET_RAW_PLEN(ip6p) != sizeof(IPV6FragHdr) + content_len) goto error; return p; @@ -1532,7 +1537,8 @@ static int DefragInOrderSimpleIpv6Test(void) reassembled = Defrag(&tv, &dtv, p3); FAIL_IF_NULL(reassembled); - FAIL_IF(IPV6_GET_PLEN(reassembled) != 19); + const IPV6Hdr *ip6h = PacketGetIPv6(reassembled); + FAIL_IF(IPV6_GET_RAW_PLEN(ip6h) != 19); /* 40 bytes in we should find 8 bytes of A. */ for (int i = 40; i < 40 + 8; i++) { @@ -1833,7 +1839,7 @@ static int DefragDoSturgesNovakIpv6Test(int policy, uint8_t *expected, size_t ex FAIL_IF_NULL(reassembled); FAIL_IF(memcmp(GET_PKT_DATA(reassembled) + 40, expected, expected_len) != 0); - FAIL_IF(IPV6_GET_PLEN(reassembled) != 192); + FAIL_IF(IPV6_GET_RAW_PLEN(PacketGetIPv6(reassembled)) != 192); SCFree(reassembled); @@ -2655,7 +2661,7 @@ static int DefragMfIpv6Test(void) /* For IPv6 the expected length is just the length of the payload * of 2 fragments, so 16. */ - FAIL_IF(IPV6_GET_PLEN(p) != 16); + FAIL_IF(IPV6_GET_RAW_PLEN(PacketGetIPv6(p)) != 16); /* Verify the payload of the IPv4 packet. */ uint8_t expected_payload[] = "AAAAAAAABBBBBBBB"; diff --git a/src/detect-csum.c b/src/detect-csum.c index dd56e74a78..3ad046d653 100644 --- a/src/detect-csum.c +++ b/src/detect-csum.c @@ -422,12 +422,11 @@ static int DetectTCPV6CsumMatch(DetectEngineThreadCtx *det_ctx, return cd->valid; } - if (p->level4_comp_csum == -1) - p->level4_comp_csum = TCPV6Checksum(p->ip6h->s_ip6_addrs, - (uint16_t *)p->tcph, - (p->payload_len + - TCP_GET_HLEN(p)), - p->tcph->th_sum); + if (p->level4_comp_csum == -1) { + const IPV6Hdr *ip6h = PacketGetIPv6(p); + p->level4_comp_csum = TCPV6Checksum(ip6h->s_ip6_addrs, (uint16_t *)p->tcph, + (p->payload_len + TCP_GET_HLEN(p)), p->tcph->th_sum); + } if (p->level4_comp_csum == 0 && cd->valid == 1) return 1; @@ -601,13 +600,11 @@ static int DetectUDPV6CsumMatch(DetectEngineThreadCtx *det_ctx, return cd->valid; } - if (p->level4_comp_csum == -1) - p->level4_comp_csum = UDPV6Checksum(p->ip6h->s_ip6_addrs, - (uint16_t *)p->udph, - (p->payload_len + - UDP_HEADER_LEN), - p->udph->uh_sum); - + if (p->level4_comp_csum == -1) { + const IPV6Hdr *ip6h = PacketGetIPv6(p); + p->level4_comp_csum = UDPV6Checksum(ip6h->s_ip6_addrs, (uint16_t *)p->udph, + (p->payload_len + UDP_HEADER_LEN), p->udph->uh_sum); + } if (p->level4_comp_csum == 0 && cd->valid == 1) return 1; else if (p->level4_comp_csum != 0 && cd->valid == 0) @@ -783,11 +780,11 @@ static int DetectICMPV6CsumMatch(DetectEngineThreadCtx *det_ctx, } if (p->level4_comp_csum == -1) { - uint16_t len = IPV6_GET_RAW_PLEN(p->ip6h) - - (uint16_t)((uint8_t *)p->icmpv6h - (uint8_t *)p->ip6h - IPV6_HEADER_LEN); - p->level4_comp_csum = ICMPV6CalculateChecksum(p->ip6h->s_ip6_addrs, - (uint16_t *)p->icmpv6h, - len); + const IPV6Hdr *ip6h = PacketGetIPv6(p); + uint16_t len = IPV6_GET_RAW_PLEN(ip6h) - + (uint16_t)((uint8_t *)p->icmpv6h - (uint8_t *)ip6h - IPV6_HEADER_LEN); + p->level4_comp_csum = + ICMPV6CalculateChecksum(ip6h->s_ip6_addrs, (uint16_t *)p->icmpv6h, len); } if (p->level4_comp_csum == p->icmpv6h->csum && cd->valid == 1) diff --git a/src/detect-ipv6hdr.c b/src/detect-ipv6hdr.c index b796294400..1616fb1eb8 100644 --- a/src/detect-ipv6hdr.c +++ b/src/detect-ipv6hdr.c @@ -103,19 +103,19 @@ static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, if (!PacketIsIPv6(p)) { return NULL; } + const IPV6Hdr *ip6h = PacketGetIPv6(p); uint32_t hlen = IPV6_HEADER_LEN + IPV6_GET_EXTHDRS_LEN(p); - if (((uint8_t *)p->ip6h + (ptrdiff_t)hlen) > - ((uint8_t *)GET_PKT_DATA(p) + (ptrdiff_t)GET_PKT_LEN(p))) - { + if (((uint8_t *)ip6h + (ptrdiff_t)hlen) > + ((uint8_t *)GET_PKT_DATA(p) + (ptrdiff_t)GET_PKT_LEN(p))) { SCLogDebug("data out of range: %p > %p (exthdrs_len %u)", - ((uint8_t *)p->ip6h + (ptrdiff_t)hlen), + ((uint8_t *)ip6h + (ptrdiff_t)hlen), ((uint8_t *)GET_PKT_DATA(p) + (ptrdiff_t)GET_PKT_LEN(p)), IPV6_GET_EXTHDRS_LEN(p)); SCReturnPtr(NULL, "InspectionBuffer"); } const uint32_t data_len = hlen; - const uint8_t *data = (const uint8_t *)p->ip6h; + const uint8_t *data = (const uint8_t *)ip6h; InspectionBufferSetup(det_ctx, list_id, buffer, data, data_len); InspectionBufferApplyTransforms(buffer, transforms); diff --git a/src/detect-l3proto.c b/src/detect-l3proto.c index c00636d3c0..98d203d13d 100644 --- a/src/detect-l3proto.c +++ b/src/detect-l3proto.c @@ -192,7 +192,7 @@ static int DetectL3protoTestSig2(void) p->src.family = AF_INET6; p->dst.family = AF_INET6; p->proto = IPPROTO_TCP; - p->ip6h = &ip6h; + UTHSetIPV6Hdr(p, &ip6h); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); FAIL_IF_NULL(de_ctx); @@ -252,7 +252,7 @@ static int DetectL3protoTestSig3(void) p->src.family = AF_INET6; p->dst.family = AF_INET6; p->proto = IPPROTO_TCP; - p->ip6h = &ip6h; + UTHSetIPV6Hdr(p, &ip6h); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); FAIL_IF_NULL(de_ctx); diff --git a/src/detect-template2.c b/src/detect-template2.c index bc622084e5..249831aaf7 100644 --- a/src/detect-template2.c +++ b/src/detect-template2.c @@ -87,7 +87,8 @@ static int DetectTemplate2Match (DetectEngineThreadCtx *det_ctx, Packet *p, const IPV4Hdr *ip4h = PacketGetIPv4(p); ptemplate2 = IPV4_GET_RAW_IPTTL(ip4h); } else if (PacketIsIPv6(p)) { - ptemplate2 = IPV6_GET_HLIM(p); + const IPV6Hdr *ip6h = PacketGetIPv6(p); + ptemplate2 = IPV6_GET_RAW_HLIM(ip6h); } else { SCLogDebug("Packet is of not IPv4 or IPv6"); return 0; @@ -148,7 +149,8 @@ PrefilterPacketTemplate2Match(DetectEngineThreadCtx *det_ctx, Packet *p, const v const IPV4Hdr *ip4h = PacketGetIPv4(p); ptemplate2 = IPV4_GET_RAW_IPTTL(ip4h); } else if (PacketIsIPv6(p)) { - ptemplate2 = IPV6_GET_HLIM(p); + const IPV6Hdr *ip6h = PacketGetIPv6(p); + ptemplate2 = IPV6_GET_RAW_HLIM(ip6h); } else { SCLogDebug("Packet is of not IPv4 or IPv6"); return; diff --git a/src/detect-ttl.c b/src/detect-ttl.c index 9a59eff2b3..e16dbf8581 100644 --- a/src/detect-ttl.c +++ b/src/detect-ttl.c @@ -91,7 +91,8 @@ static int DetectTtlMatch (DetectEngineThreadCtx *det_ctx, Packet *p, const IPV4Hdr *ip4h = PacketGetIPv4(p); pttl = IPV4_GET_RAW_IPTTL(ip4h); } else if (PacketIsIPv6(p)) { - pttl = IPV6_GET_HLIM(p); + const IPV6Hdr *ip6h = PacketGetIPv6(p); + pttl = IPV6_GET_RAW_HLIM(ip6h); } else { SCLogDebug("Packet is not IPv4 or IPv6"); return 0; @@ -150,7 +151,8 @@ PrefilterPacketTtlMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *p const IPV4Hdr *ip4h = PacketGetIPv4(p); pttl = IPV4_GET_RAW_IPTTL(ip4h); } else if (PacketIsIPv6(p)) { - pttl = IPV6_GET_HLIM(p); + const IPV6Hdr *ip6h = PacketGetIPv6(p); + pttl = IPV6_GET_RAW_HLIM(ip6h); } else { SCLogDebug("Packet is not IPv4 or IPv6"); return; diff --git a/src/flow-timeout.c b/src/flow-timeout.c index bc2327e935..2ec6b398de 100644 --- a/src/flow-timeout.c +++ b/src/flow-timeout.c @@ -177,31 +177,31 @@ static inline Packet *FlowForceReassemblyPseudoPacketSetup( } } /* set the ip header */ - p->ip6h = (IPV6Hdr *)GET_PKT_DATA(p); + IPV6Hdr *ip6h = PacketSetIPV6(p, GET_PKT_DATA(p)); /* version 6 */ - p->ip6h->s_ip6_vfc = 0x60; - p->ip6h->s_ip6_flow = 0; - p->ip6h->s_ip6_nxt = IPPROTO_TCP; - p->ip6h->s_ip6_plen = htons(20); - p->ip6h->s_ip6_hlim = 64; + ip6h->s_ip6_vfc = 0x60; + ip6h->s_ip6_flow = 0; + ip6h->s_ip6_nxt = IPPROTO_TCP; + ip6h->s_ip6_plen = htons(20); + ip6h->s_ip6_hlim = 64; if (direction == 0) { - p->ip6h->s_ip6_src[0] = f->src.addr_data32[0]; - p->ip6h->s_ip6_src[1] = f->src.addr_data32[1]; - p->ip6h->s_ip6_src[2] = f->src.addr_data32[2]; - p->ip6h->s_ip6_src[3] = f->src.addr_data32[3]; - p->ip6h->s_ip6_dst[0] = f->dst.addr_data32[0]; - p->ip6h->s_ip6_dst[1] = f->dst.addr_data32[1]; - p->ip6h->s_ip6_dst[2] = f->dst.addr_data32[2]; - p->ip6h->s_ip6_dst[3] = f->dst.addr_data32[3]; + ip6h->s_ip6_src[0] = f->src.addr_data32[0]; + ip6h->s_ip6_src[1] = f->src.addr_data32[1]; + ip6h->s_ip6_src[2] = f->src.addr_data32[2]; + ip6h->s_ip6_src[3] = f->src.addr_data32[3]; + ip6h->s_ip6_dst[0] = f->dst.addr_data32[0]; + ip6h->s_ip6_dst[1] = f->dst.addr_data32[1]; + ip6h->s_ip6_dst[2] = f->dst.addr_data32[2]; + ip6h->s_ip6_dst[3] = f->dst.addr_data32[3]; } else { - p->ip6h->s_ip6_src[0] = f->dst.addr_data32[0]; - p->ip6h->s_ip6_src[1] = f->dst.addr_data32[1]; - p->ip6h->s_ip6_src[2] = f->dst.addr_data32[2]; - p->ip6h->s_ip6_src[3] = f->dst.addr_data32[3]; - p->ip6h->s_ip6_dst[0] = f->src.addr_data32[0]; - p->ip6h->s_ip6_dst[1] = f->src.addr_data32[1]; - p->ip6h->s_ip6_dst[2] = f->src.addr_data32[2]; - p->ip6h->s_ip6_dst[3] = f->src.addr_data32[3]; + ip6h->s_ip6_src[0] = f->dst.addr_data32[0]; + ip6h->s_ip6_src[1] = f->dst.addr_data32[1]; + ip6h->s_ip6_src[2] = f->dst.addr_data32[2]; + ip6h->s_ip6_src[3] = f->dst.addr_data32[3]; + ip6h->s_ip6_dst[0] = f->src.addr_data32[0]; + ip6h->s_ip6_dst[1] = f->src.addr_data32[1]; + ip6h->s_ip6_dst[2] = f->src.addr_data32[2]; + ip6h->s_ip6_dst[3] = f->src.addr_data32[3]; } /* set the tcp header */ @@ -239,8 +239,8 @@ static inline Packet *FlowForceReassemblyPseudoPacketSetup( * a wrong checksum */ ip4h->ip_csum = IPV4Checksum((uint16_t *)ip4h, IPV4_GET_RAW_HLEN(ip4h), 0); } else if (FLOW_IS_IPV6(f)) { - p->tcph->th_sum = TCPChecksum(p->ip6h->s_ip6_addrs, - (uint16_t *)p->tcph, 20, 0); + const IPV6Hdr *ip6h = PacketGetIPv6(p); + p->tcph->th_sum = TCPChecksum(ip6h->s_ip6_addrs, (uint16_t *)p->tcph, 20, 0); } p->ts = TimeGet(); diff --git a/src/flow-util.c b/src/flow-util.c index 879a9282e6..a820ff1d72 100644 --- a/src/flow-util.c +++ b/src/flow-util.c @@ -160,9 +160,10 @@ void FlowInit(Flow *f, const Packet *p) f->min_ttl_toserver = f->max_ttl_toserver = IPV4_GET_RAW_IPTTL(ip4h); f->flags |= FLOW_IPV4; } else if (PacketIsIPv6(p)) { - FLOW_SET_IPV6_SRC_ADDR_FROM_PACKET(p, &f->src); - FLOW_SET_IPV6_DST_ADDR_FROM_PACKET(p, &f->dst); - f->min_ttl_toserver = f->max_ttl_toserver = IPV6_GET_HLIM((p)); + const IPV6Hdr *ip6h = PacketGetIPv6(p); + FLOW_SET_IPV6_SRC_ADDR_FROM_PACKET(ip6h, &f->src); + FLOW_SET_IPV6_DST_ADDR_FROM_PACKET(ip6h, &f->dst); + f->min_ttl_toserver = f->max_ttl_toserver = IPV6_GET_RAW_HLIM(ip6h); f->flags |= FLOW_IPV6; } else { SCLogDebug("neither IPv4 or IPv6, weird"); diff --git a/src/flow.c b/src/flow.c index 18c419f5ab..8a179d2b1c 100644 --- a/src/flow.c +++ b/src/flow.c @@ -441,7 +441,8 @@ void FlowHandlePacketUpdate(Flow *f, Packet *p, ThreadVars *tv, DecodeThreadVars const IPV4Hdr *ip4h = PacketGetIPv4(p); FlowUpdateTtlTS(f, p, IPV4_GET_RAW_IPTTL(ip4h)); } else if (PacketIsIPv6(p)) { - FlowUpdateTtlTS(f, p, IPV6_GET_HLIM(p)); + const IPV6Hdr *ip6h = PacketGetIPv6(p); + FlowUpdateTtlTS(f, p, IPV6_GET_RAW_HLIM(ip6h)); } } else { f->tosrcpktcnt++; @@ -464,7 +465,8 @@ void FlowHandlePacketUpdate(Flow *f, Packet *p, ThreadVars *tv, DecodeThreadVars const IPV4Hdr *ip4h = PacketGetIPv4(p); FlowUpdateTtlTC(f, p, IPV4_GET_RAW_IPTTL(ip4h)); } else if (PacketIsIPv6(p)) { - FlowUpdateTtlTC(f, p, IPV6_GET_HLIM(p)); + const IPV6Hdr *ip6h = PacketGetIPv6(p); + FlowUpdateTtlTC(f, p, IPV6_GET_RAW_HLIM(ip6h)); } } diff --git a/src/flow.h b/src/flow.h index 6a75019b4b..9905c410b2 100644 --- a/src/flow.h +++ b/src/flow.h @@ -207,18 +207,20 @@ typedef struct AppLayerParserState_ AppLayerParserState; /* Set the IPv6 addressesinto the Addrs of the Packet. * Make sure p->ip6h is initialized and validated. */ -#define FLOW_SET_IPV6_SRC_ADDR_FROM_PACKET(p, a) do { \ - (a)->addr_data32[0] = (p)->ip6h->s_ip6_src[0]; \ - (a)->addr_data32[1] = (p)->ip6h->s_ip6_src[1]; \ - (a)->addr_data32[2] = (p)->ip6h->s_ip6_src[2]; \ - (a)->addr_data32[3] = (p)->ip6h->s_ip6_src[3]; \ +#define FLOW_SET_IPV6_SRC_ADDR_FROM_PACKET(ip6h, a) \ + do { \ + (a)->addr_data32[0] = (ip6h)->s_ip6_src[0]; \ + (a)->addr_data32[1] = (ip6h)->s_ip6_src[1]; \ + (a)->addr_data32[2] = (ip6h)->s_ip6_src[2]; \ + (a)->addr_data32[3] = (ip6h)->s_ip6_src[3]; \ } while (0) -#define FLOW_SET_IPV6_DST_ADDR_FROM_PACKET(p, a) do { \ - (a)->addr_data32[0] = (p)->ip6h->s_ip6_dst[0]; \ - (a)->addr_data32[1] = (p)->ip6h->s_ip6_dst[1]; \ - (a)->addr_data32[2] = (p)->ip6h->s_ip6_dst[2]; \ - (a)->addr_data32[3] = (p)->ip6h->s_ip6_dst[3]; \ +#define FLOW_SET_IPV6_DST_ADDR_FROM_PACKET(ip6h, a) \ + do { \ + (a)->addr_data32[0] = (ip6h)->s_ip6_dst[0]; \ + (a)->addr_data32[1] = (ip6h)->s_ip6_dst[1]; \ + (a)->addr_data32[2] = (ip6h)->s_ip6_dst[2]; \ + (a)->addr_data32[3] = (ip6h)->s_ip6_dst[3]; \ } while (0) /* pkt flow flags */ diff --git a/src/output-eve-stream.c b/src/output-eve-stream.c index 8af30ba038..8a5d9252dd 100644 --- a/src/output-eve-stream.c +++ b/src/output-eve-stream.c @@ -328,10 +328,11 @@ static int EveStreamLogger(ThreadVars *tv, void *thread_data, const Packet *p) jb_set_uint(js, "ttl", IPV4_GET_RAW_IPTTL(ip4h)); jb_set_uint(js, "ipid", IPV4_GET_RAW_IPID(ip4h)); } else if (PacketIsIPv6(p)) { - jb_set_uint(js, "len", IPV6_GET_PLEN(p)); - jb_set_uint(js, "tc", IPV6_GET_CLASS(p)); - jb_set_uint(js, "hoplimit", IPV6_GET_HLIM(p)); - jb_set_uint(js, "flowlbl", IPV6_GET_FLOW(p)); + const IPV6Hdr *ip6h = PacketGetIPv6(p); + jb_set_uint(js, "len", IPV6_GET_RAW_PLEN(ip6h)); + jb_set_uint(js, "tc", IPV6_GET_RAW_CLASS(ip6h)); + jb_set_uint(js, "hoplimit", IPV6_GET_RAW_HLIM(ip6h)); + jb_set_uint(js, "flowlbl", IPV6_GET_RAW_FLOW(ip6h)); } if (PKT_IS_TCP(p)) { jb_set_uint(js, "tcpseq", TCP_GET_SEQ(p)); diff --git a/src/output-json-drop.c b/src/output-json-drop.c index f337d4e38a..38810626ee 100644 --- a/src/output-json-drop.c +++ b/src/output-json-drop.c @@ -115,10 +115,11 @@ static int DropLogJSON (JsonDropLogThread *aft, const Packet *p) jb_set_uint(js, "ipid", IPV4_GET_RAW_IPID(ip4h)); proto = IPV4_GET_RAW_IPPROTO(ip4h); } else if (PacketIsIPv6(p)) { - jb_set_uint(js, "len", IPV6_GET_PLEN(p)); - jb_set_uint(js, "tc", IPV6_GET_CLASS(p)); - jb_set_uint(js, "hoplimit", IPV6_GET_HLIM(p)); - jb_set_uint(js, "flowlbl", IPV6_GET_FLOW(p)); + const IPV6Hdr *ip6h = PacketGetIPv6(p); + jb_set_uint(js, "len", IPV6_GET_RAW_PLEN(ip6h)); + jb_set_uint(js, "tc", IPV6_GET_RAW_CLASS(ip6h)); + jb_set_uint(js, "hoplimit", IPV6_GET_RAW_HLIM(ip6h)); + jb_set_uint(js, "flowlbl", IPV6_GET_RAW_FLOW(ip6h)); proto = IPV6_GET_L4PROTO(p); } switch (proto) { diff --git a/src/respond-reject-libnet11.c b/src/respond-reject-libnet11.c index 1a64a398ee..a0856671e6 100644 --- a/src/respond-reject-libnet11.c +++ b/src/respond-reject-libnet11.c @@ -481,6 +481,7 @@ cleanup: #ifdef HAVE_LIBNET_ICMPV6_UNREACH int RejectSendLibnet11IPv6ICMP(ThreadVars *tv, Packet *p, void *data, enum RejectDirection dir) { + const IPV6Hdr *ip6h = PacketGetIPv6(p); Libnet11Packet lpacket; int result; @@ -489,7 +490,7 @@ int RejectSendLibnet11IPv6ICMP(ThreadVars *tv, Packet *p, void *data, enum Rejec lpacket.id = 0; lpacket.flow = 0; lpacket.class = 0; - const uint16_t iplen = IPV6_GET_PLEN(p); + const uint16_t iplen = IPV6_GET_RAW_PLEN(ip6h); if (g_reject_dev_mtu >= ETHERNET_HEADER_LEN + IPV6_HEADER_LEN + 8) { lpacket.len = IPV6_HEADER_LEN + MIN(g_reject_dev_mtu - ETHERNET_HEADER_LEN, iplen); } else { @@ -517,14 +518,13 @@ int RejectSendLibnet11IPv6ICMP(ThreadVars *tv, Packet *p, void *data, enum Rejec lpacket.ttl = 64; /* build the package */ - if ((libnet_build_icmpv6_unreach( - ICMP6_DST_UNREACH, /* type */ - ICMP6_DST_UNREACH_ADMIN, /* code */ - 0, /* checksum */ - (uint8_t *)p->ip6h, /* payload */ - lpacket.dsize, /* payload length */ - c, /* libnet context */ - 0)) < 0) /* libnet ptag */ + if ((libnet_build_icmpv6_unreach(ICMP6_DST_UNREACH, /* type */ + ICMP6_DST_UNREACH_ADMIN, /* code */ + 0, /* checksum */ + (uint8_t *)ip6h, /* payload */ + lpacket.dsize, /* payload length */ + c, /* libnet context */ + 0)) < 0) /* libnet ptag */ { SCLogError("libnet_build_icmpv6_unreach %s", libnet_geterror(c)); goto cleanup; diff --git a/src/stream-tcp.c b/src/stream-tcp.c index 36ce466e35..c6038f3007 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -5684,11 +5684,9 @@ static inline int StreamTcpValidateChecksum(Packet *p) p->level4_comp_csum = TCPChecksum(ip4h->s_ip_addrs, (uint16_t *)p->tcph, (p->payload_len + TCP_GET_HLEN(p)), p->tcph->th_sum); } else if (PacketIsIPv6(p)) { - p->level4_comp_csum = TCPV6Checksum(p->ip6h->s_ip6_addrs, - (uint16_t *)p->tcph, - (p->payload_len + - TCP_GET_HLEN(p)), - p->tcph->th_sum); + const IPV6Hdr *ip6h = PacketGetIPv6(p); + p->level4_comp_csum = TCPV6Checksum(ip6h->s_ip6_addrs, (uint16_t *)p->tcph, + (p->payload_len + TCP_GET_HLEN(p)), p->tcph->th_sum); } } @@ -6772,31 +6770,31 @@ static void StreamTcpPseudoPacketCreateDetectLogFlush(ThreadVars *tv, } } /* set the ip header */ - np->ip6h = (IPV6Hdr *)GET_PKT_DATA(np); + IPV6Hdr *ip6h = PacketSetIPV6(np, GET_PKT_DATA(np)); /* version 6 */ - np->ip6h->s_ip6_vfc = 0x60; - np->ip6h->s_ip6_flow = 0; - np->ip6h->s_ip6_nxt = IPPROTO_TCP; - np->ip6h->s_ip6_plen = htons(20); - np->ip6h->s_ip6_hlim = 64; + ip6h->s_ip6_vfc = 0x60; + ip6h->s_ip6_flow = 0; + ip6h->s_ip6_nxt = IPPROTO_TCP; + ip6h->s_ip6_plen = htons(20); + ip6h->s_ip6_hlim = 64; if (dir == 0) { - np->ip6h->s_ip6_src[0] = f->src.addr_data32[0]; - np->ip6h->s_ip6_src[1] = f->src.addr_data32[1]; - np->ip6h->s_ip6_src[2] = f->src.addr_data32[2]; - np->ip6h->s_ip6_src[3] = f->src.addr_data32[3]; - np->ip6h->s_ip6_dst[0] = f->dst.addr_data32[0]; - np->ip6h->s_ip6_dst[1] = f->dst.addr_data32[1]; - np->ip6h->s_ip6_dst[2] = f->dst.addr_data32[2]; - np->ip6h->s_ip6_dst[3] = f->dst.addr_data32[3]; + ip6h->s_ip6_src[0] = f->src.addr_data32[0]; + ip6h->s_ip6_src[1] = f->src.addr_data32[1]; + ip6h->s_ip6_src[2] = f->src.addr_data32[2]; + ip6h->s_ip6_src[3] = f->src.addr_data32[3]; + ip6h->s_ip6_dst[0] = f->dst.addr_data32[0]; + ip6h->s_ip6_dst[1] = f->dst.addr_data32[1]; + ip6h->s_ip6_dst[2] = f->dst.addr_data32[2]; + ip6h->s_ip6_dst[3] = f->dst.addr_data32[3]; } else { - np->ip6h->s_ip6_src[0] = f->dst.addr_data32[0]; - np->ip6h->s_ip6_src[1] = f->dst.addr_data32[1]; - np->ip6h->s_ip6_src[2] = f->dst.addr_data32[2]; - np->ip6h->s_ip6_src[3] = f->dst.addr_data32[3]; - np->ip6h->s_ip6_dst[0] = f->src.addr_data32[0]; - np->ip6h->s_ip6_dst[1] = f->src.addr_data32[1]; - np->ip6h->s_ip6_dst[2] = f->src.addr_data32[2]; - np->ip6h->s_ip6_dst[3] = f->src.addr_data32[3]; + ip6h->s_ip6_src[0] = f->dst.addr_data32[0]; + ip6h->s_ip6_src[1] = f->dst.addr_data32[1]; + ip6h->s_ip6_src[2] = f->dst.addr_data32[2]; + ip6h->s_ip6_src[3] = f->dst.addr_data32[3]; + ip6h->s_ip6_dst[0] = f->src.addr_data32[0]; + ip6h->s_ip6_dst[1] = f->src.addr_data32[1]; + ip6h->s_ip6_dst[2] = f->src.addr_data32[2]; + ip6h->s_ip6_dst[3] = f->src.addr_data32[3]; } /* set the tcp header */ diff --git a/src/tests/detect.c b/src/tests/detect.c index 3705ba9b64..4116e40cdd 100644 --- a/src/tests/detect.c +++ b/src/tests/detect.c @@ -2170,7 +2170,7 @@ static int SigTest28TCPV6Keyword(void) memset(&th_v, 0, sizeof(ThreadVars)); PACKET_RESET_CHECKSUMS(p1); - p1->ip6h = (IPV6Hdr *)(valid_raw_ipv6 + 14); + PacketSetIPV6(p1, valid_raw_ipv6 + 14); p1->tcph = (TCPHdr *) (valid_raw_ipv6 + 54); p1->src.family = AF_INET; p1->dst.family = AF_INET; @@ -2183,7 +2183,7 @@ static int SigTest28TCPV6Keyword(void) } PACKET_RESET_CHECKSUMS(p2); - p2->ip6h = (IPV6Hdr *)(invalid_raw_ipv6 + 14); + PacketSetIPV6(p2, invalid_raw_ipv6 + 14); p2->tcph = (TCPHdr *) (invalid_raw_ipv6 + 54); p2->src.family = AF_INET; p2->dst.family = AF_INET; @@ -2296,7 +2296,7 @@ static int SigTest29NegativeTCPV6Keyword(void) memset(&th_v, 0, sizeof(ThreadVars)); PACKET_RESET_CHECKSUMS(p1); - p1->ip6h = (IPV6Hdr *)(valid_raw_ipv6 + 14); + PacketSetIPV6(p1, valid_raw_ipv6 + 14); p1->tcph = (TCPHdr *) (valid_raw_ipv6 + 54); p1->src.family = AF_INET; p1->dst.family = AF_INET; @@ -2309,7 +2309,7 @@ static int SigTest29NegativeTCPV6Keyword(void) } PACKET_RESET_CHECKSUMS(p2); - p2->ip6h = (IPV6Hdr *)(invalid_raw_ipv6 + 14); + PacketSetIPV6(p2, invalid_raw_ipv6 + 14); p2->tcph = (TCPHdr *) (invalid_raw_ipv6 + 54); p2->src.family = AF_INET; p2->dst.family = AF_INET; @@ -2633,21 +2633,21 @@ static int SigTest32UDPV6Keyword(void) memset(&th_v, 0, sizeof(ThreadVars)); PACKET_RESET_CHECKSUMS(p1); - p1->ip6h = (IPV6Hdr *)(valid_raw_ipv6 + 14); + PacketSetIPV6(p1, valid_raw_ipv6 + 14); p1->udph = (UDPHdr *) (valid_raw_ipv6 + 54); p1->src.family = AF_INET; p1->dst.family = AF_INET; p1->payload = buf; - p1->payload_len = IPV6_GET_PLEN((p1)) - UDP_HEADER_LEN; + p1->payload_len = IPV6_GET_RAW_PLEN(PacketGetIPv6(p1)) - UDP_HEADER_LEN; p1->proto = IPPROTO_UDP; PACKET_RESET_CHECKSUMS(p2); - p2->ip6h = (IPV6Hdr *)(invalid_raw_ipv6 + 14); + PacketSetIPV6(p2, invalid_raw_ipv6 + 14); p2->udph = (UDPHdr *) (invalid_raw_ipv6 + 54); p2->src.family = AF_INET; p2->dst.family = AF_INET; p2->payload = buf; - p2->payload_len = IPV6_GET_PLEN((p2)) - UDP_HEADER_LEN; + p2->payload_len = IPV6_GET_RAW_PLEN(PacketGetIPv6(p2)) - UDP_HEADER_LEN; p2->proto = IPPROTO_UDP; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); @@ -2732,21 +2732,21 @@ static int SigTest33NegativeUDPV6Keyword(void) memset(&th_v, 0, sizeof(ThreadVars)); PACKET_RESET_CHECKSUMS(p1); - p1->ip6h = (IPV6Hdr *)(valid_raw_ipv6 + 14); + PacketSetIPV6(p1, valid_raw_ipv6 + 14); p1->udph = (UDPHdr *) (valid_raw_ipv6 + 54); p1->src.family = AF_INET; p1->dst.family = AF_INET; p1->payload = buf; - p1->payload_len = IPV6_GET_PLEN((p1)) - UDP_HEADER_LEN; + p1->payload_len = IPV6_GET_RAW_PLEN(PacketGetIPv6(p1)) - UDP_HEADER_LEN; p1->proto = IPPROTO_UDP; PACKET_RESET_CHECKSUMS(p2); - p2->ip6h = (IPV6Hdr *)(invalid_raw_ipv6 + 14); + PacketSetIPV6(p2, invalid_raw_ipv6 + 14); p2->udph = (UDPHdr *) (invalid_raw_ipv6 + 54); p2->src.family = AF_INET; p2->dst.family = AF_INET; p2->payload = buf; - p2->payload_len = IPV6_GET_PLEN((p2)) - UDP_HEADER_LEN; + p2->payload_len = IPV6_GET_RAW_PLEN(PacketGetIPv6(p2)) - UDP_HEADER_LEN; p2->proto = IPPROTO_UDP; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); diff --git a/src/util-checksum.c b/src/util-checksum.c index 1b75cd5e6a..12ae5aa8e9 100644 --- a/src/util-checksum.c +++ b/src/util-checksum.c @@ -44,15 +44,15 @@ int ReCalculateChecksum(Packet *p) ip4h->ip_csum = 0; ip4h->ip_csum = IPV4Checksum((uint16_t *)ip4h, IPV4_GET_RAW_HLEN(ip4h), 0); } else if (PacketIsIPv6(p)) { - /* just TCP for IPV6 */ + IPV6Hdr *ip6h = p->l3.hdrs.ip6h; if (PKT_IS_TCP(p)) { p->tcph->th_sum = 0; - p->tcph->th_sum = TCPV6Checksum(p->ip6h->s_ip6_addrs, - (uint16_t *)p->tcph, (p->payload_len + TCP_GET_HLEN(p)), 0); + p->tcph->th_sum = TCPV6Checksum( + ip6h->s_ip6_addrs, (uint16_t *)p->tcph, (p->payload_len + TCP_GET_HLEN(p)), 0); } else if (PKT_IS_UDP(p)) { p->udph->uh_sum = 0; - p->udph->uh_sum = UDPV6Checksum(p->ip6h->s_ip6_addrs, - (uint16_t *)p->udph, (p->payload_len + UDP_HEADER_LEN), 0); + p->udph->uh_sum = UDPV6Checksum( + ip6h->s_ip6_addrs, (uint16_t *)p->udph, (p->payload_len + UDP_HEADER_LEN), 0); } } diff --git a/src/util-unittest-helper.c b/src/util-unittest-helper.c index 83a9c7c297..a79e614873 100644 --- a/src/util-unittest-helper.c +++ b/src/util-unittest-helper.c @@ -128,6 +128,11 @@ void UTHSetIPV4Hdr(Packet *p, IPV4Hdr *ip4h) PacketSetIPV4(p, (uint8_t *)ip4h); } +void UTHSetIPV6Hdr(Packet *p, IPV6Hdr *ip6h) +{ + PacketSetIPV6(p, (uint8_t *)ip6h); +} + /** * \brief return the uint32_t for a ipv4 address string * @@ -177,12 +182,12 @@ Packet *UTHBuildPacketIPV6Real(uint8_t *payload, uint16_t payload_len, p->payload_len = payload_len; p->proto = ipproto; - p->ip6h = SCMalloc(sizeof(IPV6Hdr)); - if (p->ip6h == NULL) + IPV6Hdr *ip6h = SCCalloc(1, sizeof(IPV6Hdr)); + if (ip6h == NULL) goto error; - memset(p->ip6h, 0, sizeof(IPV6Hdr)); - p->ip6h->s_ip6_nxt = ipproto; - p->ip6h->s_ip6_plen = htons(payload_len + sizeof(TCPHdr)); + ip6h->s_ip6_nxt = ipproto; + ip6h->s_ip6_plen = htons(payload_len + sizeof(TCPHdr)); + UTHSetIPV6Hdr(p, ip6h); if (inet_pton(AF_INET6, src, &in) != 1) goto error; @@ -191,10 +196,10 @@ Packet *UTHBuildPacketIPV6Real(uint8_t *payload, uint16_t payload_len, p->src.addr_data32[2] = in[2]; p->src.addr_data32[3] = in[3]; p->sp = sport; - p->ip6h->s_ip6_src[0] = in[0]; - p->ip6h->s_ip6_src[1] = in[1]; - p->ip6h->s_ip6_src[2] = in[2]; - p->ip6h->s_ip6_src[3] = in[3]; + ip6h->s_ip6_src[0] = in[0]; + ip6h->s_ip6_src[1] = in[1]; + ip6h->s_ip6_src[2] = in[2]; + ip6h->s_ip6_src[3] = in[3]; if (inet_pton(AF_INET6, dst, &in) != 1) goto error; @@ -203,10 +208,10 @@ Packet *UTHBuildPacketIPV6Real(uint8_t *payload, uint16_t payload_len, p->dst.addr_data32[2] = in[2]; p->dst.addr_data32[3] = in[3]; p->dp = dport; - p->ip6h->s_ip6_dst[0] = in[0]; - p->ip6h->s_ip6_dst[1] = in[1]; - p->ip6h->s_ip6_dst[2] = in[2]; - p->ip6h->s_ip6_dst[3] = in[3]; + ip6h->s_ip6_dst[0] = in[0]; + ip6h->s_ip6_dst[1] = in[1]; + ip6h->s_ip6_dst[2] = in[2]; + ip6h->s_ip6_dst[3] = in[3]; p->tcph = SCMalloc(sizeof(TCPHdr)); if (p->tcph == NULL) @@ -220,8 +225,8 @@ Packet *UTHBuildPacketIPV6Real(uint8_t *payload, uint16_t payload_len, error: if (p != NULL) { - if (p->ip6h != NULL) { - SCFree(p->ip6h); + if (ip6h != NULL) { + SCFree(ip6h); } if (p->tcph != NULL) { SCFree(p->tcph); diff --git a/src/util-unittest-helper.h b/src/util-unittest-helper.h index d4791752fb..4d288f78aa 100644 --- a/src/util-unittest-helper.h +++ b/src/util-unittest-helper.h @@ -37,6 +37,7 @@ int TestHelperBufferToFile(const char *name, const uint8_t *data, size_t size); #endif #ifdef UNITTESTS void UTHSetIPV4Hdr(Packet *p, IPV4Hdr *ip4h); +void UTHSetIPV6Hdr(Packet *p, IPV6Hdr *ip6h); uint32_t UTHSetIPv4Address(const char *);