ipt_NETMAP.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /* NETMAP - static NAT mapping of IP network addresses (1:1).
  2. * The mapping can be applied to source (POSTROUTING),
  3. * destination (PREROUTING), or both (with separate rules).
  4. */
  5. /* (C) 2000-2001 Svenning Soerensen <svenning@post5.tele.dk>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. */
  11. #include <linux/ip.h>
  12. #include <linux/module.h>
  13. #include <linux/netdevice.h>
  14. #include <linux/netfilter.h>
  15. #include <linux/netfilter_ipv4.h>
  16. #include <linux/netfilter/x_tables.h>
  17. #ifdef CONFIG_NF_NAT_NEEDED
  18. #include <net/netfilter/nf_nat_rule.h>
  19. #else
  20. #include <linux/netfilter_ipv4/ip_nat_rule.h>
  21. #endif
  22. #define MODULENAME "NETMAP"
  23. MODULE_LICENSE("GPL");
  24. MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>");
  25. MODULE_DESCRIPTION("iptables 1:1 NAT mapping of IP networks target");
  26. #if 0
  27. #define DEBUGP printk
  28. #else
  29. #define DEBUGP(format, args...)
  30. #endif
  31. static int
  32. check(const char *tablename,
  33. const void *e,
  34. const struct xt_target *target,
  35. void *targinfo,
  36. unsigned int hook_mask)
  37. {
  38. const struct ip_nat_multi_range_compat *mr = targinfo;
  39. if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) {
  40. DEBUGP(MODULENAME":check: bad MAP_IPS.\n");
  41. return 0;
  42. }
  43. if (mr->rangesize != 1) {
  44. DEBUGP(MODULENAME":check: bad rangesize %u.\n", mr->rangesize);
  45. return 0;
  46. }
  47. return 1;
  48. }
  49. static unsigned int
  50. target(struct sk_buff **pskb,
  51. const struct net_device *in,
  52. const struct net_device *out,
  53. unsigned int hooknum,
  54. const struct xt_target *target,
  55. const void *targinfo)
  56. {
  57. struct ip_conntrack *ct;
  58. enum ip_conntrack_info ctinfo;
  59. __be32 new_ip, netmask;
  60. const struct ip_nat_multi_range_compat *mr = targinfo;
  61. struct ip_nat_range newrange;
  62. IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING
  63. || hooknum == NF_IP_POST_ROUTING
  64. || hooknum == NF_IP_LOCAL_OUT);
  65. ct = ip_conntrack_get(*pskb, &ctinfo);
  66. netmask = ~(mr->range[0].min_ip ^ mr->range[0].max_ip);
  67. if (hooknum == NF_IP_PRE_ROUTING || hooknum == NF_IP_LOCAL_OUT)
  68. new_ip = (*pskb)->nh.iph->daddr & ~netmask;
  69. else
  70. new_ip = (*pskb)->nh.iph->saddr & ~netmask;
  71. new_ip |= mr->range[0].min_ip & netmask;
  72. newrange = ((struct ip_nat_range)
  73. { mr->range[0].flags | IP_NAT_RANGE_MAP_IPS,
  74. new_ip, new_ip,
  75. mr->range[0].min, mr->range[0].max });
  76. /* Hand modified range to generic setup. */
  77. return ip_nat_setup_info(ct, &newrange, hooknum);
  78. }
  79. static struct xt_target target_module = {
  80. .name = MODULENAME,
  81. .family = AF_INET,
  82. .target = target,
  83. .targetsize = sizeof(struct ip_nat_multi_range_compat),
  84. .table = "nat",
  85. .hooks = (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_POST_ROUTING) |
  86. (1 << NF_IP_LOCAL_OUT),
  87. .checkentry = check,
  88. .me = THIS_MODULE
  89. };
  90. static int __init ipt_netmap_init(void)
  91. {
  92. return xt_register_target(&target_module);
  93. }
  94. static void __exit ipt_netmap_fini(void)
  95. {
  96. xt_unregister_target(&target_module);
  97. }
  98. module_init(ipt_netmap_init);
  99. module_exit(ipt_netmap_fini);