X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv6%2Fnetfilter%2Fip6t_esp.c;h=e39dd236fd8e60e5fc2ae95e9d31b7969e9d1564;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=ecdd48bba91131602c780c3e3fb3f1353a15994f;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/net/ipv6/netfilter/ip6t_esp.c b/net/ipv6/netfilter/ip6t_esp.c index ecdd48bba..e39dd236f 100644 --- a/net/ipv6/netfilter/ip6t_esp.c +++ b/net/ipv6/netfilter/ip6t_esp.c @@ -32,8 +32,8 @@ static inline int spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert) { int r=0; - DEBUGP("esp spi_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ', - min,spi,max); + DEBUGP("esp spi_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ', + min,spi,max); r=(spi >= min && spi <= max) ^ invert; DEBUGP(" result %s\n",r? "PASS\n" : "FAILED\n"); return r; @@ -45,11 +45,10 @@ 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) { - struct ip_esp_hdr *esp = NULL; + struct ip_esp_hdr _esp, *eh = NULL; const struct ip6t_esp *espinfo = matchinfo; unsigned int temp; int len; @@ -67,73 +66,74 @@ match(const struct sk_buff *skb, len = skb->len - ptr; temp = 0; - while (ip6t_ext_hdr(nexthdr)) { - struct ipv6_opt_hdr *hdr; - int hdrlen; + while (ip6t_ext_hdr(nexthdr)) { + struct ipv6_opt_hdr _hdr, *hp; + int hdrlen; DEBUGP("ipv6_esp header iteration \n"); /* Is there enough space for the next ext header? */ - if (len < (int)sizeof(struct ipv6_opt_hdr)) - return 0; + if (len < sizeof(struct ipv6_opt_hdr)) + return 0; /* No more exthdr -> evaluate */ - if (nexthdr == NEXTHDR_NONE) { + if (nexthdr == NEXTHDR_NONE) break; - } /* ESP -> evaluate */ - if (nexthdr == NEXTHDR_ESP) { + if (nexthdr == NEXTHDR_ESP) { temp |= MASK_ESP; 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; - else - hdrlen = ipv6_optlen(hdr); + if (nexthdr == NEXTHDR_FRAGMENT) + hdrlen = 8; + else if (nexthdr == NEXTHDR_AUTH) + hdrlen = (hp->hdrlen+2)<<2; + else + hdrlen = ipv6_optlen(hp); /* set the flag */ - switch (nexthdr){ - case NEXTHDR_HOP: - case NEXTHDR_ROUTING: - case NEXTHDR_FRAGMENT: - case NEXTHDR_AUTH: - case NEXTHDR_DEST: - break; - default: - DEBUGP("ipv6_esp match: unknown nextheader %u\n",nexthdr); - return 0; - break; + switch (nexthdr) { + case NEXTHDR_HOP: + case NEXTHDR_ROUTING: + case NEXTHDR_FRAGMENT: + case NEXTHDR_AUTH: + case NEXTHDR_DEST: + break; + default: + DEBUGP("ipv6_esp match: unknown nextheader %u\n",nexthdr); + return 0; } - nexthdr = hdr->nexthdr; - len -= hdrlen; - ptr += hdrlen; - if ( ptr > skb->len ) { + nexthdr = hp->nexthdr; + len -= hdrlen; + ptr += hdrlen; + if (ptr > skb->len) { DEBUGP("ipv6_esp: new pointer too large! \n"); break; } - } + } /* ESP header not found */ - if ( temp != MASK_ESP ) return 0; + if (temp != MASK_ESP) + return 0; - if (len < (int)sizeof(struct ip_esp_hdr)){ - *hotdrop = 1; - return 0; - } + if (len < sizeof(struct ip_esp_hdr)) { + *hotdrop = 1; + return 0; + } - esp = (struct ip_esp_hdr *) (skb->data + ptr); + eh = skb_header_pointer(skb, ptr, sizeof(_esp), &_esp); + BUG_ON(eh == NULL); - DEBUGP("IPv6 ESP SPI %u %08X\n", ntohl(esp->spi), ntohl(esp->spi)); + DEBUGP("IPv6 ESP SPI %u %08X\n", ntohl(eh->spi), ntohl(eh->spi)); - return (esp != NULL) + return (eh != NULL) && spi_match(espinfo->spis[0], espinfo->spis[1], - ntohl(esp->spi), + ntohl(eh->spi), !!(espinfo->invflags & IP6T_ESP_INV_SPI)); } @@ -157,7 +157,6 @@ checkentry(const char *tablename, espinfo->invflags); return 0; } - return 1; }