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.
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);
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;
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;
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;
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();
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;
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;
* 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;
}
* 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;
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.
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)
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 */
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);
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);
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();
#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 ?
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_
{
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_
} 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);
(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.
*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))
enum PacketL3Types {
PACKET_L3_UNKNOWN = 0,
PACKET_L3_IPV4,
+ PACKET_L3_IPV6,
};
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;
};
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 {
} 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
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;
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 */
}
}
+ 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;
}
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);
Packet *r = NULL;
uint16_t ltrim = 0;
- uint8_t more_frags;
+ bool more_frags;
uint16_t frag_offset;
/* IPv4 header length - IPv4 only. */
}
}
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",
* 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);
}
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;
/* 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;
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;
/* 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;
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;
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++) {
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);
/* 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";
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;
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)
}
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)
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);
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);
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);
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;
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;
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;
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;
}
}
/* 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 */
* 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();
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");
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++;
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));
}
}
/* 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 */
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));
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) {
#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;
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 {
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;
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);
}
}
}
}
/* 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 */
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;
}
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;
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;
}
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;
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();
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();
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);
}
}
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
*
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;
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;
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)
error:
if (p != NULL) {
- if (p->ip6h != NULL) {
- SCFree(p->ip6h);
+ if (ip6h != NULL) {
+ SCFree(ip6h);
}
if (p->tcph != NULL) {
SCFree(p->tcph);
#endif
#ifdef UNITTESTS
void UTHSetIPV4Hdr(Packet *p, IPV4Hdr *ip4h);
+void UTHSetIPV6Hdr(Packet *p, IPV6Hdr *ip6h);
uint32_t UTHSetIPv4Address(const char *);