Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* NETMAP - static NAT mapping of IP network addresses (1:1). |
2 | * The mapping can be applied to source (POSTROUTING), | |
3 | * destination (PREROUTING), or both (with separate rules). | |
4 | */ | |
5 | ||
6 | /* (C) 2000-2001 Svenning Soerensen <svenning@post5.tele.dk> | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License version 2 as | |
10 | * published by the Free Software Foundation. | |
11 | */ | |
12 | ||
1da177e4 LT |
13 | #include <linux/ip.h> |
14 | #include <linux/module.h> | |
15 | #include <linux/netdevice.h> | |
16 | #include <linux/netfilter.h> | |
17 | #include <linux/netfilter_ipv4.h> | |
6709dbbb | 18 | #include <linux/netfilter/x_tables.h> |
5b1158e9 | 19 | #include <net/netfilter/nf_nat_rule.h> |
1da177e4 | 20 | |
1da177e4 LT |
21 | MODULE_LICENSE("GPL"); |
22 | MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>"); | |
2ae15b64 | 23 | MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv4 subnets"); |
1da177e4 | 24 | |
e1931b78 | 25 | static bool |
d3c5ee6d JE |
26 | netmap_tg_check(const char *tablename, const void *e, |
27 | const struct xt_target *target, void *targinfo, | |
28 | unsigned int hook_mask) | |
1da177e4 | 29 | { |
587aa641 | 30 | const struct nf_nat_multi_range_compat *mr = targinfo; |
1da177e4 | 31 | |
1da177e4 | 32 | if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) { |
0d53778e | 33 | pr_debug("NETMAP:check: bad MAP_IPS.\n"); |
e1931b78 | 34 | return false; |
1da177e4 LT |
35 | } |
36 | if (mr->rangesize != 1) { | |
0d53778e | 37 | pr_debug("NETMAP:check: bad rangesize %u.\n", mr->rangesize); |
e1931b78 | 38 | return false; |
1da177e4 | 39 | } |
e1931b78 | 40 | return true; |
1da177e4 LT |
41 | } |
42 | ||
43 | static unsigned int | |
d3c5ee6d JE |
44 | netmap_tg(struct sk_buff *skb, const struct net_device *in, |
45 | const struct net_device *out, unsigned int hooknum, | |
46 | const struct xt_target *target, const void *targinfo) | |
1da177e4 | 47 | { |
587aa641 | 48 | struct nf_conn *ct; |
1da177e4 | 49 | enum ip_conntrack_info ctinfo; |
6a19d614 | 50 | __be32 new_ip, netmask; |
587aa641 PM |
51 | const struct nf_nat_multi_range_compat *mr = targinfo; |
52 | struct nf_nat_range newrange; | |
1da177e4 | 53 | |
6e23ae2a PM |
54 | NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING |
55 | || hooknum == NF_INET_POST_ROUTING | |
56 | || hooknum == NF_INET_LOCAL_OUT); | |
3db05fea | 57 | ct = nf_ct_get(skb, &ctinfo); |
1da177e4 LT |
58 | |
59 | netmask = ~(mr->range[0].min_ip ^ mr->range[0].max_ip); | |
60 | ||
6e23ae2a | 61 | if (hooknum == NF_INET_PRE_ROUTING || hooknum == NF_INET_LOCAL_OUT) |
3db05fea | 62 | new_ip = ip_hdr(skb)->daddr & ~netmask; |
1da177e4 | 63 | else |
3db05fea | 64 | new_ip = ip_hdr(skb)->saddr & ~netmask; |
1da177e4 LT |
65 | new_ip |= mr->range[0].min_ip & netmask; |
66 | ||
587aa641 | 67 | newrange = ((struct nf_nat_range) |
1da177e4 LT |
68 | { mr->range[0].flags | IP_NAT_RANGE_MAP_IPS, |
69 | new_ip, new_ip, | |
70 | mr->range[0].min, mr->range[0].max }); | |
71 | ||
72 | /* Hand modified range to generic setup. */ | |
cc01dcbd | 73 | return nf_nat_setup_info(ct, &newrange, HOOK2MANIP(hooknum)); |
1da177e4 LT |
74 | } |
75 | ||
d3c5ee6d | 76 | static struct xt_target netmap_tg_reg __read_mostly = { |
0d53778e | 77 | .name = "NETMAP", |
6709dbbb | 78 | .family = AF_INET, |
d3c5ee6d | 79 | .target = netmap_tg, |
587aa641 | 80 | .targetsize = sizeof(struct nf_nat_multi_range_compat), |
1d5cd909 | 81 | .table = "nat", |
6e23ae2a PM |
82 | .hooks = (1 << NF_INET_PRE_ROUTING) | |
83 | (1 << NF_INET_POST_ROUTING) | | |
84 | (1 << NF_INET_LOCAL_OUT), | |
d3c5ee6d | 85 | .checkentry = netmap_tg_check, |
e905a9ed | 86 | .me = THIS_MODULE |
1da177e4 LT |
87 | }; |
88 | ||
d3c5ee6d | 89 | static int __init netmap_tg_init(void) |
1da177e4 | 90 | { |
d3c5ee6d | 91 | return xt_register_target(&netmap_tg_reg); |
1da177e4 LT |
92 | } |
93 | ||
d3c5ee6d | 94 | static void __exit netmap_tg_exit(void) |
1da177e4 | 95 | { |
d3c5ee6d | 96 | xt_unregister_target(&netmap_tg_reg); |
1da177e4 LT |
97 | } |
98 | ||
d3c5ee6d JE |
99 | module_init(netmap_tg_init); |
100 | module_exit(netmap_tg_exit); |