ipv6: simplify ext hdr parsing

pull/2086/head
Victor Julien 9 years ago
parent abb0a31aed
commit b77d307272

@ -106,7 +106,7 @@ static inline
#endif #endif
void DecodeIPV6FragHeader(Packet *p, uint8_t *pkt, void DecodeIPV6FragHeader(Packet *p, uint8_t *pkt,
uint16_t hdrextlen, uint16_t plen, uint16_t hdrextlen, uint16_t plen,
uint16_t ip6_exthdrs_cnt, IPV6GenOptHdr *ip6_exthdrs) uint16_t prev_hdrextlen)
{ {
uint16_t frag_offset = (*(pkt + 2) << 8 | *(pkt + 3)) & 0xFFF8; uint16_t frag_offset = (*(pkt + 2) << 8 | *(pkt + 3)) & 0xFFF8;
int frag_morefrags = (*(pkt + 2) << 8 | *(pkt + 3)) & 0x0001; int frag_morefrags = (*(pkt + 2) << 8 | *(pkt + 3)) & 0x0001;
@ -135,8 +135,8 @@ void DecodeIPV6FragHeader(Packet *p, uint8_t *pkt,
p->ip6eh.fh_data_len = data_len; p->ip6eh.fh_data_len = data_len;
/* if we have a prev hdr, store the type and offset of it */ /* if we have a prev hdr, store the type and offset of it */
if (ip6_exthdrs_cnt > 1) { if (prev_hdrextlen) {
p->ip6eh.fh_prev_hdr_offset = frag_hdr_offset - ip6_exthdrs[ip6_exthdrs_cnt - 1].len; p->ip6eh.fh_prev_hdr_offset = frag_hdr_offset - prev_hdrextlen;
} }
SCLogDebug("IPV6 FH: frag_hdr_offset %u, data_offset %u, data_len %u", SCLogDebug("IPV6 FH: frag_hdr_offset %u, data_offset %u, data_len %u",
@ -151,14 +151,10 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
uint8_t *orig_pkt = pkt; uint8_t *orig_pkt = pkt;
uint8_t nh = 0; /* careful, 0 is actually a real type */ uint8_t nh = 0; /* careful, 0 is actually a real type */
uint16_t hdrextlen; uint16_t hdrextlen = 0;
uint16_t plen; uint16_t plen;
char dstopts = 0; char dstopts = 0;
char exthdr_fh_done = 0; char exthdr_fh_done = 0;
uint8_t ip6_exthdrs_cnt = 0;
IPV6GenOptHdr ip6_exthdrs[IPV6_MAX_OPT];
int hh = 0; int hh = 0;
int rh = 0; int rh = 0;
int eh = 0; int eh = 0;
@ -212,15 +208,6 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
SCReturn; SCReturn;
} }
if (ip6_exthdrs_cnt < IPV6_MAX_OPT)
{
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 (rh) { if (rh) {
ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_RH); ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_RH);
/* skip past this extension so we can continue parsing the rest /* skip past this extension so we can continue parsing the rest
@ -260,15 +247,6 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
SCReturn; SCReturn;
} }
if (ip6_exthdrs_cnt < IPV6_MAX_OPT)
{
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 */ uint8_t *ptr = pkt + 2; /* +2 to go past nxthdr and len */
/* point the pointers to right structures /* point the pointers to right structures
@ -431,6 +409,7 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
} }
case IPPROTO_FRAGMENT: case IPPROTO_FRAGMENT:
{
IPV6_SET_L4PROTO(p,nh); IPV6_SET_L4PROTO(p,nh);
/* store the offset of this extension into the packet /* store the offset of this extension into the packet
* past the ipv6 header. We use it in defrag for creating * past the ipv6 header. We use it in defrag for creating
@ -440,6 +419,7 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
exthdr_fh_done = 1; exthdr_fh_done = 1;
} }
uint16_t prev_hdrextlen = hdrextlen;
hdrextlen = sizeof(IPV6FragHdr); hdrextlen = sizeof(IPV6FragHdr);
if (hdrextlen > plen) { if (hdrextlen > plen) {
ENGINE_SET_EVENT(p, IPV6_TRUNC_EXTHDR); ENGINE_SET_EVENT(p, IPV6_TRUNC_EXTHDR);
@ -452,15 +432,6 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
/* non fatal, lets try to continue */ /* non fatal, lets try to continue */
} }
if(ip6_exthdrs_cnt<IPV6_MAX_OPT)
{
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)) { if (IPV6_EXTHDR_ISSET_FH(p)) {
ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_FH); ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_FH);
nh = *pkt; nh = *pkt;
@ -473,8 +444,7 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
IPV6_EXTHDR_SET_FH(p); IPV6_EXTHDR_SET_FH(p);
/* parse the header and setup the vars */ /* parse the header and setup the vars */
DecodeIPV6FragHeader(p, pkt, hdrextlen, plen, DecodeIPV6FragHeader(p, pkt, hdrextlen, plen, prev_hdrextlen);
ip6_exthdrs_cnt, ip6_exthdrs);
/* if FH has offset 0 and no more fragments are coming, we /* if FH has offset 0 and no more fragments are coming, we
* parse this packet further right away, no defrag will be * parse this packet further right away, no defrag will be
@ -492,7 +462,7 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
/* the rest is parsed upon reassembly */ /* the rest is parsed upon reassembly */
p->flags |= PKT_IS_FRAGMENT; p->flags |= PKT_IS_FRAGMENT;
SCReturn; SCReturn;
}
case IPPROTO_ESP: case IPPROTO_ESP:
{ {
IPV6_SET_L4PROTO(p,nh); IPV6_SET_L4PROTO(p,nh);
@ -502,15 +472,6 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
SCReturn; SCReturn;
} }
if(ip6_exthdrs_cnt<IPV6_MAX_OPT)
{
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 (eh) { if (eh) {
ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_EH); ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_EH);
SCReturn; SCReturn;
@ -545,15 +506,6 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
ENGINE_SET_EVENT(p, IPV6_EXTHDR_AH_RES_NOT_NULL); ENGINE_SET_EVENT(p, IPV6_EXTHDR_AH_RES_NOT_NULL);
} }
if(ip6_exthdrs_cnt < IPV6_MAX_OPT)
{
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 (ah) { if (ah) {
ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_AH); ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_AH);
nh = *pkt; nh = *pkt;

@ -1073,7 +1073,7 @@ error:
void DecodeIPV6FragHeader(Packet *p, uint8_t *pkt, void DecodeIPV6FragHeader(Packet *p, uint8_t *pkt,
uint16_t hdrextlen, uint16_t plen, uint16_t hdrextlen, uint16_t plen,
uint16_t ip6_exthdrs_cnt, IPV6GenOptHdr *ip6_exthdrs); uint16_t prev_hdrextlen);
static Packet * static Packet *
IPV6BuildTestPacket(uint32_t id, uint16_t off, int mf, const char content, IPV6BuildTestPacket(uint32_t id, uint16_t off, int mf, const char content,
@ -1115,7 +1115,7 @@ IPV6BuildTestPacket(uint32_t id, uint16_t off, int mf, const char content,
fh->ip6fh_ident = htonl(id); fh->ip6fh_ident = htonl(id);
fh->ip6fh_offlg = htons((off << 3) | mf); fh->ip6fh_offlg = htons((off << 3) | mf);
DecodeIPV6FragHeader(p, (uint8_t *)fh, 8, 8 + content_len, 0, NULL); DecodeIPV6FragHeader(p, (uint8_t *)fh, 8, 8 + content_len, 0);
pcontent = SCCalloc(1, content_len); pcontent = SCCalloc(1, content_len);
if (unlikely(pcontent == NULL)) if (unlikely(pcontent == NULL))

Loading…
Cancel
Save