libxt_TOS.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. * Shared library add-on to iptables to add TOS target support
  3. *
  4. * Copyright © CC Computer Consultants GmbH, 2007
  5. * Contact: Jan Engelhardt <jengelh@medozas.de>
  6. */
  7. #include <getopt.h>
  8. #include <stdbool.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <netinet/in.h>
  13. #include <xtables.h>
  14. #include <linux/netfilter/xt_DSCP.h>
  15. #include "tos_values.c"
  16. struct ipt_tos_target_info {
  17. uint8_t tos;
  18. };
  19. enum {
  20. O_SET_TOS = 0,
  21. O_AND_TOS,
  22. O_OR_TOS,
  23. O_XOR_TOS,
  24. F_SET_TOS = 1 << O_SET_TOS,
  25. F_AND_TOS = 1 << O_AND_TOS,
  26. F_OR_TOS = 1 << O_OR_TOS,
  27. F_XOR_TOS = 1 << O_XOR_TOS,
  28. F_ANY = F_SET_TOS | F_AND_TOS | F_OR_TOS | F_XOR_TOS,
  29. };
  30. static const struct xt_option_entry tos_tg_opts_v0[] = {
  31. {.name = "set-tos", .id = O_SET_TOS, .type = XTTYPE_TOSMASK,
  32. .excl = F_ANY, .max = 0xFF},
  33. XTOPT_TABLEEND,
  34. };
  35. static const struct xt_option_entry tos_tg_opts[] = {
  36. {.name = "set-tos", .id = O_SET_TOS, .type = XTTYPE_TOSMASK,
  37. .excl = F_ANY, .max = 0x3F},
  38. {.name = "and-tos", .id = O_AND_TOS, .type = XTTYPE_UINT8,
  39. .excl = F_ANY},
  40. {.name = "or-tos", .id = O_OR_TOS, .type = XTTYPE_UINT8,
  41. .excl = F_ANY},
  42. {.name = "xor-tos", .id = O_XOR_TOS, .type = XTTYPE_UINT8,
  43. .excl = F_ANY},
  44. XTOPT_TABLEEND,
  45. };
  46. static void tos_tg_help_v0(void)
  47. {
  48. const struct tos_symbol_info *symbol;
  49. printf(
  50. "TOS target options:\n"
  51. " --set-tos value Set Type of Service/Priority field to value\n"
  52. " --set-tos symbol Set TOS field (IPv4 only) by symbol\n"
  53. " Accepted symbolic names for value are:\n");
  54. for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol)
  55. printf(" (0x%02x) %2u %s\n",
  56. symbol->value, symbol->value, symbol->name);
  57. printf("\n");
  58. }
  59. static void tos_tg_help(void)
  60. {
  61. const struct tos_symbol_info *symbol;
  62. printf(
  63. "TOS target v%s options:\n"
  64. " --set-tos value[/mask] Set Type of Service/Priority field to value\n"
  65. " (Zero out bits in mask and XOR value into TOS)\n"
  66. " --set-tos symbol Set TOS field (IPv4 only) by symbol\n"
  67. " (this zeroes the 4-bit Precedence part!)\n"
  68. " Accepted symbolic names for value are:\n",
  69. XTABLES_VERSION);
  70. for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol)
  71. printf(" (0x%02x) %2u %s\n",
  72. symbol->value, symbol->value, symbol->name);
  73. printf(
  74. "\n"
  75. " --and-tos bits Binary AND the TOS value with bits\n"
  76. " --or-tos bits Binary OR the TOS value with bits\n"
  77. " --xor-tos bits Binary XOR the TOS value with bits\n"
  78. );
  79. }
  80. static void tos_tg_parse_v0(struct xt_option_call *cb)
  81. {
  82. struct ipt_tos_target_info *info = cb->data;
  83. xtables_option_parse(cb);
  84. if (cb->val.tos_mask != 0xFF)
  85. xtables_error(PARAMETER_PROBLEM, "tos match: Your kernel "
  86. "is too old to support anything besides "
  87. "/0xFF as a mask.");
  88. info->tos = cb->val.tos_value;
  89. }
  90. static void tos_tg_parse(struct xt_option_call *cb)
  91. {
  92. struct xt_tos_target_info *info = cb->data;
  93. xtables_option_parse(cb);
  94. switch (cb->entry->id) {
  95. case O_SET_TOS:
  96. info->tos_value = cb->val.tos_value;
  97. info->tos_mask = cb->val.tos_mask;
  98. break;
  99. case O_AND_TOS:
  100. info->tos_value = 0;
  101. info->tos_mask = ~cb->val.u8;
  102. break;
  103. case O_OR_TOS:
  104. info->tos_value = cb->val.u8;
  105. info->tos_mask = cb->val.u8;
  106. break;
  107. case O_XOR_TOS:
  108. info->tos_value = cb->val.u8;
  109. info->tos_mask = 0;
  110. break;
  111. }
  112. }
  113. static void tos_tg_check(struct xt_fcheck_call *cb)
  114. {
  115. if (!(cb->xflags & F_ANY))
  116. xtables_error(PARAMETER_PROBLEM,
  117. "TOS: An action is required");
  118. }
  119. static void tos_tg_print_v0(const void *ip,
  120. const struct xt_entry_target *target, int numeric)
  121. {
  122. const struct ipt_tos_target_info *info = (const void *)target->data;
  123. printf(" TOS set ");
  124. if (numeric || !tos_try_print_symbolic("", info->tos, 0xFF))
  125. printf("0x%02x", info->tos);
  126. }
  127. static void tos_tg_print(const void *ip, const struct xt_entry_target *target,
  128. int numeric)
  129. {
  130. const struct xt_tos_target_info *info = (const void *)target->data;
  131. if (numeric)
  132. printf(" TOS set 0x%02x/0x%02x",
  133. info->tos_value, info->tos_mask);
  134. else if (tos_try_print_symbolic(" TOS set",
  135. info->tos_value, info->tos_mask))
  136. /* already printed by call */
  137. return;
  138. else if (info->tos_value == 0)
  139. printf(" TOS and 0x%02x",
  140. (unsigned int)(uint8_t)~info->tos_mask);
  141. else if (info->tos_value == info->tos_mask)
  142. printf(" TOS or 0x%02x", info->tos_value);
  143. else if (info->tos_mask == 0)
  144. printf(" TOS xor 0x%02x", info->tos_value);
  145. else
  146. printf(" TOS set 0x%02x/0x%02x",
  147. info->tos_value, info->tos_mask);
  148. }
  149. static void tos_tg_save_v0(const void *ip, const struct xt_entry_target *target)
  150. {
  151. const struct ipt_tos_target_info *info = (const void *)target->data;
  152. printf(" --set-tos 0x%02x", info->tos);
  153. }
  154. static void tos_tg_save(const void *ip, const struct xt_entry_target *target)
  155. {
  156. const struct xt_tos_target_info *info = (const void *)target->data;
  157. printf(" --set-tos 0x%02x/0x%02x", info->tos_value, info->tos_mask);
  158. }
  159. static struct xtables_target tos_tg_reg[] = {
  160. {
  161. .version = XTABLES_VERSION,
  162. .name = "TOS",
  163. .revision = 0,
  164. .family = NFPROTO_IPV4,
  165. .size = XT_ALIGN(sizeof(struct xt_tos_target_info)),
  166. .userspacesize = XT_ALIGN(sizeof(struct xt_tos_target_info)),
  167. .help = tos_tg_help_v0,
  168. .print = tos_tg_print_v0,
  169. .save = tos_tg_save_v0,
  170. .x6_parse = tos_tg_parse_v0,
  171. .x6_fcheck = tos_tg_check,
  172. .x6_options = tos_tg_opts_v0,
  173. },
  174. {
  175. .version = XTABLES_VERSION,
  176. .name = "TOS",
  177. .revision = 1,
  178. .family = NFPROTO_UNSPEC,
  179. .size = XT_ALIGN(sizeof(struct xt_tos_target_info)),
  180. .userspacesize = XT_ALIGN(sizeof(struct xt_tos_target_info)),
  181. .help = tos_tg_help,
  182. .print = tos_tg_print,
  183. .save = tos_tg_save,
  184. .x6_parse = tos_tg_parse,
  185. .x6_fcheck = tos_tg_check,
  186. .x6_options = tos_tg_opts,
  187. },
  188. };
  189. void _init(void)
  190. {
  191. xtables_register_targets(tos_tg_reg, ARRAY_SIZE(tos_tg_reg));
  192. }