X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=net%2Fipv6%2Fnetfilter%2Fip6t_ipv6header.c;h=32e67f05845b44353758983ed8c5935e6a028dd0;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=ae5d1c6c8002556ea812f097594a8dbcb83c55be;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/net/ipv6/netfilter/ip6t_ipv6header.c b/net/ipv6/netfilter/ip6t_ipv6header.c index ae5d1c6c8..32e67f058 100644 --- a/net/ipv6/netfilter/ip6t_ipv6header.c +++ b/net/ipv6/netfilter/ip6t_ipv6header.c @@ -31,8 +31,7 @@ ipv6header_match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - const void *protohdr, - u_int16_t datalen, + unsigned int protoff, int *hotdrop) { const struct ip6t_ipv6header_info *info = matchinfo; @@ -52,7 +51,7 @@ ipv6header_match(const struct sk_buff *skb, temp = 0; while (ip6t_ext_hdr(nexthdr)) { - struct ipv6_opt_hdr *hdr; + struct ipv6_opt_hdr _hdr, *hp; int hdrlen; /* Is there enough space for the next ext header? */ @@ -69,15 +68,16 @@ ipv6header_match(const struct sk_buff *skb, break; } - hdr=(struct ipv6_opt_hdr *)skb->data+ptr; + hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr); + BUG_ON(hp == NULL); /* Calculate the header length */ if (nexthdr == NEXTHDR_FRAGMENT) { 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); /* set the flag */ switch (nexthdr){ @@ -101,7 +101,7 @@ ipv6header_match(const struct sk_buff *skb, break; } - nexthdr = hdr->nexthdr; + nexthdr = hp->nexthdr; len -= hdrlen; ptr += hdrlen; if (ptr > skb->len) @@ -112,10 +112,14 @@ ipv6header_match(const struct sk_buff *skb, temp |= MASK_PROTO; if (info->modeflag) - return (!( (temp & info->matchflags) - ^ info->matchflags) ^ info->invflags); - else - return (!( temp ^ info->matchflags) ^ info->invflags); + return !((temp ^ info->matchflags ^ info->invflags) + & info->matchflags); + else { + if (info->invflags) + return temp != info->matchflags; + else + return temp == info->matchflags; + } } static int @@ -125,11 +129,18 @@ ipv6header_checkentry(const char *tablename, unsigned int matchsize, unsigned int hook_mask) { + const struct ip6t_ipv6header_info *info = matchinfo; + /* Check for obvious errors */ /* This match is valid in all hooks! */ if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_ipv6header_info))) return 0; + /* invflags is 0 or 0xff in hard mode */ + if ((!info->modeflag) && info->invflags != 0x00 + && info->invflags != 0xFF) + return 0; + return 1; }