ip6table_mangle.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:7k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * IPv6 packet mangling table, a port of the IPv4 mangle table to IPv6
  3.  *
  4.  * Copyright (C) 2000-2001 by Harald Welte <laforge@gnumonks.org>
  5.  */
  6. #include <linux/module.h>
  7. #include <linux/netfilter_ipv6/ip6_tables.h>
  8. #define MANGLE_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | 
  9.     (1 << NF_IP6_LOCAL_IN) | 
  10.     (1 << NF_IP6_FORWARD) | 
  11.     (1 << NF_IP6_LOCAL_OUT) | 
  12.     (1 << NF_IP6_POST_ROUTING))
  13. #if 0
  14. #define DEBUGP(x, args...) printk(KERN_DEBUG x, ## args)
  15. #else
  16. #define DEBUGP(x, args...)
  17. #endif
  18. /* Standard entry. */
  19. struct ip6t_standard
  20. {
  21. struct ip6t_entry entry;
  22. struct ip6t_standard_target target;
  23. };
  24. struct ip6t_error_target
  25. {
  26. struct ip6t_entry_target target;
  27. char errorname[IP6T_FUNCTION_MAXNAMELEN];
  28. };
  29. struct ip6t_error
  30. {
  31. struct ip6t_entry entry;
  32. struct ip6t_error_target target;
  33. };
  34. static struct
  35. {
  36. struct ip6t_replace repl;
  37. struct ip6t_standard entries[5];
  38. struct ip6t_error term;
  39. } initial_table __initdata
  40. = { { "mangle", MANGLE_VALID_HOOKS, 6,
  41.       sizeof(struct ip6t_standard) * 5 + sizeof(struct ip6t_error),
  42.       { [NF_IP6_PRE_ROUTING]  0,
  43. [NF_IP6_LOCAL_IN] sizeof(struct ip6t_standard),
  44. [NF_IP6_FORWARD] sizeof(struct ip6t_standard) * 2,
  45. [NF_IP6_LOCAL_OUT]  sizeof(struct ip6t_standard) * 3,
  46. [NF_IP6_POST_ROUTING] sizeof(struct ip6t_standard) * 4},
  47.       { [NF_IP6_PRE_ROUTING]  0,
  48. [NF_IP6_LOCAL_IN] sizeof(struct ip6t_standard),
  49. [NF_IP6_FORWARD] sizeof(struct ip6t_standard) * 2,
  50. [NF_IP6_LOCAL_OUT]  sizeof(struct ip6t_standard) * 3,
  51. [NF_IP6_POST_ROUTING] sizeof(struct ip6t_standard) * 4},
  52.       0, NULL, { } },
  53.     {
  54.     /* PRE_ROUTING */
  55.             { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
  56. 0,
  57. sizeof(struct ip6t_entry),
  58. sizeof(struct ip6t_standard),
  59. 0, { 0, 0 }, { } },
  60.       { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
  61. -NF_ACCEPT - 1 } },
  62.     /* LOCAL_IN */
  63.             { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
  64. 0,
  65. sizeof(struct ip6t_entry),
  66. sizeof(struct ip6t_standard),
  67. 0, { 0, 0 }, { } },
  68.       { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
  69. -NF_ACCEPT - 1 } },
  70.     /* FORWARD */
  71.             { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
  72. 0,
  73. sizeof(struct ip6t_entry),
  74. sizeof(struct ip6t_standard),
  75. 0, { 0, 0 }, { } },
  76.       { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
  77. -NF_ACCEPT - 1 } },
  78.     /* LOCAL_OUT */
  79.             { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
  80. 0,
  81. sizeof(struct ip6t_entry),
  82. sizeof(struct ip6t_standard),
  83. 0, { 0, 0 }, { } },
  84.       { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
  85. -NF_ACCEPT - 1 } },
  86.     /* POST_ROUTING */
  87.     { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
  88. 0,
  89. sizeof(struct ip6t_entry),
  90. sizeof(struct ip6t_standard),
  91. 0, { 0, 0 }, { } },
  92.       { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
  93. -NF_ACCEPT - 1 } }
  94.     },
  95.     /* ERROR */
  96.     { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
  97. 0,
  98. sizeof(struct ip6t_entry),
  99. sizeof(struct ip6t_error),
  100. 0, { 0, 0 }, { } },
  101.       { { { { IP6T_ALIGN(sizeof(struct ip6t_error_target)), IP6T_ERROR_TARGET } },
  102.   { } },
  103. "ERROR"
  104.       }
  105.     }
  106. };
  107. static struct ip6t_table packet_mangler
  108. = { { NULL, NULL }, "mangle", &initial_table.repl,
  109.     MANGLE_VALID_HOOKS, RW_LOCK_UNLOCKED, NULL, THIS_MODULE };
  110. /* The work comes in here from netfilter.c. */
  111. static unsigned int
  112. ip6t_route_hook(unsigned int hook,
  113.  struct sk_buff **pskb,
  114.  const struct net_device *in,
  115.  const struct net_device *out,
  116.  int (*okfn)(struct sk_buff *))
  117. {
  118. return ip6t_do_table(pskb, hook, in, out, &packet_mangler, NULL);
  119. }
  120. static unsigned int
  121. ip6t_local_hook(unsigned int hook,
  122.    struct sk_buff **pskb,
  123.    const struct net_device *in,
  124.    const struct net_device *out,
  125.    int (*okfn)(struct sk_buff *))
  126. {
  127. unsigned long nfmark;
  128. unsigned int ret;
  129. struct in6_addr saddr, daddr;
  130. u_int8_t hop_limit;
  131. u_int32_t flowlabel;
  132. #if 0
  133. /* root is playing with raw sockets. */
  134. if ((*pskb)->len < sizeof(struct iphdr)
  135.     || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
  136. if (net_ratelimit())
  137. printk("ip6t_hook: happy cracking.n");
  138. return NF_ACCEPT;
  139. }
  140. #endif
  141. /* save source/dest address, nfmark, hoplimit, flowlabel, priority,  */
  142. memcpy(&saddr, &(*pskb)->nh.ipv6h->saddr, sizeof(saddr));
  143. memcpy(&daddr, &(*pskb)->nh.ipv6h->daddr, sizeof(daddr));
  144. nfmark = (*pskb)->nfmark;
  145. hop_limit = (*pskb)->nh.ipv6h->hop_limit;
  146. /* flowlabel and prio (includes version, which shouldn't change either */
  147. flowlabel = (u_int32_t) (*pskb)->nh.ipv6h;
  148. ret = ip6t_do_table(pskb, hook, in, out, &packet_mangler, NULL);
  149. if (ret != NF_DROP && ret != NF_STOLEN 
  150. && (memcmp(&(*pskb)->nh.ipv6h->saddr, &saddr, sizeof(saddr))
  151.     || memcmp(&(*pskb)->nh.ipv6h->daddr, &daddr, sizeof(daddr))
  152.     || (*pskb)->nfmark != nfmark
  153.     || (*pskb)->nh.ipv6h->hop_limit != hop_limit)) {
  154. /* something which could affect routing has changed */
  155. DEBUGP("ip6table_mangle: we'd need to re-route a packetn");
  156. }
  157. return ret;
  158. }
  159. static struct nf_hook_ops ip6t_ops[]
  160. = { { { NULL, NULL }, ip6t_route_hook, PF_INET6, NF_IP6_PRE_ROUTING,  NF_IP6_PRI_MANGLE },
  161.     { { NULL, NULL }, ip6t_local_hook, PF_INET6, NF_IP6_LOCAL_IN,     NF_IP6_PRI_MANGLE },
  162.     { { NULL, NULL }, ip6t_route_hook, PF_INET6, NF_IP6_FORWARD,      NF_IP6_PRI_MANGLE },
  163.     { { NULL, NULL }, ip6t_local_hook, PF_INET6, NF_IP6_LOCAL_OUT,    NF_IP6_PRI_MANGLE },
  164.     { { NULL, NULL }, ip6t_route_hook, PF_INET6, NF_IP6_POST_ROUTING, NF_IP6_PRI_MANGLE }
  165. };
  166. static int __init init(void)
  167. {
  168. int ret;
  169. /* Register table */
  170. ret = ip6t_register_table(&packet_mangler);
  171. if (ret < 0)
  172. return ret;
  173. /* Register hooks */
  174. ret = nf_register_hook(&ip6t_ops[0]);
  175. if (ret < 0)
  176. goto cleanup_table;
  177. ret = nf_register_hook(&ip6t_ops[1]);
  178. if (ret < 0)
  179. goto cleanup_hook0;
  180. ret = nf_register_hook(&ip6t_ops[2]);
  181. if (ret < 0)
  182. goto cleanup_hook1;
  183. ret = nf_register_hook(&ip6t_ops[3]);
  184. if (ret < 0)
  185. goto cleanup_hook2;
  186. ret = nf_register_hook(&ip6t_ops[4]);
  187. if (ret < 0)
  188. goto cleanup_hook3;
  189. return ret;
  190.  cleanup_hook3:
  191.         nf_unregister_hook(&ip6t_ops[3]);
  192.  cleanup_hook2:
  193. nf_unregister_hook(&ip6t_ops[2]);
  194.  cleanup_hook1:
  195. nf_unregister_hook(&ip6t_ops[1]);
  196.  cleanup_hook0:
  197. nf_unregister_hook(&ip6t_ops[0]);
  198.  cleanup_table:
  199. ip6t_unregister_table(&packet_mangler);
  200. return ret;
  201. }
  202. static void __exit fini(void)
  203. {
  204. unsigned int i;
  205. for (i = 0; i < sizeof(ip6t_ops)/sizeof(struct nf_hook_ops); i++)
  206. nf_unregister_hook(&ip6t_ops[i]);
  207. ip6t_unregister_table(&packet_mangler);
  208. }
  209. module_init(init);
  210. module_exit(fini);
  211. MODULE_LICENSE("GPL");