libip6t_ah.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include <stdio.h>
  2. #include <xtables.h>
  3. #include <linux/netfilter_ipv6/ip6t_ah.h>
  4. enum {
  5. O_AHSPI = 0,
  6. O_AHLEN,
  7. O_AHRES,
  8. };
  9. static void ah_help(void)
  10. {
  11. printf(
  12. "ah match options:\n"
  13. "[!] --ahspi spi[:spi] match spi (range)\n"
  14. "[!] --ahlen length total length of this header\n"
  15. " --ahres check the reserved field too\n");
  16. }
  17. #define s struct ip6t_ah
  18. static const struct xt_option_entry ah_opts[] = {
  19. {.name = "ahspi", .id = O_AHSPI, .type = XTTYPE_UINT32RC,
  20. .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, spis)},
  21. {.name = "ahlen", .id = O_AHLEN, .type = XTTYPE_UINT32,
  22. .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hdrlen)},
  23. {.name = "ahres", .id = O_AHRES, .type = XTTYPE_NONE},
  24. XTOPT_TABLEEND,
  25. };
  26. #undef s
  27. static void ah_parse(struct xt_option_call *cb)
  28. {
  29. struct ip6t_ah *ahinfo = cb->data;
  30. xtables_option_parse(cb);
  31. switch (cb->entry->id) {
  32. case O_AHSPI:
  33. if (cb->nvals == 1)
  34. ahinfo->spis[1] = ahinfo->spis[0];
  35. if (cb->invert)
  36. ahinfo->invflags |= IP6T_AH_INV_SPI;
  37. break;
  38. case O_AHLEN:
  39. if (cb->invert)
  40. ahinfo->invflags |= IP6T_AH_INV_LEN;
  41. break;
  42. case O_AHRES:
  43. ahinfo->hdrres = 1;
  44. break;
  45. }
  46. }
  47. static void
  48. print_spis(const char *name, uint32_t min, uint32_t max,
  49. int invert)
  50. {
  51. const char *inv = invert ? "!" : "";
  52. if (min != 0 || max != 0xFFFFFFFF || invert) {
  53. if (min == max)
  54. printf("%s:%s%u", name, inv, min);
  55. else
  56. printf("%ss:%s%u:%u", name, inv, min, max);
  57. }
  58. }
  59. static void
  60. print_len(const char *name, uint32_t len, int invert)
  61. {
  62. const char *inv = invert ? "!" : "";
  63. if (len != 0 || invert)
  64. printf("%s:%s%u", name, inv, len);
  65. }
  66. static void ah_print(const void *ip, const struct xt_entry_match *match,
  67. int numeric)
  68. {
  69. const struct ip6t_ah *ah = (struct ip6t_ah *)match->data;
  70. printf(" ah ");
  71. print_spis("spi", ah->spis[0], ah->spis[1],
  72. ah->invflags & IP6T_AH_INV_SPI);
  73. print_len("length", ah->hdrlen,
  74. ah->invflags & IP6T_AH_INV_LEN);
  75. if (ah->hdrres)
  76. printf(" reserved");
  77. if (ah->invflags & ~IP6T_AH_INV_MASK)
  78. printf(" Unknown invflags: 0x%X",
  79. ah->invflags & ~IP6T_AH_INV_MASK);
  80. }
  81. static void ah_save(const void *ip, const struct xt_entry_match *match)
  82. {
  83. const struct ip6t_ah *ahinfo = (struct ip6t_ah *)match->data;
  84. if (!(ahinfo->spis[0] == 0
  85. && ahinfo->spis[1] == 0xFFFFFFFF)) {
  86. printf("%s --ahspi ",
  87. (ahinfo->invflags & IP6T_AH_INV_SPI) ? " !" : "");
  88. if (ahinfo->spis[0]
  89. != ahinfo->spis[1])
  90. printf("%u:%u",
  91. ahinfo->spis[0],
  92. ahinfo->spis[1]);
  93. else
  94. printf("%u",
  95. ahinfo->spis[0]);
  96. }
  97. if (ahinfo->hdrlen != 0 || (ahinfo->invflags & IP6T_AH_INV_LEN) ) {
  98. printf("%s --ahlen %u",
  99. (ahinfo->invflags & IP6T_AH_INV_LEN) ? " !" : "",
  100. ahinfo->hdrlen);
  101. }
  102. if (ahinfo->hdrres != 0 )
  103. printf(" --ahres");
  104. }
  105. static struct xtables_match ah_mt6_reg = {
  106. .name = "ah",
  107. .version = XTABLES_VERSION,
  108. .family = NFPROTO_IPV6,
  109. .size = XT_ALIGN(sizeof(struct ip6t_ah)),
  110. .userspacesize = XT_ALIGN(sizeof(struct ip6t_ah)),
  111. .help = ah_help,
  112. .print = ah_print,
  113. .save = ah_save,
  114. .x6_parse = ah_parse,
  115. .x6_options = ah_opts,
  116. };
  117. void
  118. _init(void)
  119. {
  120. xtables_register_match(&ah_mt6_reg);
  121. }