ipt_ah.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /* Kernel module to match AH parameters. */
  2. /* (C) 1999-2000 Yon Uriarte <yon@astaro.de>
  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. #include <linux/in.h>
  9. #include <linux/module.h>
  10. #include <linux/skbuff.h>
  11. #include <linux/ip.h>
  12. #include <linux/netfilter_ipv4/ipt_ah.h>
  13. #include <linux/netfilter/x_tables.h>
  14. MODULE_LICENSE("GPL");
  15. MODULE_AUTHOR("Yon Uriarte <yon@astaro.de>");
  16. MODULE_DESCRIPTION("iptables AH SPI match module");
  17. #ifdef DEBUG_CONNTRACK
  18. #define duprintf(format, args...) printk(format , ## args)
  19. #else
  20. #define duprintf(format, args...)
  21. #endif
  22. /* Returns 1 if the spi is matched by the range, 0 otherwise */
  23. static inline int
  24. spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert)
  25. {
  26. int r=0;
  27. duprintf("ah spi_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ',
  28. min,spi,max);
  29. r=(spi >= min && spi <= max) ^ invert;
  30. duprintf(" result %s\n",r? "PASS" : "FAILED");
  31. return r;
  32. }
  33. static int
  34. match(const struct sk_buff *skb,
  35. const struct net_device *in,
  36. const struct net_device *out,
  37. const struct xt_match *match,
  38. const void *matchinfo,
  39. int offset,
  40. unsigned int protoff,
  41. int *hotdrop)
  42. {
  43. struct ip_auth_hdr _ahdr, *ah;
  44. const struct ipt_ah *ahinfo = matchinfo;
  45. /* Must not be a fragment. */
  46. if (offset)
  47. return 0;
  48. ah = skb_header_pointer(skb, protoff,
  49. sizeof(_ahdr), &_ahdr);
  50. if (ah == NULL) {
  51. /* We've been asked to examine this packet, and we
  52. * can't. Hence, no choice but to drop.
  53. */
  54. duprintf("Dropping evil AH tinygram.\n");
  55. *hotdrop = 1;
  56. return 0;
  57. }
  58. return spi_match(ahinfo->spis[0], ahinfo->spis[1],
  59. ntohl(ah->spi),
  60. !!(ahinfo->invflags & IPT_AH_INV_SPI));
  61. }
  62. /* Called when user tries to insert an entry of this type. */
  63. static int
  64. checkentry(const char *tablename,
  65. const void *ip_void,
  66. const struct xt_match *match,
  67. void *matchinfo,
  68. unsigned int hook_mask)
  69. {
  70. const struct ipt_ah *ahinfo = matchinfo;
  71. /* Must specify no unknown invflags */
  72. if (ahinfo->invflags & ~IPT_AH_INV_MASK) {
  73. duprintf("ipt_ah: unknown flags %X\n", ahinfo->invflags);
  74. return 0;
  75. }
  76. return 1;
  77. }
  78. static struct xt_match ah_match = {
  79. .name = "ah",
  80. .family = AF_INET,
  81. .match = match,
  82. .matchsize = sizeof(struct ipt_ah),
  83. .proto = IPPROTO_AH,
  84. .checkentry = checkentry,
  85. .me = THIS_MODULE,
  86. };
  87. static int __init ipt_ah_init(void)
  88. {
  89. return xt_register_match(&ah_match);
  90. }
  91. static void __exit ipt_ah_fini(void)
  92. {
  93. xt_unregister_match(&ah_match);
  94. }
  95. module_init(ipt_ah_init);
  96. module_exit(ipt_ah_fini);