libxt_MARK.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. #include <stdbool.h>
  2. #include <stdio.h>
  3. #include <xtables.h>
  4. #include <linux/netfilter/xt_MARK.h>
  5. /* Version 0 */
  6. struct xt_mark_target_info {
  7. unsigned long mark;
  8. };
  9. /* Version 1 */
  10. enum {
  11. XT_MARK_SET=0,
  12. XT_MARK_AND,
  13. XT_MARK_OR,
  14. };
  15. struct xt_mark_target_info_v1 {
  16. unsigned long mark;
  17. uint8_t mode;
  18. };
  19. enum {
  20. O_SET_MARK = 0,
  21. O_AND_MARK,
  22. O_OR_MARK,
  23. O_XOR_MARK,
  24. O_SET_XMARK,
  25. F_SET_MARK = 1 << O_SET_MARK,
  26. F_AND_MARK = 1 << O_AND_MARK,
  27. F_OR_MARK = 1 << O_OR_MARK,
  28. F_XOR_MARK = 1 << O_XOR_MARK,
  29. F_SET_XMARK = 1 << O_SET_XMARK,
  30. F_ANY = F_SET_MARK | F_AND_MARK | F_OR_MARK |
  31. F_XOR_MARK | F_SET_XMARK,
  32. };
  33. static void MARK_help(void)
  34. {
  35. printf(
  36. "MARK target options:\n"
  37. " --set-mark value Set nfmark value\n"
  38. " --and-mark value Binary AND the nfmark with value\n"
  39. " --or-mark value Binary OR the nfmark with value\n");
  40. }
  41. static const struct xt_option_entry MARK_opts[] = {
  42. {.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_UINT32,
  43. .excl = F_ANY},
  44. {.name = "and-mark", .id = O_AND_MARK, .type = XTTYPE_UINT32,
  45. .excl = F_ANY},
  46. {.name = "or-mark", .id = O_OR_MARK, .type = XTTYPE_UINT32,
  47. .excl = F_ANY},
  48. XTOPT_TABLEEND,
  49. };
  50. static const struct xt_option_entry mark_tg_opts[] = {
  51. {.name = "set-xmark", .id = O_SET_XMARK, .type = XTTYPE_MARKMASK32,
  52. .excl = F_ANY},
  53. {.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_MARKMASK32,
  54. .excl = F_ANY},
  55. {.name = "and-mark", .id = O_AND_MARK, .type = XTTYPE_UINT32,
  56. .excl = F_ANY},
  57. {.name = "or-mark", .id = O_OR_MARK, .type = XTTYPE_UINT32,
  58. .excl = F_ANY},
  59. {.name = "xor-mark", .id = O_XOR_MARK, .type = XTTYPE_UINT32,
  60. .excl = F_ANY},
  61. XTOPT_TABLEEND,
  62. };
  63. static void mark_tg_help(void)
  64. {
  65. printf(
  66. "MARK target options:\n"
  67. " --set-xmark value[/mask] Clear bits in mask and XOR value into nfmark\n"
  68. " --set-mark value[/mask] Clear bits in mask and OR value into nfmark\n"
  69. " --and-mark bits Binary AND the nfmark with bits\n"
  70. " --or-mark bits Binary OR the nfmark with bits\n"
  71. " --xor-mask bits Binary XOR the nfmark with bits\n"
  72. "\n");
  73. }
  74. static void MARK_parse_v0(struct xt_option_call *cb)
  75. {
  76. struct xt_mark_target_info *markinfo = cb->data;
  77. xtables_option_parse(cb);
  78. switch (cb->entry->id) {
  79. case O_SET_MARK:
  80. markinfo->mark = cb->val.mark;
  81. break;
  82. default:
  83. xtables_error(PARAMETER_PROBLEM,
  84. "MARK target: kernel too old for --%s",
  85. cb->entry->name);
  86. }
  87. }
  88. static void MARK_check(struct xt_fcheck_call *cb)
  89. {
  90. if (cb->xflags == 0)
  91. xtables_error(PARAMETER_PROBLEM,
  92. "MARK target: Parameter --set/and/or-mark"
  93. " is required");
  94. }
  95. static void MARK_parse_v1(struct xt_option_call *cb)
  96. {
  97. struct xt_mark_target_info_v1 *markinfo = cb->data;
  98. xtables_option_parse(cb);
  99. switch (cb->entry->id) {
  100. case O_SET_MARK:
  101. markinfo->mode = XT_MARK_SET;
  102. break;
  103. case O_AND_MARK:
  104. markinfo->mode = XT_MARK_AND;
  105. break;
  106. case O_OR_MARK:
  107. markinfo->mode = XT_MARK_OR;
  108. break;
  109. }
  110. markinfo->mark = cb->val.u32;
  111. }
  112. static void mark_tg_parse(struct xt_option_call *cb)
  113. {
  114. struct xt_mark_tginfo2 *info = cb->data;
  115. xtables_option_parse(cb);
  116. switch (cb->entry->id) {
  117. case O_SET_XMARK:
  118. info->mark = cb->val.mark;
  119. info->mask = cb->val.mask;
  120. break;
  121. case O_SET_MARK:
  122. info->mark = cb->val.mark;
  123. info->mask = cb->val.mark | cb->val.mask;
  124. break;
  125. case O_AND_MARK:
  126. info->mark = 0;
  127. info->mask = ~cb->val.u32;
  128. break;
  129. case O_OR_MARK:
  130. info->mark = info->mask = cb->val.u32;
  131. break;
  132. case O_XOR_MARK:
  133. info->mark = cb->val.u32;
  134. info->mask = 0;
  135. break;
  136. }
  137. }
  138. static void mark_tg_check(struct xt_fcheck_call *cb)
  139. {
  140. if (cb->xflags == 0)
  141. xtables_error(PARAMETER_PROBLEM, "MARK: One of the --set-xmark, "
  142. "--{and,or,xor,set}-mark options is required");
  143. }
  144. static void
  145. print_mark(unsigned long mark)
  146. {
  147. printf(" 0x%lx", mark);
  148. }
  149. static void MARK_print_v0(const void *ip,
  150. const struct xt_entry_target *target, int numeric)
  151. {
  152. const struct xt_mark_target_info *markinfo =
  153. (const struct xt_mark_target_info *)target->data;
  154. printf(" MARK set");
  155. print_mark(markinfo->mark);
  156. }
  157. static void MARK_save_v0(const void *ip, const struct xt_entry_target *target)
  158. {
  159. const struct xt_mark_target_info *markinfo =
  160. (const struct xt_mark_target_info *)target->data;
  161. printf(" --set-mark");
  162. print_mark(markinfo->mark);
  163. }
  164. static void MARK_print_v1(const void *ip, const struct xt_entry_target *target,
  165. int numeric)
  166. {
  167. const struct xt_mark_target_info_v1 *markinfo =
  168. (const struct xt_mark_target_info_v1 *)target->data;
  169. switch (markinfo->mode) {
  170. case XT_MARK_SET:
  171. printf(" MARK set");
  172. break;
  173. case XT_MARK_AND:
  174. printf(" MARK and");
  175. break;
  176. case XT_MARK_OR:
  177. printf(" MARK or");
  178. break;
  179. }
  180. print_mark(markinfo->mark);
  181. }
  182. static void mark_tg_print(const void *ip, const struct xt_entry_target *target,
  183. int numeric)
  184. {
  185. const struct xt_mark_tginfo2 *info = (const void *)target->data;
  186. if (info->mark == 0)
  187. printf(" MARK and 0x%x", (unsigned int)(uint32_t)~info->mask);
  188. else if (info->mark == info->mask)
  189. printf(" MARK or 0x%x", info->mark);
  190. else if (info->mask == 0)
  191. printf(" MARK xor 0x%x", info->mark);
  192. else if (info->mask == 0xffffffffU)
  193. printf(" MARK set 0x%x", info->mark);
  194. else
  195. printf(" MARK xset 0x%x/0x%x", info->mark, info->mask);
  196. }
  197. static void MARK_save_v1(const void *ip, const struct xt_entry_target *target)
  198. {
  199. const struct xt_mark_target_info_v1 *markinfo =
  200. (const struct xt_mark_target_info_v1 *)target->data;
  201. switch (markinfo->mode) {
  202. case XT_MARK_SET:
  203. printf(" --set-mark");
  204. break;
  205. case XT_MARK_AND:
  206. printf(" --and-mark");
  207. break;
  208. case XT_MARK_OR:
  209. printf(" --or-mark");
  210. break;
  211. }
  212. print_mark(markinfo->mark);
  213. }
  214. static void mark_tg_save(const void *ip, const struct xt_entry_target *target)
  215. {
  216. const struct xt_mark_tginfo2 *info = (const void *)target->data;
  217. printf(" --set-xmark 0x%x/0x%x", info->mark, info->mask);
  218. }
  219. static struct xtables_target mark_tg_reg[] = {
  220. {
  221. .family = NFPROTO_UNSPEC,
  222. .name = "MARK",
  223. .version = XTABLES_VERSION,
  224. .revision = 0,
  225. .size = XT_ALIGN(sizeof(struct xt_mark_target_info)),
  226. .userspacesize = XT_ALIGN(sizeof(struct xt_mark_target_info)),
  227. .help = MARK_help,
  228. .print = MARK_print_v0,
  229. .save = MARK_save_v0,
  230. .x6_parse = MARK_parse_v0,
  231. .x6_fcheck = MARK_check,
  232. .x6_options = MARK_opts,
  233. },
  234. {
  235. .family = NFPROTO_IPV4,
  236. .name = "MARK",
  237. .version = XTABLES_VERSION,
  238. .revision = 1,
  239. .size = XT_ALIGN(sizeof(struct xt_mark_target_info_v1)),
  240. .userspacesize = XT_ALIGN(sizeof(struct xt_mark_target_info_v1)),
  241. .help = MARK_help,
  242. .print = MARK_print_v1,
  243. .save = MARK_save_v1,
  244. .x6_parse = MARK_parse_v1,
  245. .x6_fcheck = MARK_check,
  246. .x6_options = MARK_opts,
  247. },
  248. {
  249. .version = XTABLES_VERSION,
  250. .name = "MARK",
  251. .revision = 2,
  252. .family = NFPROTO_UNSPEC,
  253. .size = XT_ALIGN(sizeof(struct xt_mark_tginfo2)),
  254. .userspacesize = XT_ALIGN(sizeof(struct xt_mark_tginfo2)),
  255. .help = mark_tg_help,
  256. .print = mark_tg_print,
  257. .save = mark_tg_save,
  258. .x6_parse = mark_tg_parse,
  259. .x6_fcheck = mark_tg_check,
  260. .x6_options = mark_tg_opts,
  261. },
  262. };
  263. void _init(void)
  264. {
  265. xtables_register_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg));
  266. }