0001
0002
0003
0004
0005
0006
0007
0008 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0009
0010 #include <linux/module.h>
0011 #include <linux/skbuff.h>
0012 #include <linux/netfilter.h>
0013 #include <linux/netfilter/x_tables.h>
0014 #include <net/netfilter/nf_nat.h>
0015
0016 static int xt_nat_checkentry_v0(const struct xt_tgchk_param *par)
0017 {
0018 const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
0019
0020 if (mr->rangesize != 1) {
0021 pr_info_ratelimited("multiple ranges no longer supported\n");
0022 return -EINVAL;
0023 }
0024 return nf_ct_netns_get(par->net, par->family);
0025 }
0026
0027 static int xt_nat_checkentry(const struct xt_tgchk_param *par)
0028 {
0029 return nf_ct_netns_get(par->net, par->family);
0030 }
0031
0032 static void xt_nat_destroy(const struct xt_tgdtor_param *par)
0033 {
0034 nf_ct_netns_put(par->net, par->family);
0035 }
0036
0037 static void xt_nat_convert_range(struct nf_nat_range2 *dst,
0038 const struct nf_nat_ipv4_range *src)
0039 {
0040 memset(&dst->min_addr, 0, sizeof(dst->min_addr));
0041 memset(&dst->max_addr, 0, sizeof(dst->max_addr));
0042 memset(&dst->base_proto, 0, sizeof(dst->base_proto));
0043
0044 dst->flags = src->flags;
0045 dst->min_addr.ip = src->min_ip;
0046 dst->max_addr.ip = src->max_ip;
0047 dst->min_proto = src->min;
0048 dst->max_proto = src->max;
0049 }
0050
0051 static unsigned int
0052 xt_snat_target_v0(struct sk_buff *skb, const struct xt_action_param *par)
0053 {
0054 const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
0055 struct nf_nat_range2 range;
0056 enum ip_conntrack_info ctinfo;
0057 struct nf_conn *ct;
0058
0059 ct = nf_ct_get(skb, &ctinfo);
0060 WARN_ON(!(ct != NULL &&
0061 (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
0062 ctinfo == IP_CT_RELATED_REPLY)));
0063
0064 xt_nat_convert_range(&range, &mr->range[0]);
0065 return nf_nat_setup_info(ct, &range, NF_NAT_MANIP_SRC);
0066 }
0067
0068 static unsigned int
0069 xt_dnat_target_v0(struct sk_buff *skb, const struct xt_action_param *par)
0070 {
0071 const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
0072 struct nf_nat_range2 range;
0073 enum ip_conntrack_info ctinfo;
0074 struct nf_conn *ct;
0075
0076 ct = nf_ct_get(skb, &ctinfo);
0077 WARN_ON(!(ct != NULL &&
0078 (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)));
0079
0080 xt_nat_convert_range(&range, &mr->range[0]);
0081 return nf_nat_setup_info(ct, &range, NF_NAT_MANIP_DST);
0082 }
0083
0084 static unsigned int
0085 xt_snat_target_v1(struct sk_buff *skb, const struct xt_action_param *par)
0086 {
0087 const struct nf_nat_range *range_v1 = par->targinfo;
0088 struct nf_nat_range2 range;
0089 enum ip_conntrack_info ctinfo;
0090 struct nf_conn *ct;
0091
0092 ct = nf_ct_get(skb, &ctinfo);
0093 WARN_ON(!(ct != NULL &&
0094 (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
0095 ctinfo == IP_CT_RELATED_REPLY)));
0096
0097 memcpy(&range, range_v1, sizeof(*range_v1));
0098 memset(&range.base_proto, 0, sizeof(range.base_proto));
0099
0100 return nf_nat_setup_info(ct, &range, NF_NAT_MANIP_SRC);
0101 }
0102
0103 static unsigned int
0104 xt_dnat_target_v1(struct sk_buff *skb, const struct xt_action_param *par)
0105 {
0106 const struct nf_nat_range *range_v1 = par->targinfo;
0107 struct nf_nat_range2 range;
0108 enum ip_conntrack_info ctinfo;
0109 struct nf_conn *ct;
0110
0111 ct = nf_ct_get(skb, &ctinfo);
0112 WARN_ON(!(ct != NULL &&
0113 (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)));
0114
0115 memcpy(&range, range_v1, sizeof(*range_v1));
0116 memset(&range.base_proto, 0, sizeof(range.base_proto));
0117
0118 return nf_nat_setup_info(ct, &range, NF_NAT_MANIP_DST);
0119 }
0120
0121 static unsigned int
0122 xt_snat_target_v2(struct sk_buff *skb, const struct xt_action_param *par)
0123 {
0124 const struct nf_nat_range2 *range = par->targinfo;
0125 enum ip_conntrack_info ctinfo;
0126 struct nf_conn *ct;
0127
0128 ct = nf_ct_get(skb, &ctinfo);
0129 WARN_ON(!(ct != NULL &&
0130 (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
0131 ctinfo == IP_CT_RELATED_REPLY)));
0132
0133 return nf_nat_setup_info(ct, range, NF_NAT_MANIP_SRC);
0134 }
0135
0136 static unsigned int
0137 xt_dnat_target_v2(struct sk_buff *skb, const struct xt_action_param *par)
0138 {
0139 const struct nf_nat_range2 *range = par->targinfo;
0140 enum ip_conntrack_info ctinfo;
0141 struct nf_conn *ct;
0142
0143 ct = nf_ct_get(skb, &ctinfo);
0144 WARN_ON(!(ct != NULL &&
0145 (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)));
0146
0147 return nf_nat_setup_info(ct, range, NF_NAT_MANIP_DST);
0148 }
0149
0150 static struct xt_target xt_nat_target_reg[] __read_mostly = {
0151 {
0152 .name = "SNAT",
0153 .revision = 0,
0154 .checkentry = xt_nat_checkentry_v0,
0155 .destroy = xt_nat_destroy,
0156 .target = xt_snat_target_v0,
0157 .targetsize = sizeof(struct nf_nat_ipv4_multi_range_compat),
0158 .family = NFPROTO_IPV4,
0159 .table = "nat",
0160 .hooks = (1 << NF_INET_POST_ROUTING) |
0161 (1 << NF_INET_LOCAL_IN),
0162 .me = THIS_MODULE,
0163 },
0164 {
0165 .name = "DNAT",
0166 .revision = 0,
0167 .checkentry = xt_nat_checkentry_v0,
0168 .destroy = xt_nat_destroy,
0169 .target = xt_dnat_target_v0,
0170 .targetsize = sizeof(struct nf_nat_ipv4_multi_range_compat),
0171 .family = NFPROTO_IPV4,
0172 .table = "nat",
0173 .hooks = (1 << NF_INET_PRE_ROUTING) |
0174 (1 << NF_INET_LOCAL_OUT),
0175 .me = THIS_MODULE,
0176 },
0177 {
0178 .name = "SNAT",
0179 .revision = 1,
0180 .checkentry = xt_nat_checkentry,
0181 .destroy = xt_nat_destroy,
0182 .target = xt_snat_target_v1,
0183 .targetsize = sizeof(struct nf_nat_range),
0184 .table = "nat",
0185 .hooks = (1 << NF_INET_POST_ROUTING) |
0186 (1 << NF_INET_LOCAL_IN),
0187 .me = THIS_MODULE,
0188 },
0189 {
0190 .name = "DNAT",
0191 .revision = 1,
0192 .checkentry = xt_nat_checkentry,
0193 .destroy = xt_nat_destroy,
0194 .target = xt_dnat_target_v1,
0195 .targetsize = sizeof(struct nf_nat_range),
0196 .table = "nat",
0197 .hooks = (1 << NF_INET_PRE_ROUTING) |
0198 (1 << NF_INET_LOCAL_OUT),
0199 .me = THIS_MODULE,
0200 },
0201 {
0202 .name = "SNAT",
0203 .revision = 2,
0204 .checkentry = xt_nat_checkentry,
0205 .destroy = xt_nat_destroy,
0206 .target = xt_snat_target_v2,
0207 .targetsize = sizeof(struct nf_nat_range2),
0208 .table = "nat",
0209 .hooks = (1 << NF_INET_POST_ROUTING) |
0210 (1 << NF_INET_LOCAL_IN),
0211 .me = THIS_MODULE,
0212 },
0213 {
0214 .name = "DNAT",
0215 .revision = 2,
0216 .checkentry = xt_nat_checkentry,
0217 .destroy = xt_nat_destroy,
0218 .target = xt_dnat_target_v2,
0219 .targetsize = sizeof(struct nf_nat_range2),
0220 .table = "nat",
0221 .hooks = (1 << NF_INET_PRE_ROUTING) |
0222 (1 << NF_INET_LOCAL_OUT),
0223 .me = THIS_MODULE,
0224 },
0225 };
0226
0227 static int __init xt_nat_init(void)
0228 {
0229 return xt_register_targets(xt_nat_target_reg,
0230 ARRAY_SIZE(xt_nat_target_reg));
0231 }
0232
0233 static void __exit xt_nat_exit(void)
0234 {
0235 xt_unregister_targets(xt_nat_target_reg, ARRAY_SIZE(xt_nat_target_reg));
0236 }
0237
0238 module_init(xt_nat_init);
0239 module_exit(xt_nat_exit);
0240
0241 MODULE_LICENSE("GPL");
0242 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
0243 MODULE_ALIAS("ipt_SNAT");
0244 MODULE_ALIAS("ipt_DNAT");
0245 MODULE_ALIAS("ip6t_SNAT");
0246 MODULE_ALIAS("ip6t_DNAT");
0247 MODULE_DESCRIPTION("SNAT and DNAT targets support");