u8 nexthdr = *nexthdrp;
while (ipv6_ext_hdr(nexthdr)) {
- struct ipv6_opt_hdr hdr;
+ struct ipv6_opt_hdr _hdr, *hp;
int hdrlen;
if (len < (int)sizeof(struct ipv6_opt_hdr))
return -1;
if (nexthdr == NEXTHDR_NONE)
return -1;
- if (skb_copy_bits(skb, start, &hdr, sizeof(hdr)))
+ hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr);
+ if (hp == NULL)
BUG();
if (nexthdr == NEXTHDR_FRAGMENT) {
- unsigned short frag_off;
- if (skb_copy_bits(skb,
- start+offsetof(struct frag_hdr,
- frag_off),
- &frag_off,
- sizeof(frag_off))) {
+ unsigned short _frag_off, *fp;
+ fp = skb_header_pointer(skb,
+ start+offsetof(struct frag_hdr,
+ frag_off),
+ sizeof(_frag_off),
+ &_frag_off);
+ if (fp == NULL)
return -1;
- }
- if (ntohs(frag_off) & ~0x7)
+ if (ntohs(*fp) & ~0x7)
break;
hdrlen = 8;
} else if (nexthdr == NEXTHDR_AUTH)
- hdrlen = (hdr.hdrlen+2)<<2;
+ hdrlen = (hp->hdrlen+2)<<2;
else
- hdrlen = ipv6_optlen(&hdr);
+ hdrlen = ipv6_optlen(hp);
- nexthdr = hdr.nexthdr;
+ nexthdr = hp->nexthdr;
len -= hdrlen;
start += hdrlen;
}