/* ebt_mark * * Authors: * Bart De Schuymer <bdschuym@pandora.be> * * July, 2002, September 2006 * * Adapted by Arturo Borrero Gonzalez <arturo@debian.org> * to use libxtables for ebtables-compat in 2015. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <getopt.h> #include <xtables.h> #include <linux/netfilter_bridge/ebt_mark_t.h> #include "iptables/nft.h" #include "iptables/nft-bridge.h" static int mark_supplied; #define MARK_TARGET '1' #define MARK_SETMARK '2' #define MARK_ORMARK '3' #define MARK_ANDMARK '4' #define MARK_XORMARK '5' static struct option brmark_opts[] = { { .name = "mark-target",.has_arg = true, .val = MARK_TARGET }, /* an oldtime messup, we should have always used the scheme * <extension-name>-<option> */ { .name = "set-mark", .has_arg = true, .val = MARK_SETMARK }, { .name = "mark-set", .has_arg = true, .val = MARK_SETMARK }, { .name = "mark-or", .has_arg = true, .val = MARK_ORMARK }, { .name = "mark-and", .has_arg = true, .val = MARK_ANDMARK }, { .name = "mark-xor", .has_arg = true, .val = MARK_XORMARK }, XT_GETOPT_TABLEEND, }; static void brmark_print_help(void) { printf( "mark target options:\n" " --mark-set value : Set nfmark value\n" " --mark-or value : Or nfmark with value (nfmark |= value)\n" " --mark-and value : And nfmark with value (nfmark &= value)\n" " --mark-xor value : Xor nfmark with value (nfmark ^= value)\n" " --mark-target target : ACCEPT, DROP, RETURN or CONTINUE\n"); } static void brmark_init(struct xt_entry_target *target) { struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)target->data; info->target = EBT_ACCEPT; info->mark = 0; mark_supplied = 0; } #define OPT_MARK_TARGET 0x01 #define OPT_MARK_SETMARK 0x02 #define OPT_MARK_ORMARK 0x04 #define OPT_MARK_ANDMARK 0x08 #define OPT_MARK_XORMARK 0x10 static int brmark_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_target **target) { struct ebt_mark_t_info *info = (struct ebt_mark_t_info *) (*target)->data; char *end; uint32_t mask; switch (c) { case MARK_TARGET: { unsigned int tmp; EBT_CHECK_OPTION(flags, OPT_MARK_TARGET); if (ebt_fill_target(optarg, &tmp)) xtables_error(PARAMETER_PROBLEM, "Illegal --mark-target target"); /* the 4 lsb are left to designate the target */ info->target = (info->target & ~EBT_VERDICT_BITS) | (tmp & EBT_VERDICT_BITS); } return 1; case MARK_SETMARK: EBT_CHECK_OPTION(flags, OPT_MARK_SETMARK); mask = (OPT_MARK_ORMARK|OPT_MARK_ANDMARK|OPT_MARK_XORMARK); if (*flags & mask) xtables_error(PARAMETER_PROBLEM, "--mark-set cannot be used together with" " specific --mark option"); info->target = (info->target & EBT_VERDICT_BITS) | MARK_SET_VALUE; break; case MARK_ORMARK: EBT_CHECK_OPTION(flags, OPT_MARK_ORMARK); mask = (OPT_MARK_SETMARK|OPT_MARK_ANDMARK|OPT_MARK_XORMARK); if (*flags & mask) xtables_error(PARAMETER_PROBLEM, "--mark-or cannot be used together with" " specific --mark option"); info->target = (info->target & EBT_VERDICT_BITS) | MARK_OR_VALUE; break; case MARK_ANDMARK: EBT_CHECK_OPTION(flags, OPT_MARK_ANDMARK); mask = (OPT_MARK_SETMARK|OPT_MARK_ORMARK|OPT_MARK_XORMARK); if (*flags & mask) xtables_error(PARAMETER_PROBLEM, "--mark-and cannot be used together with" " specific --mark option"); info->target = (info->target & EBT_VERDICT_BITS) | MARK_AND_VALUE; break; case MARK_XORMARK: EBT_CHECK_OPTION(flags, OPT_MARK_XORMARK); mask = (OPT_MARK_SETMARK|OPT_MARK_ANDMARK|OPT_MARK_ORMARK); if (*flags & mask) xtables_error(PARAMETER_PROBLEM, "--mark-xor cannot be used together with" " specific --mark option"); info->target = (info->target & EBT_VERDICT_BITS) | MARK_XOR_VALUE; break; default: return 0; } /* mutual code */ info->mark = strtoul(optarg, &end, 0); if (*end != '\0' || end == optarg) xtables_error(PARAMETER_PROBLEM, "Bad MARK value '%s'", optarg); mark_supplied = 1; return 1; } static void brmark_print(const void *ip, const struct xt_entry_target *target, int numeric) { struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)target->data; int tmp; tmp = info->target & ~EBT_VERDICT_BITS; if (tmp == MARK_SET_VALUE) printf("--mark-set"); else if (tmp == MARK_OR_VALUE) printf("--mark-or"); else if (tmp == MARK_XOR_VALUE) printf("--mark-xor"); else if (tmp == MARK_AND_VALUE) printf("--mark-and"); else xtables_error(PARAMETER_PROBLEM, "Unknown mark action"); printf(" 0x%lx", info->mark); tmp = info->target | ~EBT_VERDICT_BITS; printf(" --mark-target %s", ebt_target_name(tmp)); } static void brmark_final_check(unsigned int flags) { if (mark_supplied == 0) xtables_error(PARAMETER_PROBLEM, "No mark value supplied"); if (!flags) xtables_error(PARAMETER_PROBLEM, "You must specify some option"); } static struct xtables_target brmark_target = { .name = "mark", .revision = 0, .version = XTABLES_VERSION, .family = NFPROTO_BRIDGE, .size = XT_ALIGN(sizeof(struct ebt_mark_t_info)), .userspacesize = XT_ALIGN(sizeof(struct ebt_mark_t_info)), .help = brmark_print_help, .init = brmark_init, .parse = brmark_parse, .final_check = brmark_final_check, .print = brmark_print, .extra_opts = brmark_opts, }; void _init(void) { xtables_register_target(&brmark_target); }