diff options
Diffstat (limited to 'extensions')
-rw-r--r-- | extensions/libxt_mark.c | 140 |
1 files changed, 112 insertions, 28 deletions
diff --git a/extensions/libxt_mark.c b/extensions/libxt_mark.c index b7f007b5..e7570846 100644 --- a/extensions/libxt_mark.c +++ b/extensions/libxt_mark.c @@ -1,4 +1,5 @@ /* Shared library add-on to iptables to add NFMARK matching support. */ +#include <stdbool.h> #include <stdio.h> #include <netdb.h> #include <string.h> @@ -6,24 +7,53 @@ #include <getopt.h> #include <xtables.h> -/* For 64bit kernel / 32bit userspace */ -#include "../include/linux/netfilter/xt_mark.h" +#include <linux/netfilter/xt_mark.h> -/* Function which prints out usage message. */ -static void mark_help(void) +enum { + F_MARK = 1 << 0, +}; + +static void mark_mt_help(void) { printf( -"MARK match v%s options:\n" -"[!] --mark value[/mask] Match nfmark value with optional mask\n" -"\n", -IPTABLES_VERSION); +"mark match options:\n" +"[!] --mark value[/mask] Match nfmark value with optional mask\n" +"\n"); } -static const struct option mark_opts[] = { - { "mark", 1, NULL, '1' }, - { } +static const struct option mark_mt_opts[] = { + {.name = "mark", .has_arg = true, .val = '1'}, + {}, }; +static int mark_mt_parse(int c, char **argv, int invert, unsigned int *flags, + const void *entry, struct xt_entry_match **match) +{ + struct xt_mark_mtinfo1 *info = (void *)(*match)->data; + unsigned int mark, mask = ~0U; + char *end; + + switch (c) { + case '1': /* --mark */ + param_act(P_ONLY_ONCE, "mark", "--mark", *flags & F_MARK); + if (!strtonum(optarg, &end, &mark, 0, ~0U)) + param_act(P_BAD_VALUE, "mark", "--mark", optarg); + if (*end == '/') + if (!strtonum(end + 1, &end, &mask, 0, ~0U)) + param_act(P_BAD_VALUE, "mark", "--mark", optarg); + if (*end != '\0') + param_act(P_BAD_VALUE, "mark", "--mark", optarg); + + if (invert) + info->invert = true; + info->mark = mark; + info->mask = mask; + *flags |= F_MARK; + return true; + } + return false; +} + /* Function which parses command options; returns true if it ate an option */ static int @@ -54,21 +84,30 @@ mark_parse(int c, char **argv, int invert, unsigned int *flags, return 1; } -static void -print_mark(unsigned long mark, unsigned long mask, int numeric) +static void print_mark(unsigned int mark, unsigned int mask) { - if(mask != 0xffffffff) - printf("0x%lx/0x%lx ", mark, mask); + if (mask != 0xffffffffU) + printf("0x%x/0x%x ", mark, mask); else - printf("0x%lx ", mark); + printf("0x%x ", mark); } -/* Final check; must have specified --mark. */ -static void mark_check(unsigned int flags) +static void mark_mt_check(unsigned int flags) { - if (!flags) + if (flags == 0) exit_error(PARAMETER_PROBLEM, - "MARK match: You must specify `--mark'"); + "mark match: The --mark option is required"); +} + +static void +mark_mt_print(const void *ip, const struct xt_entry_match *match, int numeric) +{ + const struct xt_mark_mtinfo1 *info = (const void *)match->data; + + printf("mark match "); + if (info->invert) + printf("!"); + print_mark(info->mark, info->mask); } /* Prints out the matchinfo. */ @@ -82,7 +121,18 @@ mark_print(const void *ip, const struct xt_entry_match *match, int numeric) if (info->invert) printf("!"); - print_mark(info->mark, info->mask, numeric); + print_mark(info->mark, info->mask); +} + +static void mark_mt_save(const void *ip, const struct xt_entry_match *match) +{ + const struct xt_mark_mtinfo1 *info = (const void *)match->data; + + if (info->invert) + printf("!"); + + printf("--mark "); + print_mark(info->mark, info->mask); } /* Saves the union ipt_matchinfo in parsable form to stdout. */ @@ -95,39 +145,73 @@ mark_save(const void *ip, const struct xt_entry_match *match) printf("! "); printf("--mark "); - print_mark(info->mark, info->mask, 0); + print_mark(info->mark, info->mask); } static struct xtables_match mark_match = { .family = AF_INET, .name = "mark", + .revision = 0, .version = IPTABLES_VERSION, .size = XT_ALIGN(sizeof(struct xt_mark_info)), .userspacesize = XT_ALIGN(sizeof(struct xt_mark_info)), - .help = mark_help, + .help = mark_mt_help, .parse = mark_parse, - .final_check = mark_check, + .final_check = mark_mt_check, .print = mark_print, .save = mark_save, - .extra_opts = mark_opts, + .extra_opts = mark_mt_opts, }; static struct xtables_match mark_match6 = { .family = AF_INET6, .name = "mark", + .revision = 0, .version = IPTABLES_VERSION, .size = XT_ALIGN(sizeof(struct xt_mark_info)), .userspacesize = XT_ALIGN(sizeof(struct xt_mark_info)), - .help = mark_help, + .help = mark_mt_help, .parse = mark_parse, - .final_check = mark_check, + .final_check = mark_mt_check, .print = mark_print, .save = mark_save, - .extra_opts = mark_opts, + .extra_opts = mark_mt_opts, +}; + +static struct xtables_match mark_mt_reg = { + .version = IPTABLES_VERSION, + .name = "mark", + .revision = 1, + .family = AF_INET6, + .size = XT_ALIGN(sizeof(struct xt_mark_mtinfo1)), + .userspacesize = XT_ALIGN(sizeof(struct xt_mark_mtinfo1)), + .help = mark_mt_help, + .parse = mark_mt_parse, + .final_check = mark_mt_check, + .print = mark_mt_print, + .save = mark_mt_save, + .extra_opts = mark_mt_opts, +}; + +static struct xtables_match mark_mt6_reg = { + .version = IPTABLES_VERSION, + .name = "mark", + .revision = 1, + .family = AF_INET6, + .size = XT_ALIGN(sizeof(struct xt_mark_mtinfo1)), + .userspacesize = XT_ALIGN(sizeof(struct xt_mark_mtinfo1)), + .help = mark_mt_help, + .parse = mark_mt_parse, + .final_check = mark_mt_check, + .print = mark_mt_print, + .save = mark_mt_save, + .extra_opts = mark_mt_opts, }; void _init(void) { xtables_register_match(&mark_match); xtables_register_match(&mark_match6); + xtables_register_match(&mark_mt_reg); + xtables_register_match(&mark_mt6_reg); } |