]>
Commit | Line | Data |
---|---|---|
1ab1457c | 1 | /* |
0ac4f893 HW |
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> | |
6709dbbb | 12 | #include <linux/ipv6.h> |
0ac4f893 | 13 | |
6709dbbb | 14 | #include <linux/netfilter/x_tables.h> |
0ac4f893 HW |
15 | #include <linux/netfilter_ipv6/ip6t_HL.h> |
16 | ||
17 | MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>"); | |
6709dbbb | 18 | MODULE_DESCRIPTION("IP6 tables Hop Limit modification module"); |
0ac4f893 HW |
19 | MODULE_LICENSE("GPL"); |
20 | ||
3db05fea | 21 | static unsigned int ip6t_hl_target(struct sk_buff *skb, |
0ac4f893 HW |
22 | const struct net_device *in, |
23 | const struct net_device *out, | |
24 | unsigned int hooknum, | |
c4986734 | 25 | const struct xt_target *target, |
fe1cb108 | 26 | const void *targinfo) |
0ac4f893 HW |
27 | { |
28 | struct ipv6hdr *ip6h; | |
29 | const struct ip6t_HL_info *info = targinfo; | |
0ac4f893 HW |
30 | int new_hl; |
31 | ||
3db05fea | 32 | if (!skb_make_writable(skb, skb->len)) |
0ac4f893 HW |
33 | return NF_DROP; |
34 | ||
3db05fea | 35 | ip6h = ipv6_hdr(skb); |
0ac4f893 HW |
36 | |
37 | switch (info->mode) { | |
38 | case IP6T_HL_SET: | |
39 | new_hl = info->hop_limit; | |
40 | break; | |
41 | case IP6T_HL_INC: | |
42 | new_hl = ip6h->hop_limit + info->hop_limit; | |
43 | if (new_hl > 255) | |
44 | new_hl = 255; | |
45 | break; | |
46 | case IP6T_HL_DEC: | |
47 | new_hl = ip6h->hop_limit - info->hop_limit; | |
48 | if (new_hl < 0) | |
49 | new_hl = 0; | |
50 | break; | |
51 | default: | |
52 | new_hl = ip6h->hop_limit; | |
53 | break; | |
54 | } | |
55 | ||
2822b0d9 | 56 | ip6h->hop_limit = new_hl; |
0ac4f893 | 57 | |
6709dbbb | 58 | return XT_CONTINUE; |
0ac4f893 HW |
59 | } |
60 | ||
e1931b78 | 61 | static bool ip6t_hl_checkentry(const char *tablename, |
2e4e6a17 | 62 | const void *entry, |
c4986734 | 63 | const struct xt_target *target, |
0ac4f893 | 64 | void *targinfo, |
0ac4f893 HW |
65 | unsigned int hook_mask) |
66 | { | |
a47362a2 | 67 | const struct ip6t_HL_info *info = targinfo; |
0ac4f893 | 68 | |
0ac4f893 | 69 | if (info->mode > IP6T_HL_MAXMODE) { |
1ab1457c | 70 | printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n", |
0ac4f893 | 71 | info->mode); |
e1931b78 | 72 | return false; |
0ac4f893 | 73 | } |
7c4e36bc | 74 | if (info->mode != IP6T_HL_SET && info->hop_limit == 0) { |
0ac4f893 HW |
75 | printk(KERN_WARNING "ip6t_HL: increment/decrement doesn't " |
76 | "make sense with value 0\n"); | |
e1931b78 | 77 | return false; |
0ac4f893 | 78 | } |
e1931b78 | 79 | return true; |
0ac4f893 HW |
80 | } |
81 | ||
9f15c530 | 82 | static struct xt_target ip6t_HL __read_mostly = { |
1ab1457c | 83 | .name = "HL", |
6709dbbb | 84 | .family = AF_INET6, |
1ab1457c | 85 | .target = ip6t_hl_target, |
7f939713 PM |
86 | .targetsize = sizeof(struct ip6t_HL_info), |
87 | .table = "mangle", | |
1ab1457c | 88 | .checkentry = ip6t_hl_checkentry, |
0ac4f893 HW |
89 | .me = THIS_MODULE |
90 | }; | |
91 | ||
65b4b4e8 | 92 | static int __init ip6t_hl_init(void) |
0ac4f893 | 93 | { |
6709dbbb | 94 | return xt_register_target(&ip6t_HL); |
0ac4f893 HW |
95 | } |
96 | ||
65b4b4e8 | 97 | static void __exit ip6t_hl_fini(void) |
0ac4f893 | 98 | { |
6709dbbb | 99 | xt_unregister_target(&ip6t_HL); |
0ac4f893 HW |
100 | } |
101 | ||
65b4b4e8 AM |
102 | module_init(ip6t_hl_init); |
103 | module_exit(ip6t_hl_fini); |