]> git.ipfire.org Git - thirdparty/xtables-addons.git/blame - extensions/xt_CHAOS.c
build: support for Linux 6.1
[thirdparty/xtables-addons.git] / extensions / xt_CHAOS.c
CommitLineData
2fbfbe6c 1/*
74880dd6 2 * "CHAOS" target extension for Xtables
bcdb7ed4 3 * Copyright © Jan Engelhardt, 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>
ec97cd6d 16#include <linux/version.h>
2fbfbe6c
JE
17#include <linux/netfilter/x_tables.h>
18#include <linux/netfilter/xt_tcpudp.h>
19#include <linux/netfilter_ipv4/ipt_REJECT.h>
20#include <net/ip.h>
21#include "xt_CHAOS.h"
22static struct xt_match *xm_tcp;
23static struct xt_target *xt_delude, *xt_reject, *xt_tarpit;
24#include "compat_xtables.h"
25#define PFX KBUILD_MODNAME ": "
26
27/* Module parameters */
28static unsigned int reject_percentage = ~0U * .01;
29static unsigned int delude_percentage = ~0U * .0101;
30module_param(reject_percentage, uint, S_IRUGO | S_IWUSR);
31module_param(delude_percentage, uint, S_IRUGO | S_IWUSR);
32
33/* References to other matches/targets */
34
35static int have_delude, have_tarpit;
36
37/* Static data for other matches/targets */
38static const struct ipt_reject_info reject_params = {
39 .with = ICMP_HOST_UNREACH,
40};
41
42static const struct xt_tcp tcp_params = {
43 .spts = {0, ~0},
44 .dpts = {0, ~0},
45};
46
47/* CHAOS functions */
ee7e4f5a 48static void
5b472be9 49xt_chaos_total(struct sk_buff *skb, const struct xt_action_param *par)
2fbfbe6c 50{
ee7e4f5a 51 const struct xt_chaos_tginfo *info = par->targinfo;
2fbfbe6c 52 const struct iphdr *iph = ip_hdr(skb);
ee7e4f5a
JE
53 const int thoff = 4 * iph->ihl;
54 const int fragoff = ntohs(iph->frag_off) & IP_OFFSET;
2fbfbe6c
JE
55 typeof(xt_tarpit) destiny;
56 bool ret;
2fbfbe6c 57 bool hotdrop = false;
2fbfbe6c 58
54d80a73
JE
59 {
60 struct xt_action_param local_par;
a8af97b8 61 local_par.state = par->state;
54d80a73
JE
62 local_par.match = xm_tcp;
63 local_par.matchinfo = &tcp_params;
64 local_par.fragoff = fragoff;
65 local_par.thoff = thoff;
66 local_par.hotdrop = false;
67 ret = xm_tcp->match(skb, &local_par);
68 hotdrop = local_par.hotdrop;
69 }
71396f94 70 if (!ret || hotdrop || (unsigned int)get_random_u32() > delude_percentage)
2fbfbe6c
JE
71 return;
72
73 destiny = (info->variant == XTCHAOS_TARPIT) ? xt_tarpit : xt_delude;
54d80a73
JE
74 {
75 struct xt_action_param local_par;
a8af97b8 76 local_par.state = par->state;
54d80a73
JE
77 local_par.target = destiny;
78 local_par.targinfo = par->targinfo;
54d80a73
JE
79 destiny->target(skb, &local_par);
80 }
2fbfbe6c
JE
81}
82
ee7e4f5a 83static unsigned int
991c0cf4 84chaos_tg(struct sk_buff *skb, const struct xt_action_param *par)
2fbfbe6c
JE
85{
86 /*
87 * Equivalent to:
88 * -A chaos -m statistic --mode random --probability \
89 * $reject_percentage -j REJECT --reject-with host-unreach;
90 * -A chaos -p tcp -m statistic --mode random --probability \
91 * $delude_percentage -j DELUDE;
92 * -A chaos -j DROP;
93 */
ee7e4f5a 94 const struct xt_chaos_tginfo *info = par->targinfo;
2fbfbe6c
JE
95 const struct iphdr *iph = ip_hdr(skb);
96
71396f94 97 if ((unsigned int)get_random_u32() <= reject_percentage) {
54d80a73 98 struct xt_action_param local_par;
a8af97b8 99 local_par.state = par->state;
54d80a73
JE
100 local_par.target = xt_reject;
101 local_par.targinfo = &reject_params;
102 return xt_reject->target(skb, &local_par);
ee7e4f5a 103 }
2fbfbe6c
JE
104
105 /* TARPIT/DELUDE may not be called from the OUTPUT chain */
9b1c7c1c
JE
106 if (iph->protocol == IPPROTO_TCP && info->variant != XTCHAOS_NORMAL &&
107 par->state->hook != NF_INET_LOCAL_OUT)
ee7e4f5a 108 xt_chaos_total(skb, par);
2fbfbe6c
JE
109
110 return NF_DROP;
111}
112
ad146dbe 113static int chaos_tg_check(const struct xt_tgchk_param *par)
2fbfbe6c 114{
ee7e4f5a 115 const struct xt_chaos_tginfo *info = par->targinfo;
2fbfbe6c
JE
116
117 if (info->variant == XTCHAOS_DELUDE && !have_delude) {
118 printk(KERN_WARNING PFX "Error: Cannot use --delude when "
119 "DELUDE module not available\n");
ad146dbe 120 return -EINVAL;
2fbfbe6c
JE
121 }
122 if (info->variant == XTCHAOS_TARPIT && !have_tarpit) {
123 printk(KERN_WARNING PFX "Error: Cannot use --tarpit when "
124 "TARPIT module not available\n");
ad146dbe 125 return -EINVAL;
2fbfbe6c
JE
126 }
127
ad146dbe 128 return 0;
2fbfbe6c
JE
129}
130
131static struct xt_target chaos_tg_reg = {
132 .name = "CHAOS",
be6fbee5
JE
133 .revision = 0,
134 .family = NFPROTO_IPV4,
2fbfbe6c
JE
135 .table = "filter",
136 .hooks = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD) |
137 (1 << NF_INET_LOCAL_OUT),
138 .target = chaos_tg,
139 .checkentry = chaos_tg_check,
140 .targetsize = sizeof(struct xt_chaos_tginfo),
141 .me = THIS_MODULE,
142};
143
144static int __init chaos_tg_init(void)
145{
146 int ret = -EINVAL;
147
be6fbee5 148 xm_tcp = xt_request_find_match(NFPROTO_IPV4, "tcp", 0);
2fbfbe6c
JE
149 if (xm_tcp == NULL) {
150 printk(KERN_WARNING PFX "Error: Could not find or load "
151 "\"tcp\" match\n");
152 return -EINVAL;
153 }
154
be6fbee5 155 xt_reject = xt_request_find_target(NFPROTO_IPV4, "REJECT", 0);
2fbfbe6c
JE
156 if (xt_reject == NULL) {
157 printk(KERN_WARNING PFX "Error: Could not find or load "
158 "\"REJECT\" target\n");
159 goto out2;
160 }
161
be6fbee5 162 xt_tarpit = xt_request_find_target(NFPROTO_IPV4, "TARPIT", 0);
2fbfbe6c
JE
163 have_tarpit = xt_tarpit != NULL;
164 if (!have_tarpit)
165 printk(KERN_WARNING PFX "Warning: Could not find or load "
166 "\"TARPIT\" target\n");
167
be6fbee5 168 xt_delude = xt_request_find_target(NFPROTO_IPV4, "DELUDE", 0);
2fbfbe6c
JE
169 have_delude = xt_delude != NULL;
170 if (!have_delude)
171 printk(KERN_WARNING PFX "Warning: Could not find or load "
172 "\"DELUDE\" target\n");
173
bfb0516c
JE
174 ret = xt_register_target(&chaos_tg_reg);
175 if (ret != 0) {
2fbfbe6c
JE
176 printk(KERN_WARNING PFX "xt_register_target returned "
177 "error %d\n", ret);
178 goto out3;
179 }
180
181 return 0;
182
183 out3:
184 if (have_delude)
185 module_put(xt_delude->me);
186 if (have_tarpit)
187 module_put(xt_tarpit->me);
188 module_put(xt_reject->me);
189 out2:
190 module_put(xm_tcp->me);
191 return ret;
192}
193
194static void __exit chaos_tg_exit(void)
195{
196 xt_unregister_target(&chaos_tg_reg);
197 module_put(xm_tcp->me);
198 module_put(xt_reject->me);
199 if (have_delude)
200 module_put(xt_delude->me);
201 if (have_tarpit)
202 module_put(xt_tarpit->me);
2fbfbe6c
JE
203}
204
205module_init(chaos_tg_init);
206module_exit(chaos_tg_exit);
2fbfbe6c 207MODULE_DESCRIPTION("Xtables: Network scan slowdown with non-deterministic results");
bcdb7ed4 208MODULE_AUTHOR("Jan Engelhardt ");
2fbfbe6c
JE
209MODULE_LICENSE("GPL");
210MODULE_ALIAS("ipt_CHAOS");