--- ebtables-v2.0pre3.003/ebtables.c Sat Apr 27 16:57:47 2002 +++ ebtables-v2.0pre3.004/ebtables.c Wed Apr 24 19:47:02 2002 @@ -63,8 +63,8 @@ { "policy" , required_argument, 0, 'P' }, { "in-interface" , required_argument, 0, 'i' }, { "in-if" , required_argument, 0, 'i' }, - { "logical-in" , required_argument, 0, 1 }, - { "logical-out" , required_argument, 0, 2 }, + { "logical-in" , required_argument, 0, 2 }, + { "logical-out" , required_argument, 0, 3 }, { "out-interface" , required_argument, 0, 'o' }, { "out-if" , required_argument, 0, 'o' }, { "version" , no_argument , 0, 'V' }, @@ -155,6 +155,8 @@ e->ethproto = 0; strcpy(e->in, ""); strcpy(e->out, ""); + strcpy(e->logical_in, ""); + strcpy(e->logical_out, ""); e->m_list = NULL; e->w_list = NULL; // the init function of the standard target should have put the verdict @@ -1278,9 +1280,9 @@ break; case 'i': // input interface - case 1 : // logical input interface + case 2 : // logical input interface case 'o': // output interface - case 2 : // logical output interface + case 3 : // logical output interface case 'j': // target case 'p': // net family protocol case 's': // source mac @@ -1306,7 +1308,7 @@ strcpy(new_entry->in, argv[optind - 1]); break; } - if (c == 1) { + if (c == 2) { check_option(&replace.flags, OPT_LOGICALIN); if (replace.selected_hook > 2) print_error("Use logical in-interface " @@ -1342,7 +1344,7 @@ strcpy(new_entry->out, argv[optind - 1]); break; } - if (c == 2) { + if (c == 3) { check_option(&replace.flags, OPT_LOGICALOUT); if (replace.selected_hook < 2) print_error("Use logical out-interface " --- /dev/null Thu Aug 24 11:00:32 2000 +++ ebtables-v2.0pre3.004/extensions/ebt_redirect.c Sat Apr 27 17:18:16 2002 @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include +#include +#include +#include "../include/ebtables_u.h" +#include + +extern char *standard_targets[NUM_STANDARD_TARGETS]; + +#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 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) +{ + int i; + struct ebt_redirect_info *redirectinfo = + (struct ebt_redirect_info *)(*target)->data; + + switch (c) { + case REDIRECT_TARGET: + check_option(flags, OPT_REDIRECT_TARGET); + for (i = 0; i < NUM_STANDARD_TARGETS; i++) + if (!strcmp(optarg, standard_targets[i])) { + redirectinfo->target = i; + break; + } + if (i == NUM_STANDARD_TARGETS) + print_error("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 hook) +{ + if ( (hook != NF_BR_PRE_ROUTING || strcmp(name, "nat")) && + (hook != NF_BR_BROUTING || strcmp(name, "broute")) ) + 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; + + printf("redirect"); + printf(" --redirect-target %s", standard_targets[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 = +{ + EBT_REDIRECT_TARGET, + sizeof(struct ebt_redirect_info), + print_help, + init, + parse, + final_check, + print, + compare, + opts, +}; + +static void _init(void) __attribute__ ((constructor)); +static void _init(void) +{ + register_target(&redirect_target); +} --- ebtables-v2.0pre3.003/extensions/ebt_nat.c Sat Apr 27 16:57:41 2002 +++ ebtables-v2.0pre3.004/extensions/ebt_nat.c Sat Apr 27 17:16:19 2002 @@ -8,54 +8,71 @@ #include "../include/ebtables_u.h" #include +extern char *standard_targets[NUM_STANDARD_TARGETS]; + int to_source_supplied, to_dest_supplied; #define NAT_S '1' #define NAT_D '1' +#define NAT_S_TARGET '2' +#define NAT_D_TARGET '2' static struct option opts_s[] = { { "to-source" , required_argument, 0, NAT_S }, { "to-src" , required_argument, 0, NAT_S }, - { 0 }, + { "snat-target" , required_argument, 0, NAT_S_TARGET }, + { 0 } }; static struct option opts_d[] = { { "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 print_help_s() { printf( - "snat option:\n" - " --to-src address : MAC address to map source to\n"); + "snat options:\n" + " --to-src address : MAC address to map source to\n" + " --snat-target target : ACCEPT, DROP or CONTINUE\n"); } static void print_help_d() { printf( - "dnat option:\n" - " --to-dst address : MAC address to map destination to\n"); + "dnat options:\n" + " --to-dst address : MAC address to map destination to\n" + " --dnat-target target : ACCEPT, DROP or CONTINUE\n"); } static void init_s(struct ebt_entry_target *target) { + struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data; + to_source_supplied = 0; + natinfo->target = EBT_ACCEPT; return; } static void init_d(struct ebt_entry_target *target) { + struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data; + to_dest_supplied = 0; + natinfo->target = EBT_ACCEPT; + return; } -#define OPT_SNAT 0x01 +#define OPT_SNAT 0x01 +#define OPT_SNAT_TARGET 0x02 static int parse_s(int c, char **argv, int argc, const struct ebt_u_entry *entry, unsigned int *flags, struct ebt_entry_target **target) { + int i; struct ebt_nat_info *natinfo = (struct ebt_nat_info *)(*target)->data; switch (c) { @@ -65,17 +82,29 @@ if (getmac(optarg, natinfo->mac)) print_error("Problem with specified to-source mac"); break; + case NAT_S_TARGET: + check_option(flags, OPT_SNAT_TARGET); + for (i = 0; i < NUM_STANDARD_TARGETS; i++) + if (!strcmp(optarg, standard_targets[i])) { + natinfo->target = i; + break; + } + if (i == NUM_STANDARD_TARGETS) + print_error("Illegal --snat-target target"); + break; default: - return 0; + return 0; } return 1; } -#define OPT_DNAT 0x01 +#define OPT_DNAT 0x01 +#define OPT_DNAT_TARGET 0x02 static int parse_d(int c, char **argv, int argc, const struct ebt_u_entry *entry, unsigned int *flags, struct ebt_entry_target **target) { + int i; struct ebt_nat_info *natinfo = (struct ebt_nat_info *)(*target)->data; switch (c) { @@ -86,8 +115,18 @@ print_error("Problem with specified " "to-destination mac"); break; + case NAT_D_TARGET: + check_option(flags, OPT_DNAT_TARGET); + for (i = 0; i < NUM_STANDARD_TARGETS; i++) + if (!strcmp(optarg, standard_targets[i])) { + natinfo->target = i; + break; + } + if (i == NUM_STANDARD_TARGETS) + print_error("Illegal --dnat-target target"); + break; default: - return 0; + return 0; } return 1; } @@ -96,18 +135,18 @@ const struct ebt_entry_target *target, const char *name, unsigned int hook) { if (hook != NF_BR_POST_ROUTING || strcmp(name, "nat")) - print_error("Wrong chain for SNAT"); + print_error("Wrong chain for snat"); if (to_source_supplied == 0) print_error("No snat address supplied"); - } static void final_check_d(const struct ebt_u_entry *entry, const struct ebt_entry_target *target, const char *name, unsigned int hook) { - if ( (hook != NF_BR_PRE_ROUTING && hook != NF_BR_LOCAL_OUT) || - strcmp(name, "nat") ) - print_error("Wrong chain for DNAT"); + if ( ((hook != NF_BR_PRE_ROUTING && hook != NF_BR_LOCAL_OUT) || + strcmp(name, "nat")) && + (hook != NF_BR_BROUTING || strcmp(name, "broute")) ) + print_error("Wrong chain for dnat"); if (to_dest_supplied == 0) print_error("No dnat address supplied"); } @@ -122,6 +161,7 @@ for (i = 0; i < ETH_ALEN; i++) printf("%02x%s", natinfo->mac[i], (i == ETH_ALEN - 1) ? "" : ":"); + printf(" --snat-target %s", standard_targets[natinfo->target]); } static void print_d(const struct ebt_u_entry *entry, @@ -134,6 +174,7 @@ for (i = 0; i < ETH_ALEN; i++) printf("%02x%s", natinfo->mac[i], (i == ETH_ALEN - 1) ? "" : ":"); + printf(" --dnat-target %s", standard_targets[natinfo->target]); } static int compare(const struct ebt_entry_target *t1, @@ -142,13 +183,15 @@ struct ebt_nat_info *natinfo1 = (struct ebt_nat_info *)t1->data; struct ebt_nat_info *natinfo2 = (struct ebt_nat_info *)t2->data; - return !memcmp(natinfo1->mac, natinfo2->mac, sizeof(natinfo1->mac)); + + return !memcmp(natinfo1->mac, natinfo2->mac, sizeof(natinfo1->mac)) && + natinfo1->target == natinfo2->target; } static struct ebt_u_target snat_target = { EBT_SNAT_TARGET, - sizeof(struct ebt_nat_info) + sizeof(struct ebt_entry_target), + sizeof(struct ebt_nat_info), print_help_s, init_s, parse_s, --- ebtables-v2.0pre3.003/extensions/Makefile Sat Apr 6 21:56:53 2002 +++ ebtables-v2.0pre3.004/extensions/Makefile Tue Apr 23 22:46:21 2002 @@ -1,7 +1,7 @@ #! /usr/bin/make -EXT_FUNC+=nat arp ip standard log -EXT_TABLES+=filter nat +EXT_FUNC+=nat arp ip standard log redirect +EXT_TABLES+=filter nat broute EXT_OBJS+=$(foreach T,$(EXT_FUNC), extensions/ebt_$(T).o) EXT_OBJS+=$(foreach T,$(EXT_TABLES), extensions/ebtable_$(T).o) --- ebtables-v2.0pre3.003/ChangeLog Sun Apr 14 14:15:59 2002 +++ ebtables-v2.0pre3.004/ChangeLog Sat Apr 27 17:24:26 2002 @@ -1,3 +1,9 @@ +20020427 + * added broute table. + * added redirect target. + * added --redirect-target, --snat-target and --dnat-target options. + * added logical_out and logical_in + * snat bugfix (->size) 20020414 * fixed some things in the manual. * fixed -P problem. --- ebtables-v2.0pre3.003/ebtables.8 Sat Apr 27 16:57:44 2002 +++ ebtables-v2.0pre3.004/ebtables.8 Sat Apr 27 13:33:37 2002 @@ -1,4 +1,4 @@ -.TH EBTABLES 8 "14 April 2002" +.TH EBTABLES 8 "27 April 2002" .\" .\" Man page written by Bart De Schuymer .\" It is based on the iptables man page. @@ -40,7 +40,7 @@ complicated. This man page is written with the man page of iptables next to it, so don't be surprised to see copied sentences and structure. -There are two tables with each three built-in chains. Each chain is a list +There are three tables with built-in chains. Each chain is a list of rules which can match frames: each rule specifies what to do with a frame which matches. This is called a 'target'. The tables are used to divide functionality into different sets of chains. @@ -66,7 +66,7 @@ .B "TARGET EXTENSIONS" section. .SS TABLES -There are two tables. +There are three tables. .TP .B "-t, --table" This option specifies the frame matching table which the command should @@ -90,6 +90,22 @@ of chains POSTROUTING and PREROUTING: it would be more accurate to call them PREFORWARDING and POSTFORWARDING, but for all those who come from the iptables world to ebtables it is easier to have the same names. +.BR broute , +this table is used to make a brouter, it has one chain: +.BR BROUTING . +The targets +.BR DROP and ACCEPT +have special meaning in this table. +.B DROP +actually means the frame has to be routed, while +.B ACCEPT +means the frame has to be bridged. The +.B BROUTING +chain is traversed very early. It is only traversed by frames entering on +a bridge enslaved nic that is in forwarding state. Normally those frames +would be bridged, but you can decide otherwise here. The +.B redirect +target is very handy here. .SH OPTIONS The options can be divided into several different groups. .SS COMMANDS @@ -334,13 +350,21 @@ The flag .B --to-src is an alias for this option. +.br +.BR "--snat-target " "\fItarget\fP" +.br +Specifies the standard target. After doing the snat, the rule still has +to give a standard target so ebtables knows what to do. +The default target is ACCEPT. Making it CONTINUE could let you use +multiple target extensions on the same frame. Making it DROP doesn't +make sense, but you could do that too. .TP .B dnat The .B dnat target can only be used in the -.BR PREROUTING " and the -.BR OUTPUT " chains of the " nat " table." +.BR BROUTING " chain of the " broute " table and the " +.BR PREROUTING " and " OUTPUT " chains of the " nat " table." It specifies that the destination mac address has to be changed. .br .BR "--to-destination " "\fIaddress\fP" @@ -348,6 +372,31 @@ The flag .B --to-dst is an alias for this option. +.br +.BR "--dnat-target " "\fItarget\fP" +.br +Specifies the standard target. After doing the dnat, the rule still has to +give a standard target so ebtables knows what to do. +The default target is ACCEPT. Making it CONTINUE could let you use +multiple target extensions on the same frame. Making it DROP only makes +sense in the BROUTING chain but using the redirect target is more logical +there. +.TP +.B redirect +The +.B redirect +target will change the MAC target address to that of the physical nic the +frame arrived on. This target can only be used in the +.BR BROUTING " chain of the " broute " table and the " +.BR PREROUTING " chain of the " nat " table." +.br +.BR "--redirect-target " "\fItarget\fP" +.br +Specifies the standard target. After doing the MAC redirect, the rule +still has to give a standard target so ebtables knows what to do. +The default target is ACCEPT. Making it CONTINUE could let you use +multiple target extensions on the same frame. Making it DROP in the +BROUTING chain will let the frames be routed. .SH FILES .I /etc/etherproto .SH BUGS