vserver 1.9.3
[linux-2.6.git] / net / bridge / netfilter / ebt_arp.c
index eb67584..b94c48c 100644 (file)
@@ -19,72 +19,79 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in
    const struct net_device *out, const void *data, unsigned int datalen)
 {
        struct ebt_arp_info *info = (struct ebt_arp_info *)data;
-       struct arphdr arph;
+       struct arphdr _arph, *ah;
 
-       if (skb_copy_bits(skb, 0, &arph, sizeof(arph)))
+       ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph);
+       if (ah == NULL)
                return EBT_NOMATCH;
        if (info->bitmask & EBT_ARP_OPCODE && FWINV(info->opcode !=
-          arph.ar_op, EBT_ARP_OPCODE))
+          ah->ar_op, EBT_ARP_OPCODE))
                return EBT_NOMATCH;
        if (info->bitmask & EBT_ARP_HTYPE && FWINV(info->htype !=
-          arph.ar_hrd, EBT_ARP_HTYPE))
+          ah->ar_hrd, EBT_ARP_HTYPE))
                return EBT_NOMATCH;
        if (info->bitmask & EBT_ARP_PTYPE && FWINV(info->ptype !=
-          arph.ar_pro, EBT_ARP_PTYPE))
+          ah->ar_pro, EBT_ARP_PTYPE))
                return EBT_NOMATCH;
 
        if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP)) {
-               uint32_t addr;
+               uint32_t _addr, *ap;
 
                /* IPv4 addresses are always 4 bytes */
-               if (arph.ar_pln != sizeof(uint32_t))
+               if (ah->ar_pln != sizeof(uint32_t))
                        return EBT_NOMATCH;
                if (info->bitmask & EBT_ARP_SRC_IP) {
-                       if (skb_copy_bits(skb, sizeof(struct arphdr) +
-                           arph.ar_hln, &addr, sizeof(addr)))
+                       ap = skb_header_pointer(skb, sizeof(struct arphdr) +
+                                               ah->ar_hln, sizeof(_addr),
+                                               &_addr);
+                       if (ap == NULL)
                                return EBT_NOMATCH;
-                       if (FWINV(info->saddr != (addr & info->smsk),
+                       if (FWINV(info->saddr != (*ap & info->smsk),
                           EBT_ARP_SRC_IP))
                                return EBT_NOMATCH;
                }
 
                if (info->bitmask & EBT_ARP_DST_IP) {
-                       if (skb_copy_bits(skb, sizeof(struct arphdr) +
-                           2*arph.ar_hln + sizeof(uint32_t), &addr,
-                           sizeof(addr)))
+                       ap = skb_header_pointer(skb, sizeof(struct arphdr) +
+                                               2*ah->ar_hln+sizeof(uint32_t),
+                                               sizeof(_addr), &_addr);
+                       if (ap == NULL)
                                return EBT_NOMATCH;
-                       if (FWINV(info->daddr != (addr & info->dmsk),
+                       if (FWINV(info->daddr != (*ap & info->dmsk),
                           EBT_ARP_DST_IP))
                                return EBT_NOMATCH;
                }
        }
 
        if (info->bitmask & (EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC)) {
-               unsigned char mac[ETH_ALEN];
+               unsigned char _mac[ETH_ALEN], *mp;
                uint8_t verdict, i;
 
                /* MAC addresses are 6 bytes */
-               if (arph.ar_hln != ETH_ALEN)
+               if (ah->ar_hln != ETH_ALEN)
                        return EBT_NOMATCH;
                if (info->bitmask & EBT_ARP_SRC_MAC) {
-                       if (skb_copy_bits(skb, sizeof(struct arphdr), &mac,
-                           ETH_ALEN))
+                       mp = skb_header_pointer(skb, sizeof(struct arphdr),
+                                               sizeof(_mac), &_mac);
+                       if (mp == NULL)
                                return EBT_NOMATCH;
                        verdict = 0;
                        for (i = 0; i < 6; i++)
-                               verdict |= (mac[i] ^ info->smaddr[i]) &
+                               verdict |= (mp[i] ^ info->smaddr[i]) &
                                       info->smmsk[i];
                        if (FWINV(verdict != 0, EBT_ARP_SRC_MAC))
                                return EBT_NOMATCH;
                }
 
                if (info->bitmask & EBT_ARP_DST_MAC) {
-                       if (skb_copy_bits(skb, sizeof(struct arphdr) +
-                           arph.ar_hln + arph.ar_pln, &mac, ETH_ALEN))
+                       mp = skb_header_pointer(skb, sizeof(struct arphdr) +
+                                               ah->ar_hln + ah->ar_pln,
+                                               sizeof(_mac), &_mac);
+                       if (mp == NULL)
                                return EBT_NOMATCH;
                        verdict = 0;
                        for (i = 0; i < 6; i++)
-                               verdict |= (mac[i] ^ info->dmaddr[i]) &
+                               verdict |= (mp[i] ^ info->dmaddr[i]) &
                                        info->dmmsk[i];
                        if (FWINV(verdict != 0, EBT_ARP_DST_MAC))
                                return EBT_NOMATCH;
@@ -101,8 +108,8 @@ static int ebt_arp_check(const char *tablename, unsigned int hookmask,
 
        if (datalen != EBT_ALIGN(sizeof(struct ebt_arp_info)))
                return -EINVAL;
-       if ((e->ethproto != __constant_htons(ETH_P_ARP) &&
-          e->ethproto != __constant_htons(ETH_P_RARP)) ||
+       if ((e->ethproto != htons(ETH_P_ARP) &&
+          e->ethproto != htons(ETH_P_RARP)) ||
           e->invflags & EBT_IPROTO)
                return -EINVAL;
        if (info->bitmask & ~EBT_ARP_MASK || info->invflags & ~EBT_ARP_MASK)