blob: 1d16c0f28df00d17c38a52bfeff23c0a1bca0142 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * This is a module which is used for rejecting packets.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 */
4
5/* (C) 1999-2001 Paul `Rusty' Russell
6 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
Jan Engelhardtff67e4e2010-03-19 21:08:16 +010012#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
Linus Torvalds1da177e2005-04-16 15:20:36 -070013#include <linux/module.h>
14#include <linux/skbuff.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090015#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070016#include <linux/ip.h>
17#include <linux/udp.h>
18#include <linux/icmp.h>
19#include <net/icmp.h>
Jan Engelhardt6709dbb2007-02-07 15:11:19 -080020#include <linux/netfilter/x_tables.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#include <linux/netfilter_ipv4/ip_tables.h>
22#include <linux/netfilter_ipv4/ipt_REJECT.h>
Pablo Neira Ayuso1109a902014-10-01 11:19:17 +020023#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
Linus Torvalds1da177e2005-04-16 15:20:36 -070024#include <linux/netfilter_bridge.h>
25#endif
26
Eric Leblondcc70d062013-12-29 12:28:13 +010027#include <net/netfilter/ipv4/nf_reject.h>
28
Linus Torvalds1da177e2005-04-16 15:20:36 -070029MODULE_LICENSE("GPL");
30MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
Jan Engelhardt2ae15b62008-01-14 23:42:28 -080031MODULE_DESCRIPTION("Xtables: packet \"rejection\" target for IPv4");
Linus Torvalds1da177e2005-04-16 15:20:36 -070032
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080033static unsigned int
Jan Engelhardt4b560b42009-07-05 19:43:26 +020034reject_tg(struct sk_buff *skb, const struct xt_action_param *par)
Linus Torvalds1da177e2005-04-16 15:20:36 -070035{
Jan Engelhardt7eb35582008-10-08 11:35:19 +020036 const struct ipt_reject_info *reject = par->targinfo;
Florian Westphalee586bb2015-02-16 18:54:04 +010037 int hook = par->hooknum;
Linus Torvalds1da177e2005-04-16 15:20:36 -070038
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +090039 switch (reject->with) {
40 case IPT_ICMP_NET_UNREACHABLE:
Florian Westphalee586bb2015-02-16 18:54:04 +010041 nf_send_unreach(skb, ICMP_NET_UNREACH, hook);
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +090042 break;
43 case IPT_ICMP_HOST_UNREACHABLE:
Florian Westphalee586bb2015-02-16 18:54:04 +010044 nf_send_unreach(skb, ICMP_HOST_UNREACH, hook);
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +090045 break;
46 case IPT_ICMP_PROT_UNREACHABLE:
Florian Westphalee586bb2015-02-16 18:54:04 +010047 nf_send_unreach(skb, ICMP_PROT_UNREACH, hook);
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +090048 break;
49 case IPT_ICMP_PORT_UNREACHABLE:
Florian Westphalee586bb2015-02-16 18:54:04 +010050 nf_send_unreach(skb, ICMP_PORT_UNREACH, hook);
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +090051 break;
52 case IPT_ICMP_NET_PROHIBITED:
Florian Westphalee586bb2015-02-16 18:54:04 +010053 nf_send_unreach(skb, ICMP_NET_ANO, hook);
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +090054 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -070055 case IPT_ICMP_HOST_PROHIBITED:
Florian Westphalee586bb2015-02-16 18:54:04 +010056 nf_send_unreach(skb, ICMP_HOST_ANO, hook);
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +090057 break;
58 case IPT_ICMP_ADMIN_PROHIBITED:
Florian Westphalee586bb2015-02-16 18:54:04 +010059 nf_send_unreach(skb, ICMP_PKT_FILTERED, hook);
Linus Torvalds1da177e2005-04-16 15:20:36 -070060 break;
61 case IPT_TCP_RESET:
Eric W. Biederman372892e2015-09-25 15:07:27 -050062 nf_send_reset(par->net, skb, hook);
Linus Torvalds1da177e2005-04-16 15:20:36 -070063 case IPT_ICMP_ECHOREPLY:
64 /* Doesn't happen. */
65 break;
66 }
67
68 return NF_DROP;
69}
70
Jan Engelhardt135367b2010-03-19 17:16:42 +010071static int reject_tg_check(const struct xt_tgchk_param *par)
Linus Torvalds1da177e2005-04-16 15:20:36 -070072{
Jan Engelhardtaf5d6dc2008-10-08 11:35:19 +020073 const struct ipt_reject_info *rejinfo = par->targinfo;
74 const struct ipt_entry *e = par->entryinfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -070075
Linus Torvalds1da177e2005-04-16 15:20:36 -070076 if (rejinfo->with == IPT_ICMP_ECHOREPLY) {
Jan Engelhardtff67e4e2010-03-19 21:08:16 +010077 pr_info("ECHOREPLY no longer supported.\n");
Jan Engelhardtd6b00a52010-03-25 16:34:45 +010078 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -070079 } else if (rejinfo->with == IPT_TCP_RESET) {
80 /* Must specify that it's a TCP packet */
Joe Perches3666ed12009-11-23 23:17:06 +010081 if (e->ip.proto != IPPROTO_TCP ||
82 (e->ip.invflags & XT_INV_PROTO)) {
Jan Engelhardtff67e4e2010-03-19 21:08:16 +010083 pr_info("TCP_RESET invalid for non-tcp\n");
Jan Engelhardtd6b00a52010-03-25 16:34:45 +010084 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -070085 }
86 }
Jan Engelhardtd6b00a52010-03-25 16:34:45 +010087 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070088}
89
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080090static struct xt_target reject_tg_reg __read_mostly = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070091 .name = "REJECT",
Jan Engelhardtee999d82008-10-08 11:35:01 +020092 .family = NFPROTO_IPV4,
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080093 .target = reject_tg,
Patrick McHardy1d5cd902006-03-20 18:01:14 -080094 .targetsize = sizeof(struct ipt_reject_info),
95 .table = "filter",
Patrick McHardy6e23ae22007-11-19 18:53:30 -080096 .hooks = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD) |
97 (1 << NF_INET_LOCAL_OUT),
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -080098 .checkentry = reject_tg_check,
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 .me = THIS_MODULE,
100};
101
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -0800102static int __init reject_tg_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103{
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -0800104 return xt_register_target(&reject_tg_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105}
106
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -0800107static void __exit reject_tg_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108{
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -0800109 xt_unregister_target(&reject_tg_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110}
111
Jan Engelhardtd3c5ee62007-12-04 23:24:03 -0800112module_init(reject_tg_init);
113module_exit(reject_tg_exit);