Commit 5f2c3b910744f68e1a507f027398f404b3feb5fb
Committed by
David S. Miller
1 parent
29e4f8b3c3
Exists in
master
and in
7 other branches
[NETFILTER]: Add new iptables TTL target
This new iptables target allows manipulation of the TTL of an IPv4 packet. Signed-off-by: Harald Welte <laforge@netfilter.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 4 changed files with 155 additions and 0 deletions Side-by-side Diff
include/linux/netfilter_ipv4/ipt_TTL.h
1 | +/* TTL modification module for IP tables | |
2 | + * (C) 2000 by Harald Welte <laforge@netfilter.org> */ | |
3 | + | |
4 | +#ifndef _IPT_TTL_H | |
5 | +#define _IPT_TTL_H | |
6 | + | |
7 | +enum { | |
8 | + IPT_TTL_SET = 0, | |
9 | + IPT_TTL_INC, | |
10 | + IPT_TTL_DEC | |
11 | +}; | |
12 | + | |
13 | +#define IPT_TTL_MAXMODE IPT_TTL_DEC | |
14 | + | |
15 | +struct ipt_TTL_info { | |
16 | + u_int8_t mode; | |
17 | + u_int8_t ttl; | |
18 | +}; | |
19 | + | |
20 | + | |
21 | +#endif |
net/ipv4/netfilter/Kconfig
... | ... | @@ -664,6 +664,20 @@ |
664 | 664 | |
665 | 665 | To compile it as a module, choose M here. If unsure, say N. |
666 | 666 | |
667 | +config IP_NF_TARGET_TTL | |
668 | + tristate 'TTL target support' | |
669 | + depends on IP_NF_MANGLE | |
670 | + help | |
671 | + This option adds a `TTL' target, which enables the user to modify | |
672 | + the TTL value of the IP header. | |
673 | + | |
674 | + While it is safe to decrement/lower the TTL, this target also enables | |
675 | + functionality to increment and set the TTL value of the IP header to | |
676 | + arbitrary values. This is EXTREMELY DANGEROUS since you can easily | |
677 | + create immortal packets that loop forever on the network. | |
678 | + | |
679 | + To compile it as a module, choose M here. If unsure, say N. | |
680 | + | |
667 | 681 | config IP_NF_TARGET_CONNMARK |
668 | 682 | tristate 'CONNMARK target support' |
669 | 683 | depends on IP_NF_CONNTRACK_MARK && IP_NF_MANGLE |
net/ipv4/netfilter/Makefile
... | ... | @@ -85,6 +85,7 @@ |
85 | 85 | obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o |
86 | 86 | obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o |
87 | 87 | obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o |
88 | +obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o | |
88 | 89 | |
89 | 90 | # generic ARP tables |
90 | 91 | obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o |
net/ipv4/netfilter/ipt_TTL.c
1 | +/* TTL modification target for IP tables | |
2 | + * (C) 2000,2005 by Harald Welte <laforge@netfilter.org> | |
3 | + * | |
4 | + * This program is free software; you can redistribute it and/or modify | |
5 | + * it under the terms of the GNU General Public License version 2 as | |
6 | + * published by the Free Software Foundation. | |
7 | + * | |
8 | + */ | |
9 | + | |
10 | +#include <linux/module.h> | |
11 | +#include <linux/skbuff.h> | |
12 | +#include <linux/ip.h> | |
13 | +#include <net/checksum.h> | |
14 | + | |
15 | +#include <linux/netfilter_ipv4/ip_tables.h> | |
16 | +#include <linux/netfilter_ipv4/ipt_TTL.h> | |
17 | + | |
18 | +MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | |
19 | +MODULE_DESCRIPTION("IP tables TTL modification module"); | |
20 | +MODULE_LICENSE("GPL"); | |
21 | + | |
22 | +static unsigned int | |
23 | +ipt_ttl_target(struct sk_buff **pskb, const struct net_device *in, | |
24 | + const struct net_device *out, unsigned int hooknum, | |
25 | + const void *targinfo, void *userinfo) | |
26 | +{ | |
27 | + struct iphdr *iph; | |
28 | + const struct ipt_TTL_info *info = targinfo; | |
29 | + u_int16_t diffs[2]; | |
30 | + int new_ttl; | |
31 | + | |
32 | + if (!skb_make_writable(pskb, (*pskb)->len)) | |
33 | + return NF_DROP; | |
34 | + | |
35 | + iph = (*pskb)->nh.iph; | |
36 | + | |
37 | + switch (info->mode) { | |
38 | + case IPT_TTL_SET: | |
39 | + new_ttl = info->ttl; | |
40 | + break; | |
41 | + case IPT_TTL_INC: | |
42 | + new_ttl = iph->ttl + info->ttl; | |
43 | + if (new_ttl > 255) | |
44 | + new_ttl = 255; | |
45 | + break; | |
46 | + case IPT_TTL_DEC: | |
47 | + new_ttl = iph->ttl - info->ttl; | |
48 | + if (new_ttl < 0) | |
49 | + new_ttl = 0; | |
50 | + break; | |
51 | + default: | |
52 | + new_ttl = iph->ttl; | |
53 | + break; | |
54 | + } | |
55 | + | |
56 | + if (new_ttl != iph->ttl) { | |
57 | + diffs[0] = htons(((unsigned)iph->ttl) << 8) ^ 0xFFFF; | |
58 | + iph->ttl = new_ttl; | |
59 | + diffs[1] = htons(((unsigned)iph->ttl) << 8); | |
60 | + iph->check = csum_fold(csum_partial((char *)diffs, | |
61 | + sizeof(diffs), | |
62 | + iph->check^0xFFFF)); | |
63 | + } | |
64 | + | |
65 | + return IPT_CONTINUE; | |
66 | +} | |
67 | + | |
68 | +static int ipt_ttl_checkentry(const char *tablename, | |
69 | + const struct ipt_entry *e, | |
70 | + void *targinfo, | |
71 | + unsigned int targinfosize, | |
72 | + unsigned int hook_mask) | |
73 | +{ | |
74 | + struct ipt_TTL_info *info = targinfo; | |
75 | + | |
76 | + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_TTL_info))) { | |
77 | + printk(KERN_WARNING "ipt_TTL: targinfosize %u != %Zu\n", | |
78 | + targinfosize, | |
79 | + IPT_ALIGN(sizeof(struct ipt_TTL_info))); | |
80 | + return 0; | |
81 | + } | |
82 | + | |
83 | + if (strcmp(tablename, "mangle")) { | |
84 | + printk(KERN_WARNING "ipt_TTL: can only be called from " | |
85 | + "\"mangle\" table, not \"%s\"\n", tablename); | |
86 | + return 0; | |
87 | + } | |
88 | + | |
89 | + if (info->mode > IPT_TTL_MAXMODE) { | |
90 | + printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n", | |
91 | + info->mode); | |
92 | + return 0; | |
93 | + } | |
94 | + | |
95 | + if ((info->mode != IPT_TTL_SET) && (info->ttl == 0)) | |
96 | + return 0; | |
97 | + | |
98 | + return 1; | |
99 | +} | |
100 | + | |
101 | +static struct ipt_target ipt_TTL = { | |
102 | + .name = "TTL", | |
103 | + .target = ipt_ttl_target, | |
104 | + .checkentry = ipt_ttl_checkentry, | |
105 | + .me = THIS_MODULE, | |
106 | +}; | |
107 | + | |
108 | +static int __init init(void) | |
109 | +{ | |
110 | + return ipt_register_target(&ipt_TTL); | |
111 | +} | |
112 | + | |
113 | +static void __exit fini(void) | |
114 | +{ | |
115 | + ipt_unregister_target(&ipt_TTL); | |
116 | +} | |
117 | + | |
118 | +module_init(init); | |
119 | +module_exit(fini); |