char dstopts = 0;
char exthdr_fh_done = 0;
+ uint8_t ip6_exthdrs_cnt = 0;
+ IPV6GenOptHdr ip6_exthdrs[IPV6_MAX_OPT];
+
+ int hh = 0;
+ int rh = 0;
+ int eh = 0;
+ int ah = 0;
+
nh = IPV6_GET_NH(p);
plen = len;
SCReturn;
}
- if (p->IPV6_EH_CNT < IPV6_MAX_OPT)
+ if (ip6_exthdrs_cnt < IPV6_MAX_OPT)
{
- p->IPV6_EXTHDRS[p->IPV6_EH_CNT].type = nh;
- p->IPV6_EXTHDRS[p->IPV6_EH_CNT].next = *pkt;
- p->IPV6_EXTHDRS[p->IPV6_EH_CNT].len = hdrextlen;
- p->IPV6_EXTHDRS[p->IPV6_EH_CNT].data = pkt+2;
- p->IPV6_EH_CNT++;
+ ip6_exthdrs[ip6_exthdrs_cnt].type = nh;
+ ip6_exthdrs[ip6_exthdrs_cnt].next = *pkt;
+ ip6_exthdrs[ip6_exthdrs_cnt].len = hdrextlen;
+ ip6_exthdrs[ip6_exthdrs_cnt].data = pkt+2;
+ ip6_exthdrs_cnt++;
}
- if (IPV6_EXTHDR_ISSET_RH(p)) {
+ if (rh) {
ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_RH);
/* skip past this extension so we can continue parsing the rest
* of the packet */
break;
}
- IPV6_EXTHDR_SET_RH(p, pkt);
-
- /** \todo move into own function and load on demand */
- if (IPV6_EXTHDR_RH(p)->ip6rh_type == 0) {
-#if 0 // XXX usused and broken, original packet is modified in the memcpy
- uint8_t i;
-
- uint8_t n = hdrextlen / 2;
- /* because we devide the header len by 2 (as rfc 2460 tells us to)
- * we devide the result by 8 and not 16 as the header fields are
- * sized */
- for (i = 0; i < (n/8) && i < sizeof(IPV6_EXTHDR_RH(p)->ip6rh0_addr)/sizeof(struct in6_addr); ++i) {
- /* the address header fields are 16 bytes in size */
- /** \todo do this without memcpy since it's expensive */
- memcpy(&IPV6_EXTHDR_RH(p)->ip6rh0_addr[i], pkt+(i*16)+8, sizeof(IPV6_EXTHDR_RH(p)->ip6rh0_addr[i]));
- }
- IPV6_EXTHDR_RH(p)->ip6rh0_num_addrs = i;
-#endif
+ rh = 1;
+ IPV6_EXTHDR_SET_RH(p);
+
+ uint8_t ip6rh_type = *(pkt + 2);
+ if (ip6rh_type == 0) {
ENGINE_SET_EVENT(p, IPV6_EXTHDR_RH_TYPE_0);
}
+ p->ip6eh.rh_type = ip6rh_type;
nh = *pkt;
pkt += hdrextlen;
case IPPROTO_HOPOPTS:
case IPPROTO_DSTOPTS:
{
- IPV6OptHAO *hao = NULL;
- IPV6OptRA *ra = NULL;
- IPV6OptJumbo *jumbo = NULL;
+ IPV6OptHAO hao_s, *hao = &hao_s;
+ IPV6OptRA ra_s, *ra = &ra_s;
+ IPV6OptJumbo jumbo_s, *jumbo = &jumbo_s;
uint16_t optslen = 0;
IPV6_SET_L4PROTO(p,nh);
SCReturn;
}
- if (p->IPV6_EH_CNT < IPV6_MAX_OPT)
+ if (ip6_exthdrs_cnt < IPV6_MAX_OPT)
{
- p->IPV6_EXTHDRS[p->IPV6_EH_CNT].type = nh;
- p->IPV6_EXTHDRS[p->IPV6_EH_CNT].next = *pkt;
- p->IPV6_EXTHDRS[p->IPV6_EH_CNT].len = hdrextlen;
- p->IPV6_EXTHDRS[p->IPV6_EH_CNT].data = pkt+2;
- p->IPV6_EH_CNT++;
+ ip6_exthdrs[ip6_exthdrs_cnt].type = nh;
+ ip6_exthdrs[ip6_exthdrs_cnt].next = *pkt;
+ ip6_exthdrs[ip6_exthdrs_cnt].len = hdrextlen;
+ ip6_exthdrs[ip6_exthdrs_cnt].data = pkt+2;
+ ip6_exthdrs_cnt++;
}
uint8_t *ptr = pkt + 2; /* +2 to go past nxthdr and len */
/* point the pointers to right structures
* in Packet. */
if (nh == IPPROTO_HOPOPTS) {
- if (IPV6_EXTHDR_ISSET_HH(p)) {
+ if (hh) {
ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_HH);
/* skip past this extension so we can continue parsing the rest
* of the packet */
break;
}
- IPV6_EXTHDR_SET_HH(p, pkt);
- hao = &IPV6_EXTHDR_HH_HAO(p);
- ra = &IPV6_EXTHDR_HH_RA(p);
- jumbo = &IPV6_EXTHDR_HH_JUMBO(p);
+ hh = 1;
- optslen = ((IPV6_EXTHDR_HH(p)->ip6hh_len+1)<<3)-2;
+ optslen = ((*(pkt + 1) + 1 ) << 3) - 2;
}
else if (nh == IPPROTO_DSTOPTS)
{
if (dstopts == 0) {
- IPV6_EXTHDR_SET_DH1(p, pkt);
- hao = &IPV6_EXTHDR_DH1_HAO(p);
- ra = &IPV6_EXTHDR_DH1_RA(p);
- jumbo = &IPV6_EXTHDR_DH2_JUMBO(p);
- optslen = ((IPV6_EXTHDR_DH1(p)->ip6dh_len+1)<<3)-2;
+ optslen = ((*(pkt + 1) + 1 ) << 3) - 2;
dstopts = 1;
} else if (dstopts == 1) {
- IPV6_EXTHDR_SET_DH2(p, pkt);
- hao = &IPV6_EXTHDR_DH2_HAO(p);
- ra = &IPV6_EXTHDR_DH2_RA(p);
- jumbo = &IPV6_EXTHDR_DH2_JUMBO(p);
- optslen = ((IPV6_EXTHDR_DH2(p)->ip6dh_len+1)<<3)-2;
+ optslen = ((*(pkt + 1) + 1 ) << 3) - 2;
dstopts = 2;
} else {
ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_DH);
/* non fatal, lets try to continue */
}
- if(p->IPV6_EH_CNT<IPV6_MAX_OPT)
+ if(ip6_exthdrs_cnt<IPV6_MAX_OPT)
{
- p->IPV6_EXTHDRS[p->IPV6_EH_CNT].type = nh;
- p->IPV6_EXTHDRS[p->IPV6_EH_CNT].next = *pkt;
- p->IPV6_EXTHDRS[p->IPV6_EH_CNT].len = hdrextlen;
- p->IPV6_EXTHDRS[p->IPV6_EH_CNT].data = pkt+2;
- p->IPV6_EH_CNT++;
+ ip6_exthdrs[ip6_exthdrs_cnt].type = nh;
+ ip6_exthdrs[ip6_exthdrs_cnt].next = *pkt;
+ ip6_exthdrs[ip6_exthdrs_cnt].len = hdrextlen;
+ ip6_exthdrs[ip6_exthdrs_cnt].data = pkt+2;
+ ip6_exthdrs_cnt++;
}
if (IPV6_EXTHDR_ISSET_FH(p)) {
break;
}
- /* set the header ptr first */
- IPV6_EXTHDR_SET_FH(p, pkt);
+ /* set the header flag first */
+ IPV6_EXTHDR_SET_FH(p);
+
+ 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;
+
+ uint32_t fh_id;
+ memcpy(&fh_id, pkt+4, 4);
+ p->ip6eh.fh_id = ntohl(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);
+
+ // 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;
+
+ /* if we have a prev hdr, store the type and offset of it */
+ if (ip6_exthdrs_cnt > 1) {
+ p->ip6eh.fh_prev_hdr_offset = frag_hdr_offset - ip6_exthdrs[ip6_exthdrs_cnt - 1].len;
+ }
+
+ 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);
/* if FH has offset 0 and no more fragments are coming, we
* 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 (IPV6_EXTHDR_GET_FH_FLAG(p) == 0 && IPV6_EXTHDR_GET_FH_OFFSET(p) == 0) {
+ if (frag_morefrags == 0 && frag_offset == 0) {
ENGINE_SET_EVENT(p, IPV6_EXTHDR_USELESS_FH);
nh = *pkt;
SCReturn;
}
- if(p->IPV6_EH_CNT<IPV6_MAX_OPT)
+ if(ip6_exthdrs_cnt<IPV6_MAX_OPT)
{
- p->IPV6_EXTHDRS[p->IPV6_EH_CNT].type = nh;
- p->IPV6_EXTHDRS[p->IPV6_EH_CNT].next = IPPROTO_NONE;
- p->IPV6_EXTHDRS[p->IPV6_EH_CNT].len = hdrextlen;
- p->IPV6_EXTHDRS[p->IPV6_EH_CNT].data = pkt+2;
- p->IPV6_EH_CNT++;
+ ip6_exthdrs[ip6_exthdrs_cnt].type = nh;
+ ip6_exthdrs[ip6_exthdrs_cnt].next = IPPROTO_NONE;
+ ip6_exthdrs[ip6_exthdrs_cnt].len = hdrextlen;
+ ip6_exthdrs[ip6_exthdrs_cnt].data = pkt+2;
+ ip6_exthdrs_cnt++;
}
- if (IPV6_EXTHDR_ISSET_EH(p)) {
+ if (eh) {
ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_EH);
SCReturn;
}
- IPV6_EXTHDR_SET_EH(p, pkt);
+ eh = 1;
nh = IPPROTO_NONE;
pkt += hdrextlen;
ENGINE_SET_EVENT(p, IPV6_EXTHDR_AH_RES_NOT_NULL);
}
- if(p->IPV6_EH_CNT < IPV6_MAX_OPT)
+ if(ip6_exthdrs_cnt < IPV6_MAX_OPT)
{
- p->IPV6_EXTHDRS[p->IPV6_EH_CNT].type = nh;
- p->IPV6_EXTHDRS[p->IPV6_EH_CNT].next = *pkt;
- p->IPV6_EXTHDRS[p->IPV6_EH_CNT].len = hdrextlen;
- p->IPV6_EXTHDRS[p->IPV6_EH_CNT].data = pkt+2;
- p->IPV6_EH_CNT++;
+ ip6_exthdrs[ip6_exthdrs_cnt].type = nh;
+ ip6_exthdrs[ip6_exthdrs_cnt].next = *pkt;
+ ip6_exthdrs[ip6_exthdrs_cnt].len = hdrextlen;
+ ip6_exthdrs[ip6_exthdrs_cnt].data = pkt+2;
+ ip6_exthdrs_cnt++;
}
- if (IPV6_EXTHDR_ISSET_AH(p)) {
+ if (ah) {
ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_AH);
nh = *pkt;
pkt += hdrextlen;
break;
}
- IPV6_EXTHDR_SET_AH(p, pkt);
+ ah = 1;
nh = *pkt;
pkt += hdrextlen;
}
}
-#ifdef DEBUG
- if (IPV6_EXTHDR_ISSET_FH(p)) {
- SCLogDebug("IPV6 FRAG - HDRLEN: %" PRIuMAX " NH: %" PRIu32 " OFFSET: %" PRIu32 " ID: %" PRIu32 "",
- (uintmax_t)IPV6_EXTHDR_GET_FH_HDRLEN(p), IPV6_EXTHDR_GET_FH_NH(p),
- IPV6_EXTHDR_GET_FH_OFFSET(p), IPV6_EXTHDR_GET_FH_ID(p));
- }
- if (IPV6_EXTHDR_ISSET_RH(p)) {
- SCLogDebug("IPV6 ROUTE - HDRLEN: %" PRIu32 " NH: %" PRIu32 " TYPE: %" PRIu32 "",
- IPV6_EXTHDR_GET_RH_HDRLEN(p), IPV6_EXTHDR_GET_RH_NH(p),
- IPV6_EXTHDR_GET_RH_TYPE(p));
- }
- if (IPV6_EXTHDR_ISSET_HH(p)) {
- SCLogDebug("IPV6 HOPOPT - HDRLEN: %" PRIu32 " NH: %" PRIu32 "",
- IPV6_EXTHDR_GET_HH_HDRLEN(p), IPV6_EXTHDR_GET_HH_NH(p));
- }
- if (IPV6_EXTHDR_ISSET_DH1(p)) {
- SCLogDebug("IPV6 DSTOPT1 - HDRLEN: %" PRIu32 " NH: %" PRIu32 "",
- IPV6_EXTHDR_GET_DH1_HDRLEN(p), IPV6_EXTHDR_GET_DH1_NH(p));
- }
- if (IPV6_EXTHDR_ISSET_DH2(p)) {
- SCLogDebug("IPV6 DSTOPT2 - HDRLEN: %" PRIu32 " NH: %" PRIu32 "",
- IPV6_EXTHDR_GET_DH2_HDRLEN(p), IPV6_EXTHDR_GET_DH2_NH(p));
- }
-#endif
return TM_ECODE_OK;
}
*/
static int DecodeIPV6RouteTest01 (void)
{
-
uint8_t raw_pkt1[] = {
0x60, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x2b, 0x40,
0x20, 0x01, 0xaa, 0xaa, 0x00, 0x01, 0x00, 0x00,
0xfa, 0x87, 0x00, 0x00,
};
Packet *p1 = PacketGetFromAlloc();
- if (unlikely(p1 == NULL))
- return 0;
+ FAIL_IF(unlikely(p1 == NULL));
ThreadVars tv;
DecodeThreadVars dtv;
- int result = 0;
PacketQueue pq;
FlowInitConfig(FLOW_QUIET);
DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1), &pq);
- if (!(IPV6_EXTHDR_ISSET_RH(p1))) {
- printf("ipv6 routing header not detected: ");
- goto end;
- }
-
- if (p1->ip6eh.ip6_exthdrs[0].len != 8) {
- printf("ipv6 routing length incorrect: ");
- goto end;
- }
-
- result = 1;
-end:
+ FAIL_IF (!(IPV6_EXTHDR_ISSET_RH(p1)));
+ FAIL_IF (p1->ip6eh.rh_type != 0);
PACKET_RECYCLE(p1);
SCFree(p1);
FlowShutdown();
- return result;
+ PASS;
}
/**
uint8_t raw_pkt1[] = {
0x60,0x00,0x00,0x00,0x00,0x20,0x00,0x01,0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
0x02,0x0f,0xfe,0xff,0xfe,0x98,0x3d,0x01,0xff,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x3a,0x00,0x05,0x02,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x3a,0x00,0xff, /* 0xff is a nonsene opt */
+ 0x02,0x00,0x00,0x00,0x00,
0x82,0x00,0x1c,0x6f,0x27,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
Packet *p1 = PacketGetFromAlloc();
- if (unlikely(p1 == NULL))
- return 0;
+ FAIL_IF(unlikely(p1 == NULL));
ThreadVars tv;
DecodeThreadVars dtv;
- int result = 0;
PacketQueue pq;
FlowInitConfig(FLOW_QUIET);
DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1), &pq);
- if (!(IPV6_EXTHDR_ISSET_HH(p1))) {
- printf("ipv6 routing header not detected: ");
- goto end;
- }
-
- if (p1->ip6eh.ip6_exthdrs[0].len != 8) {
- printf("ipv6 routing length incorrect: ");
- goto end;
- }
+ FAIL_IF (!(ENGINE_ISSET_EVENT(p1, IPV6_HOPOPTS_UNKNOWN_OPT)));
- if (ENGINE_ISSET_EVENT(p1, IPV6_HOPOPTS_UNKNOWN_OPT)) {
- printf("engine event IPV6_HOPOPTS_UNKNOWN_OPT set: ");
- goto end;
- }
-
- result = 1;
-end:
PACKET_RECYCLE(p1);
SCFree(p1);
FlowShutdown();
- return result;
+ PASS;
}
#endif /* UNITTESTS */
(p)->ip6h = NULL; \
(p)->ip6vars.ip_opts_len = 0; \
(p)->ip6vars.l4proto = 0; \
- (p)->ip6eh.ip6fh = NULL; \
- (p)->ip6eh.fh_offset = 0; \
- (p)->ip6eh.ip6rh = NULL; \
- (p)->ip6eh.ip6eh = NULL; \
- (p)->ip6eh.ip6dh1 = NULL; \
- (p)->ip6eh.ip6dh2 = NULL; \
- (p)->ip6eh.ip6hh = NULL; \
- (p)->ip6eh.ip6_exthdrs_cnt = 0; \
+ memset(&(p)->ip6eh, 0x00, sizeof((p)->ip6eh)); \
} while (0)
/* Fragment header */
uint32_t ip6fh_ident; /* identification */
} __attribute__((__packed__)) IPV6FragHdr;
-#define IPV6_EXTHDR_GET_RAW_FH_NH(p) ((p)->ip6eh.ip6fh->ip6fh_nxt)
-#define IPV6_EXTHDR_GET_RAW_FH_HDRLEN(p) sizeof(IPV6FragHdr)
-#define IPV6_EXTHDR_GET_RAW_FH_OFFSET(p) (ntohs((p)->ip6eh.ip6fh->ip6fh_offlg) & 0xFFF8)
-#define IPV6_EXTHDR_GET_RAW_FH_FLAG(p) (ntohs((p)->ip6eh.ip6fh->ip6fh_offlg) & 0x0001)
-#define IPV6_EXTHDR_GET_RAW_FH_ID(p) (ntohl((p)->ip6eh.ip6fh->ip6fh_ident))
-
-#define IPV6_EXTHDR_GET_FH_NH(p) IPV6_EXTHDR_GET_RAW_FH_NH((p))
-#define IPV6_EXTHDR_GET_FH_HDRLEN(p) IPV6_EXTHDR_GET_RAW_FH_HDRLEN((p))
-#define IPV6_EXTHDR_GET_FH_OFFSET(p) IPV6_EXTHDR_GET_RAW_FH_OFFSET((p))
-#define IPV6_EXTHDR_GET_FH_FLAG(p) IPV6_EXTHDR_GET_RAW_FH_FLAG((p))
-#define IPV6_EXTHDR_GET_FH_ID(p) IPV6_EXTHDR_GET_RAW_FH_ID((p))
+#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
/* rfc 1826 */
typedef struct IPV6AuthHdr_
including first 8 bytes. */
uint8_t ip6rh_type; /* routing type */
uint8_t ip6rh_segsleft; /* segments left */
-#if 0
- struct in6_addr ip6rh0_addr[23]; /* type 0 addresses */
- uint8_t ip6rh0_num_addrs; /* number of actual addresses in the
- array/packet. The array is guarranteed
- to be filled up to this number. */
-#endif
} __attribute__((__packed__)) IPV6RouteHdr;
-#define IPV6_EXTHDR_GET_RAW_RH_NH(p) ((p)->ip6eh.ip6rh->ip6rh_nxt)
-#define IPV6_EXTHDR_GET_RAW_RH_HDRLEN(p) ((p)->ip6eh.ip6rh->ip6rh_len)
-#define IPV6_EXTHDR_GET_RAW_RH_TYPE(p) (ntohs((p)->ip6eh.ip6rh->ip6rh_type))
-/* XXX */
-
-#define IPV6_EXTHDR_GET_RH_NH(p) IPV6_EXTHDR_GET_RAW_RH_NH((p))
-#define IPV6_EXTHDR_GET_RH_HDRLEN(p) IPV6_EXTHDR_GET_RAW_RH_HDRLEN((p))
-#define IPV6_EXTHDR_GET_RH_TYPE(p) IPV6_EXTHDR_GET_RAW_RH_TYPE((p))
-/* XXX */
-
/* Hop-by-Hop header and Destination Options header use options that are
* defined here. */
including first 8 bytes. */
} __attribute__((__packed__)) IPV6HopOptsHdr;
-#define IPV6_EXTHDR_GET_RAW_HH_NH(p) ((p)->ip6eh.ip6hh->ip6hh_nxt)
-#define IPV6_EXTHDR_GET_RAW_HH_HDRLEN(p) ((p)->ip6eh.ip6hh->ip6hh_len)
-/* XXX */
-
-#define IPV6_EXTHDR_GET_HH_NH(p) IPV6_EXTHDR_GET_RAW_HH_NH((p))
-#define IPV6_EXTHDR_GET_HH_HDRLEN(p) IPV6_EXTHDR_GET_RAW_HH_HDRLEN((p))
-/* XXX */
-
typedef struct IPV6DstOptsHdr_
{
uint8_t ip6dh_nxt; /* next header */
including first 8 bytes. */
} __attribute__((__packed__)) IPV6DstOptsHdr;
-#define IPV6_EXTHDR_GET_RAW_DH1_NH(p) ((p)->ip6eh.ip6dh1->ip6dh_nxt)
-#define IPV6_EXTHDR_GET_RAW_DH1_HDRLEN(p) ((p)->ip6eh.ip6dh1->ip6dh_len)
-/* XXX */
-
-#define IPV6_EXTHDR_GET_DH1_NH(p) IPV6_EXTHDR_GET_RAW_DH1_NH((p))
-#define IPV6_EXTHDR_GET_DH1_HDRLEN(p) IPV6_EXTHDR_GET_RAW_DH1_HDRLEN((p))
-/* XXX */
-
-#define IPV6_EXTHDR_GET_RAW_DH2_NH(p) ((p)->ip6eh.ip6dh2->ip6dh_nxt)
-#define IPV6_EXTHDR_GET_RAW_DH2_HDRLEN(p) ((p)->ip6eh.ip6dh2->ip6dh_len)
-/* XXX */
-
-#define IPV6_EXTHDR_GET_DH2_NH(p) IPV6_EXTHDR_GET_RAW_DH2_NH((p))
-#define IPV6_EXTHDR_GET_DH2_HDRLEN(p) IPV6_EXTHDR_GET_RAW_DH2_HDRLEN((p))
-/* XXX */
-
typedef struct IPV6GenOptHdr_
{
uint8_t type;
typedef struct IPV6ExtHdrs_
{
- const IPV6FragHdr *ip6fh;
+ _Bool rh_set;
+ uint8_t rh_type;
+
+ _Bool fh_set;
+ _Bool fh_more_frags_set;
+ uint8_t fh_nh;
+
+ uint8_t fh_prev_nh;
+ uint16_t fh_prev_hdr_offset;
+
+ uint16_t fh_header_offset;
+ uint16_t fh_data_offset;
+ uint16_t fh_data_len;
+
/* In fh_offset we store the offset of this extension into the packet past
* the ipv6 header. We use it in defrag for creating a defragmented packet
* without the frag header */
- uint16_t fh_offset;
-
- const IPV6RouteHdr *ip6rh;
- const IPV6AuthHdr *ip6ah;
- const IPV6EspHdr *ip6eh;
- const IPV6DstOptsHdr *ip6dh1;
- const IPV6DstOptsHdr *ip6dh2;
- const IPV6HopOptsHdr *ip6hh;
-
- /* Hop-By-Hop options */
- IPV6OptHAO ip6hh_opt_hao;
- IPV6OptRA ip6hh_opt_ra;
- IPV6OptJumbo ip6hh_opt_jumbo;
- /* Dest Options 1 */
- IPV6OptHAO ip6dh1_opt_hao;
- IPV6OptRA ip6dh1_opt_ra;
- IPV6OptJumbo ip6dh1_opt_jumbo;
- /* Dest Options 2 */
- IPV6OptHAO ip6dh2_opt_hao;
- IPV6OptRA ip6dh2_opt_ra;
- IPV6OptJumbo ip6dh2_opt_jumbo;
-
- IPV6GenOptHdr ip6_exthdrs[IPV6_MAX_OPT];
- uint8_t ip6_exthdrs_cnt;
+ uint16_t fh_offset;
+ uint32_t fh_id;
} IPV6ExtHdrs;
-#define IPV6_EXTHDR_FH(p) (p)->ip6eh.ip6fh
-#define IPV6_EXTHDR_RH(p) (p)->ip6eh.ip6rh
-#define IPV6_EXTHDR_AH(p) (p)->ip6eh.ip6ah
-#define IPV6_EXTHDR_EH(p) (p)->ip6eh.ip6eh
-#define IPV6_EXTHDR_DH1(p) (p)->ip6eh.ip6dh1
-#define IPV6_EXTHDR_DH2(p) (p)->ip6eh.ip6dh2
-#define IPV6_EXTHDR_HH(p) (p)->ip6eh.ip6hh
-
-#define IPV6_EXTHDR_HH_HAO(p) (p)->ip6eh.ip6hh_opt_hao
-#define IPV6_EXTHDR_DH1_HAO(p) (p)->ip6eh.ip6dh1_opt_hao
-#define IPV6_EXTHDR_DH2_HAO(p) (p)->ip6eh.ip6dh2_opt_hao
-#define IPV6_EXTHDR_HH_RA(p) (p)->ip6eh.ip6hh_opt_ra
-#define IPV6_EXTHDR_DH1_RA(p) (p)->ip6eh.ip6dh1_opt_ra
-#define IPV6_EXTHDR_DH2_RA(p) (p)->ip6eh.ip6dh2_opt_ra
-#define IPV6_EXTHDR_HH_JUMBO(p) (p)->ip6eh.ip6hh_opt_jumbo
-#define IPV6_EXTHDR_DH1_JUMBO(p) (p)->ip6eh.ip6dh1_opt_jumbo
-#define IPV6_EXTHDR_DH2_JUMBO(p) (p)->ip6eh.ip6dh2_opt_jumbo
-
-#define IPV6_EXTHDR_SET_FH(p,pkt) IPV6_EXTHDR_FH((p)) = (IPV6FragHdr *)pkt
-#define IPV6_EXTHDR_ISSET_FH(p) (IPV6_EXTHDR_FH((p)) != NULL)
-#define IPV6_EXTHDR_SET_RH(p,pkt) IPV6_EXTHDR_RH((p)) = (IPV6RouteHdr *)pkt
-#define IPV6_EXTHDR_ISSET_RH(p) (IPV6_EXTHDR_RH((p)) != NULL)
-#define IPV6_EXTHDR_SET_AH(p,pkt) IPV6_EXTHDR_AH((p)) = (IPV6AuthHdr *)pkt
-#define IPV6_EXTHDR_ISSET_AH(p) (IPV6_EXTHDR_AH((p)) != NULL)
-#define IPV6_EXTHDR_SET_EH(p,pkt) IPV6_EXTHDR_EH((p)) = (IPV6EspHdr *)pkt
-#define IPV6_EXTHDR_ISSET_EH(p) (IPV6_EXTHDR_EH((p)) != NULL)
-#define IPV6_EXTHDR_SET_DH1(p,pkt) IPV6_EXTHDR_DH1((p)) = (IPV6DstOptsHdr *)pkt
-#define IPV6_EXTHDR_ISSET_DH1(p) (IPV6_EXTHDR_DH1((p)) != NULL)
-#define IPV6_EXTHDR_SET_DH2(p,pkt) IPV6_EXTHDR_DH2((p)) = (IPV6DstOptsHdr *)pkt
-#define IPV6_EXTHDR_ISSET_DH2(p) (IPV6_EXTHDR_DH2((p)) != NULL)
-#define IPV6_EXTHDR_SET_HH(p,pkt) IPV6_EXTHDR_HH((p)) = (IPV6HopOptsHdr *)pkt
-#define IPV6_EXTHDR_ISSET_HH(p) (IPV6_EXTHDR_HH((p)) != NULL)
+#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
void DecodeIPV6RegisterTests(void);