diff --git a/net/ebtables-tiny/src/Makefile b/net/ebtables-tiny/src/Makefile index 0d06846..aabe689 100644 --- a/net/ebtables-tiny/src/Makefile +++ b/net/ebtables-tiny/src/Makefile @@ -6,7 +6,7 @@ CFLAGS += -Iinclude CFLAGS += -Wall EXT_TABLES:=filter nat broute -EXT_FUNC:=arp ip6 ip limit mark mark_m nat standard +EXT_FUNC:=arp ip6 ip limit mark mark_m nat redirect standard EXT_OBJS:=$(foreach T,$(EXT_FUNC),extensions/ebt_$(T).o) $(foreach T,$(EXT_TABLES),extensions/ebtable_$(T).o) OBJECTS2:=getethertype.o communication.o libebtc.o useful_functions.o ebtables.o diff --git a/net/ebtables-tiny/src/extensions/ebt_redirect.c b/net/ebtables-tiny/src/extensions/ebt_redirect.c new file mode 100644 index 0000000..ca15d73 --- /dev/null +++ b/net/ebtables-tiny/src/extensions/ebt_redirect.c @@ -0,0 +1,114 @@ +/* ebt_redirect + * + * Authors: + * Bart De Schuymer + * + * April, 2002 + */ + +#include +#include +#include +#include +#include "../include/ebtables_u.h" +#include + +#define REDIRECT_TARGET '1' +static struct option opts[] = +{ + { "redirect-target", required_argument, 0, REDIRECT_TARGET }, + { 0 } +}; + +static void print_help() +{ + printf( + "redirect option:\n" + " --redirect-target target : ACCEPT, DROP, RETURN or CONTINUE\n"); +} + +static void init(struct ebt_entry_target *target) +{ + struct ebt_redirect_info *redirectinfo = + (struct ebt_redirect_info *)target->data; + + redirectinfo->target = EBT_ACCEPT; + return; +} + +#define OPT_REDIRECT_TARGET 0x01 +static int parse(int c, char **argv, int argc, + const struct ebt_u_entry *entry, unsigned int *flags, + struct ebt_entry_target **target) +{ + struct ebt_redirect_info *redirectinfo = + (struct ebt_redirect_info *)(*target)->data; + + switch (c) { + case REDIRECT_TARGET: + ebt_check_option2(flags, OPT_REDIRECT_TARGET); + if (FILL_TARGET(optarg, redirectinfo->target)) + ebt_print_error2("Illegal --redirect-target target"); + break; + default: + return 0; + } + return 1; +} + +static void final_check(const struct ebt_u_entry *entry, + const struct ebt_entry_target *target, const char *name, + unsigned int hookmask, unsigned int time) +{ + struct ebt_redirect_info *redirectinfo = + (struct ebt_redirect_info *)target->data; + + if (BASE_CHAIN && redirectinfo->target == EBT_RETURN) { + ebt_print_error("--redirect-target RETURN not allowed on base chain"); + return; + } + CLEAR_BASE_CHAIN_BIT; + if ( ((hookmask & ~(1 << NF_BR_PRE_ROUTING)) || strcmp(name, "nat")) && + ((hookmask & ~(1 << NF_BR_BROUTING)) || strcmp(name, "broute")) ) + ebt_print_error("Wrong chain for redirect"); +} + +static void print(const struct ebt_u_entry *entry, + const struct ebt_entry_target *target) +{ + struct ebt_redirect_info *redirectinfo = + (struct ebt_redirect_info *)target->data; + + if (redirectinfo->target == EBT_ACCEPT) + return; + printf(" --redirect-target %s", TARGET_NAME(redirectinfo->target)); +} + +static int compare(const struct ebt_entry_target *t1, + const struct ebt_entry_target *t2) +{ + struct ebt_redirect_info *redirectinfo1 = + (struct ebt_redirect_info *)t1->data; + struct ebt_redirect_info *redirectinfo2 = + (struct ebt_redirect_info *)t2->data; + + return redirectinfo1->target == redirectinfo2->target; +} + +static struct ebt_u_target redirect_target = +{ + .name = "redirect", + .size = sizeof(struct ebt_redirect_info), + .help = print_help, + .init = init, + .parse = parse, + .final_check = final_check, + .print = print, + .compare = compare, + .extra_ops = opts, +}; + +__attribute__((constructor)) static void extension_init(void) +{ + ebt_register_target(&redirect_target); +}