ip6t_mh.c 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. * Copyright (C)2006 USAGI/WIDE Project
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. *
  8. * Author:
  9. * Masahide NAKAMURA @USAGI <masahide.nakamura.cz@hitachi.com>
  10. *
  11. * Based on net/netfilter/xt_tcpudp.c
  12. *
  13. */
  14. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  15. #include <linux/types.h>
  16. #include <linux/module.h>
  17. #include <net/ip.h>
  18. #include <linux/ipv6.h>
  19. #include <net/ipv6.h>
  20. #include <net/mip6.h>
  21. #include <linux/netfilter/x_tables.h>
  22. #include <linux/netfilter_ipv6/ip6t_mh.h>
  23. MODULE_DESCRIPTION("Xtables: IPv6 Mobility Header match");
  24. MODULE_LICENSE("GPL");
  25. /* Returns 1 if the type is matched by the range, 0 otherwise */
  26. static inline bool
  27. type_match(u_int8_t min, u_int8_t max, u_int8_t type, bool invert)
  28. {
  29. return (type >= min && type <= max) ^ invert;
  30. }
  31. static bool mh_mt6(const struct sk_buff *skb, struct xt_action_param *par)
  32. {
  33. struct ip6_mh _mh;
  34. const struct ip6_mh *mh;
  35. const struct ip6t_mh *mhinfo = par->matchinfo;
  36. /* Must not be a fragment. */
  37. if (par->fragoff != 0)
  38. return false;
  39. mh = skb_header_pointer(skb, par->thoff, sizeof(_mh), &_mh);
  40. if (mh == NULL) {
  41. /* We've been asked to examine this packet, and we
  42. can't. Hence, no choice but to drop. */
  43. pr_debug("Dropping evil MH tinygram.\n");
  44. par->hotdrop = true;
  45. return false;
  46. }
  47. if (mh->ip6mh_proto != IPPROTO_NONE) {
  48. pr_debug("Dropping invalid MH Payload Proto: %u\n",
  49. mh->ip6mh_proto);
  50. par->hotdrop = true;
  51. return false;
  52. }
  53. return type_match(mhinfo->types[0], mhinfo->types[1], mh->ip6mh_type,
  54. !!(mhinfo->invflags & IP6T_MH_INV_TYPE));
  55. }
  56. static int mh_mt6_check(const struct xt_mtchk_param *par)
  57. {
  58. const struct ip6t_mh *mhinfo = par->matchinfo;
  59. /* Must specify no unknown invflags */
  60. return (mhinfo->invflags & ~IP6T_MH_INV_MASK) ? -EINVAL : 0;
  61. }
  62. static struct xt_match mh_mt6_reg __read_mostly = {
  63. .name = "mh",
  64. .family = NFPROTO_IPV6,
  65. .checkentry = mh_mt6_check,
  66. .match = mh_mt6,
  67. .matchsize = sizeof(struct ip6t_mh),
  68. .proto = IPPROTO_MH,
  69. .me = THIS_MODULE,
  70. };
  71. static int __init mh_mt6_init(void)
  72. {
  73. return xt_register_match(&mh_mt6_reg);
  74. }
  75. static void __exit mh_mt6_exit(void)
  76. {
  77. xt_unregister_match(&mh_mt6_reg);
  78. }
  79. module_init(mh_mt6_init);
  80. module_exit(mh_mt6_exit);