123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- /*
- * (C) 1999-2001 Paul `Rusty' Russell
- * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
- * (C) 2011 Patrick McHardy <kaber@trash.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
- #include <linux/module.h>
- #include <linux/skbuff.h>
- #include <linux/netfilter.h>
- #include <linux/netfilter/x_tables.h>
- #include <net/netfilter/nf_nat_core.h>
- static int xt_nat_checkentry_v0(const struct xt_tgchk_param *par)
- {
- const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
- if (mr->rangesize != 1) {
- pr_info("%s: multiple ranges no longer supported\n",
- par->target->name);
- return -EINVAL;
- }
- return 0;
- }
- static void xt_nat_convert_range(struct nf_nat_range *dst,
- const struct nf_nat_ipv4_range *src)
- {
- memset(&dst->min_addr, 0, sizeof(dst->min_addr));
- memset(&dst->max_addr, 0, sizeof(dst->max_addr));
- dst->flags = src->flags;
- dst->min_addr.ip = src->min_ip;
- dst->max_addr.ip = src->max_ip;
- dst->min_proto = src->min;
- dst->max_proto = src->max;
- }
- static unsigned int
- xt_snat_target_v0(struct sk_buff *skb, const struct xt_action_param *par)
- {
- const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
- struct nf_nat_range range;
- enum ip_conntrack_info ctinfo;
- struct nf_conn *ct;
- ct = nf_ct_get(skb, &ctinfo);
- NF_CT_ASSERT(ct != NULL &&
- (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
- ctinfo == IP_CT_RELATED_REPLY));
- xt_nat_convert_range(&range, &mr->range[0]);
- return nf_nat_setup_info(ct, &range, NF_NAT_MANIP_SRC);
- }
- static unsigned int
- xt_dnat_target_v0(struct sk_buff *skb, const struct xt_action_param *par)
- {
- const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
- struct nf_nat_range range;
- enum ip_conntrack_info ctinfo;
- struct nf_conn *ct;
- ct = nf_ct_get(skb, &ctinfo);
- NF_CT_ASSERT(ct != NULL &&
- (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
- xt_nat_convert_range(&range, &mr->range[0]);
- return nf_nat_setup_info(ct, &range, NF_NAT_MANIP_DST);
- }
- static unsigned int
- xt_snat_target_v1(struct sk_buff *skb, const struct xt_action_param *par)
- {
- const struct nf_nat_range *range = par->targinfo;
- enum ip_conntrack_info ctinfo;
- struct nf_conn *ct;
- ct = nf_ct_get(skb, &ctinfo);
- NF_CT_ASSERT(ct != NULL &&
- (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
- ctinfo == IP_CT_RELATED_REPLY));
- return nf_nat_setup_info(ct, range, NF_NAT_MANIP_SRC);
- }
- static unsigned int
- xt_dnat_target_v1(struct sk_buff *skb, const struct xt_action_param *par)
- {
- const struct nf_nat_range *range = par->targinfo;
- enum ip_conntrack_info ctinfo;
- struct nf_conn *ct;
- ct = nf_ct_get(skb, &ctinfo);
- NF_CT_ASSERT(ct != NULL &&
- (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
- return nf_nat_setup_info(ct, range, NF_NAT_MANIP_DST);
- }
- static struct xt_target xt_nat_target_reg[] __read_mostly = {
- {
- .name = "SNAT",
- .revision = 0,
- .checkentry = xt_nat_checkentry_v0,
- .target = xt_snat_target_v0,
- .targetsize = sizeof(struct nf_nat_ipv4_multi_range_compat),
- .family = NFPROTO_IPV4,
- .table = "nat",
- .hooks = (1 << NF_INET_POST_ROUTING) |
- (1 << NF_INET_LOCAL_IN),
- .me = THIS_MODULE,
- },
- {
- .name = "DNAT",
- .revision = 0,
- .checkentry = xt_nat_checkentry_v0,
- .target = xt_dnat_target_v0,
- .targetsize = sizeof(struct nf_nat_ipv4_multi_range_compat),
- .family = NFPROTO_IPV4,
- .table = "nat",
- .hooks = (1 << NF_INET_PRE_ROUTING) |
- (1 << NF_INET_LOCAL_OUT),
- .me = THIS_MODULE,
- },
- {
- .name = "SNAT",
- .revision = 1,
- .target = xt_snat_target_v1,
- .targetsize = sizeof(struct nf_nat_range),
- .table = "nat",
- .hooks = (1 << NF_INET_POST_ROUTING) |
- (1 << NF_INET_LOCAL_IN),
- .me = THIS_MODULE,
- },
- {
- .name = "DNAT",
- .revision = 1,
- .target = xt_dnat_target_v1,
- .targetsize = sizeof(struct nf_nat_range),
- .table = "nat",
- .hooks = (1 << NF_INET_PRE_ROUTING) |
- (1 << NF_INET_LOCAL_OUT),
- .me = THIS_MODULE,
- },
- };
- static int __init xt_nat_init(void)
- {
- return xt_register_targets(xt_nat_target_reg,
- ARRAY_SIZE(xt_nat_target_reg));
- }
- static void __exit xt_nat_exit(void)
- {
- xt_unregister_targets(xt_nat_target_reg, ARRAY_SIZE(xt_nat_target_reg));
- }
- module_init(xt_nat_init);
- module_exit(xt_nat_exit);
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
- MODULE_ALIAS("ipt_SNAT");
- MODULE_ALIAS("ipt_DNAT");
- MODULE_ALIAS("ip6t_SNAT");
- MODULE_ALIAS("ip6t_DNAT");
|