From cdd0312bda6af74fba04626ffe6a5891bfe1c49d Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Patrick McHardy/emailAddress=kaber@trash.net" Date: Sun, 20 Jan 2008 13:31:13 +0000 Subject: [PATCH]: libxt_MARK r2 Add support for xt_MARK target revision 2. Also consolidate libip6t_MARK.man and libipt_MARK.man. Signed-off-by: Jan Engelhardt --- extensions/libxt_MARK.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) (limited to 'extensions/libxt_MARK.c') diff --git a/extensions/libxt_MARK.c b/extensions/libxt_MARK.c index 0187298..82beb4b 100644 --- a/extensions/libxt_MARK.c +++ b/extensions/libxt_MARK.c @@ -1,4 +1,5 @@ /* Shared library add-on to iptables to add MARK target support. */ +#include #include #include #include @@ -8,6 +9,10 @@ #include #include +enum { + F_MARK = 1 << 0, +}; + /* Function which prints out usage message. */ static void MARK_help(void) { @@ -27,6 +32,27 @@ static const struct option MARK_opts[] = { { } }; +static const struct option mark_tg_opts[] = { + {.name = "set-xmark", .has_arg = true, .val = 'X'}, + {.name = "set-mark", .has_arg = true, .val = '='}, + {.name = "and-mark", .has_arg = true, .val = '&'}, + {.name = "or-mark", .has_arg = true, .val = '|'}, + {.name = "xor-mark", .has_arg = true, .val = '^'}, + {}, +}; + +static void mark_tg_help(void) +{ + printf( +"MARK target options:\n" +" --set-xmark value[/mask] Clear bits in mask and XOR value into nfmark\n" +" --set-mark value[/mask] Clear bits in mask and OR value into nfmark\n" +" --and-mark bits Binary AND the nfmark with bits\n" +" --or-mark bits Binary OR the nfmark with bits\n" +" --xor-mask bits Binary XOR the nfmark with bits\n" +"\n"); +} + /* Function which parses command options; returns true if it ate an option */ static int @@ -101,6 +127,74 @@ MARK_parse_v1(int c, char **argv, int invert, unsigned int *flags, return 1; } +static int mark_tg_parse(int c, char **argv, int invert, unsigned int *flags, + const void *entry, struct xt_entry_target **target) +{ + struct xt_mark_tginfo2 *info = (void *)(*target)->data; + unsigned int value, mask = ~0U; + char *end; + + switch (c) { + case 'X': /* --set-xmark */ + case '=': /* --set-mark */ + param_act(P_ONE_ACTION, "MARK", *flags & F_MARK); + param_act(P_NO_INVERT, "MARK", "--set-xmark/--set-mark", invert); + if (!strtonum(optarg, &end, &value, 0, ~0U)) + param_act(P_BAD_VALUE, "MARK", "--set-xmark/--set-mark", optarg); + if (*end == '/') + if (!strtonum(end + 1, &end, &mask, 0, ~0U)) + param_act(P_BAD_VALUE, "MARK", "--set-xmark/--set-mark", optarg); + if (*end != '\0') + param_act(P_BAD_VALUE, "MARK", "--set-xmark/--set-mark", optarg); + info->mark = value; + info->mask = mask; + + if (c == '=') + info->mask = value | mask; + break; + + case '&': /* --and-mark */ + param_act(P_ONE_ACTION, "MARK", *flags & F_MARK); + param_act(P_NO_INVERT, "MARK", "--and-mark", invert); + if (!strtonum(optarg, NULL, &mask, 0, ~0U)) + param_act(P_BAD_VALUE, "MARK", "--and-mark", optarg); + info->mark = 0; + info->mask = ~mask; + break; + + case '|': /* --or-mark */ + param_act(P_ONE_ACTION, "MARK", *flags & F_MARK); + param_act(P_NO_INVERT, "MARK", "--or-mark", invert); + if (!strtonum(optarg, NULL, &value, 0, ~0U)) + param_act(P_BAD_VALUE, "MARK", "--or-mark", optarg); + info->mark = value; + info->mask = value; + break; + + case '^': /* --xor-mark */ + param_act(P_ONE_ACTION, "MARK", *flags & F_MARK); + param_act(P_NO_INVERT, "MARK", "--xor-mark", invert); + if (!strtonum(optarg, NULL, &value, 0, ~0U)) + param_act(P_BAD_VALUE, "MARK", "--xor-mark", optarg); + info->mark = value; + info->mask = 0; + break; + + default: + return false; + } + + *flags |= F_MARK; + return true; +} + +static void mark_tg_check(unsigned int flags) +{ + if (flags == 0) + exit_error(PARAMETER_PROBLEM, "MARK: One of the --set-xmark, " + "--{and,or,xor,set}-mark options is required"); +} + static void print_mark(unsigned long mark) { @@ -148,6 +242,21 @@ static void MARK_print_v1(const void *ip, const struct xt_entry_target *target, print_mark(markinfo->mark); } +static void mark_tg_print(const void *ip, const struct xt_entry_target *target, + int numeric) +{ + const struct xt_mark_tginfo2 *info = (const void *)target->data; + + if (info->mark == 0) + printf("MARK and 0x%x ", (unsigned int)(u_int32_t)~info->mask); + else if (info->mark == info->mask) + printf("MARK or 0x%x ", info->mark); + else if (info->mask == 0) + printf("MARK xor 0x%x ", info->mark); + else + printf("MARK xset 0x%x/0x%x ", info->mark, info->mask); +} + /* Saves the union ipt_targinfo in parsable form to stdout. */ static void MARK_save_v1(const void *ip, const struct xt_entry_target *target) { @@ -168,6 +277,13 @@ static void MARK_save_v1(const void *ip, const struct xt_entry_target *target) print_mark(markinfo->mark); } +static void mark_tg_save(const void *ip, const struct xt_entry_target *target) +{ + const struct xt_mark_tginfo2 *info = (const void *)target->data; + + printf("--set-xmark 0x%x/0x%x ", info->mark, info->mask); +} + static struct xtables_target mark_target_v0 = { .family = AF_INET, .name = "MARK", @@ -213,9 +329,41 @@ static struct xtables_target mark_target6_v0 = { .extra_opts = MARK_opts, }; +static struct xtables_target mark_tg_reg_v2 = { + .version = IPTABLES_VERSION, + .name = "MARK", + .revision = 2, + .family = AF_INET, + .size = XT_ALIGN(sizeof(struct xt_mark_tginfo2)), + .userspacesize = XT_ALIGN(sizeof(struct xt_mark_tginfo2)), + .help = mark_tg_help, + .parse = mark_tg_parse, + .final_check = mark_tg_check, + .print = mark_tg_print, + .save = mark_tg_save, + .extra_opts = mark_tg_opts, +}; + +static struct xtables_target mark_tg6_reg_v2 = { + .version = IPTABLES_VERSION, + .name = "MARK", + .revision = 2, + .family = AF_INET6, + .size = XT_ALIGN(sizeof(struct xt_mark_tginfo2)), + .userspacesize = XT_ALIGN(sizeof(struct xt_mark_tginfo2)), + .help = mark_tg_help, + .parse = mark_tg_parse, + .final_check = mark_tg_check, + .print = mark_tg_print, + .save = mark_tg_save, + .extra_opts = mark_tg_opts, +}; + void _init(void) { xtables_register_target(&mark_target_v0); xtables_register_target(&mark_target_v1); xtables_register_target(&mark_target6_v0); + xtables_register_target(&mark_tg_reg_v2); + xtables_register_target(&mark_tg6_reg_v2); } -- cgit v1.2.3