aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorEric Leblond <eric@inl.fr>2007-02-07 18:10:09 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2007-02-08 15:39:17 -0500
commit41f4689a7c8cd76b77864461b3c58fde8f322b2c (patch)
tree29be7597bc02158ca41261f365ebcbd8047dd56f /net
parentcdd289a2f833b93e65b9a09a02c37f47a58140a8 (diff)
[NETFILTER]: NAT: optional source port randomization support
This patch adds support to NAT to randomize source ports. Signed-off-by: Eric Leblond <eric@inl.fr> Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/netfilter/ip_nat_core.c12
-rw-r--r--net/ipv4/netfilter/ip_nat_proto_tcp.c5
-rw-r--r--net/ipv4/netfilter/ip_nat_proto_udp.c5
-rw-r--r--net/ipv4/netfilter/ip_nat_rule.c4
-rw-r--r--net/ipv4/netfilter/nf_nat_core.c12
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_tcp.c4
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_udp.c4
-rw-r--r--net/ipv4/netfilter/nf_nat_rule.c4
8 files changed, 46 insertions, 4 deletions
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index 9d1a5175dcd4..5e08c2bf887d 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -246,8 +246,9 @@ get_unique_tuple(struct ip_conntrack_tuple *tuple,
246 if (maniptype == IP_NAT_MANIP_SRC) { 246 if (maniptype == IP_NAT_MANIP_SRC) {
247 if (find_appropriate_src(orig_tuple, tuple, range)) { 247 if (find_appropriate_src(orig_tuple, tuple, range)) {
248 DEBUGP("get_unique_tuple: Found current src map\n"); 248 DEBUGP("get_unique_tuple: Found current src map\n");
249 if (!ip_nat_used_tuple(tuple, conntrack)) 249 if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM))
250 return; 250 if (!ip_nat_used_tuple(tuple, conntrack))
251 return;
251 } 252 }
252 } 253 }
253 254
@@ -261,6 +262,13 @@ get_unique_tuple(struct ip_conntrack_tuple *tuple,
261 262
262 proto = ip_nat_proto_find_get(orig_tuple->dst.protonum); 263 proto = ip_nat_proto_find_get(orig_tuple->dst.protonum);
263 264
265 /* Change protocol info to have some randomization */
266 if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) {
267 proto->unique_tuple(tuple, range, maniptype, conntrack);
268 ip_nat_proto_put(proto);
269 return;
270 }
271
264 /* Only bother mapping if it's not already in range and unique */ 272 /* Only bother mapping if it's not already in range and unique */
265 if ((!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED) 273 if ((!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)
266 || proto->in_range(tuple, maniptype, &range->min, &range->max)) 274 || proto->in_range(tuple, maniptype, &range->min, &range->max))
diff --git a/net/ipv4/netfilter/ip_nat_proto_tcp.c b/net/ipv4/netfilter/ip_nat_proto_tcp.c
index b586d18b3fb3..14ff24f53a7a 100644
--- a/net/ipv4/netfilter/ip_nat_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_tcp.c
@@ -8,6 +8,7 @@
8 8
9#include <linux/types.h> 9#include <linux/types.h>
10#include <linux/init.h> 10#include <linux/init.h>
11#include <linux/random.h>
11#include <linux/netfilter.h> 12#include <linux/netfilter.h>
12#include <linux/ip.h> 13#include <linux/ip.h>
13#include <linux/tcp.h> 14#include <linux/tcp.h>
@@ -75,6 +76,10 @@ tcp_unique_tuple(struct ip_conntrack_tuple *tuple,
75 range_size = ntohs(range->max.tcp.port) - min + 1; 76 range_size = ntohs(range->max.tcp.port) - min + 1;
76 } 77 }
77 78
79 /* Start from random port to avoid prediction */
80 if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
81 port = net_random();
82
78 for (i = 0; i < range_size; i++, port++) { 83 for (i = 0; i < range_size; i++, port++) {
79 *portptr = htons(min + port % range_size); 84 *portptr = htons(min + port % range_size);
80 if (!ip_nat_used_tuple(tuple, conntrack)) { 85 if (!ip_nat_used_tuple(tuple, conntrack)) {
diff --git a/net/ipv4/netfilter/ip_nat_proto_udp.c b/net/ipv4/netfilter/ip_nat_proto_udp.c
index 5ced0877b32f..dfd521672891 100644
--- a/net/ipv4/netfilter/ip_nat_proto_udp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_udp.c
@@ -8,6 +8,7 @@
8 8
9#include <linux/types.h> 9#include <linux/types.h>
10#include <linux/init.h> 10#include <linux/init.h>
11#include <linux/random.h>
11#include <linux/netfilter.h> 12#include <linux/netfilter.h>
12#include <linux/ip.h> 13#include <linux/ip.h>
13#include <linux/udp.h> 14#include <linux/udp.h>
@@ -74,6 +75,10 @@ udp_unique_tuple(struct ip_conntrack_tuple *tuple,
74 range_size = ntohs(range->max.udp.port) - min + 1; 75 range_size = ntohs(range->max.udp.port) - min + 1;
75 } 76 }
76 77
78 /* Start from random port to avoid prediction */
79 if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
80 port = net_random();
81
77 for (i = 0; i < range_size; i++, port++) { 82 for (i = 0; i < range_size; i++, port++) {
78 *portptr = htons(min + port % range_size); 83 *portptr = htons(min + port % range_size);
79 if (!ip_nat_used_tuple(tuple, conntrack)) 84 if (!ip_nat_used_tuple(tuple, conntrack))
diff --git a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c
index a176aa3031e0..6ebaad36c06d 100644
--- a/net/ipv4/netfilter/ip_nat_rule.c
+++ b/net/ipv4/netfilter/ip_nat_rule.c
@@ -193,6 +193,10 @@ static int ipt_dnat_checkentry(const char *tablename,
193 printk("DNAT: multiple ranges no longer supported\n"); 193 printk("DNAT: multiple ranges no longer supported\n");
194 return 0; 194 return 0;
195 } 195 }
196 if (mr->range[0].flags & IP_NAT_RANGE_PROTO_RANDOM) {
197 printk("DNAT: port randomization not supported\n");
198 return 0;
199 }
196 return 1; 200 return 1;
197} 201}
198 202
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 86a92272b053..998b2557692c 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -254,8 +254,9 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
254 if (maniptype == IP_NAT_MANIP_SRC) { 254 if (maniptype == IP_NAT_MANIP_SRC) {
255 if (find_appropriate_src(orig_tuple, tuple, range)) { 255 if (find_appropriate_src(orig_tuple, tuple, range)) {
256 DEBUGP("get_unique_tuple: Found current src map\n"); 256 DEBUGP("get_unique_tuple: Found current src map\n");
257 if (!nf_nat_used_tuple(tuple, ct)) 257 if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM))
258 return; 258 if (!nf_nat_used_tuple(tuple, ct))
259 return;
259 } 260 }
260 } 261 }
261 262
@@ -269,6 +270,13 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
269 270
270 proto = nf_nat_proto_find_get(orig_tuple->dst.protonum); 271 proto = nf_nat_proto_find_get(orig_tuple->dst.protonum);
271 272
273 /* Change protocol info to have some randomization */
274 if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) {
275 proto->unique_tuple(tuple, range, maniptype, ct);
276 nf_nat_proto_put(proto);
277 return;
278 }
279
272 /* Only bother mapping if it's not already in range and unique */ 280 /* Only bother mapping if it's not already in range and unique */
273 if ((!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED) || 281 if ((!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED) ||
274 proto->in_range(tuple, maniptype, &range->min, &range->max)) && 282 proto->in_range(tuple, maniptype, &range->min, &range->max)) &&
diff --git a/net/ipv4/netfilter/nf_nat_proto_tcp.c b/net/ipv4/netfilter/nf_nat_proto_tcp.c
index 7e26a7e9bee1..439164c7a626 100644
--- a/net/ipv4/netfilter/nf_nat_proto_tcp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_tcp.c
@@ -8,6 +8,7 @@
8 8
9#include <linux/types.h> 9#include <linux/types.h>
10#include <linux/init.h> 10#include <linux/init.h>
11#include <linux/random.h>
11#include <linux/ip.h> 12#include <linux/ip.h>
12#include <linux/tcp.h> 13#include <linux/tcp.h>
13 14
@@ -75,6 +76,9 @@ tcp_unique_tuple(struct nf_conntrack_tuple *tuple,
75 range_size = ntohs(range->max.tcp.port) - min + 1; 76 range_size = ntohs(range->max.tcp.port) - min + 1;
76 } 77 }
77 78
79 if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
80 port = net_random();
81
78 for (i = 0; i < range_size; i++, port++) { 82 for (i = 0; i < range_size; i++, port++) {
79 *portptr = htons(min + port % range_size); 83 *portptr = htons(min + port % range_size);
80 if (!nf_nat_used_tuple(tuple, ct)) 84 if (!nf_nat_used_tuple(tuple, ct))
diff --git a/net/ipv4/netfilter/nf_nat_proto_udp.c b/net/ipv4/netfilter/nf_nat_proto_udp.c
index ab0ce4c8699f..8cae6e063bb6 100644
--- a/net/ipv4/netfilter/nf_nat_proto_udp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_udp.c
@@ -8,6 +8,7 @@
8 8
9#include <linux/types.h> 9#include <linux/types.h>
10#include <linux/init.h> 10#include <linux/init.h>
11#include <linux/random.h>
11#include <linux/ip.h> 12#include <linux/ip.h>
12#include <linux/udp.h> 13#include <linux/udp.h>
13 14
@@ -73,6 +74,9 @@ udp_unique_tuple(struct nf_conntrack_tuple *tuple,
73 range_size = ntohs(range->max.udp.port) - min + 1; 74 range_size = ntohs(range->max.udp.port) - min + 1;
74 } 75 }
75 76
77 if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
78 port = net_random();
79
76 for (i = 0; i < range_size; i++, port++) { 80 for (i = 0; i < range_size; i++, port++) {
77 *portptr = htons(min + port % range_size); 81 *portptr = htons(min + port % range_size);
78 if (!nf_nat_used_tuple(tuple, ct)) 82 if (!nf_nat_used_tuple(tuple, ct))
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
index b868ee0195d4..3745efe70302 100644
--- a/net/ipv4/netfilter/nf_nat_rule.c
+++ b/net/ipv4/netfilter/nf_nat_rule.c
@@ -226,6 +226,10 @@ static int ipt_dnat_checkentry(const char *tablename,
226 printk("DNAT: multiple ranges no longer supported\n"); 226 printk("DNAT: multiple ranges no longer supported\n");
227 return 0; 227 return 0;
228 } 228 }
229 if (mr->range[0].flags & IP_NAT_RANGE_PROTO_RANDOM) {
230 printk("DNAT: port randomization not supported\n");
231 return 0;
232 }
229 return 1; 233 return 1;
230} 234}
231 235