iptable_filter.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*
  2. * This is the 1999 rewrite of IP Firewalling, aiming for kernel 2.3.x.
  3. *
  4. * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
  5. * Copyright (C) 2000-2004 Netfilter Core Team <coreteam@netfilter.org>
  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. */
  12. #include <linux/module.h>
  13. #include <linux/moduleparam.h>
  14. #include <linux/netfilter_ipv4/ip_tables.h>
  15. MODULE_LICENSE("GPL");
  16. MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
  17. MODULE_DESCRIPTION("iptables filter table");
  18. #define FILTER_VALID_HOOKS ((1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT))
  19. static struct
  20. {
  21. struct ipt_replace repl;
  22. struct ipt_standard entries[3];
  23. struct ipt_error term;
  24. } initial_table __initdata
  25. = { { "filter", FILTER_VALID_HOOKS, 4,
  26. sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error),
  27. { [NF_IP_LOCAL_IN] = 0,
  28. [NF_IP_FORWARD] = sizeof(struct ipt_standard),
  29. [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 },
  30. { [NF_IP_LOCAL_IN] = 0,
  31. [NF_IP_FORWARD] = sizeof(struct ipt_standard),
  32. [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 },
  33. 0, NULL, { } },
  34. {
  35. /* LOCAL_IN */
  36. { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
  37. 0,
  38. sizeof(struct ipt_entry),
  39. sizeof(struct ipt_standard),
  40. 0, { 0, 0 }, { } },
  41. { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
  42. -NF_ACCEPT - 1 } },
  43. /* FORWARD */
  44. { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
  45. 0,
  46. sizeof(struct ipt_entry),
  47. sizeof(struct ipt_standard),
  48. 0, { 0, 0 }, { } },
  49. { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
  50. -NF_ACCEPT - 1 } },
  51. /* LOCAL_OUT */
  52. { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
  53. 0,
  54. sizeof(struct ipt_entry),
  55. sizeof(struct ipt_standard),
  56. 0, { 0, 0 }, { } },
  57. { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
  58. -NF_ACCEPT - 1 } }
  59. },
  60. /* ERROR */
  61. { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
  62. 0,
  63. sizeof(struct ipt_entry),
  64. sizeof(struct ipt_error),
  65. 0, { 0, 0 }, { } },
  66. { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } },
  67. { } },
  68. "ERROR"
  69. }
  70. }
  71. };
  72. static struct xt_table packet_filter = {
  73. .name = "filter",
  74. .valid_hooks = FILTER_VALID_HOOKS,
  75. .lock = RW_LOCK_UNLOCKED,
  76. .me = THIS_MODULE,
  77. .af = AF_INET,
  78. };
  79. /* The work comes in here from netfilter.c. */
  80. static unsigned int
  81. ipt_hook(unsigned int hook,
  82. struct sk_buff **pskb,
  83. const struct net_device *in,
  84. const struct net_device *out,
  85. int (*okfn)(struct sk_buff *))
  86. {
  87. return ipt_do_table(pskb, hook, in, out, &packet_filter);
  88. }
  89. static unsigned int
  90. ipt_local_out_hook(unsigned int hook,
  91. struct sk_buff **pskb,
  92. const struct net_device *in,
  93. const struct net_device *out,
  94. int (*okfn)(struct sk_buff *))
  95. {
  96. /* root is playing with raw sockets. */
  97. if ((*pskb)->len < sizeof(struct iphdr)
  98. || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
  99. if (net_ratelimit())
  100. printk("ipt_hook: happy cracking.\n");
  101. return NF_ACCEPT;
  102. }
  103. return ipt_do_table(pskb, hook, in, out, &packet_filter);
  104. }
  105. static struct nf_hook_ops ipt_ops[] = {
  106. {
  107. .hook = ipt_hook,
  108. .owner = THIS_MODULE,
  109. .pf = PF_INET,
  110. .hooknum = NF_IP_LOCAL_IN,
  111. .priority = NF_IP_PRI_FILTER,
  112. },
  113. {
  114. .hook = ipt_hook,
  115. .owner = THIS_MODULE,
  116. .pf = PF_INET,
  117. .hooknum = NF_IP_FORWARD,
  118. .priority = NF_IP_PRI_FILTER,
  119. },
  120. {
  121. .hook = ipt_local_out_hook,
  122. .owner = THIS_MODULE,
  123. .pf = PF_INET,
  124. .hooknum = NF_IP_LOCAL_OUT,
  125. .priority = NF_IP_PRI_FILTER,
  126. },
  127. };
  128. /* Default to forward because I got too much mail already. */
  129. static int forward = NF_ACCEPT;
  130. module_param(forward, bool, 0000);
  131. static int __init iptable_filter_init(void)
  132. {
  133. int ret;
  134. if (forward < 0 || forward > NF_MAX_VERDICT) {
  135. printk("iptables forward must be 0 or 1\n");
  136. return -EINVAL;
  137. }
  138. /* Entry 1 is the FORWARD hook */
  139. initial_table.entries[1].target.verdict = -forward - 1;
  140. /* Register table */
  141. ret = ipt_register_table(&packet_filter, &initial_table.repl);
  142. if (ret < 0)
  143. return ret;
  144. /* Register hooks */
  145. ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops));
  146. if (ret < 0)
  147. goto cleanup_table;
  148. return ret;
  149. cleanup_table:
  150. ipt_unregister_table(&packet_filter);
  151. return ret;
  152. }
  153. static void __exit iptable_filter_fini(void)
  154. {
  155. nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops));
  156. ipt_unregister_table(&packet_filter);
  157. }
  158. module_init(iptable_filter_init);
  159. module_exit(iptable_filter_fini);