xt_nat.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * (C) 1999-2001 Paul `Rusty' Russell
  3. * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
  4. * (C) 2011 Patrick McHardy <kaber@trash.net>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. #include <linux/module.h>
  11. #include <linux/skbuff.h>
  12. #include <linux/netfilter.h>
  13. #include <linux/netfilter/x_tables.h>
  14. #include <net/netfilter/nf_nat_core.h>
  15. static int xt_nat_checkentry_v0(const struct xt_tgchk_param *par)
  16. {
  17. const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
  18. if (mr->rangesize != 1) {
  19. pr_info("%s: multiple ranges no longer supported\n",
  20. par->target->name);
  21. return -EINVAL;
  22. }
  23. return 0;
  24. }
  25. static void xt_nat_convert_range(struct nf_nat_range *dst,
  26. const struct nf_nat_ipv4_range *src)
  27. {
  28. memset(&dst->min_addr, 0, sizeof(dst->min_addr));
  29. memset(&dst->max_addr, 0, sizeof(dst->max_addr));
  30. dst->flags = src->flags;
  31. dst->min_addr.ip = src->min_ip;
  32. dst->max_addr.ip = src->max_ip;
  33. dst->min_proto = src->min;
  34. dst->max_proto = src->max;
  35. }
  36. static unsigned int
  37. xt_snat_target_v0(struct sk_buff *skb, const struct xt_action_param *par)
  38. {
  39. const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
  40. struct nf_nat_range range;
  41. enum ip_conntrack_info ctinfo;
  42. struct nf_conn *ct;
  43. ct = nf_ct_get(skb, &ctinfo);
  44. NF_CT_ASSERT(ct != NULL &&
  45. (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
  46. ctinfo == IP_CT_RELATED_REPLY));
  47. xt_nat_convert_range(&range, &mr->range[0]);
  48. return nf_nat_setup_info(ct, &range, NF_NAT_MANIP_SRC);
  49. }
  50. static unsigned int
  51. xt_dnat_target_v0(struct sk_buff *skb, const struct xt_action_param *par)
  52. {
  53. const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
  54. struct nf_nat_range range;
  55. enum ip_conntrack_info ctinfo;
  56. struct nf_conn *ct;
  57. ct = nf_ct_get(skb, &ctinfo);
  58. NF_CT_ASSERT(ct != NULL &&
  59. (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
  60. xt_nat_convert_range(&range, &mr->range[0]);
  61. return nf_nat_setup_info(ct, &range, NF_NAT_MANIP_DST);
  62. }
  63. static unsigned int
  64. xt_snat_target_v1(struct sk_buff *skb, const struct xt_action_param *par)
  65. {
  66. const struct nf_nat_range *range = par->targinfo;
  67. enum ip_conntrack_info ctinfo;
  68. struct nf_conn *ct;
  69. ct = nf_ct_get(skb, &ctinfo);
  70. NF_CT_ASSERT(ct != NULL &&
  71. (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
  72. ctinfo == IP_CT_RELATED_REPLY));
  73. return nf_nat_setup_info(ct, range, NF_NAT_MANIP_SRC);
  74. }
  75. static unsigned int
  76. xt_dnat_target_v1(struct sk_buff *skb, const struct xt_action_param *par)
  77. {
  78. const struct nf_nat_range *range = par->targinfo;
  79. enum ip_conntrack_info ctinfo;
  80. struct nf_conn *ct;
  81. ct = nf_ct_get(skb, &ctinfo);
  82. NF_CT_ASSERT(ct != NULL &&
  83. (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
  84. return nf_nat_setup_info(ct, range, NF_NAT_MANIP_DST);
  85. }
  86. static struct xt_target xt_nat_target_reg[] __read_mostly = {
  87. {
  88. .name = "SNAT",
  89. .revision = 0,
  90. .checkentry = xt_nat_checkentry_v0,
  91. .target = xt_snat_target_v0,
  92. .targetsize = sizeof(struct nf_nat_ipv4_multi_range_compat),
  93. .family = NFPROTO_IPV4,
  94. .table = "nat",
  95. .hooks = (1 << NF_INET_POST_ROUTING) |
  96. (1 << NF_INET_LOCAL_IN),
  97. .me = THIS_MODULE,
  98. },
  99. {
  100. .name = "DNAT",
  101. .revision = 0,
  102. .checkentry = xt_nat_checkentry_v0,
  103. .target = xt_dnat_target_v0,
  104. .targetsize = sizeof(struct nf_nat_ipv4_multi_range_compat),
  105. .family = NFPROTO_IPV4,
  106. .table = "nat",
  107. .hooks = (1 << NF_INET_PRE_ROUTING) |
  108. (1 << NF_INET_LOCAL_OUT),
  109. .me = THIS_MODULE,
  110. },
  111. {
  112. .name = "SNAT",
  113. .revision = 1,
  114. .target = xt_snat_target_v1,
  115. .targetsize = sizeof(struct nf_nat_range),
  116. .table = "nat",
  117. .hooks = (1 << NF_INET_POST_ROUTING) |
  118. (1 << NF_INET_LOCAL_IN),
  119. .me = THIS_MODULE,
  120. },
  121. {
  122. .name = "DNAT",
  123. .revision = 1,
  124. .target = xt_dnat_target_v1,
  125. .targetsize = sizeof(struct nf_nat_range),
  126. .table = "nat",
  127. .hooks = (1 << NF_INET_PRE_ROUTING) |
  128. (1 << NF_INET_LOCAL_OUT),
  129. .me = THIS_MODULE,
  130. },
  131. };
  132. static int __init xt_nat_init(void)
  133. {
  134. return xt_register_targets(xt_nat_target_reg,
  135. ARRAY_SIZE(xt_nat_target_reg));
  136. }
  137. static void __exit xt_nat_exit(void)
  138. {
  139. xt_unregister_targets(xt_nat_target_reg, ARRAY_SIZE(xt_nat_target_reg));
  140. }
  141. module_init(xt_nat_init);
  142. module_exit(xt_nat_exit);
  143. MODULE_LICENSE("GPL");
  144. MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
  145. MODULE_ALIAS("ipt_SNAT");
  146. MODULE_ALIAS("ipt_DNAT");
  147. MODULE_ALIAS("ip6t_SNAT");
  148. MODULE_ALIAS("ip6t_DNAT");