netfilter: xtables: do centralized checkentry call (1/2)
[safe/jmp/linux-2.6] / net / bridge / netfilter / ebt_dnat.c
1 /*
2  *  ebt_dnat
3  *
4  *      Authors:
5  *      Bart De Schuymer <bdschuym@pandora.be>
6  *
7  *  June, 2002
8  *
9  */
10 #include <linux/module.h>
11 #include <net/sock.h>
12 #include <linux/netfilter.h>
13 #include <linux/netfilter/x_tables.h>
14 #include <linux/netfilter_bridge/ebtables.h>
15 #include <linux/netfilter_bridge/ebt_nat.h>
16
17 static unsigned int
18 ebt_dnat_tg(struct sk_buff *skb, const struct net_device *in,
19             const struct net_device *out, unsigned int hook_nr,
20             const struct xt_target *target, const void *data)
21 {
22         const struct ebt_nat_info *info = data;
23
24         if (!skb_make_writable(skb, 0))
25                 return EBT_DROP;
26
27         memcpy(eth_hdr(skb)->h_dest, info->mac, ETH_ALEN);
28         return info->target;
29 }
30
31 static bool
32 ebt_dnat_tg_check(const char *tablename, const void *entry,
33                   const struct xt_target *target, void *data,
34                   unsigned int hookmask)
35 {
36         const struct ebt_nat_info *info = data;
37
38         if (BASE_CHAIN && info->target == EBT_RETURN)
39                 return false;
40         CLEAR_BASE_CHAIN_BIT;
41         if ( (strcmp(tablename, "nat") ||
42            (hookmask & ~((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT)))) &&
43            (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) )
44                 return false;
45         if (INVALID_TARGET)
46                 return false;
47         return true;
48 }
49
50 static struct xt_target ebt_dnat_tg_reg __read_mostly = {
51         .name           = "dnat",
52         .revision       = 0,
53         .family         = NFPROTO_BRIDGE,
54         .hooks          = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_PRE_ROUTING) |
55                           (1 << NF_BR_LOCAL_OUT) | (1 << NF_BR_BROUTING),
56         .target         = ebt_dnat_tg,
57         .checkentry     = ebt_dnat_tg_check,
58         .targetsize     = XT_ALIGN(sizeof(struct ebt_nat_info)),
59         .me             = THIS_MODULE,
60 };
61
62 static int __init ebt_dnat_init(void)
63 {
64         return xt_register_target(&ebt_dnat_tg_reg);
65 }
66
67 static void __exit ebt_dnat_fini(void)
68 {
69         xt_unregister_target(&ebt_dnat_tg_reg);
70 }
71
72 module_init(ebt_dnat_init);
73 module_exit(ebt_dnat_fini);
74 MODULE_DESCRIPTION("Ebtables: Destination MAC address translation");
75 MODULE_LICENSE("GPL");