]>
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>"); | |
2ae15b64 | 18 | MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field modification target"); |
0ac4f893 HW |
19 | MODULE_LICENSE("GPL"); |
20 | ||
d3c5ee6d JE |
21 | static unsigned int |
22 | hl_tg6(struct sk_buff *skb, const struct net_device *in, | |
23 | const struct net_device *out, unsigned int hooknum, | |
24 | const struct xt_target *target, const void *targinfo) | |
0ac4f893 HW |
25 | { |
26 | struct ipv6hdr *ip6h; | |
27 | const struct ip6t_HL_info *info = targinfo; | |
0ac4f893 HW |
28 | int new_hl; |
29 | ||
3db05fea | 30 | if (!skb_make_writable(skb, skb->len)) |
0ac4f893 HW |
31 | return NF_DROP; |
32 | ||
3db05fea | 33 | ip6h = ipv6_hdr(skb); |
0ac4f893 HW |
34 | |
35 | switch (info->mode) { | |
36 | case IP6T_HL_SET: | |
37 | new_hl = info->hop_limit; | |
38 | break; | |
39 | case IP6T_HL_INC: | |
40 | new_hl = ip6h->hop_limit + info->hop_limit; | |
41 | if (new_hl > 255) | |
42 | new_hl = 255; | |
43 | break; | |
44 | case IP6T_HL_DEC: | |
45 | new_hl = ip6h->hop_limit - info->hop_limit; | |
46 | if (new_hl < 0) | |
47 | new_hl = 0; | |
48 | break; | |
49 | default: | |
50 | new_hl = ip6h->hop_limit; | |
51 | break; | |
52 | } | |
53 | ||
2822b0d9 | 54 | ip6h->hop_limit = new_hl; |
0ac4f893 | 55 | |
6709dbbb | 56 | return XT_CONTINUE; |
0ac4f893 HW |
57 | } |
58 | ||
d3c5ee6d JE |
59 | static bool |
60 | hl_tg6_check(const char *tablename, const void *entry, | |
61 | const struct xt_target *target, void *targinfo, | |
62 | unsigned int hook_mask) | |
0ac4f893 | 63 | { |
a47362a2 | 64 | const struct ip6t_HL_info *info = targinfo; |
0ac4f893 | 65 | |
0ac4f893 | 66 | if (info->mode > IP6T_HL_MAXMODE) { |
1ab1457c | 67 | printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n", |
0ac4f893 | 68 | info->mode); |
e1931b78 | 69 | return false; |
0ac4f893 | 70 | } |
7c4e36bc | 71 | if (info->mode != IP6T_HL_SET && info->hop_limit == 0) { |
0ac4f893 HW |
72 | printk(KERN_WARNING "ip6t_HL: increment/decrement doesn't " |
73 | "make sense with value 0\n"); | |
e1931b78 | 74 | return false; |
0ac4f893 | 75 | } |
e1931b78 | 76 | return true; |
0ac4f893 HW |
77 | } |
78 | ||
d3c5ee6d | 79 | static struct xt_target hl_tg6_reg __read_mostly = { |
1ab1457c | 80 | .name = "HL", |
ee999d8b | 81 | .family = NFPROTO_IPV6, |
d3c5ee6d | 82 | .target = hl_tg6, |
7f939713 PM |
83 | .targetsize = sizeof(struct ip6t_HL_info), |
84 | .table = "mangle", | |
d3c5ee6d | 85 | .checkentry = hl_tg6_check, |
0ac4f893 HW |
86 | .me = THIS_MODULE |
87 | }; | |
88 | ||
d3c5ee6d | 89 | static int __init hl_tg6_init(void) |
0ac4f893 | 90 | { |
d3c5ee6d | 91 | return xt_register_target(&hl_tg6_reg); |
0ac4f893 HW |
92 | } |
93 | ||
d3c5ee6d | 94 | static void __exit hl_tg6_exit(void) |
0ac4f893 | 95 | { |
d3c5ee6d | 96 | xt_unregister_target(&hl_tg6_reg); |
0ac4f893 HW |
97 | } |
98 | ||
d3c5ee6d JE |
99 | module_init(hl_tg6_init); |
100 | module_exit(hl_tg6_exit); |