vserver 1.9.5.x5
[linux-2.6.git] / net / ipv6 / netfilter / ip6t_esp.c
index ecdd48b..e39dd23 100644 (file)
@@ -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;
 }