aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorHarald Welte <laforge@netfilter.org>2005-08-28 01:37:30 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2005-08-29 19:13:29 -0400
commit0ac4f893f20ed524198da5ebf591fc0b9e2ced2f (patch)
tree63650617f3bff152c3bdbd53e470abef6764b784 /net/ipv6
parent5f2c3b910744f68e1a507f027398f404b3feb5fb (diff)
[NETFILTER6]: Add new ip6tables HOPLIMIT target
This target allows users to modify the hoplimit header field of the IPv6 header. Signed-off-by: Harald Welte <laforge@netfilter.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/netfilter/Kconfig16
-rw-r--r--net/ipv6/netfilter/Makefile1
-rw-r--r--net/ipv6/netfilter/ip6t_HL.c118
3 files changed, 135 insertions, 0 deletions
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 8a10c2d0d154..216fbe1ac65c 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -239,6 +239,22 @@ config IP6_NF_TARGET_MARK
239 239
240 To compile it as a module, choose M here. If unsure, say N. 240 To compile it as a module, choose M here. If unsure, say N.
241 241
242config IP6_NF_TARGET_HL
243 tristate 'HL (hoplimit) target support'
244 depends on IP6_NF_MANGLE
245 help
246 This option adds a `HL' target, which enables the user to decrement
247 the hoplimit value of the IPv6 header or set it to a given (lower)
248 value.
249
250 While it is safe to decrement the hoplimit value, this option also
251 enables functionality to increment and set the hoplimit value of the
252 IPv6 header to arbitrary values. This is EXTREMELY DANGEROUS since
253 you can easily create immortal packets that loop forever on the
254 network.
255
256 To compile it as a module, choose M here. If unsure, say N.
257
242#dep_tristate ' LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES 258#dep_tristate ' LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES
243config IP6_NF_RAW 259config IP6_NF_RAW
244 tristate 'raw table support (required for TRACE)' 260 tristate 'raw table support (required for TRACE)'
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index 70f6ba610102..bd9a16a5cbba 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_IP6_NF_MATCH_PHYSDEV) += ip6t_physdev.o
20obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o 20obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
21obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o 21obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
22obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o 22obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
23obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
23obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o 24obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
24obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o 25obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
25obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o 26obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
diff --git a/net/ipv6/netfilter/ip6t_HL.c b/net/ipv6/netfilter/ip6t_HL.c
new file mode 100644
index 000000000000..8f5549b72720
--- /dev/null
+++ b/net/ipv6/netfilter/ip6t_HL.c
@@ -0,0 +1,118 @@
1/*
2 * Hop Limit modification target for ip6tables
3 * Maciej Soltysiak <solt@dns.toxicfilms.tv>
4 * Based on HW's TTL module
5 *
6 * This software is distributed under the terms of GNU GPL
7 */
8
9#include <linux/module.h>
10#include <linux/skbuff.h>
11#include <linux/ip.h>
12
13#include <linux/netfilter_ipv6/ip6_tables.h>
14#include <linux/netfilter_ipv6/ip6t_HL.h>
15
16MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
17MODULE_DESCRIPTION("IP tables Hop Limit modification module");
18MODULE_LICENSE("GPL");
19
20static unsigned int ip6t_hl_target(struct sk_buff **pskb,
21 const struct net_device *in,
22 const struct net_device *out,
23 unsigned int hooknum,
24 const void *targinfo, void *userinfo)
25{
26 struct ipv6hdr *ip6h;
27 const struct ip6t_HL_info *info = targinfo;
28 u_int16_t diffs[2];
29 int new_hl;
30
31 if (!skb_make_writable(pskb, (*pskb)->len))
32 return NF_DROP;
33
34 ip6h = (*pskb)->nh.ipv6h;
35
36 switch (info->mode) {
37 case IP6T_HL_SET:
38 new_hl = info->hop_limit;
39 break;
40 case IP6T_HL_INC:
41 new_hl = ip6h->hop_limit + info->hop_limit;
42 if (new_hl > 255)
43 new_hl = 255;
44 break;
45 case IP6T_HL_DEC:
46 new_hl = ip6h->hop_limit - info->hop_limit;
47 if (new_hl < 0)
48 new_hl = 0;
49 break;
50 default:
51 new_hl = ip6h->hop_limit;
52 break;
53 }
54
55 if (new_hl != ip6h->hop_limit) {
56 diffs[0] = htons(((unsigned)ip6h->hop_limit) << 8) ^ 0xFFFF;
57 ip6h->hop_limit = new_hl;
58 diffs[1] = htons(((unsigned)ip6h->hop_limit) << 8);
59 }
60
61 return IP6T_CONTINUE;
62}
63
64static int ip6t_hl_checkentry(const char *tablename,
65 const struct ip6t_entry *e,
66 void *targinfo,
67 unsigned int targinfosize,
68 unsigned int hook_mask)
69{
70 struct ip6t_HL_info *info = targinfo;
71
72 if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_HL_info))) {
73 printk(KERN_WARNING "ip6t_HL: targinfosize %u != %Zu\n",
74 targinfosize,
75 IP6T_ALIGN(sizeof(struct ip6t_HL_info)));
76 return 0;
77 }
78
79 if (strcmp(tablename, "mangle")) {
80 printk(KERN_WARNING "ip6t_HL: can only be called from "
81 "\"mangle\" table, not \"%s\"\n", tablename);
82 return 0;
83 }
84
85 if (info->mode > IP6T_HL_MAXMODE) {
86 printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n",
87 info->mode);
88 return 0;
89 }
90
91 if ((info->mode != IP6T_HL_SET) && (info->hop_limit == 0)) {
92 printk(KERN_WARNING "ip6t_HL: increment/decrement doesn't "
93 "make sense with value 0\n");
94 return 0;
95 }
96
97 return 1;
98}
99
100static struct ip6t_target ip6t_HL = {
101 .name = "HL",
102 .target = ip6t_hl_target,
103 .checkentry = ip6t_hl_checkentry,
104 .me = THIS_MODULE
105};
106
107static int __init init(void)
108{
109 return ip6t_register_target(&ip6t_HL);
110}
111
112static void __exit fini(void)
113{
114 ip6t_unregister_target(&ip6t_HL);
115}
116
117module_init(init);
118module_exit(fini);