2 * Shared library add-on to iptables to add TOS target support
4 * Copyright © CC Computer Consultants GmbH, 2007
5 * Contact: Jan Engelhardt <jengelh@computergmbh.de>
13 #include <linux/netfilter/xt_DSCP.h>
14 #include <linux/netfilter_ipv4/ipt_TOS.h>
15 #include "tos_values.c"
21 static const struct option tos_tg_opts_v0[] = {
22 {.name = "set-tos", .has_arg = true, .val = '='},
26 static const struct option tos_tg_opts[] = {
27 {.name = "set-tos", .has_arg = true, .val = '='},
28 {.name = "and-tos", .has_arg = true, .val = '&'},
29 {.name = "or-tos", .has_arg = true, .val = '|'},
30 {.name = "xor-tos", .has_arg = true, .val = '^'},
34 static void tos_tg_help_v0(void)
36 const struct tos_symbol_info *symbol;
39 "TOS target options:\n"
40 " --set-tos value Set Type of Service/Priority field to value\n"
41 " --set-tos symbol Set TOS field (IPv4 only) by symbol\n"
42 " Accepted symbolic names for value are:\n");
44 for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol)
45 printf(" (0x%02x) %2u %s\n",
46 symbol->value, symbol->value, symbol->name);
51 static void tos_tg_help(void)
53 const struct tos_symbol_info *symbol;
56 "TOS target v%s options:\n"
57 " --set-tos value[/mask] Set Type of Service/Priority field to value\n"
58 " (Zero out bits in mask and XOR value into TOS)\n"
59 " --set-tos symbol Set TOS field (IPv4 only) by symbol\n"
60 " (this zeroes the 4-bit Precedence part!)\n"
61 " Accepted symbolic names for value are:\n",
64 for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol)
65 printf(" (0x%02x) %2u %s\n",
66 symbol->value, symbol->value, symbol->name);
70 " --and-tos bits Binary AND the TOS value with bits\n"
71 " --or-tos bits Binary OR the TOS value with bits\n"
72 " --xor-tos bits Binary XOR the TOS value with bits\n"
76 static int tos_tg_parse_v0(int c, char **argv, int invert, unsigned int *flags,
77 const void *entry, struct xt_entry_target **target)
79 struct ipt_tos_target_info *info = (void *)(*target)->data;
80 struct tos_value_mask tvm;
84 param_act(P_ONLY_ONCE, "TOS", "--set-tos", *flags & FLAG_TOS);
85 param_act(P_NO_INVERT, "TOS", "--set-tos", invert);
86 if (!tos_parse_symbolic(optarg, &tvm, 0xFF))
87 param_act(P_BAD_VALUE, "TOS", "--set-tos", optarg);
89 exit_error(PARAMETER_PROBLEM, "tos match: Your kernel "
90 "is too old to support anything besides "
92 info->tos = tvm.value;
100 static int tos_tg_parse(int c, char **argv, int invert, unsigned int *flags,
101 const void *entry, struct xt_entry_target **target)
103 struct xt_tos_target_info *info = (void *)(*target)->data;
104 struct tos_value_mask tvm;
108 case '=': /* --set-tos */
109 param_act(P_ONLY_ONCE, "TOS", "--set-tos", *flags & FLAG_TOS);
110 param_act(P_NO_INVERT, "TOS", "--set-tos", invert);
111 if (!tos_parse_symbolic(optarg, &tvm, 0x3F))
112 param_act(P_BAD_VALUE, "TOS", "--set-tos", optarg);
113 info->tos_value = tvm.value;
114 info->tos_mask = tvm.mask;
117 case '&': /* --and-tos */
118 param_act(P_ONLY_ONCE, "TOS", "--and-tos", *flags & FLAG_TOS);
119 param_act(P_NO_INVERT, "TOS", "--and-tos", invert);
120 if (!strtonum(optarg, NULL, &bits, 0, 0xFF))
121 param_act(P_BAD_VALUE, "TOS", "--and-tos", optarg);
123 info->tos_mask = ~bits;
126 case '|': /* --or-tos */
127 param_act(P_ONLY_ONCE, "TOS", "--or-tos", *flags & FLAG_TOS);
128 param_act(P_NO_INVERT, "TOS", "--or-tos", invert);
129 if (!strtonum(optarg, NULL, &bits, 0, 0xFF))
130 param_act(P_BAD_VALUE, "TOS", "--or-tos", optarg);
131 info->tos_value = bits;
132 info->tos_mask = bits;
135 case '^': /* --xor-tos */
136 param_act(P_ONLY_ONCE, "TOS", "--xor-tos", *flags & FLAG_TOS);
137 param_act(P_NO_INVERT, "TOS", "--xor-tos", invert);
138 if (!strtonum(optarg, NULL, &bits, 0, 0xFF))
139 param_act(P_BAD_VALUE, "TOS", "--xor-tos", optarg);
140 info->tos_value = bits;
152 static void tos_tg_check(unsigned int flags)
155 exit_error(PARAMETER_PROBLEM,
156 "TOS: The --set-tos parameter is required");
159 static void tos_tg_print_v0(const void *ip,
160 const struct xt_entry_target *target, int numeric)
162 const struct ipt_tos_target_info *info = (const void *)target->data;
165 if (numeric || !tos_try_print_symbolic("", info->tos, 0xFF))
166 printf("0x%02x ", info->tos);
169 static void tos_tg_print(const void *ip, const struct xt_entry_target *target,
172 const struct xt_tos_target_info *info = (const void *)target->data;
175 printf("TOS set 0x%02x/0x%02x ",
176 info->tos_value, info->tos_mask);
177 else if (tos_try_print_symbolic("TOS set ",
178 info->tos_value, info->tos_mask))
179 /* already printed by call */
181 else if (info->tos_value == 0)
182 printf("TOS and 0x%02x ",
183 (unsigned int)(u_int8_t)~info->tos_mask);
184 else if (info->tos_value == info->tos_mask)
185 printf("TOS or 0x%02x ", info->tos_value);
186 else if (info->tos_mask == 0)
187 printf("TOS xor 0x%02x ", info->tos_value);
189 printf("TOS set 0x%02x/0x%02x ",
190 info->tos_value, info->tos_mask);
193 static void tos_tg_save_v0(const void *ip, const struct xt_entry_target *target)
195 const struct ipt_tos_target_info *info = (const void *)target->data;
197 printf("--set-tos 0x%02x ", info->tos);
200 static void tos_tg_save(const void *ip, const struct xt_entry_target *target)
202 const struct xt_tos_target_info *info = (const void *)target->data;
204 printf("--set-tos 0x%02x/0x%02x ", info->tos_value, info->tos_mask);
207 static struct xtables_target tos_tg_reg_v0 = {
208 .version = XTABLES_VERSION,
212 .size = XT_ALIGN(sizeof(struct xt_tos_target_info)),
213 .userspacesize = XT_ALIGN(sizeof(struct xt_tos_target_info)),
214 .help = tos_tg_help_v0,
215 .parse = tos_tg_parse_v0,
216 .final_check = tos_tg_check,
217 .print = tos_tg_print_v0,
218 .save = tos_tg_save_v0,
219 .extra_opts = tos_tg_opts_v0,
222 static struct xtables_target tos_tg_reg = {
223 .version = XTABLES_VERSION,
227 .size = XT_ALIGN(sizeof(struct xt_tos_target_info)),
228 .userspacesize = XT_ALIGN(sizeof(struct xt_tos_target_info)),
230 .parse = tos_tg_parse,
231 .final_check = tos_tg_check,
232 .print = tos_tg_print,
234 .extra_opts = tos_tg_opts,
237 static struct xtables_target tos_tg6_reg = {
238 .version = XTABLES_VERSION,
242 .size = XT_ALIGN(sizeof(struct xt_tos_target_info)),
243 .userspacesize = XT_ALIGN(sizeof(struct xt_tos_target_info)),
245 .parse = tos_tg_parse,
246 .final_check = tos_tg_check,
247 .print = tos_tg_print,
249 .extra_opts = tos_tg_opts,
254 xtables_register_target(&tos_tg_reg_v0);
255 xtables_register_target(&tos_tg_reg);
256 xtables_register_target(&tos_tg6_reg);