1 /* Shared library add-on to iptables to add MARK target support. */
9 #include <linux/netfilter/x_tables.h>
10 #include <linux/netfilter/xt_MARK.h>
16 /* Function which prints out usage message. */
17 static void MARK_help(void)
20 "MARK target options:\n"
21 " --set-mark value Set nfmark value\n"
22 " --and-mark value Binary AND the nfmark with value\n"
23 " --or-mark value Binary OR the nfmark with value\n"
24 " --copy-xid Set nfmark to be the connection xid (PlanetLab specific)\n"
28 static const struct option MARK_opts[] = {
29 { "set-mark", 1, NULL, '1' },
30 { "and-mark", 1, NULL, '2' },
31 { "or-mark", 1, NULL, '3' },
32 { "copy-xid", 1, 0, '4' },
36 static const struct option mark_tg_opts[] = {
37 {.name = "set-xmark", .has_arg = true, .val = 'X'},
38 {.name = "set-mark", .has_arg = true, .val = '='},
39 {.name = "and-mark", .has_arg = true, .val = '&'},
40 {.name = "or-mark", .has_arg = true, .val = '|'},
41 {.name = "xor-mark", .has_arg = true, .val = '^'},
45 static void mark_tg_help(void)
48 "MARK target options:\n"
49 " --set-xmark value[/mask] Clear bits in mask and XOR value into nfmark\n"
50 " --set-mark value[/mask] Clear bits in mask and OR value into nfmark\n"
51 " --and-mark bits Binary AND the nfmark with bits\n"
52 " --or-mark bits Binary OR the nfmark with bits\n"
53 " --xor-mask bits Binary XOR the nfmark with bits\n"
57 /* Function which parses command options; returns true if it
60 MARK_parse_v0(int c, char **argv, int invert, unsigned int *flags,
61 const void *entry, struct xt_entry_target **target)
63 struct xt_mark_target_info *markinfo
64 = (struct xt_mark_target_info *)(*target)->data;
68 if (string_to_number_l(optarg, 0, 0,
70 exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
72 exit_error(PARAMETER_PROBLEM,
73 "MARK target: Can't specify --set-mark twice");
77 exit_error(PARAMETER_PROBLEM,
78 "MARK target: kernel too old for --and-mark");
80 exit_error(PARAMETER_PROBLEM,
81 "MARK target: kernel too old for --or-mark");
89 static void MARK_check(unsigned int flags)
92 exit_error(PARAMETER_PROBLEM,
93 "MARK target: Parameter --set/and/or-mark"
97 /* Function which parses command options; returns true if it
100 MARK_parse_v1(int c, char **argv, int invert, unsigned int *flags,
101 const void *entry, struct xt_entry_target **target)
103 struct xt_mark_target_info_v1 *markinfo
104 = (struct xt_mark_target_info_v1 *)(*target)->data;
108 markinfo->mode = XT_MARK_SET;
111 markinfo->mode = XT_MARK_AND;
114 markinfo->mode = XT_MARK_OR;
117 markinfo->mode = IPT_MARK_COPYXID;
123 if (string_to_number_l(optarg, 0, 0, &markinfo->mark))
124 exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
127 exit_error(PARAMETER_PROBLEM,
128 "MARK target: Can't specify --set-mark twice");
134 static int mark_tg_parse(int c, char **argv, int invert, unsigned int *flags,
135 const void *entry, struct xt_entry_target **target)
137 struct xt_mark_tginfo2 *info = (void *)(*target)->data;
138 unsigned int value, mask = ~0U;
142 case 'X': /* --set-xmark */
143 case '=': /* --set-mark */
144 param_act(P_ONE_ACTION, "MARK", *flags & F_MARK);
145 param_act(P_NO_INVERT, "MARK", "--set-xmark/--set-mark", invert);
146 if (!strtonum(optarg, &end, &value, 0, ~0U))
147 param_act(P_BAD_VALUE, "MARK", "--set-xmark/--set-mark", optarg);
149 if (!strtonum(end + 1, &end, &mask, 0, ~0U))
150 param_act(P_BAD_VALUE, "MARK", "--set-xmark/--set-mark", optarg);
152 param_act(P_BAD_VALUE, "MARK", "--set-xmark/--set-mark", optarg);
157 info->mask = value | mask;
160 case '&': /* --and-mark */
161 param_act(P_ONE_ACTION, "MARK", *flags & F_MARK);
162 param_act(P_NO_INVERT, "MARK", "--and-mark", invert);
163 if (!strtonum(optarg, NULL, &mask, 0, ~0U))
164 param_act(P_BAD_VALUE, "MARK", "--and-mark", optarg);
169 case '|': /* --or-mark */
170 param_act(P_ONE_ACTION, "MARK", *flags & F_MARK);
171 param_act(P_NO_INVERT, "MARK", "--or-mark", invert);
172 if (!strtonum(optarg, NULL, &value, 0, ~0U))
173 param_act(P_BAD_VALUE, "MARK", "--or-mark", optarg);
178 case '^': /* --xor-mark */
179 param_act(P_ONE_ACTION, "MARK", *flags & F_MARK);
180 param_act(P_NO_INVERT, "MARK", "--xor-mark", invert);
181 if (!strtonum(optarg, NULL, &value, 0, ~0U))
182 param_act(P_BAD_VALUE, "MARK", "--xor-mark", optarg);
195 static void mark_tg_check(unsigned int flags)
198 exit_error(PARAMETER_PROBLEM, "MARK: One of the --set-xmark, "
199 "--{and,or,xor,set}-mark options is required");
203 print_mark(unsigned long mark)
205 printf("0x%lx ", mark);
208 /* Prints out the targinfo. */
209 static void MARK_print_v0(const void *ip,
210 const struct xt_entry_target *target, int numeric)
212 const struct xt_mark_target_info *markinfo =
213 (const struct xt_mark_target_info *)target->data;
215 print_mark(markinfo->mark);
218 /* Saves the union ipt_targinfo in parsable form to stdout. */
219 static void MARK_save_v0(const void *ip, const struct xt_entry_target *target)
221 const struct xt_mark_target_info *markinfo =
222 (const struct xt_mark_target_info *)target->data;
224 printf("--set-mark ");
225 print_mark(markinfo->mark);
228 /* Prints out the targinfo. */
229 static void MARK_print_v1(const void *ip, const struct xt_entry_target *target,
232 const struct xt_mark_target_info_v1 *markinfo =
233 (const struct xt_mark_target_info_v1 *)target->data;
235 switch (markinfo->mode) {
245 case IPT_MARK_COPYXID:
246 printf("MARK copyxid ");
249 print_mark(markinfo->mark);
252 static void mark_tg_print(const void *ip, const struct xt_entry_target *target,
255 const struct xt_mark_tginfo2 *info = (const void *)target->data;
258 printf("MARK and 0x%x ", (unsigned int)(u_int32_t)~info->mask);
259 else if (info->mark == info->mask)
260 printf("MARK or 0x%x ", info->mark);
261 else if (info->mask == 0)
262 printf("MARK xor 0x%x ", info->mark);
264 printf("MARK xset 0x%x/0x%x ", info->mark, info->mask);
267 /* Saves the union ipt_targinfo in parsable form to stdout. */
268 static void MARK_save_v1(const void *ip, const struct xt_entry_target *target)
270 const struct xt_mark_target_info_v1 *markinfo =
271 (const struct xt_mark_target_info_v1 *)target->data;
273 switch (markinfo->mode) {
275 printf("--set-mark ");
278 printf("--and-mark ");
281 printf("--or-mark ");
283 case IPT_MARK_COPYXID:
284 printf("--copy-xid ");
287 print_mark(markinfo->mark);
290 static void mark_tg_save(const void *ip, const struct xt_entry_target *target)
292 const struct xt_mark_tginfo2 *info = (const void *)target->data;
294 printf("--set-xmark 0x%x/0x%x ", info->mark, info->mask);
297 static struct xtables_target mark_target_v0 = {
300 .version = XTABLES_VERSION,
302 .size = XT_ALIGN(sizeof(struct xt_mark_target_info)),
303 .userspacesize = XT_ALIGN(sizeof(struct xt_mark_target_info)),
305 .parse = MARK_parse_v0,
306 .final_check = MARK_check,
307 .print = MARK_print_v0,
308 .save = MARK_save_v0,
309 .extra_opts = MARK_opts,
312 static struct xtables_target mark_target_v1 = {
315 .version = XTABLES_VERSION,
317 .size = XT_ALIGN(sizeof(struct xt_mark_target_info_v1)),
318 .userspacesize = XT_ALIGN(sizeof(struct xt_mark_target_info_v1)),
320 .parse = MARK_parse_v1,
321 .final_check = MARK_check,
322 .print = MARK_print_v1,
323 .save = MARK_save_v1,
324 .extra_opts = MARK_opts,
327 static struct xtables_target mark_target6_v0 = {
330 .version = XTABLES_VERSION,
332 .size = XT_ALIGN(sizeof(struct xt_mark_target_info)),
333 .userspacesize = XT_ALIGN(sizeof(struct xt_mark_target_info)),
335 .parse = MARK_parse_v0,
336 .final_check = MARK_check,
337 .print = MARK_print_v0,
338 .save = MARK_save_v0,
339 .extra_opts = MARK_opts,
342 static struct xtables_target mark_tg_reg_v2 = {
343 .version = XTABLES_VERSION,
347 .size = XT_ALIGN(sizeof(struct xt_mark_tginfo2)),
348 .userspacesize = XT_ALIGN(sizeof(struct xt_mark_tginfo2)),
349 .help = mark_tg_help,
350 .parse = mark_tg_parse,
351 .final_check = mark_tg_check,
352 .print = mark_tg_print,
353 .save = mark_tg_save,
354 .extra_opts = mark_tg_opts,
359 xtables_register_target(&mark_target_v0);
360 xtables_register_target(&mark_target_v1);
361 xtables_register_target(&mark_target6_v0);
362 xtables_register_target(&mark_tg_reg_v2);