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 JK |
19 | #ifdef CONFIG_NF_NAT_NEEDED |
20 | #include <net/netfilter/nf_nat_rule.h> | |
21 | #else | |
1da177e4 | 22 | #include <linux/netfilter_ipv4/ip_nat_rule.h> |
5b1158e9 | 23 | #endif |
1da177e4 LT |
24 | |
25 | #define MODULENAME "NETMAP" | |
26 | MODULE_LICENSE("GPL"); | |
27 | MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>"); | |
28 | MODULE_DESCRIPTION("iptables 1:1 NAT mapping of IP networks target"); | |
29 | ||
30 | #if 0 | |
31 | #define DEBUGP printk | |
32 | #else | |
33 | #define DEBUGP(format, args...) | |
34 | #endif | |
35 | ||
36 | static int | |
37 | check(const char *tablename, | |
2e4e6a17 | 38 | const void *e, |
c4986734 | 39 | const struct xt_target *target, |
1da177e4 | 40 | void *targinfo, |
1da177e4 LT |
41 | unsigned int hook_mask) |
42 | { | |
43 | const struct ip_nat_multi_range_compat *mr = targinfo; | |
44 | ||
1da177e4 LT |
45 | if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) { |
46 | DEBUGP(MODULENAME":check: bad MAP_IPS.\n"); | |
47 | return 0; | |
48 | } | |
49 | if (mr->rangesize != 1) { | |
50 | DEBUGP(MODULENAME":check: bad rangesize %u.\n", mr->rangesize); | |
51 | return 0; | |
52 | } | |
53 | return 1; | |
54 | } | |
55 | ||
56 | static unsigned int | |
57 | target(struct sk_buff **pskb, | |
58 | const struct net_device *in, | |
59 | const struct net_device *out, | |
60 | unsigned int hooknum, | |
c4986734 | 61 | const struct xt_target *target, |
fe1cb108 | 62 | const void *targinfo) |
1da177e4 LT |
63 | { |
64 | struct ip_conntrack *ct; | |
65 | enum ip_conntrack_info ctinfo; | |
6a19d614 | 66 | __be32 new_ip, netmask; |
1da177e4 LT |
67 | const struct ip_nat_multi_range_compat *mr = targinfo; |
68 | struct ip_nat_range newrange; | |
69 | ||
70 | IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING | |
000efe1d GWS |
71 | || hooknum == NF_IP_POST_ROUTING |
72 | || hooknum == NF_IP_LOCAL_OUT); | |
1da177e4 LT |
73 | ct = ip_conntrack_get(*pskb, &ctinfo); |
74 | ||
75 | netmask = ~(mr->range[0].min_ip ^ mr->range[0].max_ip); | |
76 | ||
000efe1d | 77 | if (hooknum == NF_IP_PRE_ROUTING || hooknum == NF_IP_LOCAL_OUT) |
1da177e4 LT |
78 | new_ip = (*pskb)->nh.iph->daddr & ~netmask; |
79 | else | |
80 | new_ip = (*pskb)->nh.iph->saddr & ~netmask; | |
81 | new_ip |= mr->range[0].min_ip & netmask; | |
82 | ||
83 | newrange = ((struct ip_nat_range) | |
84 | { mr->range[0].flags | IP_NAT_RANGE_MAP_IPS, | |
85 | new_ip, new_ip, | |
86 | mr->range[0].min, mr->range[0].max }); | |
87 | ||
88 | /* Hand modified range to generic setup. */ | |
89 | return ip_nat_setup_info(ct, &newrange, hooknum); | |
90 | } | |
91 | ||
6709dbbb | 92 | static struct xt_target target_module = { |
1da177e4 | 93 | .name = MODULENAME, |
6709dbbb | 94 | .family = AF_INET, |
e905a9ed | 95 | .target = target, |
1d5cd909 PM |
96 | .targetsize = sizeof(struct ip_nat_multi_range_compat), |
97 | .table = "nat", | |
98 | .hooks = (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_POST_ROUTING) | | |
99 | (1 << NF_IP_LOCAL_OUT), | |
1da177e4 | 100 | .checkentry = check, |
e905a9ed | 101 | .me = THIS_MODULE |
1da177e4 LT |
102 | }; |
103 | ||
65b4b4e8 | 104 | static int __init ipt_netmap_init(void) |
1da177e4 | 105 | { |
6709dbbb | 106 | return xt_register_target(&target_module); |
1da177e4 LT |
107 | } |
108 | ||
65b4b4e8 | 109 | static void __exit ipt_netmap_fini(void) |
1da177e4 | 110 | { |
6709dbbb | 111 | xt_unregister_target(&target_module); |
1da177e4 LT |
112 | } |
113 | ||
65b4b4e8 AM |
114 | module_init(ipt_netmap_init); |
115 | module_exit(ipt_netmap_fini); |