]> git.ipfire.org Git - thirdparty/xtables-addons.git/blame - extensions/xt_CHAOS.c
compat_xtables: move to 2.6.35 xt_action_param (3/3)
[thirdparty/xtables-addons.git] / extensions / xt_CHAOS.c
CommitLineData
2fbfbe6c 1/*
74880dd6
JE
2 * "CHAOS" target extension for Xtables
3 * Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2006 - 2008
2fbfbe6c 4 *
74880dd6
JE
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License; either
7 * version 2 of the License, or any later version, as published by the
8 * Free Software Foundation.
2fbfbe6c
JE
9 */
10#include <linux/icmp.h>
11#include <linux/in.h>
12#include <linux/ip.h>
13#include <linux/module.h>
14#include <linux/skbuff.h>
15#include <linux/stat.h>
16#include <linux/netfilter/x_tables.h>
17#include <linux/netfilter/xt_tcpudp.h>
18#include <linux/netfilter_ipv4/ipt_REJECT.h>
19#include <net/ip.h>
20#include "xt_CHAOS.h"
21static struct xt_match *xm_tcp;
22static struct xt_target *xt_delude, *xt_reject, *xt_tarpit;
23#include "compat_xtables.h"
24#define PFX KBUILD_MODNAME ": "
25
26/* Module parameters */
27static unsigned int reject_percentage = ~0U * .01;
28static unsigned int delude_percentage = ~0U * .0101;
29module_param(reject_percentage, uint, S_IRUGO | S_IWUSR);
30module_param(delude_percentage, uint, S_IRUGO | S_IWUSR);
31
32/* References to other matches/targets */
33
34static int have_delude, have_tarpit;
35
36/* Static data for other matches/targets */
37static const struct ipt_reject_info reject_params = {
38 .with = ICMP_HOST_UNREACH,
39};
40
41static const struct xt_tcp tcp_params = {
42 .spts = {0, ~0},
43 .dpts = {0, ~0},
44};
45
46/* CHAOS functions */
ee7e4f5a 47static void
5b472be9 48xt_chaos_total(struct sk_buff *skb, const struct xt_action_param *par)
2fbfbe6c 49{
ee7e4f5a 50 const struct xt_chaos_tginfo *info = par->targinfo;
2fbfbe6c 51 const struct iphdr *iph = ip_hdr(skb);
ee7e4f5a
JE
52 const int thoff = 4 * iph->ihl;
53 const int fragoff = ntohs(iph->frag_off) & IP_OFFSET;
2fbfbe6c
JE
54 typeof(xt_tarpit) destiny;
55 bool ret;
5fd97e99 56#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
2fbfbe6c
JE
57 int hotdrop = false;
58#else
59 bool hotdrop = false;
60#endif
61
ee7e4f5a
JE
62#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
63 ret = xm_tcp->match(skb, par->in, par->out, xm_tcp, &tcp_params,
64 fragoff, thoff, &hotdrop);
65#else
66 {
67 struct xt_match_param local_par = {
68 .in = par->in,
69 .out = par->out,
70 .match = xm_tcp,
71 .matchinfo = &tcp_params,
72 .fragoff = fragoff,
73 .thoff = thoff,
74 .hotdrop = &hotdrop,
75 };
76 ret = xm_tcp->match(skb, &local_par);
77 }
78#endif
2fbfbe6c
JE
79 if (!ret || hotdrop || (unsigned int)net_random() > delude_percentage)
80 return;
81
82 destiny = (info->variant == XTCHAOS_TARPIT) ? xt_tarpit : xt_delude;
5fd97e99 83#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
ee7e4f5a 84 destiny->target(&skb, par->in, par->out, par->hooknum, destiny, NULL, NULL);
5fd97e99 85#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
ee7e4f5a
JE
86 destiny->target(&skb, par->in, par->out, par->hooknum, destiny, NULL);
87#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
88 destiny->target(skb, par->in, par->out, par->hooknum, destiny, NULL);
2fbfbe6c 89#else
ee7e4f5a 90 {
5b472be9
JE
91 struct xt_target_param local_par = {
92 .in = par->in,
93 .out = par->out,
94 .hooknum = par->hooknum,
95 .target = destiny,
96 .targinfo = par->targinfo,
97 .family = par->family,
98 };
ee7e4f5a
JE
99 destiny->target(skb, &local_par);
100 }
2fbfbe6c 101#endif
2fbfbe6c
JE
102}
103
ee7e4f5a 104static unsigned int
5b472be9 105chaos_tg(struct sk_buff **pskb, const struct xt_action_param *par)
2fbfbe6c
JE
106{
107 /*
108 * Equivalent to:
109 * -A chaos -m statistic --mode random --probability \
110 * $reject_percentage -j REJECT --reject-with host-unreach;
111 * -A chaos -p tcp -m statistic --mode random --probability \
112 * $delude_percentage -j DELUDE;
113 * -A chaos -j DROP;
114 */
ee7e4f5a 115 const struct xt_chaos_tginfo *info = par->targinfo;
ab27472e 116 struct sk_buff *skb = *pskb;
2fbfbe6c
JE
117 const struct iphdr *iph = ip_hdr(skb);
118
ee7e4f5a 119 if ((unsigned int)net_random() <= reject_percentage) {
5fd97e99 120#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
ee7e4f5a
JE
121 return xt_reject->target(pskb, par->in, par->out, par->hooknum,
122 xt_reject, &reject_params, NULL);
5fd97e99 123#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
ee7e4f5a
JE
124 return xt_reject->target(pskb, par->in, par->out, par->hooknum,
125 xt_reject, &reject_params);
126#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
127 return xt_reject->target(skb, par->in, par->out, par->hooknum,
128 xt_reject, &reject_params);
2fbfbe6c 129#else
ee7e4f5a
JE
130 struct xt_target_param local_par = {
131 .in = par->in,
132 .out = par->out,
133 .hooknum = par->hooknum,
134 .target = xt_reject,
135 .targinfo = &reject_params,
136 };
137 return xt_reject->target(skb, &local_par);
2fbfbe6c 138#endif
ee7e4f5a 139 }
2fbfbe6c
JE
140
141 /* TARPIT/DELUDE may not be called from the OUTPUT chain */
142 if (iph->protocol == IPPROTO_TCP &&
ee7e4f5a
JE
143 info->variant != XTCHAOS_NORMAL &&
144 par->hooknum != NF_INET_LOCAL_OUT)
145 xt_chaos_total(skb, par);
2fbfbe6c
JE
146
147 return NF_DROP;
148}
149
ad146dbe 150static int chaos_tg_check(const struct xt_tgchk_param *par)
2fbfbe6c 151{
ee7e4f5a 152 const struct xt_chaos_tginfo *info = par->targinfo;
2fbfbe6c
JE
153
154 if (info->variant == XTCHAOS_DELUDE && !have_delude) {
155 printk(KERN_WARNING PFX "Error: Cannot use --delude when "
156 "DELUDE module not available\n");
ad146dbe 157 return -EINVAL;
2fbfbe6c
JE
158 }
159 if (info->variant == XTCHAOS_TARPIT && !have_tarpit) {
160 printk(KERN_WARNING PFX "Error: Cannot use --tarpit when "
161 "TARPIT module not available\n");
ad146dbe 162 return -EINVAL;
2fbfbe6c
JE
163 }
164
ad146dbe 165 return 0;
2fbfbe6c
JE
166}
167
168static struct xt_target chaos_tg_reg = {
169 .name = "CHAOS",
be6fbee5
JE
170 .revision = 0,
171 .family = NFPROTO_IPV4,
2fbfbe6c
JE
172 .table = "filter",
173 .hooks = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD) |
174 (1 << NF_INET_LOCAL_OUT),
175 .target = chaos_tg,
176 .checkentry = chaos_tg_check,
177 .targetsize = sizeof(struct xt_chaos_tginfo),
178 .me = THIS_MODULE,
179};
180
181static int __init chaos_tg_init(void)
182{
183 int ret = -EINVAL;
184
be6fbee5 185 xm_tcp = xt_request_find_match(NFPROTO_IPV4, "tcp", 0);
2fbfbe6c
JE
186 if (xm_tcp == NULL) {
187 printk(KERN_WARNING PFX "Error: Could not find or load "
188 "\"tcp\" match\n");
189 return -EINVAL;
190 }
191
be6fbee5 192 xt_reject = xt_request_find_target(NFPROTO_IPV4, "REJECT", 0);
2fbfbe6c
JE
193 if (xt_reject == NULL) {
194 printk(KERN_WARNING PFX "Error: Could not find or load "
195 "\"REJECT\" target\n");
196 goto out2;
197 }
198
be6fbee5 199 xt_tarpit = xt_request_find_target(NFPROTO_IPV4, "TARPIT", 0);
2fbfbe6c
JE
200 have_tarpit = xt_tarpit != NULL;
201 if (!have_tarpit)
202 printk(KERN_WARNING PFX "Warning: Could not find or load "
203 "\"TARPIT\" target\n");
204
be6fbee5 205 xt_delude = xt_request_find_target(NFPROTO_IPV4, "DELUDE", 0);
2fbfbe6c
JE
206 have_delude = xt_delude != NULL;
207 if (!have_delude)
208 printk(KERN_WARNING PFX "Warning: Could not find or load "
209 "\"DELUDE\" target\n");
210
211 if ((ret = xt_register_target(&chaos_tg_reg)) != 0) {
212 printk(KERN_WARNING PFX "xt_register_target returned "
213 "error %d\n", ret);
214 goto out3;
215 }
216
217 return 0;
218
219 out3:
220 if (have_delude)
221 module_put(xt_delude->me);
222 if (have_tarpit)
223 module_put(xt_tarpit->me);
224 module_put(xt_reject->me);
225 out2:
226 module_put(xm_tcp->me);
227 return ret;
228}
229
230static void __exit chaos_tg_exit(void)
231{
232 xt_unregister_target(&chaos_tg_reg);
233 module_put(xm_tcp->me);
234 module_put(xt_reject->me);
235 if (have_delude)
236 module_put(xt_delude->me);
237 if (have_tarpit)
238 module_put(xt_tarpit->me);
2fbfbe6c
JE
239}
240
241module_init(chaos_tg_init);
242module_exit(chaos_tg_exit);
2fbfbe6c 243MODULE_DESCRIPTION("Xtables: Network scan slowdown with non-deterministic results");
538d74b5 244MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
2fbfbe6c
JE
245MODULE_LICENSE("GPL");
246MODULE_ALIAS("ipt_CHAOS");