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