From d891e9e5bc309d5aeb2ab774c76b34a92085b3e7 Mon Sep 17 00:00:00 2001 From: Bart De Schuymer Date: Sat, 1 Jun 2002 19:23:47 +0000 Subject: Initial revision --- .../incremental-patches/ebtables-v2.0pre2.001.diff | 121 ++ .../incremental-patches/ebtables-v2.0pre2.002.diff | 2204 ++++++++++++++++++++ .../incremental-patches/ebtables-v2.0pre2.003.diff | 40 + .../incremental-patches/ebtables-v2.0pre2.004.diff | 50 + .../incremental-patches/ebtables-v2.0pre3.001.diff | 245 +++ .../incremental-patches/ebtables-v2.0pre3.002.diff | 194 ++ .../incremental-patches/ebtables-v2.0pre3.003.diff | 66 + .../incremental-patches/ebtables-v2.0pre3.004.diff | 483 +++++ .../incremental-patches/ebtables-v2.0pre4.001.diff | 522 +++++ .../incremental-patches/ebtables-v2.0pre5.001.diff | 50 + .../incremental-patches/ebtables-v2.0pre5.002.diff | 61 + .../incremental-patches/ebtables-v2.0pre6.001.diff | 314 +++ 12 files changed, 4350 insertions(+) create mode 100644 userspace/patches/incremental-patches/ebtables-v2.0pre2.001.diff create mode 100644 userspace/patches/incremental-patches/ebtables-v2.0pre2.002.diff create mode 100644 userspace/patches/incremental-patches/ebtables-v2.0pre2.003.diff create mode 100644 userspace/patches/incremental-patches/ebtables-v2.0pre2.004.diff create mode 100644 userspace/patches/incremental-patches/ebtables-v2.0pre3.001.diff create mode 100644 userspace/patches/incremental-patches/ebtables-v2.0pre3.002.diff create mode 100644 userspace/patches/incremental-patches/ebtables-v2.0pre3.003.diff create mode 100644 userspace/patches/incremental-patches/ebtables-v2.0pre3.004.diff create mode 100644 userspace/patches/incremental-patches/ebtables-v2.0pre4.001.diff create mode 100644 userspace/patches/incremental-patches/ebtables-v2.0pre5.001.diff create mode 100644 userspace/patches/incremental-patches/ebtables-v2.0pre5.002.diff create mode 100644 userspace/patches/incremental-patches/ebtables-v2.0pre6.001.diff (limited to 'userspace/patches/incremental-patches') diff --git a/userspace/patches/incremental-patches/ebtables-v2.0pre2.001.diff b/userspace/patches/incremental-patches/ebtables-v2.0pre2.001.diff new file mode 100644 index 0000000..80cc94b --- /dev/null +++ b/userspace/patches/incremental-patches/ebtables-v2.0pre2.001.diff @@ -0,0 +1,121 @@ +Changed the Makefile hacking to initialize things (taken from iptables) +to using __attribute__ ((constructor)). Makes things cleaner. + +--- ebtables-v2.0pre1/Makefile Wed Apr 3 18:24:15 2002 ++++ ebtables-v2.0pre2/Makefile Sat Apr 6 21:53:00 2002 +@@ -26,7 +26,7 @@ + $(CC) $(CFLAGS) -DPROGVERSION=\"$(PROGVERSION)\" \ + -DPROGNAME=\"$(PROGNAME)\" -c -o $@ $< + +-ebtables: ebtables.o communication.o initext.o $(EXT_OBJS) ++ebtables: ebtables.o communication.o $(EXT_OBJS) + $(CC) $(CFLAGS) -o $@ $^ + + $(MANDIR)/man8/ebtables.8: ebtables.8 +--- ebtables-v2.0pre1/ebtables.c Wed Apr 3 20:06:18 2002 ++++ ebtables-v2.0pre2/ebtables.c Sat Apr 6 21:57:05 2002 +@@ -1051,7 +1051,6 @@ + replace.selected_hook = -1; + replace.command = 'h'; + // execute the _init functions of the extensions +- init_extensions(); + + new_entry = (struct ebt_u_entry *)malloc(sizeof(struct ebt_u_entry)); + if (!new_entry) +--- ebtables-v2.0pre1/extensions/ebt_nat.c Wed Apr 3 12:27:59 2002 ++++ ebtables-v2.0pre2/extensions/ebt_nat.c Sat Apr 6 21:59:43 2002 +@@ -160,7 +160,8 @@ + opts_d, + }; + +-void _init(void) ++static void _init(void) __attribute__ ((constructor)); ++static void _init(void) + { + register_target(&snat_target); + register_target(&dnat_target); +--- ebtables-v2.0pre1/extensions/ebt_ip.c Wed Apr 3 12:28:44 2002 ++++ ebtables-v2.0pre2/extensions/ebt_ip.c Sat Apr 6 21:58:23 2002 +@@ -301,7 +301,8 @@ + opts, + }; + +-void _init(void) ++static void _init(void) __attribute((constructor)); ++static void _init(void) + { + register_match(&ip_match); + } +--- ebtables-v2.0pre1/extensions/ebt_arp.c Wed Apr 3 12:29:17 2002 ++++ ebtables-v2.0pre2/extensions/ebt_arp.c Sat Apr 6 21:58:05 2002 +@@ -271,7 +271,8 @@ + opts, + }; + +-void _init(void) ++static void _init(void) __attribute__ ((constructor)); ++static void _init(void) + { + register_match(&arp_match); + } +--- ebtables-v2.0pre1/extensions/ebt_log.c Wed Apr 3 16:23:56 2002 ++++ ebtables-v2.0pre2/extensions/ebt_log.c Sat Apr 6 21:59:34 2002 +@@ -182,7 +182,9 @@ + opts, + }; + +-void _init(void) ++#undef _init ++static void _init(void) __attribute__ ((constructor)); ++static void _init(void) + { + register_watcher(&log_watcher); + } +--- ebtables-v2.0pre1/extensions/ebt_standard.c Mon Apr 1 12:49:59 2002 ++++ ebtables-v2.0pre2/extensions/ebt_standard.c Sat Apr 6 22:01:29 2002 +@@ -59,7 +59,8 @@ + opts + }; + +-void _init(void) ++static void _init(void) __attribute__ ((constructor)); ++static void _init(void) + { + register_target(&standard); + } +--- ebtables-v2.0pre1/extensions/ebtable_filter.c Mon Apr 1 21:25:57 2002 ++++ ebtables-v2.0pre2/extensions/ebtable_filter.c Sat Apr 6 22:00:02 2002 +@@ -24,7 +24,8 @@ + NULL + }; + +-void _init(void) ++static void _init(void) __attribute__ ((constructor)); ++static void _init(void) + { + register_table(&table); + } +--- ebtables-v2.0pre1/extensions/ebtable_nat.c Wed Apr 3 10:16:46 2002 ++++ ebtables-v2.0pre2/extensions/ebtable_nat.c Sat Apr 6 21:59:53 2002 +@@ -24,7 +24,8 @@ + NULL + }; + +-void _init(void) ++static void _init(void) __attribute__ ((constructor)); ++static void _init(void) + { + register_table(&table); + } +--- ebtables-v2.0pre1/include/ebtables_u.h Wed Apr 3 17:20:17 2002 ++++ ebtables-v2.0pre2/include/ebtables_u.h Sat Apr 6 21:56:16 2002 +@@ -25,9 +25,6 @@ + #define EBTABLES_U_H + #include + #include +-#ifdef _INIT +-#define _init _INIT +-#endif + + struct ebt_u_entries + { diff --git a/userspace/patches/incremental-patches/ebtables-v2.0pre2.002.diff b/userspace/patches/incremental-patches/ebtables-v2.0pre2.002.diff new file mode 100644 index 0000000..c638367 --- /dev/null +++ b/userspace/patches/incremental-patches/ebtables-v2.0pre2.002.diff @@ -0,0 +1,2204 @@ +This is a big patch. +Hope I didn't break anything. + +--- ebtables-v2.0pre2.001/Makefile Thu Apr 11 18:27:45 2002 ++++ ebtables-v2.0pre2.002/Makefile Thu Apr 11 18:38:47 2002 +@@ -2,8 +2,7 @@ + + KERNEL_DIR?=/usr/src/linux + PROGNAME:=ebtables +-PROGVERSION:="2.0pre1 (April 2002)" +- ++PROGVERSION:="2.0pre2.001 (April 2002)" + + MANDIR?=/usr/local/man + CFLAGS:=-Wall -Wunused +--- ebtables-v2.0pre2.001/ebtables.c Thu Apr 11 18:27:45 2002 ++++ ebtables-v2.0pre2.002/ebtables.c Wed Apr 10 22:46:27 2002 +@@ -34,7 +34,8 @@ + #include + #include "include/ebtables_u.h" + +-// here are the number-name correspondences kept for the ethernet frame type field ++// here are the number-name correspondences kept for the ethernet ++// frame type field + #define PROTOCOLFILE "/etc/etherproto" + + #define DATABASEHOOKNR NF_BR_NUMHOOKS +@@ -81,27 +82,28 @@ + + // yup, all the possible target names + char* standard_targets[NUM_STANDARD_TARGETS] = { +- "ACCEPT" , ++ "ACCEPT", + "DROP", + "CONTINUE", + }; + + // tells what happened to the old rules +-unsigned short *counterchanges; ++static unsigned short *counterchanges; + // holds all the data +-struct ebt_u_replace replace; ++static struct ebt_u_replace replace; + + // the chosen table +-struct ebt_u_table *table = NULL; ++static struct ebt_u_table *table = NULL; + // the lists of supported tables, matches, watchers and targets +-struct ebt_u_table *tables = NULL; +-struct ebt_u_match *matches = NULL; +-struct ebt_u_watcher *watchers = NULL; +-struct ebt_u_target *targets = NULL; ++static struct ebt_u_table *tables = NULL; ++static struct ebt_u_match *matches = NULL; ++static struct ebt_u_watcher *watchers = NULL; ++static struct ebt_u_target *targets = NULL; + + struct ebt_u_target *find_target(const char *name) + { + struct ebt_u_target *t = targets; ++ + while(t && strcmp(t->name, name)) + t = t->next; + return t; +@@ -110,6 +112,7 @@ + struct ebt_u_match *find_match(const char *name) + { + struct ebt_u_match *m = matches; ++ + while(m && strcmp(m->name, name)) + m = m->next; + return m; +@@ -118,6 +121,7 @@ + struct ebt_u_watcher *find_watcher(const char *name) + { + struct ebt_u_watcher *w = watchers; ++ + while(w && strcmp(w->name, name)) + w = w->next; + return w; +@@ -126,17 +130,18 @@ + struct ebt_u_table *find_table(char *name) + { + struct ebt_u_table *t = tables; ++ + while (t && strcmp(t->name, name)) + t = t->next; + return t; + } + +-// the pointers in here are special: +-// the struct ebt_target * pointer is actually a struct ebt_u_target * pointer +-// instead of making yet a few other structs, we just do a cast +-// we need a struct ebt_u_target pointer because we know the address of the data they +-// point to won't change. We want to allow that the struct ebt_u_target.t member can +-// change. ++// The pointers in here are special: ++// The struct ebt_target * pointer is actually a struct ebt_u_target * pointer. ++// instead of making yet a few other structs, we just do a cast. ++// We need a struct ebt_u_target pointer because we know the address of the data ++// they point to won't change. We want to allow that the struct ebt_u_target.t ++// member can change. + // Same holds for the struct ebt_match and struct ebt_watcher pointers + struct ebt_u_entry *new_entry; + +@@ -149,13 +154,14 @@ + strcpy(e->out, ""); + e->m_list = NULL; + e->w_list = NULL; +- // the init function of the standard target should have put the verdict on CONTINUE ++ // the init function of the standard target should have put the verdict ++ // on CONTINUE + e->t = (struct ebt_entry_target *)find_target(EBT_STANDARD_TARGET); + if (!e->t) + print_bug("Couldn't load standard target\n"); + } + +-// this doesn't free e, basically becoz it's lazy ++// this doesn't free e, becoz the calling function might need e->next + void free_u_entry(struct ebt_u_entry *e) + { + struct ebt_u_match_list *m_l, *m_l2; +@@ -178,6 +184,40 @@ + free(e->t); + } + ++// the user will use the match, so put it in new_entry ++static void add_match(struct ebt_u_match *m) ++{ ++ struct ebt_u_match_list **m_list, *new; ++ ++ m->used = 1; ++ for (m_list = &new_entry->m_list; ++ *m_list; m_list = &(*m_list)->next); ++ new = (struct ebt_u_match_list *) ++ malloc(sizeof(struct ebt_u_match_list)); ++ if (!new) ++ print_memory(); ++ *m_list = new; ++ new->next = NULL; ++ new->m = (struct ebt_entry_match *)m; ++} ++ ++static void add_watcher(struct ebt_u_watcher *w) ++{ ++ struct ebt_u_watcher_list **w_list; ++ struct ebt_u_watcher_list *new; ++ ++ w->used = 1; ++ for (w_list = &new_entry->w_list; ++ *w_list; w_list = &(*w_list)->next); ++ new = (struct ebt_u_watcher_list *) ++ malloc(sizeof(struct ebt_u_watcher_list)); ++ if (!new) ++ print_memory(); ++ *w_list = new; ++ new->next = NULL; ++ new->w = (struct ebt_entry_watcher *)w; ++} ++ + static int global_option_offset = 0; + #define OPTION_OFFSET 256 + static struct option * +@@ -196,6 +236,8 @@ + *options_offset = global_option_offset; + + merge = malloc(sizeof(struct option) * (num_new + num_old + 1)); ++ if (!merge) ++ print_memory(); + memcpy(merge, oldopts, num_old * sizeof(struct option)); + for (i = 0; i < num_new; i++) { + merge[num_old + i] = newopts[i]; +@@ -219,7 +261,8 @@ + print_memory(); + strcpy(m->m->u.name, m->name); + m->m->match_size = size; +- ebt_options = merge_options(ebt_options, m->extra_ops, &(m->option_offset)); ++ ebt_options = merge_options ++ (ebt_options, m->extra_ops, &(m->option_offset)); + m->init(m->m); + + for (i = &matches; *i; i = &((*i)->next)); +@@ -237,7 +280,8 @@ + print_memory(); + strcpy(w->w->u.name, w->name); + w->w->watcher_size = size; +- ebt_options = merge_options(ebt_options, w->extra_ops, &(w->option_offset)); ++ ebt_options = merge_options ++ (ebt_options, w->extra_ops, &(w->option_offset)); + w->init(w->w); + + for (i = &watchers; *i; i = &((*i)->next)); +@@ -255,7 +299,8 @@ + print_memory(); + strcpy(t->t->u.name, t->name); + t->t->target_size = size; +- ebt_options = merge_options(ebt_options, t->extra_ops, &(t->option_offset)); ++ ebt_options = merge_options ++ (ebt_options, t->extra_ops, &(t->option_offset)); + t->init(t->t); + for (i = &targets; *i; i = &((*i)->next)); + t->next = NULL; +@@ -292,7 +337,7 @@ + return 0; + } + +-/* helper function: processes a line of data from the file brebt_protocolnames */ ++// helper function: processes a line of data from the file /etc/etherproto + int get_a_line(char *buffer, char *value, FILE *ifp) + { + int i, hlp; +@@ -314,7 +359,7 @@ + + // buffer[0] already contains the first letter + for (i = 1; i < 21; i++) { +- hlp = fscanf(ifp, "%c", buffer+i); ++ hlp = fscanf(ifp, "%c", buffer + i); + if (hlp == EOF || hlp == 0) return -1; + if (buffer[i] == '\t' || buffer[i] == ' ') + break; +@@ -327,7 +372,8 @@ + // buffer[0] already contains the first letter + for (i = 1; i < 5; i++) { + hlp = fscanf(ifp, "%c", value+i); +- if (value[i] == '\n' || value[i] == '\t' || value[i] == ' ' || hlp == EOF) ++ if (value[i] == '\n' || value[i] == '\t' || ++ value[i] == ' ' || hlp == EOF) + break; + } + if (i == 5) return -1; +@@ -342,7 +388,7 @@ + return 0; + } + +-/* helper function for list_em() */ ++// helper function for list_em() + int number_to_name(unsigned short proto, char *name) + { + FILE *ifp; +@@ -363,13 +409,12 @@ + fclose(ifp); + return 0; + } +- return -1; + } + +-/* helper function for list_rules() */ ++// helper function for list_rules() + static void list_em(int hooknr) + { +- int i, space = 0; ++ int i, j, space = 0, digits; + struct ebt_u_entry *hlp; + struct ebt_u_match_list *m_l; + struct ebt_u_watcher_list *w_l; +@@ -379,7 +424,8 @@ + char name[21]; + + hlp = replace.hook_entry[hooknr]->entries; +- printf("\nBridge chain: %s\nPolicy: %s\n", hooknames[hooknr], standard_targets[(int)(replace.hook_entry[hooknr]->policy)]); ++ printf("\nBridge chain: %s\nPolicy: %s\n", hooknames[hooknr], ++ standard_targets[replace.hook_entry[hooknr]->policy]); + printf("nr. of entries: %d \n", replace.hook_entry[hooknr]->nentries); + + i = replace.hook_entry[hooknr]->nentries; +@@ -389,19 +435,18 @@ + } + + for (i = 0; i < replace.hook_entry[hooknr]->nentries; i++) { +- int j = i + 1, space2 = 0; +- // a little work to get nice rule numbers +- // this can probably be done easier - so what ++ digits = 0; ++ // A little work to get nice rule numbers. + while (j > 9) { +- space2++; ++ digits++; + j /= 10; + } +- for (j = 0; j < space - space2; j++) ++ for (j = 0; j < space - digits; j++) + printf(" "); + printf("%d. ", i + 1); + +- // don't print anything about the protocol if no protocol was specified +- // obviously this means any protocol will do ++ // Don't print anything about the protocol if no protocol was ++ // specified, obviously this means any protocol will do. + if (!(hlp->bitmask & EBT_NOPROTO)) { + printf("eth proto: "); + if (hlp->invflags & EBT_IPROTO) +@@ -416,20 +461,20 @@ + } + } + if (hlp->bitmask & EBT_SOURCEMAC) { +- int j; + printf("source mac: "); + if (hlp->invflags & EBT_ISOURCE) + printf("! "); + for (j = 0; j < ETH_ALEN; j++) +- printf("%02x%s", hlp->sourcemac[j], (j == ETH_ALEN - 1) ? ", " : ":"); ++ printf("%02x%s", hlp->sourcemac[j], ++ (j == ETH_ALEN - 1) ? ", " : ":"); + } + if (hlp->bitmask & EBT_DESTMAC) { +- int j; + printf("dest mac: "); + if (hlp->invflags & EBT_IDEST) + printf("! "); + for (j = 0; j < ETH_ALEN; j++) +- printf("%02x%s", hlp->destmac[j], (j == ETH_ALEN - 1) ? ", " : ":"); ++ printf("%02x%s", hlp->destmac[j], ++ (j == ETH_ALEN - 1) ? ", " : ":"); + } + if (hlp->in[0] != '\0') { + if (hlp->invflags & EBT_IIN) +@@ -462,9 +507,10 @@ + printf("target: "); + t = find_target(hlp->t->u.name); + if (!t) +- print_error("Target not found."); ++ print_bug("Target not found"); + t->print(hlp, hlp->t); +- printf(", count = %llu", replace.counters[replace.counter_entry[hooknr] + i].pcnt); ++ printf(", count = %llu", ++ replace.counters[replace.counter_entry[hooknr] + i].pcnt); + printf("\n"); + hlp = hlp->next; + } +@@ -492,30 +538,30 @@ + struct ebt_u_watcher_list *w_l; + + printf( +- "%s v%s\n" +- "Usage:\n" +- "ebtables -[ADI] chain rule-specification [options]\n" +- "ebtables -P chain target\n" +- "ebtables -[LFZ] [chain]\n" +- "ebtables -[b] [y,n]\n" +- "Commands:\n" +- "--append -A chain : Append to chain\n" +- "--delete -D chain : Delete matching rule from chain\n" +- "--delete -D chain rulenum : Delete rule at position rulenum from chain\n" +- "--insert -I chain rulenum : insert rule at position rulenum in chain\n" +- "--list -L [chain] : List the rules in a chain or in all chains\n" +- "--list -L "DATABASEHOOKNAME" : List the database (if present)\n" +- "--flush -F [chain] : Delete all rules in chain or in all chains\n" +- "--zero -Z [chain] : Put counters on zero in chain or in all chains\n" +- "--policy -P chain target : Change policy on chain to target\n" +- "Options:\n" +- "--proto -p [!] proto : protocol hexadecimal, by name or LENGTH\n" +- "--src -s [!] address : source mac address\n" +- "--dst -d [!] address : destination mac address\n" +- "--in-if -i [!] name : network input interface name\n" +- "--out-if -o [!] name : network output interface name\n" +- "--version -V : print package version\n" +- "\n" , ++"%s v%s\n" ++"Usage:\n" ++"ebtables -[ADI] chain rule-specification [options]\n" ++"ebtables -P chain target\n" ++"ebtables -[LFZ] [chain]\n" ++"ebtables -[b] [y,n]\n" ++"Commands:\n" ++"--append -A chain : Append to chain\n" ++"--delete -D chain : Delete matching rule from chain\n" ++"--delete -D chain rulenum : Delete rule at position rulenum from chain\n" ++"--insert -I chain rulenum : insert rule at position rulenum in chain\n" ++"--list -L [chain] : List the rules in a chain or in all chains\n" ++"--list -L "DATABASEHOOKNAME" : List the database (if present)\n" ++"--flush -F [chain] : Delete all rules in chain or in all chains\n" ++"--zero -Z [chain] : Put counters on zero in chain or in all chains\n" ++"--policy -P chain target : Change policy on chain to target\n" ++"Options:\n" ++"--proto -p [!] proto : protocol hexadecimal, by name or LENGTH\n" ++"--src -s [!] address : source mac address\n" ++"--dst -d [!] address : destination mac address\n" ++"--in-if -i [!] name : network input interface name\n" ++"--out-if -o [!] name : network output interface name\n" ++"--version -V : print package version\n" ++"\n" , + prog_name, + prog_version); + +@@ -538,7 +584,7 @@ + exit(0); + } + +-/* execute command L */ ++// execute command L + static void list_rules() + { + int i; +@@ -563,7 +609,8 @@ + replace.num_counters = replace.nentries; + if (replace.nentries) { + // '+ 1' for the CNT_END +- if ( !(counterchanges = (unsigned short *)malloc((replace.nentries + 1) * sizeof(unsigned short))) ) ++ if (!(counterchanges = (unsigned short *) malloc( ++ (replace.nentries + 1) * sizeof(unsigned short)))) + print_memory(); + // done nothing special to the rules + for (i = 0; i < replace.nentries; i++) +@@ -611,12 +658,14 @@ + if (replace.hook_entry[replace.selected_hook]->nentries == 0) + exit(0); + oldnentries = replace.nentries; +- replace.nentries = replace.nentries - replace.hook_entry[replace.selected_hook]->nentries; ++ replace.nentries = replace.nentries - ++ replace.hook_entry[replace.selected_hook]->nentries; + + // delete the counters belonging to the specified chain + if (replace.nentries) { + // +1 for CNT_END +- if ( !(counterchanges = (unsigned short *)malloc((oldnentries + 1) * sizeof(unsigned short))) ) ++ if ( !(counterchanges = (unsigned short *) ++ malloc((oldnentries + 1) * sizeof(unsigned short))) ) + print_memory(); + cnt = counterchanges; + for (i = 0; i < NF_BR_NUMHOOKS; i++) { +@@ -660,23 +709,31 @@ + + // handle '-D chain rulenr' command + if (rule_nr != -1) { +- if (rule_nr > replace.hook_entry[replace.selected_hook]->nentries) ++ if (rule_nr > ++ replace.hook_entry[replace.selected_hook]->nentries) + return 0; ++ // user starts counting from 1 + return rule_nr - 1; + } + u_e = replace.hook_entry[replace.selected_hook]->entries; +- // check for an existing rule (if there are duplicate rules, take the first occurance) +- for (i = 0; i < replace.hook_entry[replace.selected_hook]->nentries; i++, u_e = u_e->next) { ++ // check for an existing rule (if there are duplicate rules, ++ // take the first occurance) ++ for (i = 0; i < replace.hook_entry[replace.selected_hook]->nentries; ++ i++, u_e = u_e->next) { + if (!u_e) + print_bug("Hmm, trouble"); + if ( u_e->ethproto == new_entry->ethproto +- && !strncmp(u_e->in, new_entry->in, IFNAMSIZ) +- && !strncmp(u_e->out, new_entry->out, IFNAMSIZ) && u_e->bitmask == new_entry->bitmask) { +- if (new_entry->bitmask & EBT_SOURCEMAC && strncmp(u_e->sourcemac, new_entry->sourcemac, ETH_ALEN)) ++ && !strcmp(u_e->in, new_entry->in) ++ && !strcmp(u_e->out, new_entry->out) ++ && u_e->bitmask == new_entry->bitmask) { ++ if (new_entry->bitmask & EBT_SOURCEMAC && ++ strcmp(u_e->sourcemac, new_entry->sourcemac)) + continue; +- if (new_entry->bitmask & EBT_DESTMAC && strncmp(u_e->destmac, new_entry->destmac, ETH_ALEN)) ++ if (new_entry->bitmask & EBT_DESTMAC && ++ strcmp(u_e->destmac, new_entry->destmac)) + continue; +- if (new_entry->bitmask != u_e->bitmask || new_entry->invflags != u_e->invflags) ++ if (new_entry->bitmask != u_e->bitmask || ++ new_entry->invflags != u_e->invflags) + continue; + // compare all matches + m_l = new_entry->m_list; +@@ -684,7 +741,8 @@ + while (m_l) { + m = (struct ebt_u_match *)(m_l->m); + m_l2 = u_e->m_list; +- while (m_l2 && strcmp(m_l2->m->u.name, m->m->u.name)) ++ while (m_l2 && ++ strcmp(m_l2->m->u.name, m->m->u.name)) + m_l2 = m_l2->next; + if (!m_l2 || !m->compare(m->m, m_l2->m)) + goto letscontinue; +@@ -707,7 +765,8 @@ + while (w_l) { + w = (struct ebt_u_watcher *)(w_l->w); + w_l2 = u_e->w_list; +- while (w_l2 && strcmp(w_l2->w->u.name, w->w->u.name)) ++ while (w_l2 && ++ strcmp(w_l2->w->u.name, w->w->u.name)) + w_l2 = w_l2->next; + if (!w_l2 || !w->compare(w->w, w_l2->w)) + goto letscontinue; +@@ -743,8 +802,10 @@ + struct ebt_u_watcher_list *w_l; + + if (rule_nr != -1) { // command -I +- if (--rule_nr > replace.hook_entry[replace.selected_hook]->nentries) +- print_error("rule nr too high: %d > %d.", rule_nr, replace.hook_entry[replace.selected_hook]->nentries); ++ if (--rule_nr > ++ replace.hook_entry[replace.selected_hook]->nentries) ++ print_error("rule nr too high: %d > %d", rule_nr, ++ replace.hook_entry[replace.selected_hook]->nentries); + } else + rule_nr = replace.hook_entry[replace.selected_hook]->nentries; + // we're adding one rule +@@ -754,7 +815,8 @@ + + // handle counter stuff + // +1 for CNT_END +- if ( !(counterchanges = (unsigned short *)malloc((replace.nentries + 1) * sizeof(unsigned short))) ) ++ if ( !(counterchanges = (unsigned short *) ++ malloc((replace.nentries + 1) * sizeof(unsigned short))) ) + print_memory(); + cnt = counterchanges; + for (i = 0; i < replace.selected_hook; i++) { +@@ -813,7 +875,7 @@ + struct ebt_u_entry *u_e, *u_e2; + + if ( (i = check_rule_exists(rule_nr)) == -1 ) +- print_error("Sorry, rule does not exists."); ++ print_error("Sorry, rule does not exists"); + + // we're deleting a rule + replace.num_counters = replace.nentries; +@@ -827,7 +889,8 @@ + } + lentmp += i; + // +1 for CNT_END +- if ( !(counterchanges = (unsigned short *)malloc((replace.num_counters + 1) * sizeof(unsigned short))) ) ++ if ( !(counterchanges = (unsigned short *)malloc( ++ (replace.num_counters + 1) * sizeof(unsigned short))) ) + print_memory(); + cnt = counterchanges; + for (j = 0; j < lentmp; j++) { +@@ -871,8 +934,8 @@ + + if (zerochain == -1) { + // tell main() we don't update the counters +- // this results in tricking the kernel to zero his counters, naively expecting +- // userspace to update its counters. Muahahaha ++ // this results in tricking the kernel to zero his counters, ++ // naively expecting userspace to update its counters. Muahahaha + counterchanges = NULL; + replace.num_counters = 0; + } else { +@@ -881,7 +944,10 @@ + + if (replace.hook_entry[zerochain]->nentries == 0) + exit(0); +- counterchanges = (unsigned short *)malloc((replace.nentries + 1) * sizeof(unsigned short)); ++ counterchanges = (unsigned short *) ++ malloc((replace.nentries + 1) * sizeof(unsigned short)); ++ if (!counterchanges) ++ print_memory(); + cnt = counterchanges; + for (i = 0; i < zerochain; i++) { + if (!(replace.valid_hooks & (1 << i))) +@@ -915,10 +981,12 @@ + + // 0 : database disabled (-db n) + if (!(nr.nentries)) +- print_error("Database not present (disabled), try ebtables --db y."); +- (nr.nentries)--; +- if (!nr.nentries) print_error("Database empty."); +- if ( !(db = (struct brdb_dbentry *) malloc(nr.nentries * sizeof(struct brdb_dbentry))) ) ++ print_error("Database not present" ++ " (disabled), try ebtables --db y"); ++ nr.nentries--; ++ if (!nr.nentries) print_error("Database empty"); ++ if ( !(db = (struct brdb_dbentry *) ++ malloc(nr.nentries * sizeof(struct brdb_dbentry))) ) + print_memory(); + + get_db(nr.nentries, db); +@@ -931,7 +999,7 @@ + "out-if : %s\n" + "protocol: ", i + 1, hooknames[db->hook], db->in, db->out); + if (db->ethproto == IDENTIFY802_3) +- printf("NO PROTO, OLD 802.3 STYLE LENGTH FIELD\n"); ++ printf("802.2/802.3 STYLE LENGTH FIELD\n"); + else { + if (number_to_name(ntohs(db->ethproto), name)) + printf("%x\n",ntohs(db->ethproto)); +@@ -943,13 +1011,13 @@ + exit(0); + } + +-// handle counter and db disabling and enabling ++// handle db [dis,en]abling + static void allowdb(char yorn) + { + __u16 decision; + + if (yorn != 'y' && yorn != 'n') +- print_error("Option [y] or [n] needed."); ++ print_error("Option [y] or [n] needed"); + + if (yorn == 'y') + decision = BRDB_DB; +@@ -980,7 +1048,8 @@ + if (strcasecmp(buffer, name)) + continue; + i = (unsigned short) strtol(value, &bfr, 16); +- if (*bfr != '\0') return -1; ++ if (*bfr != '\0') ++ return -1; + new_entry->ethproto = i; + fclose(ifp); + return 0; +@@ -1022,7 +1091,7 @@ + void check_option(unsigned int *flags, unsigned int mask) + { + if (*flags & mask) +- print_error("Multiple use of same option not allowed."); ++ print_error("Multiple use of same option not allowed"); + *flags |= mask; + } + +@@ -1040,17 +1109,21 @@ + { + char *buffer, allowbc = 'n'; + int c, i; +- int zerochain = -1; // this special one for the -Z option (we can have -Z -L ) ++ // this special one for the -Z option (we can have -Z -L ) ++ int zerochain = -1; + int policy = -1; + int rule_nr = -1;// used for -D chain number + struct ebt_u_target *t; ++ struct ebt_u_match *m; ++ struct ebt_u_watcher *w; ++ struct ebt_u_match_list *m_l; ++ struct ebt_u_watcher_list *w_l; + +- // initialize the table name, OPT_ flags and selected hook ++ // initialize the table name, OPT_ flags, selected hook and command + strcpy(replace.name, "filter"); + replace.flags = 0; + replace.selected_hook = -1; + replace.command = 'h'; +- // execute the _init functions of the extensions + + new_entry = (struct ebt_u_entry *)malloc(sizeof(struct ebt_u_entry)); + if (!new_entry) +@@ -1059,7 +1132,8 @@ + initialize_entry(new_entry); + + // getopt saves the day +- while ((c = getopt_long(argc, argv, "-A:D:I:L::Z::F::P:Vhi:o:j:p:b:s:d:t:", ebt_options, NULL)) != -1) { ++ while ((c = getopt_long(argc, argv, ++ "-A:D:I:L::Z::F::P:Vhi:o:j:p:b:s:d:t:", ebt_options, NULL)) != -1) { + switch (c) { + + case 'A': // add a rule +@@ -1068,33 +1142,39 @@ + case 'I': // insert a rule + replace.command = c; + if (replace.flags & OPT_COMMAND) +- print_error("Multiple commands not allowed."); ++ print_error("Multiple commands not allowed"); + replace.flags |= OPT_COMMAND; + if ((replace.selected_hook = get_hooknr(optarg)) == -1) +- print_error("Bad chain."); +- // '-' denotes another option, if no other option it must be the (optional) rule number +- if (c == 'D' && optind < argc && argv[optind][0] != '-') { ++ print_error("Bad chain"); ++ if (c == 'D' && optind < argc && ++ argv[optind][0] != '-') { + rule_nr = strtol(argv[optind], &buffer, 10); + if (*buffer != '\0' || rule_nr < 0) +- print_error("Problem with the specified rule number."); ++ print_error("Problem with the " ++ "specified rule number"); + optind++; + } + if (c == 'P') { + if (optind >= argc) +- print_error("No policy specified."); ++ print_error("No policy specified"); + for (i = 0; i < 2; i++) +- if (!strcmp(argv[optind], standard_targets[i])) ++ if (!strcmp(argv[optind], ++ standard_targets[i])) { + policy = i; ++ break; ++ } + if (policy == -1) +- print_error("Wrong policy."); ++ print_error("Wrong policy"); + optind++; + } + if (c == 'I') { + if (optind >= argc) +- print_error("No rulenr for -I specified."); ++ print_error("No rulenr for -I" ++ " specified"); + rule_nr = strtol(argv[optind], &buffer, 10); + if (*buffer != '\0' || rule_nr < 0) +- print_error("Problem with the specified rule number."); ++ print_error("Problem with the specified" ++ " rule number"); + optind++; + } + break; +@@ -1104,24 +1184,29 @@ + case 'Z': // zero counters + if (c == 'Z') { + if (replace.flags & OPT_ZERO) +- print_error("Multiple commands not allowed."); +- if ( (replace.flags & OPT_COMMAND && replace.command != 'L')) +- print_error("command -Z only allowed together with command -L."); ++ print_error("Multiple commands" ++ " not allowed"); ++ if ( (replace.flags & OPT_COMMAND && ++ replace.command != 'L')) ++ print_error("command -Z only allowed " ++ "together with command -L"); + replace.flags |= OPT_ZERO; + } else { + replace.command = c; + if (replace.flags & OPT_COMMAND) +- print_error("Multiple commands not allowed."); ++ print_error("Multiple commands" ++ " not allowed"); + replace.flags |= OPT_COMMAND; + } + i = -1; + if (optarg) { + if ( (i = get_hooknr(optarg)) == -1 ) +- print_error("Bad chain."); ++ print_error("Bad chain"); + } else + if (optind < argc && argv[optind][0] != '-') { +- if ( (i = get_hooknr(argv[optind])) == -1 ) +- print_error("Bad chain."); ++ if ((i = get_hooknr(argv[optind])) ++ == -1) ++ print_error("Bad chain"); + optind++; + } + if (i != -1) { +@@ -1135,47 +1220,34 @@ + case 'V': // version + replace.command = 'V'; + if (replace.flags & OPT_COMMAND) +- print_error("Multiple commands not allowed."); ++ print_error("Multiple commands not allowed"); + printf("%s, %s\n", prog_name, prog_version); + exit(0); + + case 'h': // help + if (replace.flags & OPT_COMMAND) +- print_error("Multiple commands not allowed."); ++ print_error("Multiple commands not allowed"); + replace.command = 'h'; + // All other arguments should be extension names + while (optind < argc) { + struct ebt_u_match *m; + struct ebt_u_watcher *w; + +- if ((m = find_match(argv[optind]))) { +- struct ebt_u_match_list **m_list, *new; +- +- m->used = 1; +- for (m_list = &new_entry->m_list; *m_list; m_list = &(*m_list)->next); +- new = (struct ebt_u_match_list *)malloc(sizeof(struct ebt_u_match_list)); +- if (!new) +- print_memory(); +- *m_list = new; +- new->next = NULL; +- new->m = (struct ebt_entry_match *)m; +- } else if ((w = find_watcher(argv[optind]))) { +- struct ebt_u_watcher_list **w_list, *new; +- w->used = 1; +- for (w_list = &new_entry->w_list; *w_list; w_list = &(*w_list)->next); +- new = (struct ebt_u_watcher_list *)malloc(sizeof(struct ebt_u_watcher_list)); +- if (!new) +- print_memory(); +- *w_list = new; +- new->next = NULL; +- new->w = (struct ebt_entry_watcher *)w; +- } else { ++ if ((m = find_match(argv[optind]))) ++ add_match(m); ++ else if ((w = find_watcher(argv[optind]))) ++ add_watcher(w); ++ else { + if (!(t = find_target(argv[optind]))) +- print_error("Extension %s not found.", argv[optind]); ++ print_error("Extension %s " ++ "not found", argv[optind]); + if (replace.flags & OPT_JUMP) +- print_error("Sorry, you can only see help for one target extension each time."); ++ print_error("Sorry, you can " ++ "only see help for one " ++ "target extension each time"); + replace.flags |= OPT_JUMP; +- new_entry->t = (struct ebt_entry_target *)t; ++ new_entry->t = ++ (struct ebt_entry_target *)t; + } + optind++; + } +@@ -1184,7 +1256,7 @@ + case 't': // table + check_option(&replace.flags, OPT_TABLE); + if (strlen(optarg) > EBT_TABLE_MAXNAMELEN) +- print_error("Table name too long."); ++ print_error("Table name too long"); + strcpy(replace.name, optarg); + break; + +@@ -1195,56 +1267,69 @@ + case 's': // source mac + case 'd': // destination mac + if ((replace.flags & OPT_COMMAND) == 0) +- print_error("No command specified."); +- if ( replace.command != 'A' && replace.command != 'D' && replace.command != 'I') +- print_error("Command and option do not match."); ++ print_error("No command specified"); ++ if ( replace.command != 'A' && ++ replace.command != 'D' && replace.command != 'I') ++ print_error("Command and option do not match"); + if (c == 'i') { + check_option(&replace.flags, OPT_IN); +- if (replace.selected_hook == 2) +- print_error("Use in-interface only in INPUT, FORWARD and PREROUTING chains."); ++ if (replace.selected_hook > 2) ++ print_error("Use in-interface only in " ++ "INPUT, FORWARD and PREROUTING chains"); + if (check_inverse(optarg)) + new_entry->invflags |= EBT_IIN; + + if (optind > argc) +- print_error("Missing interface argument."); ++ print_error("No in-interface " ++ "specified"); + if (strlen(argv[optind - 1]) >= IFNAMSIZ) +- print_error("Illegal interfacelength."); +- strncpy(new_entry->in, argv[optind - 1], IFNAMSIZ); ++ print_error("Illegal interfacelength"); ++ strcpy(new_entry->in, argv[optind - 1]); + break; + } + if (c == 'o') { + check_option(&replace.flags, OPT_OUT); +- if (replace.selected_hook == 0) +- print_error("Use out-interface only in OUTPUT, FORWARD and POSTROUTING chains."); ++ if (replace.selected_hook < 2) ++ print_error("Use out-interface only" ++ " in OUTPUT, FORWARD and " ++ "POSTROUTING chains"); + if (check_inverse(optarg)) + new_entry->invflags |= EBT_IOUT; + + if (optind > argc) +- print_error("Missing interface argument."); ++ print_error("No out-interface " ++ "specified"); ++ + if (strlen(argv[optind - 1]) >= IFNAMSIZ) +- print_error("Illegal interface length."); +- strncpy(new_entry->out, argv[optind - 1], IFNAMSIZ); ++ print_error("Illegal interface " ++ "length"); ++ strcpy(new_entry->out, argv[optind - 1]); + break; + } + if (c == 'j') { + + check_option(&replace.flags, OPT_JUMP); + for (i = 0; i < NUM_STANDARD_TARGETS; i++) +- if (!strcmp(optarg, standard_targets[i])) { +- t = find_target(EBT_STANDARD_TARGET); +- ((struct ebt_standard_target *)t->t)->verdict = i; ++ if (!strcmp(optarg, ++ standard_targets[i])) { ++ t = find_target( ++ EBT_STANDARD_TARGET); ++ ((struct ebt_standard_target *) ++ t->t)->verdict = i; + break; + } + // must be an extension then + if (i == NUM_STANDARD_TARGETS) { + struct ebt_u_target *t; + t = find_target(optarg); +- if (!t) +- print_error("Illegal target name."); +- new_entry->t = (struct ebt_entry_target *)t; +- } else +- ((struct ebt_standard_target *)(((struct ebt_u_target *)new_entry->t)->t))->verdict = i; +- ++ // -j standard not allowed either ++ if (!t || t == ++ (struct ebt_u_target *)new_entry->t) ++ print_error("Illegal target " ++ "name"); ++ new_entry->t = ++ (struct ebt_entry_target *)t; ++ } + break; + } + if (c == 's') { +@@ -1253,9 +1338,12 @@ + new_entry->invflags |= EBT_ISOURCE; + + if (optind > argc) +- print_error("Missing source mac argument."); +- if (getmac(argv[optind - 1], new_entry->sourcemac)) +- print_error("Problem with specified source mac."); ++ print_error("No source mac " ++ "specified"); ++ if (getmac(argv[optind - 1], ++ new_entry->sourcemac)) ++ print_error("Problem with specified " ++ "source mac"); + new_entry->bitmask |= EBT_SOURCEMAC; + break; + } +@@ -1265,9 +1353,12 @@ + new_entry->invflags |= EBT_IDEST; + + if (optind > argc) +- print_error("Missing destination mac argument."); +- if (getmac(argv[optind - 1], new_entry->destmac)) +- print_error("Problem with specified destination mac."); ++ print_error("No destination mac " ++ "specified"); ++ if (getmac(argv[optind - 1], ++ new_entry->destmac)) ++ print_error("Problem with specified " ++ "destination mac"); + new_entry->bitmask |= EBT_DESTMAC; + break; + } +@@ -1276,22 +1367,26 @@ + new_entry->invflags |= EBT_IPROTO; + + if (optind > argc) +- print_error("Missing protocol argument."); ++ print_error("No protocol specified"); + new_entry->bitmask &= ~((unsigned int)EBT_NOPROTO); + i = strtol(argv[optind - 1], &buffer, 16); + if (*buffer == '\0' && (i < 0 || i > 0xFFFF)) +- print_error("Problem with the specified protocol."); ++ print_error("Problem with the specified " ++ "protocol"); + new_entry->ethproto = i; + if (*buffer != '\0') + if (name_to_protocol(argv[optind - 1]) == -1) +- print_error("Problem with the specified protocol."); +- if (new_entry->ethproto < 1536 && !(new_entry->bitmask & EBT_802_3)) +- print_error("Sorry, protocols have values above or equal to 1536 (0x0600)."); ++ print_error("Problem with the specified" ++ " protocol"); ++ if (new_entry->ethproto < 1536 && ++ !(new_entry->bitmask & EBT_802_3)) ++ print_error("Sorry, protocols have values above" ++ " or equal to 1536 (0x0600)"); + break; + + case 'b': // allow database? + if (replace.flags & OPT_COMMAND) +- print_error("Multiple commands not allowed."); ++ print_error("Multiple commands not allowed"); + replace.command = c; + allowbc = *optarg; + break; +@@ -1300,49 +1395,32 @@ + + // is it a target option? + t = (struct ebt_u_target *)new_entry->t; +- if (!(t->parse(c - t->option_offset, argv, argc, new_entry, &t->flags, &t->t))) { +- struct ebt_u_match *m; +- +- // is it a match_option? +- for (m = matches; m; m = m->next) +- if (m->parse(c - m->option_offset, argv, argc, new_entry, &m->flags, &m->m)) +- break; ++ if ((t->parse(c - t->option_offset, argv, argc, ++ new_entry, &t->flags, &t->t))) ++ continue; + +- if (m == NULL) { +- struct ebt_u_watcher *w; ++ // is it a match_option? ++ for (m = matches; m; m = m->next) ++ if (m->parse(c - m->option_offset, argv, ++ argc, new_entry, &m->flags, &m->m)) ++ break; + +- // is it a watcher option? +- for (w = watchers; w; w = w->next) +- if (w->parse(c - w->option_offset, argv, argc, new_entry, &w->flags, &w->w)) +- break; +- +- if (w == NULL) +- print_error("Unknown argument."); +- if (w->used == 0) { +- struct ebt_u_watcher_list **w_list, *new; +- w->used = 1; +- for (w_list = &new_entry->w_list; *w_list; w_list = &(*w_list)->next); +- new = (struct ebt_u_watcher_list *)malloc(sizeof(struct ebt_u_watcher_list)); +- if (!new) +- print_memory(); +- *w_list = new; +- new->next = NULL; +- new->w = (struct ebt_entry_watcher *)w; +- } +- } else { +- if (m->used == 0) { +- struct ebt_u_match_list **m_list, *new; +- m->used = 1; +- for (m_list = &new_entry->m_list; *m_list; m_list = &(*m_list)->next); +- new = (struct ebt_u_match_list *)malloc(sizeof(struct ebt_u_match_list)); +- if (!new) +- print_memory(); +- *m_list = new; +- new->next = NULL; +- new->m = (struct ebt_entry_match *)m; +- } +- } ++ if (m != NULL) { ++ if (m->used == 0) ++ add_match(m); ++ continue; + } ++ ++ // is it a watcher option? ++ for (w = watchers; w; w = w->next) ++ if (w->parse(c-w->option_offset, argv, ++ argc, new_entry, &w->flags, &w->w)) ++ break; ++ ++ if (w == NULL) ++ print_error("Unknown argument"); ++ if (w->used == 0) ++ add_watcher(w); + } + } + +@@ -1352,43 +1430,40 @@ + if (replace.command == 'L' && replace.selected_hook == DATABASEHOOKNR) + list_db(); + +- if ( (replace.flags & OPT_COMMAND) && replace.command != 'L' && replace.flags & OPT_ZERO ) +- print_error("Command -Z only allowed together with command -L."); ++ if ( (replace.flags & OPT_COMMAND) && replace.command != 'L' && ++ replace.flags & OPT_ZERO ) ++ print_error("Command -Z only allowed together with command -L"); + +- if (replace.command == 'A' || replace.command == 'I' || replace.command == 'D') { ++ if (replace.command == 'A' || replace.command == 'I' || ++ replace.command == 'D') { + if (replace.selected_hook == -1) +- print_error("Not enough information."); ++ print_error("Not enough information"); + } + + if ( !(table = find_table(replace.name)) ) +- print_error("Bad table name."); ++ print_error("Bad table name"); + + // do this after parsing everything, so we can print specific info + if (replace.command == 'h' && !(replace.flags & OPT_ZERO)) + print_help(); + + // do the final checks +- { +- struct ebt_u_match_list *m_l = new_entry->m_list; +- struct ebt_u_match *m; +- struct ebt_u_watcher_list *w_l = new_entry->w_list; +- struct ebt_u_watcher *w; +- struct ebt_u_target *t = (struct ebt_u_target *)new_entry->t; +- ++ m_l = new_entry->m_list; ++ w_l = new_entry->w_list; ++ t = (struct ebt_u_target *)new_entry->t; + while (m_l) { + m = (struct ebt_u_match *)(m_l->m); +- m->final_check(new_entry, m->m, replace.name, replace.selected_hook); ++ m->final_check(new_entry, m->m, replace.name, ++ replace.selected_hook); + m_l = m_l->next; + } +- + while (w_l) { + w = (struct ebt_u_watcher *)(w_l->w); +- w->final_check(new_entry, w->w, replace.name, replace.selected_hook); ++ w->final_check(new_entry, w->w, replace.name, ++ replace.selected_hook); + w_l = w_l->next; + } +- + t->final_check(new_entry, t->t, replace.name, replace.selected_hook); +- } + + // so, the extensions can work with the host endian + // the kernel does not have to do this ofcourse +@@ -1396,10 +1471,10 @@ + + // get the kernel's information + get_table(&replace); +- replace.nentries = replace.nentries; + // check if selected_hook is a valid_hook +- if (replace.selected_hook >= 0 && !(replace.valid_hooks & (1 << replace.selected_hook))) +- print_error("Bad chain name."); ++ if (replace.selected_hook >= 0 && ++ !(replace.valid_hooks & (1 << replace.selected_hook))) ++ print_error("Bad chain name"); + if (replace.command == 'P') + change_policy(policy); + else if (replace.command == 'L') { +--- ebtables-v2.0pre2.001/communication.c Wed Apr 3 17:22:39 2002 ++++ ebtables-v2.0pre2.002/communication.c Wed Apr 10 22:10:49 2002 +@@ -25,12 +25,6 @@ + + extern char* hooknames[NF_BR_NUMHOOKS]; + +-void print_memory() +-{ +- printf("Out of memory\n"); +- exit(0); +-} +- + int sockfd = -1; + + void get_sockfd() +@@ -38,7 +32,7 @@ + if (sockfd == -1) { + sockfd = socket(AF_INET, SOCK_RAW, PF_INET); + if (sockfd < 0) +- print_error("Problem getting a socket."); ++ print_error("Problem getting a socket"); + } + } + +@@ -60,7 +54,8 @@ + new->nentries = u_repl->nentries; + new->num_counters = u_repl->num_counters; + new->counters = u_repl->counters; +- memcpy(new->counter_entry, u_repl->counter_entry, sizeof(new->counter_entry)); ++ memcpy(new->counter_entry, u_repl->counter_entry, ++ sizeof(new->counter_entry)); + // determine size + for (i = 0; i < NF_BR_NUMHOOKS; i++) { + if (!(new->valid_hooks & (1 << i))) +@@ -86,7 +81,8 @@ + } + // a little sanity check + if (j != u_repl->hook_entry[i]->nentries) +- print_bug("Wrong nentries: %d != %d, hook = %s", j, u_repl->hook_entry[i]->nentries, hooknames[i]); ++ print_bug("Wrong nentries: %d != %d, hook = %s", j, ++ u_repl->hook_entry[i]->nentries, hooknames[i]); + } + + new->entries_size = entries_size; +@@ -116,7 +112,8 @@ + tmp->ethproto = e->ethproto; + memcpy(tmp->in, e->in, sizeof(tmp->in)); + memcpy(tmp->out, e->out, sizeof(tmp->out)); +- memcpy(tmp->sourcemac, e->sourcemac, sizeof(tmp->sourcemac)); ++ memcpy(tmp->sourcemac, e->sourcemac, ++ sizeof(tmp->sourcemac)); + memcpy(tmp->destmac, e->destmac, sizeof(tmp->destmac)); + + base = p; +@@ -159,11 +156,13 @@ + // give the data to the kernel + optlen = sizeof(struct ebt_replace) + repl->entries_size; + if (setsockopt(sockfd, IPPROTO_IP, EBT_SO_SET_ENTRIES, repl, optlen)) +- print_error("Couldn't update kernel chains, you probably need to insmod an extension."); ++ print_error("Couldn't update kernel chains, you probably need " ++ "to insmod an extension"); + } + + // gets executed after deliver_table +-void deliver_counters(struct ebt_u_replace *u_repl, unsigned short *counterchanges) ++void ++deliver_counters(struct ebt_u_replace *u_repl, unsigned short *counterchanges) + { + unsigned short *point; + struct ebt_counter *old, *new, *newcounters; +@@ -173,7 +172,8 @@ + if (u_repl->nentries == 0) + return; + +- newcounters = (struct ebt_counter *)malloc(u_repl->nentries * sizeof(struct ebt_counter)); ++ newcounters = (struct ebt_counter *) ++ malloc(u_repl->nentries * sizeof(struct ebt_counter)); + if (!newcounters) + print_memory(); + memset(newcounters, 0, u_repl->nentries * sizeof(struct ebt_counter)); +@@ -208,7 +208,8 @@ + free(u_repl->counters); + u_repl->counters = newcounters; + u_repl->num_counters = u_repl->nentries; +- optlen = u_repl->nentries * sizeof(struct ebt_counter) + sizeof(struct ebt_replace); ++ optlen = u_repl->nentries * sizeof(struct ebt_counter) + ++ sizeof(struct ebt_replace); + // now put the stuff in the kernel's struct ebt_replace + repl.counters = u_repl->counters; + repl.num_counters = u_repl->num_counters; +@@ -224,7 +225,8 @@ + { + struct ebt_u_match_list *new; + +- new = (struct ebt_u_match_list *)malloc(sizeof(struct ebt_u_match_list)); ++ new = (struct ebt_u_match_list *) ++ malloc(sizeof(struct ebt_u_match_list)); + if (!new) + print_memory(); + new->m = (struct ebt_entry_match *)malloc(m->match_size); +@@ -235,12 +237,14 @@ + **l = new; + *l = &new->next; + if (find_match(new->m->u.name) == NULL) +- print_error("Kernel match %s unsupported by userspace tool.", new->m->u.name); ++ print_error("Kernel match %s unsupported by userspace tool", ++ new->m->u.name); + return 0; + } + + static int +-ebt_translate_watcher(struct ebt_entry_watcher *w, struct ebt_u_watcher_list ***l) ++ebt_translate_watcher(struct ebt_entry_watcher *w, ++ struct ebt_u_watcher_list ***l) + { + struct ebt_u_watcher_list *new; + +@@ -255,13 +259,15 @@ + **l = new; + *l = &new->next; + if (find_watcher(new->w->u.name) == NULL) +- print_error("Kernel watcher %s unsupported by userspace tool.", new->w->u.name); ++ print_error("Kernel watcher %s unsupported by userspace tool", ++ new->w->u.name); + return 0; + } + + static int +-ebt_translate_entry(struct ebt_entry *e, unsigned int *hook, int *n, int *cnt, int *totalcnt, +- struct ebt_u_entry ***u_e, struct ebt_u_replace *u_repl, unsigned int valid_hooks) ++ebt_translate_entry(struct ebt_entry *e, unsigned int *hook, int *n, int *cnt, ++ int *totalcnt, struct ebt_u_entry ***u_e, struct ebt_u_replace *u_repl, ++ unsigned int valid_hooks) + { + // an entry + if (e->bitmask & EBT_ENTRY_OR_ENTRIES) { +@@ -295,7 +301,8 @@ + if (!new->t) + print_memory(); + if (find_target(t->u.name) == NULL) +- print_error("Kernel target %s unsupported by userspace tool.", t->u.name); ++ print_error("Kernel target %s unsupported by " ++ "userspace tool", t->u.name); + memcpy(new->t, t, t->target_size); + + // I love pointers +@@ -304,7 +311,7 @@ + (*cnt)++; + (*totalcnt)++; + return 0; +- } else {// a new chain ++ } else { // a new chain + int i; + struct ebt_entries *entries = (struct ebt_entries *)e; + struct ebt_u_entries *new; +@@ -319,7 +326,8 @@ + print_bug("Nr of entries in the chain is wrong"); + *n = entries->nentries; + *cnt = 0; +- new = (struct ebt_u_entries *)malloc(sizeof(struct ebt_u_entries)); ++ new = (struct ebt_u_entries *) ++ malloc(sizeof(struct ebt_u_entries)); + if (!new) + print_memory(); + new->nentries = entries->nentries; +@@ -344,12 +352,14 @@ + optlen = sizeof(struct ebt_replace); + strcpy(repl.name, u_repl->name); + if (getsockopt(sockfd, IPPROTO_IP, EBT_SO_GET_INFO, &repl, &optlen)) +- print_bug("hmm, what is wrong??? bug#3"); ++ print_error("A kernel module needed by your command is probably" ++ " not loaded. Try insmod ebtables or the like"); + + if ( !(repl.entries = (char *) malloc(repl.entries_size)) ) + print_memory(); + if (repl.nentries) { +- if (!(repl.counters = (struct ebt_counter *) malloc(repl.nentries * sizeof(struct ebt_counter))) ) ++ if (!(repl.counters = (struct ebt_counter *) ++ malloc(repl.nentries * sizeof(struct ebt_counter))) ) + print_memory(); + } + else +@@ -357,7 +367,8 @@ + + // we want to receive the counters + repl.num_counters = repl.nentries; +- optlen += repl.entries_size + repl.num_counters * sizeof(struct ebt_counter); ++ optlen += repl.entries_size + repl.num_counters * ++ sizeof(struct ebt_counter); + if (getsockopt(sockfd, IPPROTO_IP, EBT_SO_GET_ENTRIES, &repl, &optlen)) + print_bug("hmm, what is wrong??? bug#1"); + +@@ -367,12 +378,15 @@ + u_repl->nentries = repl.nentries; + u_repl->num_counters = repl.num_counters; + u_repl->counters = repl.counters; +- memcpy(u_repl->counter_entry, repl.counter_entry, sizeof(repl.counter_entry)); ++ memcpy(u_repl->counter_entry, repl.counter_entry, ++ sizeof(repl.counter_entry)); + hook = -1; + i = 0; // holds the expected nr. of entries for the chain + j = 0; // holds the up to now counted entries for the chain +- k = 0; // holds the total nr. of entries, should equal u_repl->nentries afterwards +- EBT_ENTRY_ITERATE(repl.entries, repl.entries_size, ebt_translate_entry, &hook, &i, &j, &k, &u_e, u_repl, u_repl->valid_hooks); ++ k = 0; // holds the total nr. of entries, ++ // should equal u_repl->nentries afterwards ++ EBT_ENTRY_ITERATE(repl.entries, repl.entries_size, ebt_translate_entry, ++ &hook, &i, &j, &k, &u_e, u_repl, u_repl->valid_hooks); + if (k != u_repl->nentries) + print_bug("Wrong total nentries"); + } +@@ -384,7 +398,8 @@ + get_sockfd(); + + if (getsockopt(sockfd, IPPROTO_IP, BRDB_SO_GET_DBINFO, nr, &optlen)) +- print_error("Sorry, br_db code probably not in kernel, try insmod br_db."); ++ print_error("Sorry, br_db code probably not in kernel, " ++ "try insmod br_db"); + } + + void get_db(int len, struct brdb_dbentry *db) +@@ -405,5 +420,6 @@ + get_sockfd(); + + if (setsockopt(sockfd, IPPROTO_IP, BRDB_SO_SET_ALLOWDB, decision, optlen)) +- print_error("Sorry, br_db code probably not in kernel, try insmod br_db."); ++ print_error("Sorry, br_db code probably not in kernel, " ++ "try insmod br_db"); + } +--- ebtables-v2.0pre2.001/extensions/ebt_nat.c Thu Apr 11 18:27:45 2002 ++++ ebtables-v2.0pre2.002/extensions/ebt_nat.c Thu Apr 11 18:12:55 2002 +@@ -52,8 +52,9 @@ + } + + #define OPT_SNAT 0x01 +-static int parse_s(int c, char **argv, int argc, const struct ebt_u_entry *entry, unsigned int *flags, +- struct ebt_entry_target **target) ++static int parse_s(int c, char **argv, int argc, ++ const struct ebt_u_entry *entry, unsigned int *flags, ++ struct ebt_entry_target **target) + { + struct ebt_nat_info *natinfo = (struct ebt_nat_info *)(*target)->data; + +@@ -62,7 +63,7 @@ + check_option(flags, OPT_SNAT); + to_source_supplied = 1; + if (getmac(optarg, natinfo->mac)) +- print_error("Problem with specified to-source mac."); ++ print_error("Problem with specified to-source mac"); + break; + default: + return 0; +@@ -71,8 +72,9 @@ + } + + #define OPT_DNAT 0x01 +-static int parse_d(int c, char **argv, int argc, const struct ebt_u_entry *entry, unsigned int *flags, +- struct ebt_entry_target **target) ++static int parse_d(int c, char **argv, int argc, ++ const struct ebt_u_entry *entry, unsigned int *flags, ++ struct ebt_entry_target **target) + { + struct ebt_nat_info *natinfo = (struct ebt_nat_info *)(*target)->data; + +@@ -81,7 +83,8 @@ + check_option(flags, OPT_DNAT); + to_dest_supplied = 1; + if (getmac(optarg, natinfo->mac)) +- print_error("Problem with specified to-destination mac."); ++ print_error("Problem with specified " ++ "to-destination mac"); + break; + default: + return 0; +@@ -89,44 +92,52 @@ + return 1; + } + +-static void final_check_s(const struct ebt_u_entry *entry, const struct ebt_entry_target *target, const char *name, unsigned int hook) ++static void final_check_s(const struct ebt_u_entry *entry, ++ 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."); ++ 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) ++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") ) ++ print_error("Wrong chain for DNAT"); + if (to_dest_supplied == 0) +- print_error("No dnat address supplied."); ++ print_error("No dnat address supplied"); + } + +-static void print_s(const struct ebt_u_entry *entry, const struct ebt_entry_target *target) ++static void print_s(const struct ebt_u_entry *entry, ++ const struct ebt_entry_target *target) + { + struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data; + int i; + + printf("snat - to: "); + for (i = 0; i < ETH_ALEN; i++) +- printf("%02x%s", natinfo->mac[i], (i == ETH_ALEN - 1) ? "" : ":"); ++ printf("%02x%s", ++ natinfo->mac[i], (i == ETH_ALEN - 1) ? "" : ":"); + } + +-static void print_d(const struct ebt_u_entry *entry, const struct ebt_entry_target *target) ++static void print_d(const struct ebt_u_entry *entry, ++ const struct ebt_entry_target *target) + { + struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data; + int i; + + printf("dnat - to: "); + for (i = 0; i < ETH_ALEN; i++) +- printf("%02x%s", natinfo->mac[i], (i == ETH_ALEN - 1) ? "" : ":"); ++ printf("%02x%s", ++ natinfo->mac[i], (i == ETH_ALEN - 1) ? "" : ":"); + } + +-static int compare(const struct ebt_entry_target *t1, const struct ebt_entry_target *t2) ++static int compare(const struct ebt_entry_target *t1, ++ const struct ebt_entry_target *t2) + { + struct ebt_nat_info *natinfo1 = (struct ebt_nat_info *)t1->data; + struct ebt_nat_info *natinfo2 = (struct ebt_nat_info *)t2->data; +--- ebtables-v2.0pre2.001/extensions/ebt_ip.c Thu Apr 11 18:27:45 2002 ++++ ebtables-v2.0pre2.002/extensions/ebt_ip.c Wed Apr 10 23:28:40 2002 +@@ -40,16 +40,16 @@ + return -1; + *q = '\0'; + onebyte = strtol(p, &end, 10); +- if (*end != '\0' || onebyte >255 || onebyte < 0) ++ if (*end != '\0' || onebyte > 255 || onebyte < 0) + return -1; +- ip2[i] = (unsigned char) onebyte; ++ ip2[i] = (unsigned char)onebyte; + p = q + 1; + } + + onebyte = strtol(p, &end, 10); + if (*end != '\0' || onebyte >255 || onebyte < 0) + return -1; +- ip2[3] = (unsigned char) onebyte; ++ ip2[3] = (unsigned char)onebyte; + + return 0; + } +@@ -88,15 +88,15 @@ + *p = '\0'; + i = ip_mask(p + 1, (unsigned char *)msk); + if (i) +- print_error("Problem with the ip mask."); ++ print_error("Problem with the ip mask"); + } + else + *msk = 0xFFFFFFFF; + + i = undot_ip(address, (unsigned char *)addr); +- *addr = *addr & *msk; + if (i) +- print_error("Problem with the ip address."); ++ print_error("Problem with the ip address"); ++ *addr = *addr & *msk; + } + + // transform the ip mask into a string ready for output +@@ -106,7 +106,6 @@ + static char buf[20]; + __u32 maskaddr, bits; + +- // cool hack I copied from iptables.c ... Think about it :-) + maskaddr = ntohl(mask); + + // don't print /32 +@@ -114,7 +113,7 @@ + return ""; + + i = 32; +- bits = 0xFFFFFFFEL;// case 0xFFFFFFFF has just been dealt with ++ bits = 0xFFFFFFFEL; // case 0xFFFFFFFF has just been dealt with + while (--i >= 0 && maskaddr != bits) + bits <<= 1; + +@@ -123,9 +122,10 @@ + else if (!i) + *buf = '\0'; + else +- /* mask was not a decent combination of 1's and 0's */ +- sprintf(buf, "/%d.%d.%d.%d", ((unsigned char *)&mask)[0], ((unsigned char *)&mask)[1], +- ((unsigned char *)&mask)[2], ((unsigned char *)&mask)[3]); ++ // mask was not a decent combination of 1's and 0's ++ sprintf(buf, "/%d.%d.%d.%d", ((unsigned char *)&mask)[0], ++ ((unsigned char *)&mask)[1], ((unsigned char *)&mask)[2], ++ ((unsigned char *)&mask)[3]); + + return buf; + } +@@ -133,11 +133,11 @@ + static void print_help() + { + printf( +- "ip options:\n" +- "--ip-src [!] address[/mask]: ip source specification\n" +- "--ip-dst [!] address[/mask]: ip destination specification\n" +- "--ip-tos [!] tos : ip tos specification\n" +- "--ip-proto [!] protocol : ip protocol specification\n"); ++"ip options:\n" ++"--ip-src [!] address[/mask]: ip source specification\n" ++"--ip-dst [!] address[/mask]: ip destination specification\n" ++"--ip-tos [!] tos : ip tos specification\n" ++"--ip-proto [!] protocol : ip protocol specification\n"); + } + + static void init(struct ebt_entry_match *match) +@@ -152,9 +152,8 @@ + #define OPT_DEST 0x02 + #define OPT_TOS 0x04 + #define OPT_PROTO 0x08 +-static int parse(int c, char **argv, int argc, +- const struct ebt_u_entry *entry, unsigned int *flags, +- struct ebt_entry_match **match) ++static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, ++ unsigned int *flags, struct ebt_entry_match **match) + { + struct ebt_ip_info *ipinfo = (struct ebt_ip_info *)(*match)->data; + char *end, *buffer; +@@ -163,13 +162,13 @@ + switch (c) { + case IP_SOURCE: + check_option(flags, OPT_SOURCE); ++ ipinfo->bitmask |= EBT_IP_SOURCE; ++ + case IP_DEST: +- if (c == IP_DEST) ++ if (c == IP_DEST) { + check_option(flags, OPT_DEST); +- if (c == IP_SOURCE) +- ipinfo->bitmask |= EBT_IP_SOURCE; +- else + ipinfo->bitmask |= EBT_IP_DEST; ++ } + if (check_inverse(optarg)) { + if (c == IP_SOURCE) + ipinfo->invflags |= EBT_IP_SOURCE; +@@ -178,34 +177,38 @@ + } + + if (optind > argc) +- print_error("Missing ip address argument."); ++ print_error("Missing ip address argument"); + if (c == IP_SOURCE) +- parse_ip_address(argv[optind - 1], &ipinfo->saddr, &ipinfo->smsk); ++ parse_ip_address(argv[optind - 1], &ipinfo->saddr, ++ &ipinfo->smsk); + else +- parse_ip_address(argv[optind - 1], &ipinfo->daddr, &ipinfo->dmsk); ++ parse_ip_address(argv[optind - 1], &ipinfo->daddr, ++ &ipinfo->dmsk); + break; ++ + case IP_myTOS: + check_option(flags, OPT_TOS); + if (check_inverse(optarg)) + ipinfo->invflags |= EBT_IP_TOS; + + if (optind > argc) +- print_error("Missing ip tos argument."); ++ print_error("Missing ip tos argument"); + i = strtol(argv[optind - 1], &end, 16); + if (i < 0 || i > 255 || *buffer != '\0') +- print_error("Problem with specified ip tos."); ++ print_error("Problem with specified ip tos"); + ipinfo->tos = i; + ipinfo->bitmask |= EBT_IP_TOS; + break; ++ + case IP_PROTO: + check_option(flags, OPT_PROTO); + if (check_inverse(optarg)) + ipinfo->invflags |= EBT_IP_PROTO; + if (optind > argc) +- print_error("Missing ip protocol argument."); ++ print_error("Missing ip protocol argument"); + i = strtol(argv[optind - 1], &end, 10); + if (i < 0 || i > 255 || *end != '\0') +- print_error("Problem with specified ip protocol."); ++ print_error("Problem with specified ip protocol"); + ipinfo->protocol = i; + ipinfo->bitmask |= EBT_IP_PROTO; + break; +@@ -215,13 +218,17 @@ + return 1; + } + +-static void final_check(const struct ebt_u_entry *entry, const struct ebt_entry_match *match, const char *name, unsigned int hook) ++static void final_check(const struct ebt_u_entry *entry, ++ const struct ebt_entry_match *match, const char *name, unsigned int hook) + { +- if (entry->bitmask & EBT_NOPROTO || entry->bitmask & EBT_802_3 || entry->ethproto != ETH_P_IP) +- print_error("For IP filtering the protocol must be specified as IPV4."); ++ if (entry->bitmask & EBT_NOPROTO || entry->bitmask & EBT_802_3 || ++ entry->ethproto != ETH_P_IP) ++ print_error("For IP filtering the protocol must be " ++ "specified as IPv4"); + } + +-static void print(const struct ebt_u_entry *entry, const struct ebt_entry_match *match) ++static void print(const struct ebt_u_entry *entry, ++ const struct ebt_entry_match *match) + { + struct ebt_ip_info *ipinfo = (struct ebt_ip_info *)match->data; + int j; +@@ -231,7 +238,8 @@ + if (ipinfo->invflags & EBT_IP_SOURCE) + printf("! "); + for (j = 0; j < 4; j++) +- printf("%d%s", ((unsigned char *)&ipinfo->saddr)[j], (j == 3) ? "" : "."); ++ printf("%d%s",((unsigned char *)&ipinfo->saddr)[j], ++ (j == 3) ? "" : "."); + printf("%s, ", mask_to_dotted(ipinfo->smsk)); + } + if (ipinfo->bitmask & EBT_IP_DEST) { +@@ -239,7 +247,8 @@ + if (ipinfo->invflags & EBT_IP_DEST) + printf("! "); + for (j = 0; j < 4; j++) +- printf("%d%s", ((unsigned char *)&ipinfo->daddr)[j], (j == 3) ? "" : "."); ++ printf("%d%s", ((unsigned char *)&ipinfo->daddr)[j], ++ (j == 3) ? "" : "."); + printf("%s, ", mask_to_dotted(ipinfo->dmsk)); + } + if (ipinfo->bitmask & EBT_IP_TOS) { +@@ -256,7 +265,8 @@ + } + } + +-static int compare(const struct ebt_entry_match *m1, const struct ebt_entry_match *m2) ++static int compare(const struct ebt_entry_match *m1, ++ const struct ebt_entry_match *m2) + { + struct ebt_ip_info *ipinfo1 = (struct ebt_ip_info *)m1->data; + struct ebt_ip_info *ipinfo2 = (struct ebt_ip_info *)m2->data; +--- ebtables-v2.0pre2.001/extensions/ebt_arp.c Thu Apr 11 18:27:45 2002 ++++ ebtables-v2.0pre2.002/extensions/ebt_arp.c Wed Apr 10 23:05:29 2002 +@@ -44,20 +44,20 @@ + int i = 0; + + printf( +- "arp options:\n" +- "--arp-opcode opcode : ARP opcode (integer or string)\n" +- "--arp-htype type : ARP hardware type (integer or string)\n" +- "--arp-ptype type : ARP protocol type (hexadecimal or string)\n" +- "--arp-ip-src [!] address[/mask]: ARP ip source specification\n" +- "--arp-ip-dst [!] address[/mask]: ARP ip target specification\n" +- " opcode strings: \n"); ++"arp options:\n" ++"--arp-opcode opcode : ARP opcode (integer or string)\n" ++"--arp-htype type : ARP hardware type (integer or string)\n" ++"--arp-ptype type : ARP protocol type (hexadecimal or string)\n" ++"--arp-ip-src [!] address[/mask]: ARP ip source specification\n" ++"--arp-ip-dst [!] address[/mask]: ARP ip target specification\n" ++" opcode strings: \n"); + while (strcmp(opcodes[i], "")) { + printf("%d = %s\n", i + 1, opcodes[i]); + i++; + } + printf( +- " hardware type string: \n 1 = Ethernet\n" +- " protocol type string: \n 0x0800 = IPv4\n"); ++" hardware type string: \n 1 = Ethernet\n" ++" protocol type string: \n 0x0800 = IPv4\n"); + } + + static void init(struct ebt_entry_match *match) +@@ -68,7 +68,8 @@ + arpinfo->bitmask = 0; + } + +-void parse_ip_address(char *address, __u32 *addr, __u32 *msk); // defined in ebt_ip.c ++// defined in ebt_ip.c ++void parse_ip_address(char *address, __u32 *addr, __u32 *msk); + + #define OPT_OPCODE 0x01 + #define OPT_HTYPE 0x02 +@@ -87,15 +88,14 @@ + + switch (c) { + case ARP_OPCODE: +- + check_option(flags, OPT_OPCODE); + if (check_inverse(optarg)) + arpinfo->invflags |= EBT_ARP_OPCODE; + + if (optind > argc) +- print_error("Missing arp opcode argument."); ++ print_error("Missing arp opcode argument"); + i = strtol(argv[optind - 1], &end, 10); +- if (i < 0 || i > (0x1 << 16) || *end !='\0') { ++ if (i < 0 || i >= (0x1 << 16) || *end !='\0') { + i = 0; + while (strcmp(opcodes[i], "")) { + if (!strcasecmp(opcodes[i], optarg)) +@@ -103,7 +103,8 @@ + i++; + } + if (!strcmp(opcodes[i], "")) +- print_error("Problem with specified arp opcode."); ++ print_error("Problem with specified " ++ "arp opcode"); + } + arpinfo->opcode = htons(i); + arpinfo->bitmask |= EBT_ARP_OPCODE; +@@ -115,13 +116,14 @@ + arpinfo->invflags |= EBT_ARP_HTYPE; + + if (optind > argc) +- print_error("Missing arp hardware type argument."); ++ print_error("Missing arp hardware type argument"); + i = strtol(argv[optind - 1], &end, 10); +- if (i < 0 || i > (0x1 << 16) || *end !='\0') { ++ if (i < 0 || i >= (0x1 << 16) || *end !='\0') { + if (!strcasecmp("Ethernet", argv[optind - 1])) + i = 1; + else +- print_error("Problem with specified arp hardware type."); ++ print_error("Problem with specified arp " ++ "hardware type"); + } + arpinfo->htype = htons(i); + arpinfo->bitmask |= EBT_ARP_HTYPE; +@@ -133,13 +135,14 @@ + arpinfo->invflags |= EBT_ARP_PTYPE; + + if (optind > argc) +- print_error("Missing arp protocol type argument."); ++ print_error("Missing arp protocol type argument"); + i = strtol(argv[optind - 1], &end, 16); +- if (i < 0 || i > (0x1 << 16) || *end !='\0') { ++ if (i < 0 || i >= (0x1 << 16) || *end !='\0') { + if (!strcasecmp("IPv4", argv[optind - 1])) + i = 0x0800; + else +- print_error("Problem with specified arp protocol type."); ++ print_error("Problem with specified arp " ++ "protocol type"); + } + arpinfo->ptype = htons(i); + arpinfo->bitmask |= EBT_ARP_PTYPE; +@@ -165,7 +168,7 @@ + arpinfo->invflags |= EBT_ARP_DST_IP; + } + if (optind > argc) +- print_error("Missing ip address argument."); ++ print_error("Missing ip address argument"); + parse_ip_address(argv[optind - 1], addr, mask); + break; + default: +@@ -174,14 +177,19 @@ + return 1; + } + +-static void final_check(const struct ebt_u_entry *entry, const struct ebt_entry_match *match, const char *name, unsigned int hook) ++static void final_check(const struct ebt_u_entry *entry, ++const struct ebt_entry_match *match, const char *name, unsigned int hook) + { +- if (entry->bitmask & EBT_NOPROTO || entry->bitmask & EBT_802_3 || (entry->ethproto != ETH_P_ARP && entry->ethproto != ETH_P_RARP)) +- print_error("For (R)ARP filtering the protocol must be specified as ARP or RARP."); ++ if (entry->bitmask & EBT_NOPROTO || entry->bitmask & EBT_802_3 || ++ (entry->ethproto != ETH_P_ARP && entry->ethproto != ETH_P_RARP)) ++ print_error("For (R)ARP filtering the protocol must be " ++ "specified as ARP or RARP"); + } + +-char *mask_to_dotted(__u32 mask); // defined in the ebt_ip.c +-static void print(const struct ebt_u_entry *entry, const struct ebt_entry_match *match) ++// defined in the ebt_ip.c ++char *mask_to_dotted(__u32 mask); ++static void print(const struct ebt_u_entry *entry, ++ const struct ebt_entry_match *match) + { + struct ebt_arp_info *arpinfo = (struct ebt_arp_info *)match->data; + int i; +@@ -209,7 +217,8 @@ + if (arpinfo->invflags & EBT_ARP_SRC_IP) + printf("! "); + for (i = 0; i < 4; i++) +- printf("%d%s", ((unsigned char *)&arpinfo->saddr)[i], (i == 3) ? "" : "."); ++ printf("%d%s", ((unsigned char *)&arpinfo->saddr)[i], ++ (i == 3) ? "" : "."); + printf("%s, ", mask_to_dotted(arpinfo->smsk)); + } + if (arpinfo->bitmask & EBT_ARP_DST_IP) { +@@ -217,12 +226,14 @@ + if (arpinfo->invflags & EBT_ARP_DST_IP) + printf("! "); + for (i = 0; i < 4; i++) +- printf("%d%s", ((unsigned char *)&arpinfo->daddr)[i], (i == 3) ? "" : "."); ++ printf("%d%s", ((unsigned char *)&arpinfo->daddr)[i], ++ (i == 3) ? "" : "."); + printf("%s, ", mask_to_dotted(arpinfo->dmsk)); + } + } + +-static int compare(const struct ebt_entry_match *m1, const struct ebt_entry_match *m2) ++static int compare(const struct ebt_entry_match *m1, ++ const struct ebt_entry_match *m2) + { + struct ebt_arp_info *arpinfo1 = (struct ebt_arp_info *)m1->data; + struct ebt_arp_info *arpinfo2 = (struct ebt_arp_info *)m2->data; +--- ebtables-v2.0pre2.001/extensions/ebt_log.c Thu Apr 11 18:27:45 2002 ++++ ebtables-v2.0pre2.002/extensions/ebt_log.c Wed Apr 10 23:51:18 2002 +@@ -9,14 +9,14 @@ + + // copied from syslog.h + // used for the LOG target +-#define LOG_EMERG 0 /* system is unusable */ +-#define LOG_ALERT 1 /* action must be taken immediately */ +-#define LOG_CRIT 2 /* critical conditions */ +-#define LOG_ERR 3 /* error conditions */ +-#define LOG_WARNING 4 /* warning conditions */ +-#define LOG_NOTICE 5 /* normal but significant condition */ +-#define LOG_INFO 6 /* informational */ +-#define LOG_DEBUG 7 /* debug-level messages */ ++#define LOG_EMERG 0 // system is unusable ++#define LOG_ALERT 1 // action must be taken immediately ++#define LOG_CRIT 2 // critical conditions ++#define LOG_ERR 3 // error conditions ++#define LOG_WARNING 4 // warning conditions ++#define LOG_NOTICE 5 // normal but significant condition ++#define LOG_INFO 6 // informational ++#define LOG_DEBUG 7 // debug-level messages + #define LOG_DEFAULT_LEVEL LOG_INFO + + typedef struct _code { +@@ -70,16 +70,17 @@ + int i; + + printf( +- "log options:\n" +- "--log : use this if you're not specifying anything\n" +- "--log-level level : level = [1-8] or a string\n" +- "--log-prefix prefix : max. %d chars.\n" +- "--log-ip : put ip info. in the log for ip packets\n" +- "--log-arp : put (r)arp info. in the log for (r)arp packets\n" ++"log options:\n" ++"--log : use this if you're not specifying anything\n" ++"--log-level level : level = [1-8] or a string\n" ++"--log-prefix prefix : max. %d chars.\n" ++"--log-ip : put ip info. in the log for ip packets\n" ++"--log-arp : put (r)arp info. in the log for (r)arp packets\n" + , EBT_LOG_PREFIX_SIZE - 1); + printf("levels:\n"); + for (i = 0; i < 8; i++) +- printf("%d = %s\n", eight_priority[i].c_val, eight_priority[i].c_name); ++ printf("%d = %s\n", eight_priority[i].c_val, ++ eight_priority[i].c_name); + } + + static void init(struct ebt_entry_watcher *watcher) +@@ -88,7 +89,7 @@ + + loginfo->bitmask = 0; + loginfo->prefix[0] = '\0'; +- loginfo->loglevel = 6; ++ loginfo->loglevel = LOG_NOTICE; + } + + #define OPT_PREFIX 0x01 +@@ -96,9 +97,8 @@ + #define OPT_ARP 0x04 + #define OPT_IP 0x08 + #define OPT_LOG 0x10 +-static int parse(int c, char **argv, int argc, +- const struct ebt_u_entry *entry, unsigned int *flags, +- struct ebt_entry_watcher **watcher) ++static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, ++ unsigned int *flags, struct ebt_entry_watcher **watcher) + { + struct ebt_log_info *loginfo = (struct ebt_log_info *)(*watcher)->data; + int i; +@@ -108,9 +108,10 @@ + case LOG_PREFIX: + check_option(flags, OPT_PREFIX); + if (strlen(optarg) > sizeof(loginfo->prefix) - 1) +- print_error("Prefix too long."); ++ print_error("Prefix too long"); + strcpy(loginfo->prefix, optarg); + break; ++ + case LOG_LEVEL: + check_option(flags, OPT_LEVEL); + i = strtol(optarg, &end, 16); +@@ -119,16 +120,19 @@ + else + loginfo->loglevel = i; + if (loginfo->loglevel == 9) +- print_error("Problem with the log-level."); ++ print_error("Problem with the log-level"); + break; ++ + case LOG_IP: + check_option(flags, OPT_IP); + loginfo->bitmask |= EBT_LOG_IP; + break; ++ + case LOG_ARP: + check_option(flags, OPT_ARP); + loginfo->bitmask |= EBT_LOG_ARP; + break; ++ + case LOG_LOG: + check_option(flags, OPT_LOG); + break; +@@ -138,16 +142,18 @@ + return 1; + } + +-static void final_check(const struct ebt_u_entry *entry, const struct ebt_entry_watcher *watcher, const char *name, unsigned int hook) ++static void final_check(const struct ebt_u_entry *entry, ++ const struct ebt_entry_watcher *watcher, const char *name, unsigned int hook) + { + return; + } + +-static void print(const struct ebt_u_entry *entry, const struct ebt_entry_watcher *watcher) ++static void print(const struct ebt_u_entry *entry, ++ const struct ebt_entry_watcher *watcher) + { + struct ebt_log_info *loginfo = (struct ebt_log_info *)watcher->data; + +- printf("log: log-level = %s - log-prefix = '%s'", ++ printf("log: log-level = %s - log-prefix = \"%s\"", + eight_priority[loginfo->loglevel].c_name, + loginfo->prefix); + if (loginfo->bitmask & EBT_LOG_IP) +@@ -157,7 +163,8 @@ + printf(" "); + } + +-static int compare(const struct ebt_entry_watcher *w1, const struct ebt_entry_watcher *w2) ++static int compare(const struct ebt_entry_watcher *w1, ++ const struct ebt_entry_watcher *w2) + { + struct ebt_log_info *loginfo1 = (struct ebt_log_info *)w1->data; + struct ebt_log_info *loginfo2 = (struct ebt_log_info *)w2->data; +--- ebtables-v2.0pre2.001/extensions/ebt_standard.c Thu Apr 11 18:27:45 2002 ++++ ebtables-v2.0pre2.002/extensions/ebt_standard.c Thu Apr 11 18:14:07 2002 +@@ -19,17 +19,19 @@ + ((struct ebt_standard_target *)t)->verdict = EBT_CONTINUE; + } + +-static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, unsigned int *flags, +- struct ebt_entry_target **target) ++static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, ++ unsigned int *flags, struct ebt_entry_target **target) + { + return 0; + } + +-static void final_check(const struct ebt_u_entry *entry, const struct ebt_entry_target *target, const char *name, unsigned int hook) ++static void final_check(const struct ebt_u_entry *entry, ++ const struct ebt_entry_target *target, const char *name, unsigned int hook) + { + } + +-static void print(const struct ebt_u_entry *entry, const struct ebt_entry_target *target) ++static void print(const struct ebt_u_entry *entry, ++ const struct ebt_entry_target *target) + { + __u8 verdict = ((struct ebt_standard_target *)target)->verdict; + +@@ -41,9 +43,11 @@ + printf("Drop "); + } + +-static int compare(const struct ebt_entry_target *t1, const struct ebt_entry_target *t2) ++static int compare(const struct ebt_entry_target *t1, ++ const struct ebt_entry_target *t2) + { +- return ((struct ebt_standard_target *)t1)->verdict == ((struct ebt_standard_target *)t2)->verdict; ++ return ((struct ebt_standard_target *)t1)->verdict == ++ ((struct ebt_standard_target *)t2)->verdict; + } + + static struct ebt_u_target standard = +--- ebtables-v2.0pre2.001/extensions/ebtable_filter.c Thu Apr 11 18:27:45 2002 ++++ ebtables-v2.0pre2.002/extensions/ebtable_filter.c Thu Apr 11 18:14:40 2002 +@@ -3,7 +3,8 @@ + #include + #include "../include/ebtables_u.h" + +-#define FILTER_VALID_HOOKS ((1 << NF_BR_LOCAL_IN) | (1 << NF_BR_FORWARD) | (1 << NF_BR_LOCAL_OUT)) ++#define FILTER_VALID_HOOKS ((1 << NF_BR_LOCAL_IN) | (1 << NF_BR_FORWARD) | \ ++ (1 << NF_BR_LOCAL_OUT)) + + static void print_help(char **hn) + { +--- ebtables-v2.0pre2.001/extensions/ebtable_nat.c Thu Apr 11 18:27:45 2002 ++++ ebtables-v2.0pre2.002/extensions/ebtable_nat.c Thu Apr 11 18:14:57 2002 +@@ -2,7 +2,8 @@ + #include + #include "../include/ebtables_u.h" + +-#define NAT_VALID_HOOKS ((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT) | (1 << NF_BR_POST_ROUTING)) ++#define NAT_VALID_HOOKS ((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT) | \ ++ (1 << NF_BR_POST_ROUTING)) + + static void print_help(char **hn) + { +--- ebtables-v2.0pre2.001/ChangeLog Wed Apr 3 16:56:37 2002 ++++ ebtables-v2.0pre2.002/ChangeLog Thu Apr 11 18:26:21 2002 +@@ -1,3 +1,12 @@ ++20020411 ++ * -j standard no longer works, is this cryptic? good :) ++ * lots of beautification. ++ - made some code smaller ++ - made everything fit within 80 columns ++ * fix problems with -i and -o option ++ * print_memory now prints useful info ++ * trying to see the tables when ebtables is not loaded in kernel ++ no longer makes this be seen as a bug. + 20020403 + ebtables v2.0 released, changes: + * A complete rewrite, made everything modular. +--- ebtables-v2.0pre2.001/include/ebtables_u.h Thu Apr 11 18:27:45 2002 ++++ ebtables-v2.0pre2.002/include/ebtables_u.h Wed Apr 10 22:29:01 2002 +@@ -38,20 +38,28 @@ + { + char name[EBT_TABLE_MAXNAMELEN]; + unsigned int valid_hooks; +- unsigned int nentries; // nr of rules in the table ++ // nr of rules in the table ++ unsigned int nentries; + struct ebt_u_entries *hook_entry[NF_BR_NUMHOOKS]; +- unsigned int counter_entry[NF_BR_NUMHOOKS]; // how many counters in front of it? +- unsigned int num_counters; // nr of counters the userspace expects back +- struct ebt_counter *counters; // where the kernel will put the old counters +- unsigned int flags; // can be used e.g. to know if a standard option has been specified twice +- char command; // we stick the specified command (e.g. -A) in here +- int selected_hook; // here we stick the hook to do our thing on (can be -1 if unspecified) ++ // how many counters in front of it? ++ unsigned int counter_entry[NF_BR_NUMHOOKS]; ++ // nr of counters userspace expects back ++ unsigned int num_counters; ++ // where the kernel will put the old counters ++ struct ebt_counter *counters; ++ // can be used e.g. to know if a standard option ++ // has been specified twice ++ unsigned int flags; ++ // we stick the specified command (e.g. -A) in here ++ char command; ++ // here we stick the hook to do our thing on (can be -1 if unspecified) ++ int selected_hook; + }; + + struct ebt_u_table + { + char name[EBT_TABLE_MAXNAMELEN]; +- int (*check) (struct ebt_u_replace *repl); ++ int (*check)(struct ebt_u_replace *repl); + void (*help)(char **); + struct ebt_u_table *next; + }; +@@ -70,9 +78,9 @@ + + struct ebt_u_entry + { +- __u32 bitmask; // this needs to be the first field ++ __u32 bitmask; + __u32 invflags; +- __u16 ethproto; /* packet type ID field */ ++ __u16 ethproto; + __u8 in[IFNAMSIZ]; + __u8 out[IFNAMSIZ]; + __u8 sourcemac[ETH_ALEN]; +@@ -86,35 +94,47 @@ + struct ebt_u_match + { + char name[EBT_FUNCTION_MAXNAMELEN]; +- unsigned int size;// size of the real match data ++ // size of the real match data + sizeof struct ebt_match ++ unsigned int size; + void (*help)(void); + void (*init)(struct ebt_entry_match *m); + int (*parse)(int c, char **argv, int argc, + const struct ebt_u_entry *entry, unsigned int *flags, + struct ebt_entry_match **match); +- void (*final_check)(const struct ebt_u_entry *entry, const struct ebt_entry_match *match, const char *name, unsigned int hook); +- void (*print)(const struct ebt_u_entry *entry, const struct ebt_entry_match *match); +- int (*compare)(const struct ebt_entry_match *m1, const struct ebt_entry_match *m2); ++ void (*final_check)(const struct ebt_u_entry *entry, ++ const struct ebt_entry_match *match, ++ const char *name, unsigned int hook); ++ void (*print)(const struct ebt_u_entry *entry, ++ const struct ebt_entry_match *match); ++ int (*compare)(const struct ebt_entry_match *m1, ++ const struct ebt_entry_match *m2); + const struct option *extra_ops; +- unsigned int flags;// can be used e.g. to check for multiple occurance of the same option ++ // can be used e.g. to check for multiple occurance of the same option ++ unsigned int flags; + unsigned int option_offset; + struct ebt_entry_match *m; +- unsigned int used;// if used == 1 we no longer have to add it to the match chain of the new entry ++ // if used == 1 we no longer have to add it to ++ // the match chain of the new entry ++ unsigned int used; + struct ebt_u_match *next; + }; + + struct ebt_u_watcher + { + char name[EBT_FUNCTION_MAXNAMELEN]; +- unsigned int size;// size of the real match data ++ unsigned int size; + void (*help)(void); + void (*init)(struct ebt_entry_watcher *w); + int (*parse)(int c, char **argv, int argc, +- const struct ebt_u_entry *entry, unsigned int *flags, +- struct ebt_entry_watcher **watcher); +- void (*final_check)(const struct ebt_u_entry *entry, const struct ebt_entry_watcher *watch, const char *name, unsigned int hook); +- void (*print)(const struct ebt_u_entry *entry, const struct ebt_entry_watcher *watcher); +- int (*compare)(const struct ebt_entry_watcher *w1, const struct ebt_entry_watcher *w2); ++ const struct ebt_u_entry *entry, unsigned int *flags, ++ struct ebt_entry_watcher **watcher); ++ void (*final_check)(const struct ebt_u_entry *entry, ++ const struct ebt_entry_watcher *watch, const char *name, ++ unsigned int hook); ++ void (*print)(const struct ebt_u_entry *entry, ++ const struct ebt_entry_watcher *watcher); ++ int (*compare)(const struct ebt_entry_watcher *w1, ++ const struct ebt_entry_watcher *w2); + const struct option *extra_ops; + unsigned int flags; + unsigned int option_offset; +@@ -126,14 +146,19 @@ + struct ebt_u_target + { + char name[EBT_FUNCTION_MAXNAMELEN]; +- unsigned int size;// size of the real match data ++ unsigned int size; + void (*help)(void); + void (*init)(struct ebt_entry_target *t); +- int (*parse)(int c, char **argv, int argc, const struct ebt_u_entry *entry, unsigned int *flags, +- struct ebt_entry_target **target); +- void (*final_check)(const struct ebt_u_entry *entry, const struct ebt_entry_target *target, const char *name, unsigned int hook); +- void (*print)(const struct ebt_u_entry *entry, const struct ebt_entry_target *target); +- int (*compare)(const struct ebt_entry_target *t1, const struct ebt_entry_target *t2); ++ int (*parse)(int c, char **argv, int argc, ++ const struct ebt_u_entry *entry, unsigned int *flags, ++ struct ebt_entry_target **target); ++ void (*final_check)(const struct ebt_u_entry *entry, ++ const struct ebt_entry_target *target, const char *name, ++ unsigned int hook); ++ void (*print)(const struct ebt_u_entry *entry, ++ const struct ebt_entry_target *target); ++ int (*compare)(const struct ebt_entry_target *t1, ++ const struct ebt_entry_target *t2); + const struct option *extra_ops; + unsigned int option_offset; + unsigned int flags; +@@ -150,19 +175,21 @@ + struct ebt_u_target *find_target(const char *name); + struct ebt_u_match *find_match(const char *name); + struct ebt_u_watcher *find_watcher(const char *name); +-void deliver_counters(struct ebt_u_replace *repl, unsigned short * counterchanges); ++void deliver_counters(struct ebt_u_replace *repl, ++ unsigned short * counterchanges); + void deliver_table(struct ebt_u_replace *repl); +-void get_sockfd(); + void get_dbinfo(struct brdb_dbinfo *nr); + void get_db(int len, struct brdb_dbentry *db); + void deliver_allowdb(__u16 *decision); +-void print_memory(); +-void init_extensions(); + int getmac(char *from, char *to); + void check_option(unsigned int *flags, unsigned int mask); + int check_inverse(const char option[]); +-#define print_bug(format, args...) {printf("BUG: "format"\n", ##args); exit(-1);} +-#define print_error(format, args...) {printf(format"\n", ##args); exit(-1);} ++#define print_bug(format, args...) \ ++ {printf("BUG: "format".\n", ##args); exit(-1);} ++#define print_error(format, args...) {printf(format".\n", ##args); exit(-1);} ++#define print_memory() {printf("Ebtables: " __FILE__ " " __FUNCTION__ \ ++ " %d :Out of memory.\n", __LINE__); exit(-1);} ++ + + + // used for keeping the rule counters right during rule adds or deletes diff --git a/userspace/patches/incremental-patches/ebtables-v2.0pre2.003.diff b/userspace/patches/incremental-patches/ebtables-v2.0pre2.003.diff new file mode 100644 index 0000000..aac6a6f --- /dev/null +++ b/userspace/patches/incremental-patches/ebtables-v2.0pre2.003.diff @@ -0,0 +1,40 @@ +--- ebtables-v2.0pre2.002/Makefile Sat Apr 13 17:39:08 2002 ++++ ebtables-v2.0pre2.003/Makefile Sat Apr 13 17:43:09 2002 +@@ -2,7 +2,7 @@ + + KERNEL_DIR?=/usr/src/linux + PROGNAME:=ebtables +-PROGVERSION:="2.0pre2.001 (April 2002)" ++PROGVERSION:="2.0pre2.003 (April 2002)" + + MANDIR?=/usr/local/man + CFLAGS:=-Wall -Wunused +--- ebtables-v2.0pre2.002/ebtables.c Sat Apr 13 17:39:08 2002 ++++ ebtables-v2.0pre2.003/ebtables.c Sat Apr 13 17:37:00 2002 +@@ -1490,7 +1490,7 @@ + flush_chains(); + else if (replace.command == 'A' || replace.command == 'I') + add_rule(rule_nr); +- else ++ else if (replace.command == 'D') + delete_rule(rule_nr); + + if (table->check) +--- ebtables-v2.0pre2.002/THANKS Wed Apr 3 17:44:44 2002 ++++ ebtables-v2.0pre2.003/THANKS Sat Apr 13 17:40:35 2002 +@@ -5,3 +5,5 @@ + Harald Welte + Jason Lunz + Tim Gardner ++Loïc Minier ++ +--- ebtables-v2.0pre2.002/ebtables.8 Wed Apr 3 16:29:11 2002 ++++ ebtables-v2.0pre2.003/ebtables.8 Sat Apr 13 17:32:23 2002 +@@ -128,6 +128,7 @@ + Put the counters of the selected chain on zero. If no chain is selected, all the counters + are put on zero. This can be used in conjunction with the -L command (see above). + This will cause the rule counters to be printed on the screen before they are put on zero. ++.TP + .B "-P, --policy" + Set the policy for the chain to the given target. The policy is either + .B ACCEPT diff --git a/userspace/patches/incremental-patches/ebtables-v2.0pre2.004.diff b/userspace/patches/incremental-patches/ebtables-v2.0pre2.004.diff new file mode 100644 index 0000000..87ed4dc --- /dev/null +++ b/userspace/patches/incremental-patches/ebtables-v2.0pre2.004.diff @@ -0,0 +1,50 @@ +--- ebtables-v2.0pre2.003/Makefile Sun Apr 14 15:01:46 2002 ++++ ebtables-v2.0pre2.004/Makefile Sun Apr 14 15:03:11 2002 +@@ -2,7 +2,7 @@ + + KERNEL_DIR?=/usr/src/linux + PROGNAME:=ebtables +-PROGVERSION:="2.0pre2.003 (April 2002)" ++PROGVERSION:="2.0pre2 (April 2002)" + + MANDIR?=/usr/local/man + CFLAGS:=-Wall -Wunused +--- ebtables-v2.0pre2.003/ChangeLog Sat Apr 13 17:39:08 2002 ++++ ebtables-v2.0pre2.004/ChangeLog Sun Apr 14 14:15:59 2002 +@@ -1,3 +1,6 @@ ++20020414 ++ * fixed some things in the manual. ++ * fixed -P problem. + 20020411 + * -j standard no longer works, is this cryptic? good :) + * lots of beautification. +--- ebtables-v2.0pre2.003/ebtables.8 Sun Apr 14 15:01:46 2002 ++++ ebtables-v2.0pre2.004/ebtables.8 Sun Apr 14 14:58:15 2002 +@@ -1,4 +1,4 @@ +-.TH EBTABLES 8 "03 April 2002" ++.TH EBTABLES 8 "14 April 2002" + .\" + .\" Man page written by Bart De Schuymer + .\" It is based on the iptables man page. +@@ -21,7 +21,7 @@ + .\" + .\" + .SH NAME +-ebtables(v.2) \- ethernet bridge packet table administration ++ebtables(v.2.0) \- ethernet bridge packet table administration + .SH SYNOPSIS + .BR "ebtables -[ADI] " "chain rule-specification [options]" + .br +@@ -263,6 +263,12 @@ + .BR "--arp-ptype " "[!] \fIprotocol type\fP" + The protocol type for which the (r)arp is used (hexadecimal or the string "IPv4"). + This is normally IPv4 (0x0800). ++.TP ++.BR "--arp-ip-src " "[!] \fIaddress\fP[/\fImask\fP]" ++The ARP IP source address specification. ++.TP ++.BR "--arp-ip-dst " "[!] \fIaddress\fP[/\fImask\fP]" ++The ARP IP destination address specification. + .SH WATCHER EXTENSION(S) + Watchers are things that only look at frames passing by. These watchers only see the + frame if the frame passes all the matches of the rule. diff --git a/userspace/patches/incremental-patches/ebtables-v2.0pre3.001.diff b/userspace/patches/incremental-patches/ebtables-v2.0pre3.001.diff new file mode 100644 index 0000000..12c7a2b --- /dev/null +++ b/userspace/patches/incremental-patches/ebtables-v2.0pre3.001.diff @@ -0,0 +1,245 @@ +Adjust to the kernel's wish that the size members represent the size +of the actual data. + +Make a little note in the man page about the chain naming. + +--- ebtables-v2.0pre2/ebtables.c Sat Apr 13 17:37:00 2002 ++++ ebtables-v2.0pre3.001/ebtables.c Fri Apr 19 19:44:33 2002 +@@ -253,14 +253,14 @@ + + void register_match(struct ebt_u_match *m) + { +- int size = m->size; ++ int size = m->size + sizeof(struct ebt_entry_match); + struct ebt_u_match **i; + + m->m = (struct ebt_entry_match *)malloc(size); + if (!m->m) + print_memory(); + strcpy(m->m->u.name, m->name); +- m->m->match_size = size; ++ m->m->match_size = m->size; + ebt_options = merge_options + (ebt_options, m->extra_ops, &(m->option_offset)); + m->init(m->m); +@@ -272,14 +272,14 @@ + + void register_watcher(struct ebt_u_watcher *w) + { +- int size = w->size; ++ int size = w->size + sizeof(struct ebt_entry_watcher); + struct ebt_u_watcher **i; + + w->w = (struct ebt_entry_watcher *)malloc(size); + if (!w->w) + print_memory(); + strcpy(w->w->u.name, w->name); +- w->w->watcher_size = size; ++ w->w->watcher_size = w->size; + ebt_options = merge_options + (ebt_options, w->extra_ops, &(w->option_offset)); + w->init(w->w); +@@ -291,14 +291,14 @@ + + void register_target(struct ebt_u_target *t) + { +- int size = t->size; ++ int size = t->size + sizeof(struct ebt_entry_target); + struct ebt_u_target **i; + + t->t = (struct ebt_entry_target *)malloc(size); + if (!t->t) + print_memory(); + strcpy(t->t->u.name, t->name); +- t->t->target_size = size; ++ t->t->target_size = t->size; + ebt_options = merge_options + (ebt_options, t->extra_ops, &(t->option_offset)); + t->init(t->t); +--- ebtables-v2.0pre2/communication.c Wed Apr 10 22:10:49 2002 ++++ ebtables-v2.0pre3.001/communication.c Fri Apr 19 22:02:45 2002 +@@ -68,15 +68,18 @@ + entries_size += sizeof(struct ebt_entry); + m_l = e->m_list; + while (m_l) { +- entries_size += m_l->m->match_size; ++ entries_size += m_l->m->match_size + ++ sizeof(struct ebt_entry_match); + m_l = m_l->next; + } + w_l = e->w_list; + while (w_l) { +- entries_size += w_l->w->watcher_size; ++ entries_size += w_l->w->watcher_size + ++ sizeof(struct ebt_entry_watcher); + w_l = w_l->next; + } +- entries_size += e->t->target_size; ++ entries_size += e->t->target_size + ++ sizeof(struct ebt_entry_target); + e = e->next; + } + // a little sanity check +@@ -120,20 +123,26 @@ + p += sizeof(struct ebt_entry); + m_l = e->m_list; + while (m_l) { +- memcpy(p, m_l->m, m_l->m->match_size); +- p += m_l->m->match_size; ++ memcpy(p, m_l->m, m_l->m->match_size + ++ sizeof(struct ebt_entry_match)); ++ p += m_l->m->match_size + ++ sizeof(struct ebt_entry_match); + m_l = m_l->next; + } + tmp->watchers_offset = p - base; + w_l = e->w_list; + while (w_l) { +- memcpy(p, w_l->w, w_l->w->watcher_size); +- p += w_l->w->watcher_size; ++ memcpy(p, w_l->w, w_l->w->watcher_size + ++ sizeof(struct ebt_entry_watcher)); ++ p += w_l->w->watcher_size + ++ sizeof(struct ebt_entry_watcher); + w_l = w_l->next; + } + tmp->target_offset = p - base; +- memcpy(p, e->t, e->t->target_size); +- p += e->t->target_size; ++ memcpy(p, e->t, e->t->target_size + ++ sizeof(struct ebt_entry_target)); ++ p += e->t->target_size + ++ sizeof(struct ebt_entry_target); + tmp->next_offset = p - base; + e = e->next; + } +@@ -229,10 +238,11 @@ + malloc(sizeof(struct ebt_u_match_list)); + if (!new) + print_memory(); +- new->m = (struct ebt_entry_match *)malloc(m->match_size); ++ new->m = (struct ebt_entry_match *) ++ malloc(m->match_size + sizeof(struct ebt_entry_match)); + if (!new->m) + print_memory(); +- memcpy(new->m, m, m->match_size); ++ memcpy(new->m, m, m->match_size + sizeof(struct ebt_entry_match)); + new->next = NULL; + **l = new; + *l = &new->next; +@@ -248,13 +258,15 @@ + { + struct ebt_u_watcher_list *new; + +- new = (struct ebt_u_watcher_list *)malloc(sizeof(struct ebt_u_watcher_list)); ++ new = (struct ebt_u_watcher_list *) ++ malloc(sizeof(struct ebt_u_watcher_list)); + if (!new) + print_memory(); +- new->w = (struct ebt_entry_watcher *)malloc(w->watcher_size); ++ new->w = (struct ebt_entry_watcher *) ++ malloc(w->watcher_size + sizeof(struct ebt_entry_watcher)); + if (!new->w) + print_memory(); +- memcpy(new->w, w, w->watcher_size); ++ memcpy(new->w, w, w->watcher_size + sizeof(struct ebt_entry_watcher)); + new->next = NULL; + **l = new; + *l = &new->next; +@@ -297,13 +309,15 @@ + EBT_WATCHER_ITERATE(e, ebt_translate_watcher, &w_l); + + t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); +- new->t = (struct ebt_entry_target *)malloc(t->target_size); ++ new->t = (struct ebt_entry_target *) ++ malloc(t->target_size + sizeof(struct ebt_entry_target)); + if (!new->t) + print_memory(); + if (find_target(t->u.name) == NULL) + print_error("Kernel target %s unsupported by " + "userspace tool", t->u.name); +- memcpy(new->t, t, t->target_size); ++ memcpy(new->t, t, t->target_size + ++ sizeof(struct ebt_entry_target)); + + // I love pointers + **u_e = new; +@@ -419,7 +433,8 @@ + + get_sockfd(); + +- if (setsockopt(sockfd, IPPROTO_IP, BRDB_SO_SET_ALLOWDB, decision, optlen)) ++ if (setsockopt(sockfd, IPPROTO_IP, BRDB_SO_SET_ALLOWDB, ++ decision, optlen)) + print_error("Sorry, br_db code probably not in kernel, " + "try insmod br_db"); + } +--- ebtables-v2.0pre2/extensions/ebt_nat.c Thu Apr 11 18:12:55 2002 ++++ ebtables-v2.0pre3.001/extensions/ebt_nat.c Fri Apr 19 19:41:04 2002 +@@ -161,7 +161,7 @@ + static struct ebt_u_target dnat_target = + { + EBT_DNAT_TARGET, +- sizeof(struct ebt_nat_info) + sizeof(struct ebt_entry_target), ++ sizeof(struct ebt_nat_info), + print_help_d, + init_d, + parse_d, +--- ebtables-v2.0pre2/extensions/ebt_ip.c Wed Apr 10 23:28:40 2002 ++++ ebtables-v2.0pre3.001/extensions/ebt_ip.c Fri Apr 19 19:40:18 2002 +@@ -301,7 +301,7 @@ + static struct ebt_u_match ip_match = + { + EBT_IP_MATCH, +- sizeof(struct ebt_ip_info) + sizeof(struct ebt_entry_match), ++ sizeof(struct ebt_ip_info), + print_help, + init, + parse, +--- ebtables-v2.0pre2/extensions/ebt_arp.c Wed Apr 10 23:05:29 2002 ++++ ebtables-v2.0pre3.001/extensions/ebt_arp.c Fri Apr 19 19:40:40 2002 +@@ -272,7 +272,7 @@ + static struct ebt_u_match arp_match = + { + EBT_ARP_MATCH, +- sizeof(struct ebt_arp_info) + sizeof(struct ebt_entry_match), ++ sizeof(struct ebt_arp_info), + print_help, + init, + parse, +--- ebtables-v2.0pre2/extensions/ebt_log.c Wed Apr 10 23:51:18 2002 ++++ ebtables-v2.0pre3.001/extensions/ebt_log.c Fri Apr 19 19:40:52 2002 +@@ -179,7 +179,7 @@ + static struct ebt_u_watcher log_watcher = + { + EBT_LOG_WATCHER, +- sizeof(struct ebt_log_info) + sizeof(struct ebt_entry_watcher), ++ sizeof(struct ebt_log_info), + print_help, + init, + parse, +--- ebtables-v2.0pre2/extensions/ebt_standard.c Thu Apr 11 18:14:07 2002 ++++ ebtables-v2.0pre3.001/extensions/ebt_standard.c Fri Apr 19 19:44:54 2002 +@@ -53,7 +53,7 @@ + static struct ebt_u_target standard = + { + EBT_STANDARD_TARGET, +- sizeof(struct ebt_standard_target), ++ sizeof(struct ebt_standard_target) - sizeof(struct ebt_entry_target), + print_help, + init, + parse, +--- ebtables-v2.0pre2/ebtables.8 Sun Apr 14 14:58:15 2002 ++++ ebtables-v2.0pre3.001/ebtables.8 Thu Apr 18 18:44:40 2002 +@@ -86,7 +86,10 @@ + .B OUTPUT + (for altering locally generated frames before they are bridged) and + .B POSTROUTING +-(for altering frames as they are about to go out). ++(for altering frames as they are about to go out). A small note on the naming ++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. + .SH OPTIONS + The options can be divided into several different groups. + .SS COMMANDS diff --git a/userspace/patches/incremental-patches/ebtables-v2.0pre3.002.diff b/userspace/patches/incremental-patches/ebtables-v2.0pre3.002.diff new file mode 100644 index 0000000..175f9df --- /dev/null +++ b/userspace/patches/incremental-patches/ebtables-v2.0pre3.002.diff @@ -0,0 +1,194 @@ +--- ebtables-v2.0pre3.001/ebtables.c Fri Apr 19 22:07:46 2002 ++++ ebtables-v2.0pre3.002/ebtables.c Fri Apr 19 23:43:05 2002 +@@ -62,6 +62,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 }, + { "out-interface" , required_argument, 0, 'o' }, + { "out-if" , required_argument, 0, 'o' }, + { "version" , no_argument , 0, 'V' }, +@@ -481,6 +483,16 @@ + printf("! "); + printf("in-if: %s, ", hlp->in); + } ++ if (hlp->logical_in[0] != '\0') { ++ if (hlp->invflags & EBT_ILOGICALIN) ++ printf("! "); ++ printf("logical in-if: %s, ", hlp->logical_in); ++ } ++ if (hlp->logical_out[0] != '\0') { ++ if (hlp->invflags & EBT_ILOGICALOUT) ++ printf("! "); ++ printf("logical out-if: %s, ", hlp->logical_out); ++ } + if (hlp->out[0] != '\0') { + if (hlp->invflags & EBT_IOUT) + printf("! "); +@@ -560,6 +572,8 @@ + "--dst -d [!] address : destination mac address\n" + "--in-if -i [!] name : network input interface name\n" + "--out-if -o [!] name : network output interface name\n" ++"--logical-in [!] name : logical bridge input interface name\n" ++"--logical-out [!] name : logical bridge output interface name\n" + "--version -V : print package version\n" + "\n" , + prog_name, +@@ -1095,15 +1109,17 @@ + *flags |= mask; + } + +-#define OPT_COMMAND 0x01 +-#define OPT_TABLE 0x02 +-#define OPT_IN 0x04 +-#define OPT_OUT 0x08 +-#define OPT_JUMP 0x10 +-#define OPT_PROTOCOL 0x20 +-#define OPT_SOURCE 0x40 +-#define OPT_DEST 0x80 +-#define OPT_ZERO 0x100 ++#define OPT_COMMAND 0x01 ++#define OPT_TABLE 0x02 ++#define OPT_IN 0x04 ++#define OPT_OUT 0x08 ++#define OPT_JUMP 0x10 ++#define OPT_PROTOCOL 0x20 ++#define OPT_SOURCE 0x40 ++#define OPT_DEST 0x80 ++#define OPT_ZERO 0x100 ++#define OPT_LOGICALIN 0x200 ++#define OPT_LOGICALOUT 0x400 + // the main thing + int main(int argc, char *argv[]) + { +@@ -1261,7 +1277,9 @@ + break; + + case 'i': // input interface ++ case 1 : // logical input interface + case 'o': // output interface ++ case 2 : // logical output interface + case 'j': // target + case 'p': // net family protocol + case 's': // source mac +@@ -1287,6 +1305,23 @@ + strcpy(new_entry->in, argv[optind - 1]); + break; + } ++ if (c == 1) { ++ check_option(&replace.flags, OPT_LOGICALIN); ++ if (replace.selected_hook > 2) ++ print_error("Use logical in-interface " ++ "only in INPUT, FORWARD and " ++ "PREROUTING chains"); ++ if (check_inverse(optarg)) ++ new_entry->invflags |= EBT_ILOGICALIN; ++ ++ if (optind > argc) ++ print_error("No logical in-interface " ++ "specified"); ++ if (strlen(argv[optind - 1]) >= IFNAMSIZ) ++ print_error("Illegal interfacelength"); ++ strcpy(new_entry->logical_in, argv[optind - 1]); ++ break; ++ } + if (c == 'o') { + check_option(&replace.flags, OPT_OUT); + if (replace.selected_hook < 2) +@@ -1304,6 +1339,26 @@ + print_error("Illegal interface " + "length"); + strcpy(new_entry->out, argv[optind - 1]); ++ break; ++ } ++ if (c == 2) { ++ check_option(&replace.flags, OPT_LOGICALOUT); ++ if (replace.selected_hook < 2) ++ print_error("Use logical out-interface " ++ "only in OUTPUT, FORWARD and " ++ "POSTROUTING chains"); ++ if (check_inverse(optarg)) ++ new_entry->invflags |= EBT_ILOGICALOUT; ++ ++ if (optind > argc) ++ print_error("No logical out-interface " ++ "specified"); ++ ++ if (strlen(argv[optind - 1]) >= IFNAMSIZ) ++ print_error("Illegal interface " ++ "length"); ++ strcpy(new_entry->logical_out, ++ argv[optind - 1]); + break; + } + if (c == 'j') { +--- ebtables-v2.0pre3.001/communication.c Fri Apr 19 22:07:46 2002 ++++ ebtables-v2.0pre3.002/communication.c Fri Apr 19 22:57:13 2002 +@@ -115,6 +115,10 @@ + tmp->ethproto = e->ethproto; + memcpy(tmp->in, e->in, sizeof(tmp->in)); + memcpy(tmp->out, e->out, sizeof(tmp->out)); ++ memcpy(tmp->logical_in, e->logical_in, ++ sizeof(tmp->logical_in)); ++ memcpy(tmp->logical_out, e->logical_out, ++ sizeof(tmp->logical_out)); + memcpy(tmp->sourcemac, e->sourcemac, + sizeof(tmp->sourcemac)); + memcpy(tmp->destmac, e->destmac, sizeof(tmp->destmac)); +@@ -298,6 +302,10 @@ + new->ethproto = e->ethproto; + memcpy(new->in, e->in, sizeof(new->in)); + memcpy(new->out, e->out, sizeof(new->out)); ++ memcpy(new->logical_in, e->logical_in, ++ sizeof(new->logical_in)); ++ memcpy(new->logical_out, e->logical_out, ++ sizeof(new->logical_out)); + memcpy(new->sourcemac, e->sourcemac, sizeof(new->sourcemac)); + memcpy(new->destmac, e->destmac, sizeof(new->destmac)); + new->m_list = NULL; +--- ebtables-v2.0pre3.001/ebtables.8 Fri Apr 19 22:07:46 2002 ++++ ebtables-v2.0pre3.002/ebtables.8 Fri Apr 19 23:28:06 2002 +@@ -184,6 +184,14 @@ + .B --in-if + is an alias for this option. + .TP ++.BR "--logical-in " "[!] \fIname\fP" ++The (logical) bridge interface via which a frame is received (for the ++.BR INPUT , ++.B FORWARD ++and ++.B PREROUTING ++chains). ++.TP + .BR "-o, --out-interface " "[!] \fIname\fP" + The interface via which a frame is going to be sent (for the + .BR OUTPUT , +@@ -193,6 +201,15 @@ + chains). The flag + .B --out-if + is an alias for this option. ++.TP ++.BR "--logical-out " "[!] \fIname\fP" ++The (logical) bridge interface via which a frame is going to be sent (for ++the ++.BR OUTPUT , ++.B FORWARD ++and ++.B POSTROUTING ++chains). + .TP + .BR "-s, --source " "[!] \fIaddress\fP" + The source mac address. The flag +--- ebtables-v2.0pre3.001/include/ebtables_u.h Wed Apr 10 22:29:01 2002 ++++ ebtables-v2.0pre3.002/include/ebtables_u.h Fri Apr 19 22:55:15 2002 +@@ -82,7 +82,9 @@ + __u32 invflags; + __u16 ethproto; + __u8 in[IFNAMSIZ]; ++ __u8 logical_in[IFNAMSIZ]; + __u8 out[IFNAMSIZ]; ++ __u8 logical_out[IFNAMSIZ]; + __u8 sourcemac[ETH_ALEN]; + __u8 destmac[ETH_ALEN]; + struct ebt_u_match_list *m_list; diff --git a/userspace/patches/incremental-patches/ebtables-v2.0pre3.003.diff b/userspace/patches/incremental-patches/ebtables-v2.0pre3.003.diff new file mode 100644 index 0000000..1a80a01 --- /dev/null +++ b/userspace/patches/incremental-patches/ebtables-v2.0pre3.003.diff @@ -0,0 +1,66 @@ +* Add brouter support +* Give better advice when a table is not found by the kernel + +--- ebtables-v2.0pre3.002/Makefile Sun Apr 14 15:03:11 2002 ++++ ebtables-v2.0pre3.003/Makefile Mon Apr 22 20:05:21 2002 +@@ -2,7 +2,7 @@ + + KERNEL_DIR?=/usr/src/linux + PROGNAME:=ebtables +-PROGVERSION:="2.0pre2 (April 2002)" ++PROGVERSION:="2.0pre3 (April 2002)" + + MANDIR?=/usr/local/man + CFLAGS:=-Wall -Wunused +--- ebtables-v2.0pre3.002/ebtables.c Mon Apr 22 20:08:03 2002 ++++ ebtables-v2.0pre3.003/ebtables.c Sat Apr 20 20:07:42 2002 +@@ -48,7 +48,8 @@ + [NF_BR_LOCAL_IN]"INPUT", + [NF_BR_FORWARD]"FORWARD", + [NF_BR_LOCAL_OUT]"OUTPUT", +- [NF_BR_POST_ROUTING]"POSTROUTING" ++ [NF_BR_POST_ROUTING]"POSTROUTING", ++ [NF_BR_BROUTING]"BROUTING" + }; + + // default command line options +--- ebtables-v2.0pre3.002/communication.c Mon Apr 22 20:08:03 2002 ++++ ebtables-v2.0pre3.003/communication.c Sun Apr 21 15:38:38 2002 +@@ -375,7 +375,8 @@ + strcpy(repl.name, u_repl->name); + if (getsockopt(sockfd, IPPROTO_IP, EBT_SO_GET_INFO, &repl, &optlen)) + print_error("A kernel module needed by your command is probably" +- " not loaded. Try insmod ebtables or the like"); ++ " not loaded. Try insmod ebtables or" ++ " insmod ebtable_%s", repl.name); + + if ( !(repl.entries = (char *) malloc(repl.entries_size)) ) + print_memory(); +--- /dev/null Thu Aug 24 11:00:32 2000 ++++ ebtables-v2.0pre3.003/extensions/ebtable_broute.c Sat Apr 20 20:12:26 2002 +@@ -0,0 +1,25 @@ ++#include ++#include ++#include "../include/ebtables_u.h" ++ ++ ++static void print_help(char **hn) ++{ ++ printf("Supported chain for the nat table:\n"); ++ printf("%s\n",hn[NF_BR_BROUTING]); ++} ++ ++static struct ++ebt_u_table table = ++{ ++ "broute", ++ NULL, ++ print_help, ++ NULL ++}; ++ ++static void _init(void) __attribute__ ((constructor)); ++static void _init(void) ++{ ++ register_table(&table); ++} diff --git a/userspace/patches/incremental-patches/ebtables-v2.0pre3.004.diff b/userspace/patches/incremental-patches/ebtables-v2.0pre3.004.diff new file mode 100644 index 0000000..9a3bc67 --- /dev/null +++ b/userspace/patches/incremental-patches/ebtables-v2.0pre3.004.diff @@ -0,0 +1,483 @@ +--- 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 diff --git a/userspace/patches/incremental-patches/ebtables-v2.0pre4.001.diff b/userspace/patches/incremental-patches/ebtables-v2.0pre4.001.diff new file mode 100644 index 0000000..c4a9e39 --- /dev/null +++ b/userspace/patches/incremental-patches/ebtables-v2.0pre4.001.diff @@ -0,0 +1,522 @@ +--- ebtables-v2.0pre3/Makefile Sat Apr 27 22:31:19 2002 ++++ ebtables-v2.0pre4.001/Makefile Thu May 2 19:02:44 2002 +@@ -2,7 +2,7 @@ + + KERNEL_DIR?=/usr/src/linux + PROGNAME:=ebtables +-PROGVERSION:="2.0pre3 (April 2002)" ++PROGVERSION:="2.0pre4 (April 2002)" + + MANDIR?=/usr/local/man + CFLAGS:=-Wall -Wunused +@@ -32,12 +32,12 @@ + mkdir -p $(@D) + install -m 0644 -o root -g root $< $@ + +-/etc/etherproto: etherproto ++/etc/ethertypes: ethertypes + mkdir -p $(@D) + install -m 0644 -o root -g root $< $@ + + install: $(MANDIR)/man8/ebtables.8 headers \ +- ebtables /etc/etherproto ++ ebtables /etc/ethertypes + + clean: + -rm -f ebtables +--- ebtables-v2.0pre3/ebtables.c Sat Apr 27 22:31:21 2002 ++++ ebtables-v2.0pre4.001/ebtables.c Fri May 3 20:56:14 2002 +@@ -36,7 +36,7 @@ + + // here are the number-name correspondences kept for the ethernet + // frame type field +-#define PROTOCOLFILE "/etc/etherproto" ++#define PROTOCOLFILE "/etc/ethertypes" + + #define DATABASEHOOKNR NF_BR_NUMHOOKS + #define DATABASEHOOKNAME "DB" +@@ -90,6 +90,13 @@ + "CONTINUE", + }; + ++unsigned char mac_type_unicast[ETH_ALEN] = {0,0,0,0,0,0}; ++unsigned char msk_type_unicast[ETH_ALEN] = {1,0,0,0,0,0}; ++unsigned char mac_type_multicast[ETH_ALEN] = {1,0,0,0,0,0}; ++unsigned char msk_type_multicast[ETH_ALEN] = {1,0,0,0,0,0}; ++unsigned char mac_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255}; ++unsigned char msk_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255}; ++ + // tells what happened to the old rules + static unsigned short *counterchanges; + // holds all the data +@@ -466,20 +473,70 @@ + } + } + if (hlp->bitmask & EBT_SOURCEMAC) { ++ char hlpmsk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ + printf("source mac: "); + if (hlp->invflags & EBT_ISOURCE) + printf("! "); ++ if (!memcmp(hlp->sourcemac, mac_type_unicast, 6) && ++ !memcmp(hlp->sourcemsk, msk_type_unicast, 6)) { ++ printf("Unicast"); ++ goto endsrc; ++ } ++ if (!memcmp(hlp->sourcemac, mac_type_multicast, 6) && ++ !memcmp(hlp->sourcemsk, msk_type_multicast, 6)) { ++ printf("Multicast"); ++ goto endsrc; ++ } ++ if (!memcmp(hlp->sourcemac, mac_type_broadcast, 6) && ++ !memcmp(hlp->sourcemsk, msk_type_broadcast, 6)) { ++ printf("Broadcast"); ++ goto endsrc; ++ } + for (j = 0; j < ETH_ALEN; j++) + printf("%02x%s", hlp->sourcemac[j], +- (j == ETH_ALEN - 1) ? ", " : ":"); ++ (j == ETH_ALEN - 1) ? "" : ":"); ++ if (memcmp(hlp->sourcemsk, hlpmsk, 6)) { ++ printf("/"); ++ for (j = 0; j < ETH_ALEN; j++) ++ printf("%02x%s", hlp->sourcemsk[j], ++ (j == ETH_ALEN - 1) ? "" : ":"); ++ } ++endsrc: ++ printf(", "); + } + if (hlp->bitmask & EBT_DESTMAC) { ++ char hlpmsk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ + printf("dest mac: "); + if (hlp->invflags & EBT_IDEST) + printf("! "); ++ if (!memcmp(hlp->destmac, mac_type_unicast, 6) && ++ !memcmp(hlp->destmsk, msk_type_unicast, 6)) { ++ printf("Unicast"); ++ goto enddst; ++ } ++ if (!memcmp(hlp->destmac, mac_type_multicast, 6) && ++ !memcmp(hlp->destmsk, msk_type_multicast, 6)) { ++ printf("Multicast"); ++ goto enddst; ++ } ++ if (!memcmp(hlp->destmac, mac_type_broadcast, 6) && ++ !memcmp(hlp->destmsk, msk_type_broadcast, 6)) { ++ printf("Broadcast"); ++ goto enddst; ++ } + for (j = 0; j < ETH_ALEN; j++) + printf("%02x%s", hlp->destmac[j], +- (j == ETH_ALEN - 1) ? ", " : ":"); ++ (j == ETH_ALEN - 1) ? "" : ":"); ++ if (memcmp(hlp->destmsk, hlpmsk, 6)) { ++ printf("/"); ++ for (j = 0; j < ETH_ALEN; j++) ++ printf("%02x%s", hlp->destmsk[j], ++ (j == ETH_ALEN - 1) ? "" : ":"); ++ } ++enddst: ++ printf(", "); + } + if (hlp->in[0] != '\0') { + if (hlp->invflags & EBT_IIN) +@@ -1096,6 +1153,39 @@ + return 0; + } + ++int getmac_and_mask(char *from, char *to, char *mask) ++{ ++ char *p; ++ int i; ++ ++ if (strcasecmp(from, "Unicast") == 0) { ++ memcpy(to, mac_type_unicast, ETH_ALEN); ++ memcpy(mask, msk_type_unicast, ETH_ALEN); ++ return 0; ++ } ++ if (strcasecmp(from, "Multicast") == 0) { ++ memcpy(to, mac_type_multicast, ETH_ALEN); ++ memcpy(mask, msk_type_multicast, ETH_ALEN); ++ return 0; ++ } ++ if (strcasecmp(from, "Broadcast") == 0) { ++ memcpy(to, mac_type_broadcast, ETH_ALEN); ++ memcpy(mask, msk_type_broadcast, ETH_ALEN); ++ return 0; ++ } ++ if ( (p = strrchr(from, '/')) != NULL) { ++ *p = '\0'; ++ if (getmac(p + 1, mask)) ++ return -1; ++ } else ++ memset(mask, 0xff, ETH_ALEN); ++ if (getmac(from, to)) ++ return -1; ++ for (i = 0; i < ETH_ALEN; i++) ++ to[i] &= mask[i]; ++ return 0; ++} ++ + int check_inverse(const char option[]) + { + if (strcmp(option, "!") == 0) { +@@ -1294,9 +1384,11 @@ + print_error("Command and option do not match"); + if (c == 'i') { + check_option(&replace.flags, OPT_IN); +- if (replace.selected_hook > 2) ++ if (replace.selected_hook > 2 && ++ replace.selected_hook < NF_BR_BROUTING) + print_error("Use in-interface only in " +- "INPUT, FORWARD and PREROUTING chains"); ++ "INPUT, FORWARD, PREROUTING and" ++ "BROUTING chains"); + if (check_inverse(optarg)) + new_entry->invflags |= EBT_IIN; + +@@ -1310,10 +1402,11 @@ + } + if (c == 2) { + check_option(&replace.flags, OPT_LOGICALIN); +- if (replace.selected_hook > 2) ++ if (replace.selected_hook > 2 && ++ replace.selected_hook < NF_BR_BROUTING) + print_error("Use logical in-interface " +- "only in INPUT, FORWARD and " +- "PREROUTING chains"); ++ "only in INPUT, FORWARD, " ++ "PREROUTING and BROUTING chains"); + if (check_inverse(optarg)) + new_entry->invflags |= EBT_ILOGICALIN; + +@@ -1398,8 +1491,8 @@ + if (optind > argc) + print_error("No source mac " + "specified"); +- if (getmac(argv[optind - 1], +- new_entry->sourcemac)) ++ if (getmac_and_mask(argv[optind - 1], ++ new_entry->sourcemac, new_entry->sourcemsk)) + print_error("Problem with specified " + "source mac"); + new_entry->bitmask |= EBT_SOURCEMAC; +@@ -1413,8 +1506,8 @@ + if (optind > argc) + print_error("No destination mac " + "specified"); +- if (getmac(argv[optind - 1], +- new_entry->destmac)) ++ if (getmac_and_mask(argv[optind - 1], ++ new_entry->destmac, new_entry->destmsk)) + print_error("Problem with specified " + "destination mac"); + new_entry->bitmask |= EBT_DESTMAC; +--- ebtables-v2.0pre3/communication.c Sat Apr 27 22:31:19 2002 ++++ ebtables-v2.0pre4.001/communication.c Thu May 2 19:02:44 2002 +@@ -121,7 +121,10 @@ + sizeof(tmp->logical_out)); + memcpy(tmp->sourcemac, e->sourcemac, + sizeof(tmp->sourcemac)); ++ memcpy(tmp->sourcemsk, e->sourcemsk, ++ sizeof(tmp->sourcemsk)); + memcpy(tmp->destmac, e->destmac, sizeof(tmp->destmac)); ++ memcpy(tmp->destmsk, e->destmsk, sizeof(tmp->destmsk)); + + base = p; + p += sizeof(struct ebt_entry); +@@ -307,7 +310,9 @@ + memcpy(new->logical_out, e->logical_out, + sizeof(new->logical_out)); + memcpy(new->sourcemac, e->sourcemac, sizeof(new->sourcemac)); ++ memcpy(new->sourcemsk, e->sourcemsk, sizeof(new->sourcemsk)); + memcpy(new->destmac, e->destmac, sizeof(new->destmac)); ++ memcpy(new->destmsk, e->destmsk, sizeof(new->destmsk)); + new->m_list = NULL; + new->w_list = NULL; + new->next = NULL; +--- ebtables-v2.0pre3/ChangeLog Sat Apr 27 22:31:21 2002 ++++ ebtables-v2.0pre4.001/ChangeLog Thu May 2 19:02:44 2002 +@@ -1,3 +1,11 @@ ++20020501 ++ * allow -i and --logical-in in BROUTING ++ * update the manual page ++ * rename /etc/etherproto into /etc/ethertypes (seems to be a more ++ standard name) ++ * add MAC mask for -s and -d, also added Unicast, Multicast and ++ Broadcast specification for specifying a (family of) MAC ++ addresses. + 20020427 + * added broute table. + * added redirect target. +--- ebtables-v2.0pre3/ebtables.8 Sat Apr 27 22:31:21 2002 ++++ ebtables-v2.0pre4.001/ebtables.8 Thu May 2 19:02:44 2002 +@@ -1,4 +1,4 @@ +-.TH EBTABLES 8 "27 April 2002" ++.TH EBTABLES 8 "01 May 2002" + .\" + .\" Man page written by Bart De Schuymer + .\" It is based on the iptables man page. +@@ -31,7 +31,7 @@ + .br + .B "ebtables -L DB" + .br +-.BR "ebtables -[cb] [" "y/n" "]" ++.BR "ebtables -[b] [" "y/n" "]" + .br + .SH DESCRIPTION + .B ebtables +@@ -88,13 +88,14 @@ + .B POSTROUTING + (for altering frames as they are about to go out). A small note on the naming + 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. ++PREFORWARDING and POSTFORWARDING, but for all those who come from the ++.BR 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 ++.BR DROP " and " ACCEPT + have special meaning in this table. + .B DROP + actually means the frame has to be routed, while +@@ -178,8 +179,9 @@ + .B ebtables + for these frames is + .BR LENGTH . ++.br + The file +-.B /etc/etherproto ++.B /etc/ethertypes + can be used to show readable + characters instead of hexadecimal numbers for the protocols. For example, + .I 0x0800 +@@ -193,9 +195,8 @@ + .BR "-i, --in-interface " "[!] \fIname\fP" + The interface via which a frame is received (for the + .BR INPUT , +-.B FORWARD +-and +-.B PREROUTING ++.BR FORWARD , ++.BR PREROUTING " and " BROUTING + chains). The flag + .B --in-if + is an alias for this option. +@@ -203,9 +204,8 @@ + .BR "--logical-in " "[!] \fIname\fP" + The (logical) bridge interface via which a frame is received (for the + .BR INPUT , +-.B FORWARD +-and +-.B PREROUTING ++.BR FORWARD , ++.BR PREROUTING " and " BROUTING + chains). + .TP + .BR "-o, --out-interface " "[!] \fIname\fP" +@@ -227,23 +227,31 @@ + .B POSTROUTING + chains). + .TP +-.BR "-s, --source " "[!] \fIaddress\fP" +-The source mac address. The flag ++.BR "-s, --source " "[!] \fIaddress\fP[/\fImask\fP]" ++The source mac address. Both mask and address are written as 6 hexadecimal ++numbers seperated by colons. Alternatively one can specify Unicast, ++Multicast or Broadcast. ++.br ++Unicast=00:00:00:00:00:00/01:00:00:00:00:00, ++Multicast=01:00:00:00:00:00/01:00:00:00:00:00 and ++Broadcast=ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff. Note that a broadcast ++address will also match the multicast specification. The flag + .B --src + is an alias for this option. + .TP +-.BR "-d, --destination " "[!] \fIaddress\fP" +-The destination mac address. The flag ++.BR "-d, --destination " "[!] \fIaddress\fP[/\fImask\fP]" ++The destination mac address. See -s (above) for more details. The flag + .B --dst + is an alias for this option. + + .SS OTHER OPTIONS ++.TP + .B "-V, --version" + Show the version of the userprogram. + .TP + .B "-h, --help" +-Give a brief description of the command syntax. Here you can specify names of +-extensions and ++Give a brief description of the command syntax. Here you can also specify ++names of extensions and + .B ebtables + will try to write help about those extensions. E.g. ebtables -h snat log ip arp. + .TP +@@ -258,7 +266,8 @@ + or a target extension, see + .BR "TARGET EXTENSIONS" . + .SH MATCH EXTENSIONS +-ebtables extensions are precompiled into the userspace tool. So there is no need ++.B ebtables ++extensions are precompiled into the userspace tool. So there is no need + to explicitly load them with a -m option like in iptables. However, these + extensions deal with functionality supported by supplemental kernel modules. + .SS ip +@@ -291,10 +300,11 @@ + .BR ARP " or " RARP . + .TP + .BR "--arp-opcode " "[!] \fIopcode\fP" +-The (r)arp opcode (decimal or a string, see ebtables help). ++The (r)arp opcode (decimal or a string, for more details see ebtables -h arp). + .TP + .BR "--arp-htype " "[!] \fIhardware type\fP" +-The hardware type (decimal or the string "Ethernet"). This is normally Ethernet (value 1). ++The hardware type, this can be a decimal or the string "Ethernet". This ++is normally Ethernet (value 1). + .TP + .BR "--arp-ptype " "[!] \fIprotocol type\fP" + The protocol type for which the (r)arp is used (hexadecimal or the string "IPv4"). +@@ -354,7 +364,9 @@ + .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. ++to give a standard target so ++.B 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. +@@ -376,7 +388,9 @@ + .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. ++give a standard target so ++.B 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 +@@ -385,7 +399,7 @@ + .B redirect + The + .B redirect +-target will change the MAC target address to that of the physical nic the ++target will change the MAC target address to that of the bridge device 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." +@@ -393,12 +407,14 @@ + .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. ++still has to give a standard target so ++.B 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 ++.I /etc/ethertypes + .SH BUGS + This won't work on an architecture with a user32/kernel64 situation like the Sparc64. + .SH AUTHOR +--- ebtables-v2.0pre3/etherproto Wed Apr 3 13:16:59 2002 ++++ /dev/null Thu Aug 24 11:00:32 2000 +@@ -1,36 +0,0 @@ +- # all whitespace is ignored +- # comment lines must have a '#' as the first character +- # all protocol numbers are in hexadecimal form +- # maximum namesize = 20 characters +- # always put tabs or spaces between the name and the protocol number +-# don't use more than 4 digits for the protocol number +-# programs using this file should not be case sensitive +-# that's all :-)) +-IPV4 0800 put your comments behind, on the same line, after a tab +-X25 0800 or whitespace +-ARP 0806 +-IPX 8137 +-IPV6 86DD +-NetBEUI 8191 +- +-# some definitions from the kernel (/include/linux/if_ether.h) +- +-BPQ 08FF G8BPQ AX.25 Ethernet Packet +-DEC 6000 DEC Assigned proto +-DNA_DL 6001 DEC DNA Dump/Load +-DNA_RC 6002 DEC DNA Remote Console +-DNA_RT 6003 DEC DNA Routing +-LAT 6004 DEC LAT +-DIAG 6005 DEC Diagnostics +-CUST 6006 DEC Customer use +-SCA 6007 DEC Systems Comms Arch +-RARP 8035 Reverse Addr Res packet +-ATALK 809B Appletalk DDP +-AARP 80F3 Appletalk AARP +-IPX 8137 IPX over DIX +-PPP_DISC 8863 PPPoE discovery messages +-PPP_SES 8864 PPPoE session messages +-ATMMPOA 884C MultiProtocol over ATM +-ATMFATE 8884 Frame-based ATM Transport over Ethernet +- +- +--- /dev/null Thu Aug 24 11:00:32 2000 ++++ ebtables-v2.0pre4.001/ethertypes Thu May 2 19:02:44 2002 +@@ -0,0 +1,36 @@ ++ # all whitespace is ignored ++ # comment lines must have a '#' as the first character ++ # all protocol numbers are in hexadecimal form ++ # maximum namesize = 20 characters ++ # always put tabs or spaces between the name and the protocol number ++# don't use more than 4 digits for the protocol number ++# programs using this file should not be case sensitive ++# that's all :-)) ++IPV4 0800 put your comments behind, on the same line, after a tab ++X25 0800 or whitespace ++ARP 0806 ++IPX 8137 ++IPV6 86DD ++NetBEUI 8191 ++ ++# some definitions from the kernel (/include/linux/if_ether.h) ++ ++BPQ 08FF G8BPQ AX.25 Ethernet Packet ++DEC 6000 DEC Assigned proto ++DNA_DL 6001 DEC DNA Dump/Load ++DNA_RC 6002 DEC DNA Remote Console ++DNA_RT 6003 DEC DNA Routing ++LAT 6004 DEC LAT ++DIAG 6005 DEC Diagnostics ++CUST 6006 DEC Customer use ++SCA 6007 DEC Systems Comms Arch ++RARP 8035 Reverse Addr Res packet ++ATALK 809B Appletalk DDP ++AARP 80F3 Appletalk AARP ++IPX 8137 IPX over DIX ++PPP_DISC 8863 PPPoE discovery messages ++PPP_SES 8864 PPPoE session messages ++ATMMPOA 884C MultiProtocol over ATM ++ATMFATE 8884 Frame-based ATM Transport over Ethernet ++ ++ +--- ebtables-v2.0pre3/include/ebtables_u.h Sat Apr 27 22:31:16 2002 ++++ ebtables-v2.0pre4.001/include/ebtables_u.h Thu May 2 19:02:44 2002 +@@ -86,7 +86,9 @@ + __u8 out[IFNAMSIZ]; + __u8 logical_out[IFNAMSIZ]; + __u8 sourcemac[ETH_ALEN]; ++ __u8 sourcemsk[ETH_ALEN]; + __u8 destmac[ETH_ALEN]; ++ __u8 destmsk[ETH_ALEN]; + struct ebt_u_match_list *m_list; + struct ebt_u_watcher_list *w_list; + struct ebt_entry_target *t; diff --git a/userspace/patches/incremental-patches/ebtables-v2.0pre5.001.diff b/userspace/patches/incremental-patches/ebtables-v2.0pre5.001.diff new file mode 100644 index 0000000..42202a4 --- /dev/null +++ b/userspace/patches/incremental-patches/ebtables-v2.0pre5.001.diff @@ -0,0 +1,50 @@ +update help and VLAN ethertype in /etc/ethertypes + +--- ebtables-v2.0pre4/Makefile Fri May 3 21:08:24 2002 ++++ ebtables-v2.0pre5.001/Makefile Fri May 3 21:34:23 2002 +@@ -2,7 +2,7 @@ + + KERNEL_DIR?=/usr/src/linux + PROGNAME:=ebtables +-PROGVERSION:="2.0pre4 (April 2002)" ++PROGVERSION:="2.0pre5 (April 2002)" + + MANDIR?=/usr/local/man + CFLAGS:=-Wall -Wunused +--- ebtables-v2.0pre4/ebtables.c Fri May 3 21:08:24 2002 ++++ ebtables-v2.0pre5.001/ebtables.c Fri May 3 21:33:55 2002 +@@ -628,8 +628,8 @@ + "--policy -P chain target : Change policy on chain to target\n" + "Options:\n" + "--proto -p [!] proto : protocol hexadecimal, by name or LENGTH\n" +-"--src -s [!] address : source mac address\n" +-"--dst -d [!] address : destination mac address\n" ++"--src -s [!] address[/mask]: source mac address\n" ++"--dst -d [!] address[/mask]: destination mac address\n" + "--in-if -i [!] name : network input interface name\n" + "--out-if -o [!] name : network output interface name\n" + "--logical-in [!] name : logical bridge input interface name\n" +--- ebtables-v2.0pre4/ChangeLog Fri May 3 21:08:25 2002 ++++ ebtables-v2.0pre5.001/ChangeLog Sat May 18 10:30:44 2002 +@@ -1,3 +1,5 @@ ++ * update help for -s and -d ++ * add VLAN in ethertypes + 20020501 + * allow -i and --logical-in in BROUTING + * update the manual page +--- ebtables-v2.0pre4/ethertypes Fri May 3 21:08:25 2002 ++++ ebtables-v2.0pre5.001/ethertypes Sat May 18 10:30:10 2002 +@@ -9,12 +9,10 @@ + IPV4 0800 put your comments behind, on the same line, after a tab + X25 0800 or whitespace + ARP 0806 ++VLAN 8100 + IPX 8137 + IPV6 86DD + NetBEUI 8191 +- +-# some definitions from the kernel (/include/linux/if_ether.h) +- + BPQ 08FF G8BPQ AX.25 Ethernet Packet + DEC 6000 DEC Assigned proto + DNA_DL 6001 DEC DNA Dump/Load diff --git a/userspace/patches/incremental-patches/ebtables-v2.0pre5.002.diff b/userspace/patches/incremental-patches/ebtables-v2.0pre5.002.diff new file mode 100644 index 0000000..5b2d037 --- /dev/null +++ b/userspace/patches/incremental-patches/ebtables-v2.0pre5.002.diff @@ -0,0 +1,61 @@ +--- ebtables-v2.0pre5.001/Makefile Mon May 20 13:59:48 2002 ++++ ebtables-v2.0pre5.002/Makefile Mon May 20 14:06:38 2002 +@@ -2,12 +2,19 @@ + + KERNEL_DIR?=/usr/src/linux + PROGNAME:=ebtables +-PROGVERSION:="2.0pre5 (April 2002)" ++PROGVERSION:="2.0pre5 (May 2002)" + + MANDIR?=/usr/local/man + CFLAGS:=-Wall -Wunused + include extensions/Makefile + ++# Some kernel testers prefer to use a symlink for /usr/include/linux ++ifeq ($(SYMLINK), y) ++KERNEL_INCLUDES=symlink ++else ++KERNEL_INCLUDES=headers ++endif ++ + .PHONY: headers + headers: + mkdir -p /usr/include/linux/netfilter_bridge +@@ -18,6 +25,10 @@ + cp -f $(KERNEL_DIR)/include/linux/netfilter_bridge.h \ + /usr/include/linux/netfilter_bridge.h + ++.PHONY: symlink ++symlink: ++ ln -fs $(KERNEL_DIR)/include/linux /usr/include/linux ++ + communication.o: communication.c include/ebtables_u.h + $(CC) $(CFLAGS) -c -o $@ $< + +@@ -36,7 +47,7 @@ + mkdir -p $(@D) + install -m 0644 -o root -g root $< $@ + +-install: $(MANDIR)/man8/ebtables.8 headers \ ++install: $(MANDIR)/man8/ebtables.8 $(KERNEL_INCLUDES) \ + ebtables /etc/ethertypes + + clean: +--- ebtables-v2.0pre5.001/THANKS Sat Apr 13 17:40:35 2002 ++++ ebtables-v2.0pre5.002/THANKS Mon May 20 13:49:50 2002 +@@ -6,4 +6,4 @@ + Jason Lunz + Tim Gardner + Loïc Minier +- ++Nick Fedchik +--- ebtables-v2.0pre5.001/ChangeLog Mon May 20 13:59:48 2002 ++++ ebtables-v2.0pre5.002/ChangeLog Mon May 20 13:49:27 2002 +@@ -1,5 +1,7 @@ ++20020520 + * update help for -s and -d + * add VLAN in ethertypes ++ * add SYMLINK option for compiling + 20020501 + * allow -i and --logical-in in BROUTING + * update the manual page diff --git a/userspace/patches/incremental-patches/ebtables-v2.0pre6.001.diff b/userspace/patches/incremental-patches/ebtables-v2.0pre6.001.diff new file mode 100644 index 0000000..a143d62 --- /dev/null +++ b/userspace/patches/incremental-patches/ebtables-v2.0pre6.001.diff @@ -0,0 +1,314 @@ +--- ebtables-v2.0pre5/Makefile Mon May 20 14:06:38 2002 ++++ ebtables-v2.0pre6.001/Makefile Thu May 30 18:39:04 2002 +@@ -2,7 +2,7 @@ + + KERNEL_DIR?=/usr/src/linux + PROGNAME:=ebtables +-PROGVERSION:="2.0pre5 (May 2002)" ++PROGVERSION:="2.0pre6 (May 2002)" + + MANDIR?=/usr/local/man + CFLAGS:=-Wall -Wunused +@@ -15,6 +15,8 @@ + KERNEL_INCLUDES=headers + endif + ++all: ebtables ++ + .PHONY: headers + headers: + mkdir -p /usr/include/linux/netfilter_bridge +@@ -52,3 +54,5 @@ + + clean: + -rm -f ebtables ++ rm -f *.o *.c~ ++ rm -f extensions/*.o extensions/*.c~ +--- /dev/null Thu Aug 24 11:00:32 2000 ++++ ebtables-v2.0pre6.001/extensions/ebt_vlan.c Thu May 30 18:38:44 2002 +@@ -0,0 +1,231 @@ ++/* ++ * Summary: ebt_vlan userspace module ++ * ++ * Description: 802.1Q Virtual LAN match support module for ebtables project. ++ * Enable to match 802.1Q VLAN tagged frames by VLAN numeric ++ * identifier (12-bites field) and frame priority (3-bites field) ++ * ++ * Authors: ++ * Bart De Schuymer ++ * Nick Fedchik ++ * ++ * May, 2002 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "../include/ebtables_u.h" ++#include ++ ++#define VLAN_ID '1' ++#define VLAN_PRIO '2' ++ ++static struct option opts[] = { ++ {"vlan-id", required_argument, 0, VLAN_ID}, ++ {"vlan-prio", required_argument, 0, VLAN_PRIO}, ++ {0} ++}; ++ ++/* ++ * Print out help for ebtables -h vlan ++ */ ++static void print_help () ++{ ++ printf ("802.1Q VLAN options:\n" ++ "--vlan-id [!] id : VLAN ID 1-4095 (integer)\n" ++ "--vlan-prio [!] prio : VLAN Priority 0-7 (integer)\n"); ++} ++ ++/* ++ * Initialization function ++ */ ++static void init (struct ebt_entry_match *match) ++{ ++ struct ebt_vlan_info *vlaninfo = ++ (struct ebt_vlan_info *) match->data; ++ /* ++ * Just clean initial values ++ */ ++ vlaninfo->id = 0; ++ vlaninfo->prio = 0; ++ vlaninfo->invflags = 0; ++ vlaninfo->bitmask = 0; ++} ++ ++#define OPT_VLAN_ID 0x01 ++#define OPT_VLAN_PRIO 0x02 ++static int ++parse (int c, char **argv, int argc, ++ const struct ebt_u_entry *entry, unsigned int *flags, ++ struct ebt_entry_match **match) ++{ ++ struct ebt_vlan_info *vlaninfo = ++ (struct ebt_vlan_info *) (*match)->data; ++ unsigned short i; ++ char *end; ++ ++ switch (c) { ++ case VLAN_ID: ++ check_option (flags, OPT_VLAN_ID); ++ /* ++ * Check If we got inversed arg for VID, ++ * otherwise unset inversion flag ++ */ ++ if (check_inverse (optarg)) ++ vlaninfo->invflags |= EBT_VLAN_ID; ++ /* ++ * Check arg value presense ++ */ ++ if (optind > argc) ++ print_error ("Missing VLAN ID argument\n"); ++ /* ++ * Convert argv to long int, ++ * set *end to end of argv string, ++ * base set 10 for decimal only ++ */ ++ (unsigned short) i = strtol (argv[optind - 1], &end, 10); ++ /* ++ * Check arg val range ++ */ ++ if (i < 1 || i >= 4096 || *end != '\0') { ++ i = 0; ++ print_error ++ ("Problem with specified VLAN ID range\n"); ++ } ++ vlaninfo->id = i; ++ vlaninfo->bitmask|=EBT_VLAN_ID; ++ break; ++ ++ case VLAN_PRIO: ++ check_option (flags, OPT_VLAN_PRIO); ++ if (check_inverse (optarg)) ++ vlaninfo->invflags |= EBT_VLAN_PRIO; ++ if (optind > argc) ++ print_error ++ ("Missing VLAN Priority level argument\n"); ++ /* ++ * Convert argv to long int, ++ * set *end to end of argv string, ++ * base set 10 for decimal only ++ */ ++ (unsigned short) i = strtol (argv[optind - 1], &end, 10); ++ /* ++ * Check arg val range ++ */ ++ if (i >= 8 || *end != '\0') { ++ i = 0; ++ print_error ++ ("Problem with specified VLAN Priority range\n"); ++ } ++ vlaninfo->prio = i; ++ vlaninfo->bitmask|=EBT_VLAN_PRIO; ++ break; ++ ++ default: ++ return 0; ++ } ++ return 1; ++} ++ ++/* ++ * Final check ++ */ ++static void ++final_check (const struct ebt_u_entry *entry, ++ const struct ebt_entry_match *match, ++ const char *name, unsigned int hook) ++{ ++ /* ++ * Is any proto supplied there? Or specified proto isn't 802.1Q? ++ */ ++ if (entry->bitmask & EBT_NOPROTO || entry->ethproto != ETH_P_8021Q) ++ print_error ++ ("For matching 802.1Q VLAN the protocol must be specified as 802_1Q\n"); ++} ++ ++/* ++ * Print line when listing rules by ebtables -L ++ */ ++static void ++print (const struct ebt_u_entry *entry, ++ const struct ebt_entry_match *match) ++{ ++ struct ebt_vlan_info *vlaninfo = ++ (struct ebt_vlan_info *) match->data; ++ ++ /* ++ * Print VLAN ID if they are specified ++ */ ++ if (vlaninfo->bitmask & EBT_VLAN_ID) { ++ printf ("vlan id: %s%d, ", ++ vlaninfo->invflags & EBT_VLAN_ID ? "!" : "", ++ vlaninfo->id); ++ } ++ /* ++ * Print VLAN priority if they are specified ++ */ ++ if (vlaninfo->bitmask & EBT_VLAN_PRIO) { ++ printf ("vlan prio: %s%d, ", ++ vlaninfo->invflags & EBT_VLAN_PRIO ? "!" : "", ++ vlaninfo->prio); ++ } ++} ++ ++ ++static int ++compare (const struct ebt_entry_match *vlan1, ++ const struct ebt_entry_match *vlan2) ++{ ++ struct ebt_vlan_info *vlaninfo1 = ++ (struct ebt_vlan_info *) vlan1->data; ++ struct ebt_vlan_info *vlaninfo2 = ++ (struct ebt_vlan_info *) vlan2->data; ++ /* ++ * Compare argc ++ */ ++ if (vlaninfo1->bitmask != vlaninfo2->bitmask) ++ return 0; ++ /* ++ * Compare inv flags ++ */ ++ if (vlaninfo1->invflags != vlaninfo2->invflags) ++ return 0; ++ /* ++ * Compare VLAN ID if they are present ++ */ ++ if (vlaninfo1->bitmask & EBT_VLAN_ID) { ++ if (vlaninfo1->id != vlaninfo2->id) ++ return 0; ++ }; ++ /* ++ * Compare VLAN Prio if they are present ++ */ ++ if (vlaninfo1->bitmask & EBT_VLAN_PRIO) { ++ if (vlaninfo1->prio != vlaninfo2->prio) ++ return 0; ++ }; ++ return 1; ++} ++ ++static struct ebt_u_match vlan_match = { ++ EBT_VLAN_MATCH, ++ sizeof (struct ebt_vlan_info), ++ print_help, ++ init, ++ parse, ++ final_check, ++ print, ++ compare, ++ opts, ++}; ++ ++static void _init (void) __attribute__ ((constructor)); ++static void _init (void) ++{ ++ register_match (&vlan_match); ++} +--- ebtables-v2.0pre5/extensions/Makefile Sat Apr 27 22:31:21 2002 ++++ ebtables-v2.0pre6.001/extensions/Makefile Thu May 30 18:38:44 2002 +@@ -1,6 +1,6 @@ + #! /usr/bin/make + +-EXT_FUNC+=nat arp ip standard log redirect ++EXT_FUNC+=nat arp ip standard log redirect vlan + 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.0pre5/ebtables.8 Fri May 3 21:08:25 2002 ++++ ebtables-v2.0pre6.001/ebtables.8 Thu May 30 18:43:19 2002 +@@ -315,6 +315,17 @@ + .TP + .BR "--arp-ip-dst " "[!] \fIaddress\fP[/\fImask\fP]" + The ARP IP destination address specification. ++.SS vlan ++Specify 802.1Q VLAN specific fields. These will only work if the protocol equals ++.BR 802_1Q . ++For more details see ++.BR "ebtables -h vlan" . ++.TP ++.BR "--vlan-id " "[!] \fIid\fP" ++The VLAN identifier (decimal number from 0 to 4095). ++.TP ++.BR "--vlan-prio " "[!] \fIprio\fP" ++The VLAN priority type, this can be a decimal number from 0 to 7. The default value is 0. + .SH WATCHER EXTENSION(S) + Watchers are things that only look at frames passing by. These watchers only see the + frame if the frame passes all the matches of the rule. +--- ebtables-v2.0pre5/ethertypes Sat May 18 10:30:10 2002 ++++ ebtables-v2.0pre6.001/ethertypes Thu May 30 18:38:44 2002 +@@ -1,15 +1,15 @@ +- # all whitespace is ignored +- # comment lines must have a '#' as the first character +- # all protocol numbers are in hexadecimal form +- # maximum namesize = 20 characters +- # always put tabs or spaces between the name and the protocol number ++# all whitespace is ignored ++# comment lines must have a '#' as the first character ++# all protocol numbers are in hexadecimal form ++# maximum namesize = 20 characters ++# always put tabs or spaces between the name and the protocol number + # don't use more than 4 digits for the protocol number + # programs using this file should not be case sensitive + # that's all :-)) + IPV4 0800 put your comments behind, on the same line, after a tab + X25 0800 or whitespace + ARP 0806 +-VLAN 8100 ++802_1Q 8100 802.1Q Virtual LAN tagged frame + IPX 8137 + IPV6 86DD + NetBEUI 8191 -- cgit v1.2.3