libxt_physdev.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #include <stdio.h>
  2. #include <xtables.h>
  3. #include <linux/netfilter/xt_physdev.h>
  4. enum {
  5. O_PHYSDEV_IN = 0,
  6. O_PHYSDEV_OUT,
  7. O_PHYSDEV_IS_IN,
  8. O_PHYSDEV_IS_OUT,
  9. O_PHYSDEV_IS_BRIDGED,
  10. };
  11. static void physdev_help(void)
  12. {
  13. printf(
  14. "physdev match options:\n"
  15. " [!] --physdev-in inputname[+] bridge port name ([+] for wildcard)\n"
  16. " [!] --physdev-out outputname[+] bridge port name ([+] for wildcard)\n"
  17. " [!] --physdev-is-in arrived on a bridge device\n"
  18. " [!] --physdev-is-out will leave on a bridge device\n"
  19. " [!] --physdev-is-bridged it's a bridged packet\n");
  20. }
  21. #define s struct xt_physdev_info
  22. static const struct xt_option_entry physdev_opts[] = {
  23. {.name = "physdev-in", .id = O_PHYSDEV_IN, .type = XTTYPE_STRING,
  24. .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, physindev)},
  25. {.name = "physdev-out", .id = O_PHYSDEV_OUT, .type = XTTYPE_STRING,
  26. .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, physoutdev)},
  27. {.name = "physdev-is-in", .id = O_PHYSDEV_IS_IN, .type = XTTYPE_NONE,
  28. .flags = XTOPT_INVERT},
  29. {.name = "physdev-is-out", .id = O_PHYSDEV_IS_OUT,
  30. .type = XTTYPE_NONE, .flags = XTOPT_INVERT},
  31. {.name = "physdev-is-bridged", .id = O_PHYSDEV_IS_BRIDGED,
  32. .type = XTTYPE_NONE, .flags = XTOPT_INVERT},
  33. XTOPT_TABLEEND,
  34. };
  35. #undef s
  36. static void physdev_parse(struct xt_option_call *cb)
  37. {
  38. struct xt_physdev_info *info = cb->data;
  39. xtables_option_parse(cb);
  40. switch (cb->entry->id) {
  41. case O_PHYSDEV_IN:
  42. xtables_parse_interface(cb->arg, info->physindev,
  43. (unsigned char *)info->in_mask);
  44. if (cb->invert)
  45. info->invert |= XT_PHYSDEV_OP_IN;
  46. info->bitmask |= XT_PHYSDEV_OP_IN;
  47. break;
  48. case O_PHYSDEV_OUT:
  49. xtables_parse_interface(cb->arg, info->physoutdev,
  50. (unsigned char *)info->out_mask);
  51. if (cb->invert)
  52. info->invert |= XT_PHYSDEV_OP_OUT;
  53. info->bitmask |= XT_PHYSDEV_OP_OUT;
  54. break;
  55. case O_PHYSDEV_IS_IN:
  56. info->bitmask |= XT_PHYSDEV_OP_ISIN;
  57. if (cb->invert)
  58. info->invert |= XT_PHYSDEV_OP_ISIN;
  59. break;
  60. case O_PHYSDEV_IS_OUT:
  61. info->bitmask |= XT_PHYSDEV_OP_ISOUT;
  62. if (cb->invert)
  63. info->invert |= XT_PHYSDEV_OP_ISOUT;
  64. break;
  65. case O_PHYSDEV_IS_BRIDGED:
  66. if (cb->invert)
  67. info->invert |= XT_PHYSDEV_OP_BRIDGED;
  68. info->bitmask |= XT_PHYSDEV_OP_BRIDGED;
  69. break;
  70. }
  71. }
  72. static void physdev_check(struct xt_fcheck_call *cb)
  73. {
  74. if (cb->xflags == 0)
  75. xtables_error(PARAMETER_PROBLEM, "PHYSDEV: no physdev option specified");
  76. }
  77. static void
  78. physdev_print(const void *ip, const struct xt_entry_match *match, int numeric)
  79. {
  80. const struct xt_physdev_info *info = (const void *)match->data;
  81. printf(" PHYSDEV match");
  82. if (info->bitmask & XT_PHYSDEV_OP_ISIN)
  83. printf("%s --physdev-is-in",
  84. info->invert & XT_PHYSDEV_OP_ISIN ? " !":"");
  85. if (info->bitmask & XT_PHYSDEV_OP_IN)
  86. printf("%s --physdev-in %s",
  87. (info->invert & XT_PHYSDEV_OP_IN) ? " !":"", info->physindev);
  88. if (info->bitmask & XT_PHYSDEV_OP_ISOUT)
  89. printf("%s --physdev-is-out",
  90. info->invert & XT_PHYSDEV_OP_ISOUT ? " !":"");
  91. if (info->bitmask & XT_PHYSDEV_OP_OUT)
  92. printf("%s --physdev-out %s",
  93. (info->invert & XT_PHYSDEV_OP_OUT) ? " !":"", info->physoutdev);
  94. if (info->bitmask & XT_PHYSDEV_OP_BRIDGED)
  95. printf("%s --physdev-is-bridged",
  96. info->invert & XT_PHYSDEV_OP_BRIDGED ? " !":"");
  97. }
  98. static void physdev_save(const void *ip, const struct xt_entry_match *match)
  99. {
  100. const struct xt_physdev_info *info = (const void *)match->data;
  101. if (info->bitmask & XT_PHYSDEV_OP_ISIN)
  102. printf("%s --physdev-is-in",
  103. (info->invert & XT_PHYSDEV_OP_ISIN) ? " !" : "");
  104. if (info->bitmask & XT_PHYSDEV_OP_IN)
  105. printf("%s --physdev-in %s",
  106. (info->invert & XT_PHYSDEV_OP_IN) ? " !" : "",
  107. info->physindev);
  108. if (info->bitmask & XT_PHYSDEV_OP_ISOUT)
  109. printf("%s --physdev-is-out",
  110. (info->invert & XT_PHYSDEV_OP_ISOUT) ? " !" : "");
  111. if (info->bitmask & XT_PHYSDEV_OP_OUT)
  112. printf("%s --physdev-out %s",
  113. (info->invert & XT_PHYSDEV_OP_OUT) ? " !" : "",
  114. info->physoutdev);
  115. if (info->bitmask & XT_PHYSDEV_OP_BRIDGED)
  116. printf("%s --physdev-is-bridged",
  117. (info->invert & XT_PHYSDEV_OP_BRIDGED) ? " !" : "");
  118. }
  119. static struct xtables_match physdev_match = {
  120. .family = NFPROTO_UNSPEC,
  121. .name = "physdev",
  122. .version = XTABLES_VERSION,
  123. .size = XT_ALIGN(sizeof(struct xt_physdev_info)),
  124. .userspacesize = XT_ALIGN(sizeof(struct xt_physdev_info)),
  125. .help = physdev_help,
  126. .print = physdev_print,
  127. .save = physdev_save,
  128. .x6_parse = physdev_parse,
  129. .x6_fcheck = physdev_check,
  130. .x6_options = physdev_opts,
  131. };
  132. void _init(void)
  133. {
  134. xtables_register_match(&physdev_match);
  135. }