From 84c04e36eab024efa7c396ee370bf053c89af895 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 10 Apr 2018 10:55:30 +0200 Subject: ebtables-compat: add nat match extensions adds snat and dnat. Translation for snat isn't complete, the --snat-arp switch isn't supported so far. Signed-off-by: Florian Westphal --- extensions/libebt_dnat.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 extensions/libebt_dnat.c (limited to 'extensions/libebt_dnat.c') diff --git a/extensions/libebt_dnat.c b/extensions/libebt_dnat.c new file mode 100644 index 00000000..c179d8c1 --- /dev/null +++ b/extensions/libebt_dnat.c @@ -0,0 +1,134 @@ +/* ebt_nat + * + * Authors: + * Bart De Schuymer + * + * June, 2002 + */ + +#include +#include +#include +#include +#include +#include +#include +#include "iptables/nft.h" +#include "iptables/nft-bridge.h" + +#define NAT_D '1' +#define NAT_D_TARGET '2' +static const struct option brdnat_opts[] = +{ + { "to-destination", required_argument, 0, NAT_D }, + { "to-dst" , required_argument, 0, NAT_D }, + { "dnat-target" , required_argument, 0, NAT_D_TARGET }, + { 0 } +}; + +static void brdnat_print_help(void) +{ + printf( + "dnat options:\n" + " --to-dst address : MAC address to map destination to\n" + " --dnat-target target : ACCEPT, DROP, RETURN or CONTINUE\n"); +} + +static void brdnat_init(struct xt_entry_target *target) +{ + struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data; + + natinfo->target = EBT_ACCEPT; +} + +#define OPT_DNAT 0x01 +#define OPT_DNAT_TARGET 0x02 +static int brdnat_parse(int c, char **argv, int invert, unsigned int *flags, + const void *entry, struct xt_entry_target **target) +{ + struct ebt_nat_info *natinfo = (struct ebt_nat_info *)(*target)->data; + struct ether_addr *addr; + + switch (c) { + case NAT_D: + EBT_CHECK_OPTION(flags, OPT_DNAT); + if (!(addr = ether_aton(optarg))) + xtables_error(PARAMETER_PROBLEM, "Problem with specified --to-destination mac"); + memcpy(natinfo->mac, addr, ETH_ALEN); + break; + case NAT_D_TARGET: + EBT_CHECK_OPTION(flags, OPT_DNAT_TARGET); + if (ebt_fill_target(optarg, (unsigned int *)&natinfo->target)) + xtables_error(PARAMETER_PROBLEM, "Illegal --dnat-target target"); + break; + default: + return 0; + } + return 1; +} + +static void brdnat_final_check(unsigned int flags) +{ + if (!flags) + xtables_error(PARAMETER_PROBLEM, + "You must specify proper arguments"); +} + +static void ebt_print_mac(const unsigned char *mac) +{ + printf("%s", ether_ntoa((struct ether_addr *) mac)); +} + +static void brdnat_print(const void *ip, const struct xt_entry_target *target, int numeric) +{ + struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data; + + printf("--to-dst "); + ebt_print_mac(natinfo->mac); + printf(" --dnat-target %s", ebt_target_name(natinfo->target)); +} + +static const char* brdnat_verdict(int verdict) +{ + switch (verdict) { + case EBT_ACCEPT: return "accept"; + case EBT_DROP: return "drop"; + case EBT_CONTINUE: return "continue"; + case EBT_RETURN: return "return"; + } + + return ""; +} + +static int brdnat_xlate(struct xt_xlate *xl, + const struct xt_xlate_tg_params *params) +{ + const struct ebt_nat_info *natinfo = (const void*)params->target->data; + + xt_xlate_add(xl, "ether daddr set %s %s ", + ether_ntoa((struct ether_addr *)natinfo->mac), + brdnat_verdict(natinfo->target)); + + return 1; +} + +static struct xtables_target brdnat_target = +{ + .name = "dnat", + .version = XTABLES_VERSION, + .family = NFPROTO_BRIDGE, + .size = XT_ALIGN(sizeof(struct ebt_nat_info)), + .userspacesize = XT_ALIGN(sizeof(struct ebt_nat_info)), + .help = brdnat_print_help, + .init = brdnat_init, + .parse = brdnat_parse, + .final_check = brdnat_final_check, + .print = brdnat_print, + .xlate = brdnat_xlate, + .extra_opts = brdnat_opts, +}; + +void _init(void) +{ + xtables_register_target(&brdnat_target); +} -- cgit v1.2.3