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.
pull/10971/head
Victor Julien 2 years ago committed by Victor Julien
parent 2d5c381c3b
commit a40d6f5c4f

@ -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();

@ -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();

@ -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);

@ -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 */

@ -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";

@ -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)

@ -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);

@ -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);

@ -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;

@ -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;

@ -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();

@ -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");

@ -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));
}
}

@ -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 */

@ -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));

@ -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) {

@ -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;

@ -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 */

@ -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();

@ -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);
}
}

@ -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);

@ -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 *);

Loading…
Cancel
Save