1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * (C) 1999-2001 Paul `Rusty' Russell 4 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org> 5 * Copyright (c) 2011 Patrick McHardy <kaber@trash.net> 6 * 7 * Based on Rusty Russell's IPv4 REDIRECT target. Development of IPv6 8 * NAT funded by Astaro. 9 */ 10 11 #include <linux/if.h> 12 #include <linux/inetdevice.h> 13 #include <linux/ip.h> 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/netdevice.h> 17 #include <linux/netfilter.h> 18 #include <linux/types.h> 19 #include <linux/netfilter_ipv4.h> 20 #include <linux/netfilter_ipv6.h> 21 #include <linux/netfilter/x_tables.h> 22 #include <net/addrconf.h> 23 #include <net/checksum.h> 24 #include <net/protocol.h> 25 #include <net/netfilter/nf_nat.h> 26 #include <net/netfilter/nf_nat_redirect.h> 27 28 static unsigned int 29 redirect_tg6(struct sk_buff *skb, const struct xt_action_param *par) 30 { 31 return nf_nat_redirect_ipv6(skb, par->targinfo, xt_hooknum(par)); 32 } 33 34 static int redirect_tg6_checkentry(const struct xt_tgchk_param *par) 35 { 36 const struct nf_nat_range2 *range = par->targinfo; 37 38 if (range->flags & NF_NAT_RANGE_MAP_IPS) 39 return -EINVAL; 40 41 return nf_ct_netns_get(par->net, par->family); 42 } 43 44 static void redirect_tg_destroy(const struct xt_tgdtor_param *par) 45 { 46 nf_ct_netns_put(par->net, par->family); 47 } 48 49 /* FIXME: Take multiple ranges --RR */ 50 static int redirect_tg4_check(const struct xt_tgchk_param *par) 51 { 52 const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo; 53 54 if (mr->range[0].flags & NF_NAT_RANGE_MAP_IPS) { 55 pr_debug("bad MAP_IPS.\n"); 56 return -EINVAL; 57 } 58 if (mr->rangesize != 1) { 59 pr_debug("bad rangesize %u.\n", mr->rangesize); 60 return -EINVAL; 61 } 62 return nf_ct_netns_get(par->net, par->family); 63 } 64 65 static unsigned int 66 redirect_tg4(struct sk_buff *skb, const struct xt_action_param *par) 67 { 68 return nf_nat_redirect_ipv4(skb, par->targinfo, xt_hooknum(par)); 69 } 70 71 static struct xt_target redirect_tg_reg[] __read_mostly = { 72 { 73 .name = "REDIRECT", 74 .family = NFPROTO_IPV6, 75 .revision = 0, 76 .table = "nat", 77 .checkentry = redirect_tg6_checkentry, 78 .destroy = redirect_tg_destroy, 79 .target = redirect_tg6, 80 .targetsize = sizeof(struct nf_nat_range), 81 .hooks = (1 << NF_INET_PRE_ROUTING) | 82 (1 << NF_INET_LOCAL_OUT), 83 .me = THIS_MODULE, 84 }, 85 { 86 .name = "REDIRECT", 87 .family = NFPROTO_IPV4, 88 .revision = 0, 89 .table = "nat", 90 .target = redirect_tg4, 91 .checkentry = redirect_tg4_check, 92 .destroy = redirect_tg_destroy, 93 .targetsize = sizeof(struct nf_nat_ipv4_multi_range_compat), 94 .hooks = (1 << NF_INET_PRE_ROUTING) | 95 (1 << NF_INET_LOCAL_OUT), 96 .me = THIS_MODULE, 97 }, 98 }; 99 100 static int __init redirect_tg_init(void) 101 { 102 return xt_register_targets(redirect_tg_reg, 103 ARRAY_SIZE(redirect_tg_reg)); 104 } 105 106 static void __exit redirect_tg_exit(void) 107 { 108 xt_unregister_targets(redirect_tg_reg, ARRAY_SIZE(redirect_tg_reg)); 109 } 110 111 module_init(redirect_tg_init); 112 module_exit(redirect_tg_exit); 113 114 MODULE_LICENSE("GPL"); 115 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 116 MODULE_DESCRIPTION("Xtables: Connection redirection to localhost"); 117 MODULE_ALIAS("ip6t_REDIRECT"); 118 MODULE_ALIAS("ipt_REDIRECT"); 119