1/* Everything about the rules for NAT. */ 2#define __NO_VERSION__ 3#include <linux/types.h> 4#include <linux/ip.h> 5#include <linux/netfilter.h> 6#include <linux/netfilter_ipv4.h> 7#include <linux/module.h> 8#include <linux/kmod.h> 9#include <linux/skbuff.h> 10#include <linux/proc_fs.h> 11#include <net/checksum.h> 12#include <linux/bitops.h> 13#include <linux/version.h> 14 15#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock) 16#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock) 17 18#include <linux/netfilter_ipv4/ip_tables.h> 19#include <linux/netfilter_ipv4/ip_nat.h> 20#include <linux/netfilter_ipv4/ip_nat_core.h> 21#include <linux/netfilter_ipv4/ip_nat_rule.h> 22#include <linux/netfilter_ipv4/listhelp.h> 23 24#define DEBUGP(format, args...) 25 26#define NAT_VALID_HOOKS ((1<<NF_IP_PRE_ROUTING) | (1<<NF_IP_POST_ROUTING) | (1<<NF_IP_LOCAL_OUT)) 27 28/* Standard entry. */ 29struct ipt_standard 30{ 31 struct ipt_entry entry; 32 struct ipt_standard_target target; 33}; 34 35struct ipt_error_target 36{ 37 struct ipt_entry_target target; 38 char errorname[IPT_FUNCTION_MAXNAMELEN]; 39}; 40 41struct ipt_error 42{ 43 struct ipt_entry entry; 44 struct ipt_error_target target; 45}; 46 47static struct 48{ 49 struct ipt_replace repl; 50 struct ipt_standard entries[3]; 51 struct ipt_error term; 52} nat_initial_table __initdata 53= { { "nat", NAT_VALID_HOOKS, 4, 54 sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error), 55 { [NF_IP_PRE_ROUTING] 0, 56 [NF_IP_POST_ROUTING] sizeof(struct ipt_standard), 57 [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) * 2 }, 58 { [NF_IP_PRE_ROUTING] 0, 59 [NF_IP_POST_ROUTING] sizeof(struct ipt_standard), 60 [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) * 2 }, 61 0, NULL, { } }, 62 { 63 /* PRE_ROUTING */ 64 { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, 65 0, 66 sizeof(struct ipt_entry), 67 sizeof(struct ipt_standard), 68 0, { 0, 0 }, { } }, 69 { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, 70 -NF_ACCEPT - 1 } }, 71 /* POST_ROUTING */ 72 { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, 73 0, 74 sizeof(struct ipt_entry), 75 sizeof(struct ipt_standard), 76 0, { 0, 0 }, { } }, 77 { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, 78 -NF_ACCEPT - 1 } }, 79 /* LOCAL_OUT */ 80 { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, 81 0, 82 sizeof(struct ipt_entry), 83 sizeof(struct ipt_standard), 84 0, { 0, 0 }, { } }, 85 { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, 86 -NF_ACCEPT - 1 } } 87 }, 88 /* ERROR */ 89 { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, 90 0, 91 sizeof(struct ipt_entry), 92 sizeof(struct ipt_error), 93 0, { 0, 0 }, { } }, 94 { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } }, 95 { } }, 96 "ERROR" 97 } 98 } 99}; 100 101static struct ipt_table nat_table 102= { { NULL, NULL }, "nat", &nat_initial_table.repl, 103 NAT_VALID_HOOKS, RW_LOCK_UNLOCKED, NULL, THIS_MODULE }; 104 105/* Source NAT */ 106static unsigned int ipt_snat_target(struct sk_buff **pskb, 107 unsigned int hooknum, 108 const struct net_device *in, 109 const struct net_device *out, 110 const void *targinfo, 111 void *userinfo) 112{ 113 struct ip_conntrack *ct; 114 enum ip_conntrack_info ctinfo; 115 116 IP_NF_ASSERT(hooknum == NF_IP_POST_ROUTING); 117 118 ct = ip_conntrack_get(*pskb, &ctinfo); 119 120 /* Connection must be valid and new. */ 121 IP_NF_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)); 122 IP_NF_ASSERT(out); 123 124 return ip_nat_setup_info(ct, targinfo, hooknum); 125} 126 127static unsigned int ipt_dnat_target(struct sk_buff **pskb, 128 unsigned int hooknum, 129 const struct net_device *in, 130 const struct net_device *out, 131 const void *targinfo, 132 void *userinfo) 133{ 134 struct ip_conntrack *ct; 135 enum ip_conntrack_info ctinfo; 136 137#ifdef CONFIG_IP_NF_NAT_LOCAL 138 IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING 139 || hooknum == NF_IP_LOCAL_OUT); 140#else 141 IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING); 142#endif 143 144 ct = ip_conntrack_get(*pskb, &ctinfo); 145 146 /* Connection must be valid and new. */ 147 IP_NF_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)); 148 149 return ip_nat_setup_info(ct, targinfo, hooknum); 150} 151 152static int ipt_snat_checkentry(const char *tablename, 153 const struct ipt_entry *e, 154 void *targinfo, 155 unsigned int targinfosize, 156 unsigned int hook_mask) 157{ 158 struct ip_nat_multi_range *mr = targinfo; 159 160 /* Must be a valid range */ 161 if (targinfosize < sizeof(struct ip_nat_multi_range)) { 162 DEBUGP("SNAT: Target size %u too small\n", targinfosize); 163 return 0; 164 } 165 166 if (targinfosize != IPT_ALIGN((sizeof(struct ip_nat_multi_range) 167 + (sizeof(struct ip_nat_range) 168 * (mr->rangesize - 1))))) { 169 DEBUGP("SNAT: Target size %u wrong for %u ranges\n", 170 targinfosize, mr->rangesize); 171 return 0; 172 } 173 174 /* Only allow these for NAT. */ 175 if (strcmp(tablename, "nat") != 0) { 176 DEBUGP("SNAT: wrong table %s\n", tablename); 177 return 0; 178 } 179 180 if (hook_mask & ~(1 << NF_IP_POST_ROUTING)) { 181 DEBUGP("SNAT: hook mask 0x%x bad\n", hook_mask); 182 return 0; 183 } 184 return 1; 185} 186 187static int ipt_dnat_checkentry(const char *tablename, 188 const struct ipt_entry *e, 189 void *targinfo, 190 unsigned int targinfosize, 191 unsigned int hook_mask) 192{ 193 struct ip_nat_multi_range *mr = targinfo; 194 195 /* Must be a valid range */ 196 if (targinfosize < sizeof(struct ip_nat_multi_range)) { 197 DEBUGP("DNAT: Target size %u too small\n", targinfosize); 198 return 0; 199 } 200 201 if (targinfosize != IPT_ALIGN((sizeof(struct ip_nat_multi_range) 202 + (sizeof(struct ip_nat_range) 203 * (mr->rangesize - 1))))) { 204 DEBUGP("DNAT: Target size %u wrong for %u ranges\n", 205 targinfosize, mr->rangesize); 206 return 0; 207 } 208 209 /* Only allow these for NAT. */ 210 if (strcmp(tablename, "nat") != 0) { 211 DEBUGP("DNAT: wrong table %s\n", tablename); 212 return 0; 213 } 214 215 if (hook_mask & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT))) { 216 DEBUGP("DNAT: hook mask 0x%x bad\n", hook_mask); 217 return 0; 218 } 219 220#ifndef CONFIG_IP_NF_NAT_LOCAL 221 if (hook_mask & (1 << NF_IP_LOCAL_OUT)) { 222 DEBUGP("DNAT: CONFIG_IP_NF_NAT_LOCAL not enabled\n"); 223 return 0; 224 } 225#endif 226 227 return 1; 228} 229 230static inline unsigned int 231alloc_null_binding(struct ip_conntrack *conntrack, 232 struct ip_nat_info *info, 233 unsigned int hooknum) 234{ 235 /* Force range to this IP; let proto decide mapping for 236 per-proto parts (hence not IP_NAT_RANGE_PROTO_SPECIFIED). 237 Use reply in case it's already been mangled (eg local packet). 238 */ 239 u_int32_t ip 240 = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC 241 ? conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip 242 : conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip); 243 struct ip_nat_multi_range mr 244 = { 1, { { IP_NAT_RANGE_MAP_IPS, ip, ip, { 0 }, { 0 } } } }; 245 246 DEBUGP("Allocating NULL binding for %p (%u.%u.%u.%u)\n", conntrack, 247 NIPQUAD(ip)); 248 return ip_nat_setup_info(conntrack, &mr, hooknum); 249} 250 251int ip_nat_rule_find(struct sk_buff **pskb, 252 unsigned int hooknum, 253 const struct net_device *in, 254 const struct net_device *out, 255 struct ip_conntrack *ct, 256 struct ip_nat_info *info) 257{ 258 int ret; 259 260 ret = ipt_do_table(pskb, hooknum, in, out, &nat_table, NULL); 261 262 if (ret == NF_ACCEPT) { 263 if (!(info->initialized & (1 << HOOK2MANIP(hooknum)))) 264 /* NUL mapping */ 265 ret = alloc_null_binding(ct, info, hooknum); 266 } 267 return ret; 268} 269 270static struct ipt_target ipt_snat_reg 271= { { NULL, NULL }, "SNAT", ipt_snat_target, ipt_snat_checkentry, NULL }; 272static struct ipt_target ipt_dnat_reg 273= { { NULL, NULL }, "DNAT", ipt_dnat_target, ipt_dnat_checkentry, NULL }; 274 275int __init ip_nat_rule_init(void) 276{ 277 int ret; 278 279 ret = ipt_register_table(&nat_table); 280 if (ret != 0) 281 return ret; 282 ret = ipt_register_target(&ipt_snat_reg); 283 if (ret != 0) 284 goto unregister_table; 285 286 ret = ipt_register_target(&ipt_dnat_reg); 287 if (ret != 0) 288 goto unregister_snat; 289 290 return ret; 291 292 unregister_snat: 293 ipt_unregister_target(&ipt_snat_reg); 294 unregister_table: 295 ipt_unregister_table(&nat_table); 296 297 return ret; 298} 299 300void ip_nat_rule_cleanup(void) 301{ 302 ipt_unregister_target(&ipt_dnat_reg); 303 ipt_unregister_target(&ipt_snat_reg); 304 ipt_unregister_table(&nat_table); 305} 306