From a88c8e16f4942deeb39c526bb02c33539202deb8 Mon Sep 17 00:00:00 2001 From: Bart De Schuymer Date: Sun, 8 Dec 2002 17:25:45 +0000 Subject: *** empty log message *** --- .../v2.0/ebtables-v2.0.2.001.diff | 2445 ++++++++++++++++++++ .../patches/zipped/v2.0/ebtables-v2.0.2.tar.gz | Bin 0 -> 55074 bytes 2 files changed, 2445 insertions(+) create mode 100644 userspace/patches/incremental-patches/v2.0/ebtables-v2.0.2.001.diff create mode 100644 userspace/patches/zipped/v2.0/ebtables-v2.0.2.tar.gz diff --git a/userspace/patches/incremental-patches/v2.0/ebtables-v2.0.2.001.diff b/userspace/patches/incremental-patches/v2.0/ebtables-v2.0.2.001.diff new file mode 100644 index 0000000..d7b588c --- /dev/null +++ b/userspace/patches/incremental-patches/v2.0/ebtables-v2.0.2.001.diff @@ -0,0 +1,2445 @@ +--- ebtables-v2.0.1/Makefile Thu Oct 17 23:27:29 2002 ++++ ebtables-v2.0.2/Makefile Sat Dec 7 13:09:40 2002 +@@ -1,64 +1,86 @@ + # ebtables Makefile + +-KERNEL_DIR?=/usr/src/linux + PROGNAME:=ebtables +-PROGVERSION:="2.0.1" +-PROGDATE:="October 2002" ++PROGVERSION:=2.0.2 ++PROGDATE:=December\ 2002 + + MANDIR?=/usr/local/man + CFLAGS:=-Wall -Wunused + CC:=gcc ++ + include extensions/Makefile + +-# Some kernel testers prefer to use a symlink for /usr/include/linux +-ifeq ($(SYMLINK), y) +-KERNEL_INCLUDES=symlink ++OBJECTS:=getethertype.o ebtables.o communication.o $(EXT_OBJS) ++ ++# Use the option NONSTANDARD=y when you don't want to use the kernel includes ++# that are included in this package. You should set KERNEL_INCLUDES to ++# the right directory (eg /usr/src/linux/include). ++# You should only need this when compiling the CVS or when adding new code. ++ifeq ($(NONSTANDARD), y) ++KERNEL_INCLUDES?=/usr/include/ + else +-KERNEL_INCLUDES=headers ++KERNEL_INCLUDES:=include/ ++endif ++ ++ifeq ($(ETHERTYPESPATH),) ++ETHERTYPESPATH:=/etc/ + endif ++ETHERTYPESFILE:=$(ETHERTYPESPATH)ethertypes + +-all: ebtables ++PROGSPECS:=-DPROGVERSION=\"$(PROGVERSION)\" \ ++ -DPROGNAME=\"$(PROGNAME)\" \ ++ -DPROGDATE=\"$(PROGDATE)\" \ ++ -D_PATH_ETHERTYPES=\"$(ETHERTYPESFILE)\" + +-.PHONY: headers +-headers: +- mkdir -p /usr/include/linux/netfilter_bridge +- cp -f $(KERNEL_DIR)/include/linux/netfilter_bridge/* \ +- /usr/include/linux/netfilter_bridge/ +- cp -f $(KERNEL_DIR)/include/linux/netfilter_bridge.h \ +- /usr/include/linux/netfilter_bridge.h +- cp -f $(KERNEL_DIR)/include/linux/if_ether.h \ +- /usr/include/linux/if_ether.h +- +-.PHONY: symlink +-symlink: +- rm -f /usr/include/linux +- ln -fs $(KERNEL_DIR)/include/linux /usr/include/linux ++ ++all: ebtables + + communication.o: communication.c include/ebtables_u.h +- $(CC) $(CFLAGS) -DPROGVERSION=\"$(PROGVERSION)\" -c -o $@ $< ++ $(CC) $(CFLAGS) $(PROGSPECS) -c -o $@ $< -I$(KERNEL_INCLUDES) ++ ++getethertype.o: getethertype.c include/ethernetdb.h ++ $(CC) $(CFLAGS) $(PROGSPECS) -c -o $@ $< -Iinclude/ + + ebtables.o: ebtables.c include/ebtables_u.h +- $(CC) $(CFLAGS) -DPROGVERSION=\"$(PROGVERSION)\" \ +- -DPROGNAME=\"$(PROGNAME)\" -DPROGDATE=\"$(PROGDATE)\" -c -o $@ $< ++ $(CC) $(CFLAGS) $(PROGSPECS) -c -o $@ $< -I$(KERNEL_INCLUDES) + +-ebtables: ebtables.o communication.o $(EXT_OBJS) +- $(CC) $(CFLAGS) -o $@ $^ ++ebtables: $(OBJECTS) ++ $(CC) $(CFLAGS) -o $@ $^ -I$(KERNEL_INCLUDES) + + $(MANDIR)/man8/ebtables.8: ebtables.8 + mkdir -p $(@D) + install -m 0644 -o root -g root $< $@ + +-/etc/ethertypes: ethertypes ++$(ETHERTYPESFILE): ethertypes + mkdir -p $(@D) + install -m 0644 -o root -g root $< $@ ++ + .PHONY: exec + exec: ebtables + install -m 0755 -o root -g root $< /sbin/ebtables + +-install: $(MANDIR)/man8/ebtables.8 $(KERNEL_INCLUDES) \ +- ebtables /etc/ethertypes exec ++.PHONY: install ++install: $(MANDIR)/man8/ebtables.8 ebtables $(ETHERTYPESFILE) exec + ++.PHONY: clean + clean: + rm -f ebtables + rm -f *.o *.c~ + rm -f extensions/*.o extensions/*.c~ ++ ++DIR:=$(PROGNAME)-v$(PROGVERSION) ++# This is used to make a new userspace release ++.PHONY: release ++release: ++ mkdir -p include/linux/netfilter_bridge ++ install -m 0644 -o root -g root \ ++ $(KERNEL_INCLUDES)/linux/netfilter_bridge.h include/linux/ ++# To keep possible compile error complaints about undefined ETH_P_8021Q ++# off my back ++ install -m 0644 -o root -g root \ ++ $(KERNEL_INCLUDES)/linux/if_ether.h include/linux/ ++ install -m 0644 -o root -g root \ ++ $(KERNEL_INCLUDES)/linux/netfilter_bridge/*.h \ ++ include/linux/netfilter_bridge/ ++ make clean ++ cd ..;tar -c $(DIR) | gzip >$(DIR).tar.gz +--- ebtables-v2.0.1/ebtables.c Thu Oct 17 22:51:12 2002 ++++ ebtables-v2.0.2/ebtables.c Tue Dec 3 22:52:12 2002 +@@ -28,11 +28,14 @@ + #include + #include + #include "include/ebtables_u.h" ++#include "include/ethernetdb.h" + #include + #include + #include + +-// Don't use this function, use print_bug() ++/* ++ * Don't use this function, use print_bug() ++ */ + void __print_bug(char *file, int line, char *format, ...) + { + va_list l; +@@ -45,13 +48,10 @@ + exit (-1); + } + +-// here are the number-name correspondences kept for the Ethernet +-// frame type field +-#define PROTOCOLFILE "/etc/ethertypes" +- + #ifndef PROC_SYS_MODPROBE + #define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe" + #endif ++#define ATOMIC_ENV_VARIABLE "EBTABLES_ATOMIC_FILE" + + char *hooknames[NF_BR_NUMHOOKS] = + { +@@ -63,9 +63,11 @@ + [NF_BR_BROUTING]"BROUTING" + }; + +-// default command line options +-// do not mess around with the already assigned numbers unless +-// you know what you are doing ++/* ++ * default command line options ++ * do not mess around with the already assigned numbers unless ++ * you know what you are doing ++ */ + static struct option ebt_original_options[] = + { + { "append" , required_argument, 0, 'A' }, +@@ -99,17 +101,16 @@ + { "new-chain" , required_argument, 0, 'N' }, + { "rename-chain" , required_argument, 0, 'E' }, + { "delete-chain" , required_argument, 0, 'X' }, +- { "atomic-init" , required_argument, 0, 7 }, +- { "atomic-commit" , required_argument, 0, 8 }, +- { "atomic" , required_argument, 0, 9 }, +- { "atomic-save" , required_argument, 0, 10 }, ++ { "atomic-init" , no_argument , 0, 7 }, ++ { "atomic-commit" , no_argument , 0, 8 }, ++ { "atomic-file" , required_argument, 0, 9 }, ++ { "atomic-save" , no_argument , 0, 10 }, + { "init-table" , no_argument , 0, 11 }, + { 0 } + }; + + static struct option *ebt_options = ebt_original_options; + +-// yup, all the possible target names + char* standard_targets[NUM_STANDARD_TARGETS] = + { + "ACCEPT", +@@ -125,12 +126,18 @@ + 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}; + +-// holds all the data ++/* ++ * holds all the data ++ */ + static struct ebt_u_replace replace; + +-// the chosen table ++/* ++ * the chosen table ++ */ + static struct ebt_u_table *table = NULL; +-// the lists of supported tables, matches, watchers and targets ++/* ++ * the lists of supported tables, matches, watchers and targets ++ */ + static struct ebt_u_table *tables = NULL; + static struct ebt_u_match *matches = NULL; + static struct ebt_u_watcher *watchers = NULL; +@@ -172,13 +179,15 @@ + 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. +-// Same holds for the struct ebt_match and struct ebt_watcher pointers ++/* ++ * 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; + + static void initialize_entry(struct ebt_u_entry *e) +@@ -199,7 +208,9 @@ + print_bug("Couldn't load standard target"); + } + +-// this doesn't free e, becoz the calling function might need e->next ++/* ++ * this doesn't free e, becoz the calling function might need e->next ++ */ + static void free_u_entry(struct ebt_u_entry *e) + { + struct ebt_u_match_list *m_l, *m_l2; +@@ -222,7 +233,9 @@ + free(e->t); + } + +-// the user will use the match, so put it in new_entry ++/* ++ * 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; +@@ -350,8 +363,10 @@ + tables = t; + } + +-// blatently stolen (again) from iptables.c userspace program +-// find out where the modprobe utility is located ++/* ++ * blatently stolen (again) from iptables.c userspace program ++ * find out where the modprobe utility is located ++ */ + static char *get_modprobe(void) + { + int procfile; +@@ -411,59 +426,16 @@ + return 0; + } + +-// helper function: processes a line of data from the file /etc/ethertypes +-static int get_a_line(char *buffer, char *value, FILE *ifp) +-{ +- char line[80], *p; +- const char delim[] = " \t\n"; +- +- while (fgets(line, sizeof(line), ifp)) { +- p = strtok(line, delim); +- if (!p || p[0] == '#') +- continue; +- if (strlen(p) > 20) +- continue; +- strcpy(buffer, p); +- p = strtok(NULL, delim); +- if (!p || strlen(p) > 10) +- continue; +- strcpy(value, p); +- return 0; +- } +- return -1; +-} +- +-// translate a hexadecimal number to a protocol name, parsing /etc/ethertypes +-// returns 0 on success +-// this demands the name buffer to be of size at least 21 +-int number_to_name(unsigned short proto, char *name) +-{ +- FILE *ifp; +- char buffer[21], value[11], *bfr; +- unsigned short i; +- +- if ( !(ifp = fopen(PROTOCOLFILE, "r")) ) +- return -1; +- while (1) { +- if (get_a_line(buffer, value, ifp)) { +- fclose(ifp); +- return -1; +- } +- i = (unsigned short) strtol(value, &bfr, 16); +- if (*bfr != '\0' || i != proto) +- continue; +- strcpy(name, buffer); +- fclose(ifp); +- return 0; +- } +-} +- +-// we use replace.flags, so we can't use the following values: +-// 0x01 == OPT_COMMAND, 0x02 == OPT_TABLE, 0x100 == OPT_ZERO ++/* ++ * we use replace.flags, so we can't use the following values: ++ * 0x01 == OPT_COMMAND, 0x02 == OPT_TABLE, 0x100 == OPT_ZERO ++ */ + #define LIST_N 0x04 + #define LIST_C 0x08 + #define LIST_X 0x10 +-// helper function for list_rules() ++/* ++ * helper function for list_rules() ++ */ + static void list_em(struct ebt_u_entries *entries) + { + int i, j, space = 0, digits; +@@ -473,7 +445,6 @@ + struct ebt_u_match *m; + struct ebt_u_watcher *w; + struct ebt_u_target *t; +- char name[21]; + + hlp = entries->entries; + if (replace.flags & LIST_X && entries->policy != EBT_ACCEPT) { +@@ -508,8 +479,10 @@ + printf("ebtables -t %s -A %s ", + replace.name, entries->name); + +- // 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("-p "); + if (hlp->invflags & EBT_IPROTO) +@@ -517,10 +490,13 @@ + if (hlp->bitmask & EBT_802_3) + printf("Length "); + else { +- if (number_to_name(ntohs(hlp->ethproto), name)) ++ struct ethertypeent *ent; ++ ++ ent = getethertypebynumber(ntohs(hlp->ethproto)); ++ if (!ent) + printf("0x%x ", ntohs(hlp->ethproto)); + else +- printf("%s ", name); ++ printf("%s ", ent->e_name); + } + } + if (hlp->bitmask & EBT_SOURCEMAC) { +@@ -665,7 +641,7 @@ + } + } + +-static struct ebt_u_entries *to_chain() ++static inline struct ebt_u_entries *to_chain() + { + return nr_to_chain(replace.selected_hook); + } +@@ -686,7 +662,9 @@ + struct ebt_u_entry *e; + + i = -1; +- // initialize hook_mask to 0 ++ /* ++ * initialize hook_mask to 0 ++ */ + while (1) { + i++; + if (i < NF_BR_NUMHOOKS && !(replace.valid_hooks & (1 << i))) +@@ -703,13 +681,17 @@ + print_memory(); + } + +- // check for loops, starting from every base chain ++ /* ++ * check for loops, starting from every base chain ++ */ + for (i = 0; i < NF_BR_NUMHOOKS; i++) { + if (!(replace.valid_hooks & (1 << i))) + continue; + entries = nr_to_chain(i); +- // (1 << NF_BR_NUMHOOKS) implies it's a standard chain +- // (usefull in the final_check() funtions) ++ /* ++ * (1 << NF_BR_NUMHOOKS) implies it's a standard chain ++ * (usefull in the final_check() funtions) ++ */ + entries->hook_mask = (1 << i) | (1 << NF_BR_NUMHOOKS); + chain_nr = i; + +@@ -722,13 +704,17 @@ + goto letscontinue; + entries2 = nr_to_chain(verdict + NF_BR_NUMHOOKS); + entries2->hook_mask |= entries->hook_mask; +- // now see if we've been here before ++ /* ++ * now see if we've been here before ++ */ + for (k = 0; k < sp; k++) + if (stack[k].chain_nr == verdict + NF_BR_NUMHOOKS) + print_error("Loop from chain %s to chain %s", + nr_to_chain(chain_nr)->name, + nr_to_chain(stack[k].chain_nr)->name); +- // jump to the chain, make sure we know how to get back ++ /* ++ * jump to the chain, make sure we know how to get back ++ */ + stack[sp].chain_nr = chain_nr; + stack[sp].n = j; + stack[sp].entries = entries; +@@ -742,10 +728,14 @@ + letscontinue: + e = e->next; + } +- // we are at the end of a standard chain ++ /* ++ * we are at the end of a standard chain ++ */ + if (sp == 0) + continue; +- // go back to the chain one level higher ++ /* ++ * go back to the chain one level higher ++ */ + sp--; + j = stack[sp].n; + chain_nr = stack[sp].chain_nr; +@@ -757,8 +747,10 @@ + return; + } + +-// parse the chain name and return the corresponding nr +-// returns -1 on failure ++/* ++ * parse the chain name and return the corresponding nr ++ * returns -1 on failure ++ */ + int get_hooknr(char* arg) + { + int i; +@@ -779,7 +771,6 @@ + return -1; + } + +-// yup, print out help + static void print_help() + { + struct ebt_u_match_list *m_l; +@@ -790,7 +781,8 @@ + "ebtables -[ADI] chain rule-specification [options]\n" + "ebtables -P chain target\n" + "ebtables -[LFZ] [chain]\n" +-"ebtables -[b] [y,n]\n" ++"ebtables -[NX] [chain]\n" ++"ebtables -E old-chain-name new-chain-name\n\n" + "Commands:\n" + "--append -A chain : append to chain\n" + "--delete -D chain : delete matching rule from chain\n" +@@ -804,10 +796,10 @@ + "--new-chain -N chain : create a user defined chain\n" + "--rename-chain -E old new : rename a chain\n" + "--delete-chain -X chain : delete a user defined chain\n" +-"--atomic-commit file : update the kernel w/ the table contained in file\n" +-"--atomic-init file : put the initial kernel table into file\n" +-"--atomic-save file : put the current kernel table into file\n" +-"--atomic file : write changes to file instead of kernel\n" ++"--atomic-commit : update the kernel w/t table contained in \n" ++"--atomic-init : put the initial kernel table into \n" ++"--atomic-save : put the current kernel table into \n" ++"--atomic file : set to file\n\n" + "Options:\n" + "--proto -p [!] proto : protocol hexadecimal, by name or LENGTH\n" + "--src -s [!] address[/mask]: source mac address\n" +@@ -817,8 +809,10 @@ + "--logical-in [!] name : logical bridge input interface name\n" + "--logical-out [!] name : logical bridge output interface name\n" + "--modprobe -M program : try to insert modules using this program\n" +-"--version -V : print package version\n" +-"\n"); ++"--version -V : print package version\n\n" ++"Environment variable:\n" ++ATOMIC_ENV_VARIABLE " : if set (see above) will equal its value" ++"\n\n"); + + m_l = new_entry->m_list; + while (m_l) { +@@ -839,7 +833,9 @@ + exit(0); + } + +-// execute command L ++/* ++ * execute command L ++ */ + static void list_rules() + { + int i; +@@ -851,7 +847,9 @@ + } else { + struct ebt_u_chain_list *cl = replace.udc; + +- // create new chains and rename standard chains when necessary ++ /* ++ * create new chains and rename standard chains when necessary ++ */ + if (replace.flags & LIST_X) { + while (cl) { + printf("ebtables -t %s -N %s\n", replace.name, +@@ -883,22 +881,30 @@ + } + } + +-// execute command P ++/* ++ * execute command P ++ */ + static void change_policy(int policy) + { + int i; + struct ebt_u_entries *entries = to_chain(); + +- // don't do anything if the policy is the same ++ /* ++ * don't do anything if the policy is the same ++ */ + if (entries->policy != policy) { + entries->policy = policy; + replace.num_counters = replace.nentries; + if (replace.nentries) { +- // '+ 1' for the CNT_END ++ /* ++ * '+ 1' for the CNT_END ++ */ + if (!(replace.counterchanges = (unsigned short *) malloc( + (replace.nentries + 1) * sizeof(unsigned short)))) + print_memory(); +- // done nothing special to the rules ++ /* ++ * done nothing special to the rules ++ */ + for (i = 0; i < replace.nentries; i++) + replace.counterchanges[i] = CNT_NORM; + replace.counterchanges[replace.nentries] = CNT_END; +@@ -910,9 +916,11 @@ + exit(0); + } + +-// flush one chain or the complete table +-// -1 == nothing to do +-// 0 == give back to kernel ++/* ++ * flush one chain or the complete table ++ * -1 == nothing to do ++ * 0 == give back to kernel ++ */ + static int flush_chains() + { + int i, j, oldnentries, numdel; +@@ -920,15 +928,21 @@ + struct ebt_u_entry *u_e, *tmp; + struct ebt_u_entries *entries = to_chain(); + +- // flush whole table ++ /* ++ * flush whole table ++ */ + if (!entries) { + if (replace.nentries == 0) + return -1; + replace.nentries = 0; +- // no need for the kernel to give us counters back ++ /* ++ * no need for the kernel to give us counters back ++ */ + replace.num_counters = 0; + +- // free everything and zero (n)entries ++ /* ++ * free everything and zero (n)entries ++ */ + i = -1; + while (1) { + i++; +@@ -960,13 +974,17 @@ + numdel = entries->nentries; + + if (replace.nentries) { +- // +1 for CNT_END ++ /* ++ * +1 for CNT_END ++ */ + if ( !(replace.counterchanges = (unsigned short *) + malloc((oldnentries + 1) * sizeof(unsigned short))) ) + print_memory(); + } +- // delete the counters belonging to the specified chain, +- // update counter_offset ++ /* ++ * delete the counters belonging to the specified chain, ++ * update counter_offset ++ */ + i = -1; + cnt = replace.counterchanges; + while (1) { +@@ -994,8 +1012,7 @@ + if (replace.nentries) { + *cnt = CNT_END; + replace.num_counters = oldnentries; +- } +- else ++ } else + replace.num_counters = 0; + + entries = to_chain(); +@@ -1011,7 +1028,9 @@ + return 0; + } + +-// -1 == no match ++/* ++ * -1 == no match ++ */ + static int check_rule_exists(int rule_nr) + { + struct ebt_u_entry *u_e; +@@ -1023,16 +1042,22 @@ + struct ebt_u_entries *entries = to_chain(); + int i, j, k; + +- // handle '-D chain rulenr' command ++ /* ++ * handle '-D chain rulenr' command ++ */ + if (rule_nr != -1) { + if (rule_nr > entries->nentries) + return -1; +- // user starts counting from 1 ++ /* ++ * user starts counting from 1 ++ */ + return rule_nr - 1; + } + u_e = entries->entries; +- // check for an existing rule (if there are duplicate rules, +- // take the first occurance) ++ /* ++ * check for an existing rule (if there are duplicate rules, ++ * take the first occurance) ++ */ + for (i = 0; i < entries->nentries; i++, u_e = u_e->next) { + if (!u_e) + print_bug("Hmm, trouble"); +@@ -1055,7 +1080,9 @@ + if (new_entry->bitmask != u_e->bitmask || + new_entry->invflags != u_e->invflags) + continue; +- // compare all matches ++ /* ++ * compare all matches ++ */ + m_l = new_entry->m_list; + j = 0; + while (m_l) { +@@ -1068,7 +1095,9 @@ + j++; + m_l = m_l->next; + } +- // now be sure they have the same nr of matches ++ /* ++ * now be sure they have the same nr of matches ++ */ + k = 0; + m_l = u_e->m_list; + while (m_l) { +@@ -1078,7 +1107,9 @@ + if (j != k) + continue; + +- // compare all watchers ++ /* ++ * compare all watchers ++ */ + w_l = new_entry->w_list; + j = 0; + while (w_l) { +@@ -1119,19 +1150,23 @@ + struct ebt_u_watcher_list *w_l; + struct ebt_u_entries *entries = to_chain(), *entries2; + +- if (rule_nr != -1) { // command -I ++ if (rule_nr != -1) { /* command -I */ + if (--rule_nr > entries->nentries) + print_error("rule nr too high: %d > %d", rule_nr + 1, + entries->nentries + 1); + } else + rule_nr = entries->nentries; +- // we're adding one rule ++ /* ++ * we're adding one rule ++ */ + replace.num_counters = replace.nentries; + replace.nentries++; + entries->nentries++; + +- // handle counter stuff +- // +1 for CNT_END ++ /* ++ * handle counter stuff ++ * +1 for CNT_END ++ */ + if ( !(replace.counterchanges = (unsigned short *) + malloc((replace.nentries + 1) * sizeof(unsigned short))) ) + print_memory(); +@@ -1157,15 +1192,21 @@ + } + *cnt = CNT_END; + +- // go to the right position in the chain ++ /* ++ * go to the right position in the chain ++ */ + u_e = &entries->entries; + for (i = 0; i < rule_nr; i++) + u_e = &(*u_e)->next; +- // insert the rule ++ /* ++ * insert the rule ++ */ + new_entry->next = *u_e; + *u_e = new_entry; + +- // put the ebt_[match, watcher, target] pointers in place ++ /* ++ * put the ebt_[match, watcher, target] pointers in place ++ */ + m_l = new_entry->m_list; + while (m_l) { + m_l->m = ((struct ebt_u_match *)m_l->m)->m; +@@ -1178,7 +1219,9 @@ + } + new_entry->t = ((struct ebt_u_target *)new_entry->t)->t; + +- // update the counter_offset of chains behind this one ++ /* ++ * update the counter_offset of chains behind this one ++ */ + i = replace.selected_hook; + while (1) { + i++; +@@ -1193,21 +1236,27 @@ + } + } + +-// execute command D +-static void delete_rule(int rule_nr) ++/* ++ * execute command D ++ */ ++static void delete_rule(int begin, int end) + { +- int i, j, lentmp = 0; ++ int j, lentmp = 0, nr_deletes; + unsigned short *cnt; + struct ebt_u_entry **u_e, *u_e2; + struct ebt_u_entries *entries = to_chain(), *entries2; + +- if ( (i = check_rule_exists(rule_nr)) == -1 ) ++ if ((begin = check_rule_exists(begin)) == -1 || ++ (end = check_rule_exists(end)) == -1) + print_error("Sorry, rule does not exist"); + +- // we're deleting a rule ++ /* ++ * we're deleting rules ++ */ + replace.num_counters = replace.nentries; +- replace.nentries--; +- entries->nentries--; ++ nr_deletes = end - begin + 1; ++ replace.nentries -= nr_deletes; ++ entries->nentries -= nr_deletes; + + if (replace.nentries) { + for (j = 0; j < replace.selected_hook; j++) { +@@ -1217,61 +1266,75 @@ + entries2 = nr_to_chain(j); + lentmp += entries2->nentries; + } +- lentmp += i; +- // +1 for CNT_END ++ lentmp += begin; ++ /* ++ * +1 for CNT_END ++ */ + if ( !(replace.counterchanges = (unsigned short *)malloc( + (replace.num_counters + 1) * sizeof(unsigned short))) ) + print_memory(); + cnt = replace.counterchanges; +- for (j = 0; j < lentmp; j++) { ++ for (j = 0; j < lentmp; j++, cnt++) + *cnt = CNT_NORM; +- cnt++; +- } +- *cnt = CNT_DEL; +- cnt++; +- for (j = 0; j < replace.num_counters - lentmp; j++) { ++ for (j = 0; j < nr_deletes; j++, cnt++) ++ *cnt = CNT_DEL; ++ ++ for (j = 0; j < replace.num_counters - lentmp - nr_deletes; ++ j++, cnt++) + *cnt = CNT_NORM; +- cnt++; +- } ++ + *cnt = CNT_END; + } + else + replace.num_counters = 0; + +- // go to the right position in the chain ++ /* ++ * go to the right position in the chain ++ */ + u_e = &entries->entries; +- for (j = 0; j < i; j++) ++ for (j = 0; j < begin; j++) + u_e = &(*u_e)->next; +- // remove the rule +- u_e2 = *u_e; +- *u_e = (*u_e)->next; +- // free everything +- free_u_entry(u_e2); +- free(u_e2); +- +- // update the counter_offset of chains behind this one +- i = replace.selected_hook; ++ /* ++ * remove the rules ++ */ ++ j = nr_deletes; ++ while(j--) { ++ u_e2 = *u_e; ++ *u_e = (*u_e)->next; ++ // free everything ++ free_u_entry(u_e2); ++ free(u_e2); ++ } ++ ++ /* ++ * update the counter_offset of chains behind this one ++ */ ++ j = replace.selected_hook; + while (1) { +- i++; +- entries = nr_to_chain(i); ++ j++; ++ entries = nr_to_chain(j); + if (!entries) { +- if (i < NF_BR_NUMHOOKS) ++ if (j < NF_BR_NUMHOOKS) + continue; + else + break; +- } else +- entries->counter_offset--; ++ } else ++ entries->counter_offset -= nr_deletes; + } + } + +-// execute command Z ++/* ++ * execute command Z ++ */ + static void zero_counters(int zerochain) + { + + if (zerochain == -1) { +- // tell main() we don't update the counters +- // this results in tricking the kernel to zero its counters, +- // naively expecting userspace to update its counters. Muahahaha ++ /* ++ * tell main() we don't update the counters ++ * this results in tricking the kernel to zero its counters, ++ * naively expecting userspace to update its counters. Muahahaha ++ */ + replace.counterchanges = NULL; + replace.num_counters = 0; + } else { +@@ -1308,38 +1371,21 @@ + } + } + +-// 0 == success +-// 1 == success, but for the special 'protocol' LENGTH +-// -1 == failure +-int name_to_number(char *name, __u16 *proto) +-{ +- FILE *ifp; +- char buffer[21], value[11], *bfr; +- unsigned short i; +- +- if (!strcasecmp("LENGTH", name)) { +- *proto = 0; +- new_entry->bitmask |= EBT_802_3; +- return 1; +- } +- if ( !(ifp = fopen(PROTOCOLFILE, "r")) ) +- return -1; +- while (1) { +- if (get_a_line(buffer, value, ifp)) +- return -1; +- if (strcasecmp(buffer, name)) +- continue; +- fclose(ifp); +- i = (unsigned short) strtol(value, &bfr, 16); +- if (*bfr != '\0') +- return -1; +- *proto = i; +- return 0; +- } +- return -1; ++/* ++ * Checks the type for validity and calls getethertypebynumber() ++ */ ++struct ethertypeent *parseethertypebynumber(int type) ++{ ++ if (type < 1536) ++ print_error("Ethernet protocols have values >= 0x0600"); ++ if (type > 0xffff) ++ print_error("Ethernet protocols have values <= 0xffff"); ++ return getethertypebynumber(type); + } + +-// put the mac address into 6 (ETH_ALEN) bytes ++/* ++ * put the mac address into 6 (ETH_ALEN) bytes ++ */ + int getmac_and_mask(char *from, char *to, char *mask) + { + char *p; +@@ -1376,7 +1422,9 @@ + return 0; + } + +-// executes the final_check() function for all extensions used by the rule ++/* ++ * executes the final_check() function for all extensions used by the rule ++ */ + static void do_final_checks(struct ebt_u_entry *e, struct ebt_u_entries *entries) + { + struct ebt_u_match_list *m_l; +@@ -1404,7 +1452,9 @@ + entries->hook_mask, 1); + } + +-// used for the -X command ++/* ++ * used for the -X command ++ */ + static void check_for_references(int chain_nr) + { + int i = -1, j; +@@ -1436,13 +1486,45 @@ + } + } + ++static int parse_delete_rule(const char *argv, int *rule_nr, int *rule_nr_end) ++{ ++ char *colon = strchr(argv, ':'), *buffer; ++ ++ if (colon) { ++ *colon = '\0'; ++ if (*(colon + 1) == '\0') ++ *rule_nr_end = -1; ++ else { ++ *rule_nr_end = strtol(colon + 1, &buffer, 10); ++ if (*buffer != '\0' || *rule_nr_end < 0) ++ return -1; ++ } ++ } ++ if (colon == argv) ++ *rule_nr = 1; ++ else { ++ *rule_nr = strtol(argv, &buffer, 10); ++ if (*buffer != '\0' || *rule_nr < 0) ++ return -1; ++ } ++ if (!colon) ++ *rule_nr_end = *rule_nr; ++ if (*rule_nr_end != -1 && *rule_nr > *rule_nr_end) ++ return -1; ++ return 0; ++} ++ ++static int invert = 0; + int check_inverse(const char option[]) + { + if (strcmp(option, "!") == 0) { ++ if (invert == 1) ++ print_error("double use of '!' not allowed"); + optind++; ++ invert = 1; + return 1; + } +- return 0; ++ return invert; + } + + void check_option(unsigned int *flags, unsigned int mask) +@@ -1456,15 +1538,19 @@ + { + if ( !(table = find_table(replace.name)) ) + print_error("Bad table name"); +- // get the kernel's information ++ /* ++ * get the kernel's information ++ */ + if (get_table(&replace)) { + ebtables_insmod("ebtables", modprobe); + if (get_table(&replace)) + print_error("The kernel doesn't support the ebtables " + "%s table", replace.name); + } +- // when listing a table contained in a file, we don't expect the user +- // to know what the table's name is ++ /* ++ * when listing a table contained in a file, we don't demand that ++ * the user knows the table's name ++ */ + if ( !(table = find_table(replace.name)) ) + print_error("Bad table name"); + } +@@ -1482,15 +1568,18 @@ + #define OPT_ZERO 0x100 + #define OPT_LOGICALIN 0x200 + #define OPT_LOGICALOUT 0x400 +-// the main thing ++/* the main thing */ + int main(int argc, char *argv[]) + { + char *buffer; + int c, i; +- // 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 = 0; +- int rule_nr = -1;// used for -[D,I] chain number ++ int rule_nr = -1; /* used for -[D,I] */ ++ int rule_nr_end = -1; /* used for -I */ + struct ebt_u_target *t; + struct ebt_u_match *m; + struct ebt_u_watcher *w; +@@ -1499,36 +1588,46 @@ + struct ebt_u_entries *entries; + const char *modprobe = NULL; + +- // initialize the table name, OPT_ flags, selected hook and command ++ opterr = 0; ++ ++ replace.filename = getenv(ATOMIC_ENV_VARIABLE); ++ /* ++ * initialize the table name, OPT_ flags, selected hook and command ++ */ + strcpy(replace.name, "filter"); + replace.flags = 0; + replace.selected_hook = -1; + replace.command = 'h'; +- replace.filename = NULL; + replace.counterchanges = NULL; + + new_entry = (struct ebt_u_entry *)malloc(sizeof(struct ebt_u_entry)); + if (!new_entry) + print_memory(); +- // put some sane values in our new entry ++ /* ++ * put some sane values in our new entry ++ */ + initialize_entry(new_entry); + +- // The scenario induced by this loop makes that: +- // '-t' ,'-M' and --atomic (if specified) have to come +- // before '-A' and the like +- +- // getopt saves the day ++ /* ++ * The scenario induced by this loop makes that: ++ * '-t' ,'-M' and --atomic (if specified) have to come ++ * before '-A' and the like ++ */ ++ ++ /* ++ * getopt saves the day ++ */ + while ((c = getopt_long(argc, argv, + "-A:D:I:N:E:X:L::Z::F::P:Vhi:o:j:p:s:d:t:M:", ebt_options, NULL)) != -1) { + switch (c) { + +- case 'A': // add a rule +- case 'D': // delete a rule +- case 'P': // define policy +- case 'I': // insert a rule +- case 'N': // make a user defined chain +- case 'E': // rename chain +- case 'X': // delete chain ++ case 'A': /* add a rule */ ++ case 'D': /* delete a rule */ ++ case 'P': /* define policy */ ++ case 'I': /* insert a rule */ ++ case 'N': /* make a user defined chain */ ++ case 'E': /* rename chain */ ++ case 'X': /* delete chain */ + replace.command = c; + if (replace.flags & OPT_COMMAND) + print_error("Multiple commands not allowed"); +@@ -1564,7 +1663,9 @@ + strcpy(cl->udc->name, optarg); + cl->udc->entries = NULL; + cl->kernel_start = NULL; +- // put the new chain at the end ++ /* ++ * put the new chain at the end ++ */ + cl2 = &replace.udc; + while (*cl2) + cl2 = &((*cl2)->next); +@@ -1596,7 +1697,9 @@ + + if (replace.selected_hook < NF_BR_NUMHOOKS) + print_error("You can't remove a standard chain"); +- // if the chain is referenced, don't delete it ++ /* ++ * if the chain is referenced, don't delete it ++ */ + check_for_references(replace.selected_hook - NF_BR_NUMHOOKS); + flush_chains(); + entries = to_chain(); +@@ -1610,8 +1713,15 @@ + break; + } + +- if ( (c == 'D' && optind < argc && +- argv[optind][0] != '-') || c == 'I') { ++ if (c == 'D' && optind < argc && ++ argv[optind][0] != '-') { ++ if (parse_delete_rule(argv[optind], ++ &rule_nr, &rule_nr_end)) ++ print_error("Problem with the " ++ "specified rule number(s)"); ++ optind++; ++ } ++ if (c == 'I') { + if (optind >= argc || argv[optind][0] == '-') + print_error("No rulenr for -I" + " specified"); +@@ -1639,9 +1749,9 @@ + } + break; + +- case 'L': // list +- case 'F': // flush +- case 'Z': // zero counters ++ case 'L': /* list */ ++ case 'F': /* flush */ ++ case 'Z': /* zero counters */ + if (c == 'Z') { + if (replace.flags & OPT_ZERO) + print_error("Multiple commands" +@@ -1677,24 +1787,26 @@ + } + break; + +- case 'V': // version ++ case 'V': /* version */ + replace.command = 'V'; + if (replace.flags & OPT_COMMAND) + print_error("Multiple commands not allowed"); + printf(PROGNAME" v"PROGVERSION" ("PROGDATE")\n"); + exit(0); + +- case 'M': // modprobe ++ case 'M': /* modprobe */ + if (replace.command != 'h') + print_error("Please put the -M option earlier"); + modprobe = optarg; + break; + +- case 'h': // help ++ case 'h': /* help */ + if (replace.flags & OPT_COMMAND) + print_error("Multiple commands not allowed"); + replace.command = 'h'; +- // All other arguments should be extension names ++ /* ++ * All other arguments should be extension names ++ */ + while (optind < argc) { + struct ebt_u_match *m; + struct ebt_u_watcher *w; +@@ -1719,7 +1831,7 @@ + } + break; + +- case 't': // table ++ case 't': /* table */ + if (replace.command != 'h') + print_error("Please put the -t option first"); + check_option(&replace.flags, OPT_TABLE); +@@ -1728,14 +1840,14 @@ + strcpy(replace.name, optarg); + break; + +- case 'i': // input interface +- case 2 : // logical input interface +- case 'o': // output interface +- case 3 : // logical output interface +- case 'j': // target +- case 'p': // net family protocol +- case 's': // source mac +- case 'd': // destination mac ++ case 'i': /* input interface */ ++ case 2 : /* logical input interface */ ++ case 'o': /* output interface */ ++ case 3 : /* logical output interface */ ++ case 'j': /* target */ ++ case 'p': /* net family protocol */ ++ case 's': /* source mac */ ++ case 'd': /* destination mac */ + if ((replace.flags & OPT_COMMAND) == 0) + print_error("No command specified"); + if ( replace.command != 'A' && +@@ -1843,11 +1955,15 @@ + break; + } + else { +- // must be an extension then ++ /* ++ * must be an extension then ++ */ + struct ebt_u_target *t; + + t = find_target(optarg); +- // -j standard not allowed either ++ /* ++ * -j standard not allowed either ++ */ + if (!t || t == + (struct ebt_u_target *)new_entry->t) + print_error("Illegal target " +@@ -1900,12 +2016,17 @@ + "protocol"); + new_entry->ethproto = i; + if (*buffer != '\0') { +- if ((i = name_to_number(argv[optind - 1], +- &new_entry->ethproto)) == -1) ++ struct ethertypeent *ent; ++ ++ if (!strcasecmp(argv[optind - 1], "LENGTH")) { ++ new_entry->bitmask |= EBT_802_3; ++ break; ++ } ++ ent = getethertypebyname(argv[optind - 1]); ++ if (!ent) + print_error("Problem with the specified" + " protocol"); +- if (i == 1) +- new_entry->bitmask |= EBT_802_3; ++ new_entry->ethproto = ent->e_ethertype; + } + if (new_entry->ethproto < 1536 && + !(new_entry->bitmask & EBT_802_3)) +@@ -1944,12 +2065,11 @@ + if (replace.flags & OPT_COMMAND) + print_error("Multiple commands not allowed"); + replace.flags |= OPT_COMMAND; +- if (replace.filename) +- print_error("--atomic incompatible with " +- "command"); +- replace.filename = (char *)malloc(strlen(optarg) + 1); +- strcpy(replace.filename, optarg); +- // get the information from the file ++ if (!replace.filename) ++ print_error("No atomic file specified"); ++ /* ++ * get the information from the file ++ */ + get_table(&replace); + if (replace.nentries) { + replace.counterchanges = (unsigned short *) +@@ -1958,25 +2078,36 @@ + replace.counterchanges[i] = CNT_NORM; + replace.counterchanges[i] = CNT_END; + } +- // we don't want the kernel giving us its counters, they would +- // overwrite the counters extracted from the file ++ /* ++ * we don't want the kernel giving us its counters, they would ++ * overwrite the counters extracted from the file ++ */ + replace.num_counters = 0; +- // make sure the table will be written to the kernel +- free(replace.filename); ++ /* ++ * make sure the table will be written to the kernel ++ * possible memory leak here ++ */ + replace.filename = NULL; + ebtables_insmod("ebtables", modprobe); + break; +- case 7 : // atomic-init +- case 10: // atomic-save +- case 11: // init-table ++ case 7 : /* atomic-init */ ++ case 10: /* atomic-save */ ++ case 11: /* init-table */ + replace.command = c; + if (replace.flags & OPT_COMMAND) + print_error("Multiple commands not allowed"); ++ if (c != 11 && !replace.filename) ++ print_error("No atomic file specified"); + replace.flags |= OPT_COMMAND; +- if (replace.filename) +- print_error("--atomic incompatible with " +- "command"); +- get_kernel_table(modprobe); ++ { ++ char *tmp = replace.filename; ++ ++ tmp = replace.filename; ++ /* get the kernel table */ ++ replace.filename = NULL; ++ get_kernel_table(modprobe); ++ replace.filename = tmp; ++ } + if (replace.nentries) { + replace.counterchanges = (unsigned short *) + malloc(sizeof(unsigned short) * (replace.nentries + 1)); +@@ -1984,24 +2115,37 @@ + replace.counterchanges[i] = CNT_NORM; + replace.counterchanges[i] = CNT_END; + } +- if (c == 11) +- break; +- case 9 : // atomic +- if (c == 9 && (replace.flags & OPT_COMMAND)) ++ break; ++ case 9 : /* atomic */ ++ if (replace.flags & OPT_COMMAND) + print_error("--atomic has to come before" + " the command"); ++ /* another possible memory leak here */ + replace.filename = (char *)malloc(strlen(optarg) + 1); + strcpy(replace.filename, optarg); + break; +- ++ case 1 : ++ if (!strcmp(optarg, "!")) ++ check_inverse(optarg); ++ else ++ print_error("Bad argument : %s", optarg); ++ /* ++ * check_inverse() did optind++ ++ */ ++ optind--; ++ continue; + default: +- // is it a target option? ++ /* ++ * 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))) + goto check_extension; + +- // is it a match_option? ++ /* ++ * 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)) +@@ -2013,7 +2157,9 @@ + goto check_extension; + } + +- // is it a watcher option? ++ /* ++ * 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)) +@@ -2028,6 +2174,7 @@ + replace.command != 'D') + print_error("Extensions only for -A, -I and -D"); + } ++ invert = 0; + } + + if ( !table && !(table = find_table(replace.name)) ) +@@ -2037,14 +2184,20 @@ + replace.flags & OPT_ZERO ) + print_error("Command -Z only allowed together with command -L"); + +- // do this after parsing everything, so we can print specific info ++ /* ++ * 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 ++ /* ++ * do the final checks ++ */ + if (replace.command == 'A' || replace.command == 'I' || + replace.command == 'D') { +- // this will put the hook_mask right for the chains ++ /* ++ * this will put the hook_mask right for the chains ++ */ + check_for_loops(); + entries = to_chain(); + m_l = new_entry->m_list; +@@ -2065,8 +2218,10 @@ + t->final_check(new_entry, t->t, replace.name, + entries->hook_mask, 0); + } +- // so, the extensions can work with the host endian +- // the kernel does not have to do this ofcourse ++ /* ++ * so, the extensions can work with the host endian ++ * the kernel does not have to do this ofcourse ++ */ + new_entry->ethproto = htons(new_entry->ethproto); + + if (replace.command == 'P') { +@@ -2090,8 +2245,10 @@ + } else if (replace.command == 'A' || replace.command == 'I') { + add_rule(rule_nr); + check_for_loops(); +- // do the final_check(), for all entries +- // needed when adding a rule that has a chain target ++ /* ++ * do the final_check(), for all entries ++ * needed when adding a rule that has a chain target ++ */ + i = -1; + while (1) { + struct ebt_u_entry *e; +@@ -2106,17 +2263,24 @@ + } + e = entries->entries; + while (e) { +- // userspace extensions use host endian ++ /* ++ * userspace extensions use host endian ++ */ + e->ethproto = ntohs(e->ethproto); + do_final_checks(e, entries); + e->ethproto = htons(e->ethproto); + e = e->next; + } + } +- } else if (replace.command == 'D') +- delete_rule(rule_nr); +- // commands -N, -E, -X, --atomic-commit, --atomic-commit, --atomic-save, +- // --init-table fall through ++ } else if (replace.command == 'D') { ++ if (rule_nr != -1 && rule_nr_end == -1) ++ rule_nr_end = entries->nentries; ++ delete_rule(rule_nr, rule_nr_end); ++ } ++ /* ++ * commands -N, -E, -X, --atomic-commit, --atomic-commit, --atomic-save, ++ * --init-table fall through ++ */ + + if (table->check) + table->check(&replace); +--- /dev/null Thu Aug 24 11:00:32 2000 ++++ ebtables-v2.0.2/getethertype.c Sat Dec 7 13:28:57 2002 +@@ -0,0 +1,162 @@ ++/* ++* getethertype.c ++* ++* This file was part of the NYS Library. ++* ++** The NYS Library is free software; you can redistribute it and/or ++** modify it under the terms of the GNU Library General Public License as ++** published by the Free Software Foundation; either version 2 of the ++** License, or (at your option) any later version. ++* ++* This program is free software; you can redistribute it and/or modify ++* it under the terms of the GNU General Public License as published by ++* the Free Software Foundation; either version 2 of the License, or ++* (at your option) any later version. ++* ++* This program is distributed in the hope that it will be useful, ++* but WITHOUT ANY WARRANTY; without even the implied warranty of ++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++* GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License ++* along with this program; if not, write to the Free Software ++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++*/ ++ ++/******************************************************************** ++* Description: Ethertype name service switch and the ethertypes ++* database access functions ++* Author: Nick Fedchik ++* Checker: Bart De Schuymer ++* Origin: uClibc-0.9.16/libc/inet/getproto.c ++* Created at: Mon Nov 11 12:20:11 EET 2002 ++********************************************************************/ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "ethernetdb.h" ++ ++#define MAXALIASES 35 ++ ++static FILE *etherf = NULL; ++static char line[BUFSIZ + 1]; ++static struct ethertypeent et_ent; ++static char *ethertype_aliases[MAXALIASES]; ++static int ethertype_stayopen; ++ ++void setethertypeent(int f) ++{ ++ if (etherf == NULL) ++ etherf = fopen(_PATH_ETHERTYPES, "r"); ++ else ++ rewind(etherf); ++ ethertype_stayopen |= f; ++} ++ ++void endethertypeent(void) ++{ ++ if (etherf) { ++ fclose(etherf); ++ etherf = NULL; ++ } ++ ethertype_stayopen = 0; ++} ++ ++struct ethertypeent *getethertypeent(void) ++{ ++ char *e; ++ char *endptr; ++ register char *cp, **q; ++ ++ if (etherf == NULL ++ && (etherf = fopen(_PATH_ETHERTYPES, "r")) == NULL) { ++ return (NULL); ++ } ++ ++again: ++ if ((e = fgets(line, BUFSIZ, etherf)) == NULL) { ++ return (NULL); ++ } ++ if (*e == '#') ++ goto again; ++ cp = strpbrk(e, "#\n"); ++ if (cp == NULL) ++ goto again; ++ *cp = '\0'; ++ et_ent.e_name = e; ++ cp = strpbrk(e, " \t"); ++ if (cp == NULL) ++ goto again; ++ *cp++ = '\0'; ++ while (*cp == ' ' || *cp == '\t') ++ cp++; ++ e = strpbrk(cp, " \t"); ++ if (e != NULL) ++ *e++ = '\0'; ++// Check point ++ et_ent.e_ethertype = strtol(cp, &endptr, 16); ++ if (*endptr != '\0' ++ || (et_ent.e_ethertype < ETH_ZLEN ++ || et_ent.e_ethertype > 0xFFFF)) ++ goto again; // Skip invalid etherproto type entry ++ q = et_ent.e_aliases = ethertype_aliases; ++ if (e != NULL) { ++ cp = e; ++ while (cp && *cp) { ++ if (*cp == ' ' || *cp == '\t') { ++ cp++; ++ continue; ++ } ++ if (q < ðertype_aliases[MAXALIASES - 1]) ++ *q++ = cp; ++ cp = strpbrk(cp, " \t"); ++ if (cp != NULL) ++ *cp++ = '\0'; ++ } ++ } ++ *q = NULL; ++ return (&et_ent); ++} ++ ++ ++struct ethertypeent *getethertypebyname(const char *name) ++{ ++ register struct ethertypeent *e; ++ register char **cp; ++ ++ setethertypeent(ethertype_stayopen); ++ while ((e = getethertypeent()) != NULL) { ++ if (strcasecmp(e->e_name, name) == 0) ++ break; ++ for (cp = e->e_aliases; *cp != 0; cp++) ++ if (strcasecmp(*cp, name) == 0) ++ goto found; ++ } ++found: ++ if (!ethertype_stayopen) ++ endethertypeent(); ++ return (e); ++} ++ ++struct ethertypeent *getethertypebynumber(int type) ++{ ++ register struct ethertypeent *e; ++ ++ setethertypeent(ethertype_stayopen); ++ while ((e = getethertypeent()) != NULL) ++ if (e->e_ethertype == type) ++ break; ++ if (!ethertype_stayopen) ++ endethertypeent(); ++ return (e); ++} +--- ebtables-v2.0.1/extensions/ebt_arp.c Thu Aug 29 18:48:36 2002 ++++ ebtables-v2.0.2/extensions/ebt_arp.c Fri Nov 22 20:43:47 2002 +@@ -3,6 +3,7 @@ + #include + #include + #include "../include/ebtables_u.h" ++#include "../include/ethernetdb.h" + #include + + #define ARP_OPCODE '1' +@@ -52,7 +53,7 @@ + printf("%d = %s\n", i + 1, opcodes[i]); + printf( + " hardware type string: 1 = Ethernet\n" +-" protocol type string: see /etc/ethertypes\n"); ++" protocol type string: see "_PATH_ETHERTYPES"\n"); + } + + static void init(struct ebt_entry_match *match) +@@ -133,9 +134,14 @@ + print_error("Missing ARP protocol type argument"); + i = strtol(argv[optind - 1], &end, 16); + if (i < 0 || i >= (0x1 << 16) || *end !='\0') { +- if (name_to_number (argv[optind - 1], &proto) == -1) ++ struct ethertypeent *ent; ++ ++ ent = getethertypebyname(argv[optind - 1]); ++ if (!ent) + print_error("Problem with specified ARP " + "protocol type"); ++ proto = ent->e_ethertype; ++ + } else + proto = i; + arpinfo->ptype = htons(proto); +@@ -190,7 +196,6 @@ + { + struct ebt_arp_info *arpinfo = (struct ebt_arp_info *)match->data; + int i; +- char name[21]; + + if (arpinfo->bitmask & EBT_ARP_OPCODE) { + int opcode = ntohs(arpinfo->opcode); +@@ -209,13 +214,16 @@ + printf("%d ", ntohs(arpinfo->htype)); + } + if (arpinfo->bitmask & EBT_ARP_PTYPE) { ++ struct ethertypeent *ent; ++ + printf("--arp-ptype "); + if (arpinfo->invflags & EBT_ARP_PTYPE) + printf("! "); +- if (number_to_name(ntohs(arpinfo->ptype), name)) ++ ent = getethertypebynumber(ntohs(arpinfo->ptype)); ++ if (!ent) + printf("0x%x ", ntohs(arpinfo->ptype)); + else +- printf("%s ", name); ++ printf("%s ", ent->e_name); + } + if (arpinfo->bitmask & EBT_ARP_SRC_IP) { + printf("--arp-ip-src "); +--- ebtables-v2.0.1/extensions/ebt_vlan.c Thu Aug 29 18:48:36 2002 ++++ ebtables-v2.0.2/extensions/ebt_vlan.c Sat Dec 7 13:29:16 2002 +@@ -34,39 +34,73 @@ + #include + #include + #include ++#include + #include "../include/ebtables_u.h" ++#include "../include/ethernetdb.h" + #include ++#include ++ + + #define GET_BITMASK(_MASK_) vlaninfo->bitmask & _MASK_ + #define SET_BITMASK(_MASK_) vlaninfo->bitmask |= _MASK_ + #define INV_FLAG(_inv_flag_) (vlaninfo->invflags & _inv_flag_) ? "! " : "" ++#define CHECK_IF_MISSING_VALUE if (optind > argc) print_error ("Missing %s value", opts[c].name); ++#define CHECK_INV_FLAG(_INDEX_) if (check_inverse (optarg)) vlaninfo->invflags |= _INDEX_; ++#define CHECK_RANGE(_RANGE_) if (_RANGE_) print_error ("Invalid %s range", opts[c].name); ++ ++#define NAME_VLAN_ID "id" ++#define NAME_VLAN_PRIO "prio" ++#define NAME_VLAN_ENCAP "encap" + + #define VLAN_ID 0 + #define VLAN_PRIO 1 + #define VLAN_ENCAP 2 ++ + static struct option opts[] = { +- {"vlan-id", required_argument, NULL, VLAN_ID}, +- {"vlan-prio", required_argument, NULL, VLAN_PRIO}, +- {"vlan-encap", required_argument, NULL, VLAN_ENCAP}, ++ {EBT_VLAN_MATCH "-" NAME_VLAN_ID, required_argument, NULL, ++ VLAN_ID}, ++ {EBT_VLAN_MATCH "-" NAME_VLAN_PRIO, required_argument, NULL, ++ VLAN_PRIO}, ++ {EBT_VLAN_MATCH "-" NAME_VLAN_ENCAP, required_argument, NULL, ++ VLAN_ENCAP}, + {NULL} + }; + ++/* ++ * option inverse flags definition ++ */ ++#define OPT_VLAN_ID 0x01 ++#define OPT_VLAN_PRIO 0x02 ++#define OPT_VLAN_ENCAP 0x04 ++#define OPT_VLAN_FLAGS (OPT_VLAN_ID | OPT_VLAN_PRIO | OPT_VLAN_ENCAP) ++ ++struct ethertypeent *ethent; + + /* +- * Print out local help by "ebtables -h vlan" ++ * Print out local help by "ebtables -h " + */ +-static void print_help () ++ ++static void print_help() + { +- printf ("802.1Q VLAN extension options:\n" +- "--vlan-id [!] id : VLAN-tagged frame identifier, 0,1-4094 (integer)\n" +- "--vlan-prio [!] prio : Priority-tagged frame user_priority, 0-7 (integer)\n" +- "--vlan-encap [!] proto : Encapsulated protocol (hexadecimal)\n"); ++#define HELP_TITLE "802.1Q VLAN extension" ++ ++ printf(HELP_TITLE " options:\n"); ++ printf("--" EBT_VLAN_MATCH "-" NAME_VLAN_ID " %s" NAME_VLAN_ID ++ " : VLAN-tagged frame identifier, 0,1-4096 (integer), default 1\n", ++ OPT_VLAN_FLAGS & OPT_VLAN_ID ? "[!] " : ""); ++ printf("--" EBT_VLAN_MATCH "-" NAME_VLAN_PRIO " %s" NAME_VLAN_PRIO ++ " : Priority-tagged frame user_priority, 0-7 (integer), default 0\n", ++ OPT_VLAN_FLAGS & OPT_VLAN_PRIO ? "[!] " : ""); ++ printf("--" EBT_VLAN_MATCH "-" NAME_VLAN_ENCAP " %s" ++ NAME_VLAN_ENCAP ++ " : Encapsulated frame type (hexadecimal), default IP (0800)\n", ++ OPT_VLAN_FLAGS & OPT_VLAN_ENCAP ? "[!] " : ""); + } + + /* + * Initialization function + */ +-static void init (struct ebt_entry_match *match) ++static void init(struct ebt_entry_match *match) + { + struct ebt_vlan_info *vlaninfo = + (struct ebt_vlan_info *) match->data; +@@ -80,131 +114,72 @@ + vlaninfo->bitmask = 0; + } + +-/* +- * option flags definition +- */ +-#define OPT_VLAN_ID 0x01 +-#define OPT_VLAN_PRIO 0x02 +-#define OPT_VLAN_ENCAP 0x04 + + /* + * Parse passed arguments values (ranges, flags, etc...) + * int c - parameter number from static struct option opts[] + * int argc - total amout of arguments (std argc value) +- * ++ * int argv - arguments (std argv value) ++ * const struct ebt_u_entry *entry - default ebtables entry set ++ * 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) ++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 long i; + char *end; +- uint16_t encap; ++ struct ebt_vlan_info local; ++ + switch (c) { + case VLAN_ID: +- /* +- * ebtables.c:check_option(unsigned int *flags, unsigned int mask) +- * checking for multiple usage of same option +- */ +- check_option (flags, OPT_VLAN_ID); +- /* +- * Check If we got inversed arg for vlan-id option, +- * otherwise unset inversion flag +- */ +- if (check_inverse (optarg)) +- vlaninfo->invflags |= EBT_VLAN_ID; +- /* +- * Check arg value presence +- */ +- if (optind > argc) +- print_error ("Missing VLAN ID argument value"); +- /* +- * 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 > 4094 || *end != '\0') +- print_error +- ("Specified VLAN ID is out of range (0-4094)"); +- /* +- * Set up parameter value +- */ +- vlaninfo->id = i; +- /* +- * Set up parameter presence flag +- */ +- SET_BITMASK (EBT_VLAN_ID); ++ check_option(flags, OPT_VLAN_ID); ++ CHECK_INV_FLAG(EBT_VLAN_ID); ++ CHECK_IF_MISSING_VALUE; ++ (unsigned short) local.id = ++ strtoul(argv[optind - 1], &end, 10); ++ CHECK_RANGE(local.id > 4094 || *end != '\0'); ++ vlaninfo->id = local.id; ++ SET_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 user_priority argument value"); +- /* +- * Convert argv to long int, +- * set *end to end of argv string, +- * base set 10 for decimal only +- */ +- (unsigned char) i = strtol (argv[optind - 1], &end, 10); +- /* +- * Check arg val range +- */ +- if (i >= 8 || *end != '\0') +- print_error +- ("Specified user_priority is out of range (0-7)"); +- /* +- * Set up parameter value +- */ +- vlaninfo->prio = i; +- /* +- * Set up parameter presence flag +- */ +- SET_BITMASK (EBT_VLAN_PRIO); ++ check_option(flags, OPT_VLAN_PRIO); ++ CHECK_INV_FLAG(EBT_VLAN_PRIO); ++ CHECK_IF_MISSING_VALUE; ++ (unsigned char) local.prio = ++ strtoul(argv[optind - 1], &end, 10); ++ CHECK_RANGE(local.prio >= 8 || *end != '\0'); ++ vlaninfo->prio = local.prio; ++ SET_BITMASK(EBT_VLAN_PRIO); + break; + + case VLAN_ENCAP: +- check_option (flags, OPT_VLAN_ENCAP); +- if (check_inverse (optarg)) +- vlaninfo->invflags |= EBT_VLAN_ENCAP; +- if (optind > argc) +- print_error +- ("Missing encapsulated frame type argument value"); +- /* +- * Parameter can be decimal, hexadecimal, or string. +- * Check arg val range (still raw area) +- */ +- (unsigned short) encap = strtol (argv[optind - 1], &end, 16); +- if (*end == '\0' && (encap < ETH_ZLEN || encap > 0xFFFF)) +- print_error +- ("Specified encapsulated frame type is out of range"); +- if (*end != '\0') +- if (name_to_number (argv[optind - 1], &encap) == -1) +- print_error +- ("Problem with the specified encapsulated" +- "protocol"); +- /* +- * Set up parameter value (network notation) +- */ +- vlaninfo->encap = htons (encap); +- /* +- * Set up parameter presence flag +- */ +- SET_BITMASK (EBT_VLAN_ENCAP); ++ check_option(flags, OPT_VLAN_ENCAP); ++ CHECK_INV_FLAG(EBT_VLAN_ENCAP); ++ CHECK_IF_MISSING_VALUE; ++ (unsigned short) local.encap = ++ strtoul(argv[optind - 1], &end, 16); ++ if (*end != '\0') { ++ ethent = getethertypebyname(argv[optind - 1]); ++ if (ethent == NULL) ++ print_error("Unknown %s encap", ++ opts[c].name); ++ local.encap = ethent->e_ethertype; ++ } ++ CHECK_RANGE(local.encap < ETH_ZLEN); ++ vlaninfo->encap = htons(local.encap); ++ SET_BITMASK(EBT_VLAN_ENCAP); + break; ++ + default: + return 0; ++ + } + return 1; + } +@@ -213,9 +188,9 @@ + * Final check - logical conditions + */ + static void +-final_check (const struct ebt_u_entry *entry, +- const struct ebt_entry_match *match, +- const char *name, unsigned int hookmask, unsigned int time) ++final_check(const struct ebt_u_entry *entry, ++ const struct ebt_entry_match *match, ++ const char *name, unsigned int hookmask, unsigned int time) + { + + struct ebt_vlan_info *vlaninfo = +@@ -223,16 +198,25 @@ + /* + * Specified proto isn't 802.1Q? + */ +- if (entry->ethproto != ETH_P_8021Q || +- entry->invflags & EBT_IPROTO) ++ if (entry->ethproto != ETH_P_8021Q || entry->invflags & EBT_IPROTO) + print_error + ("For use 802.1Q extension the protocol must be specified as 802_1Q"); + /* ++ * Check if specified vlan-encap=0x8100 (802.1Q Frame) ++ * when vlan-encap specified. ++ */ ++ if (GET_BITMASK(EBT_VLAN_ENCAP)) { ++ if (vlaninfo->encap == htons(0x8100)) ++ print_error ++ ("Encapsulated frame type can not be 802.1Q (0x8100)"); ++ } ++ ++ /* + * Check if specified vlan-id=0 (priority-tagged frame condition) + * when vlan-prio was specified. + */ +- if (GET_BITMASK (EBT_VLAN_PRIO)) { +- if (vlaninfo->id && GET_BITMASK (EBT_VLAN_ID)) ++ if (GET_BITMASK(EBT_VLAN_PRIO)) { ++ if (vlaninfo->id && GET_BITMASK(EBT_VLAN_ID)) + print_error + ("For use user_priority the specified vlan-id must be 0"); + } +@@ -242,49 +226,46 @@ + * Print line when listing rules by ebtables -L + */ + static void +-print (const struct ebt_u_entry *entry, +- const struct ebt_entry_match *match) ++print(const struct ebt_u_entry *entry, const struct ebt_entry_match *match) + { + struct ebt_vlan_info *vlaninfo = + (struct ebt_vlan_info *) match->data; + +- char ethertype_name[21]; + /* + * Print VLAN ID if they are specified + */ +- if (GET_BITMASK (EBT_VLAN_ID)) { +- printf ("--%s %s%d ", +- opts[VLAN_ID].name, +- INV_FLAG (EBT_VLAN_ID), vlaninfo->id); ++ if (GET_BITMASK(EBT_VLAN_ID)) { ++ printf("--%s %s%d ", ++ opts[VLAN_ID].name, ++ INV_FLAG(EBT_VLAN_ID), vlaninfo->id); + } + /* + * Print user priority if they are specified + */ +- if (GET_BITMASK (EBT_VLAN_PRIO)) { +- printf ("--%s %s%d ", +- opts[VLAN_PRIO].name, +- INV_FLAG (EBT_VLAN_PRIO), vlaninfo->prio); ++ if (GET_BITMASK(EBT_VLAN_PRIO)) { ++ printf("--%s %s%d ", ++ opts[VLAN_PRIO].name, ++ INV_FLAG(EBT_VLAN_PRIO), vlaninfo->prio); + } + /* + * Print encapsulated frame type if they are specified + */ +- if (GET_BITMASK (EBT_VLAN_ENCAP)) { +- printf ("--%s %s", +- opts[VLAN_ENCAP].name, INV_FLAG (EBT_VLAN_ENCAP)); +- bzero (ethertype_name, 21); +- if (!number_to_name +- (ntohs (vlaninfo->encap), ethertype_name)) { +- printf ("%s ", ethertype_name); ++ if (GET_BITMASK(EBT_VLAN_ENCAP)) { ++ printf("--%s %s", ++ opts[VLAN_ENCAP].name, INV_FLAG(EBT_VLAN_ENCAP)); ++ ethent = getethertypebynumber(ntohs(vlaninfo->encap)); ++ if (ethent != NULL) { ++ printf("%s ", ethent->e_name); + } else { +- printf ("%2.4X ", ntohs (vlaninfo->encap)); ++ printf("%4.4X ", ntohs(vlaninfo->encap)); + } + } + } + + + static int +-compare (const struct ebt_entry_match *vlan1, +- const struct ebt_entry_match *vlan2) ++compare(const struct ebt_entry_match *vlan1, ++ const struct ebt_entry_match *vlan2) + { + struct ebt_vlan_info *vlaninfo1 = + (struct ebt_vlan_info *) vlan1->data; +@@ -321,12 +302,13 @@ + if (vlaninfo1->encap != vlaninfo2->encap) + return 0; + }; ++ + return 1; + } + + static struct ebt_u_match vlan_match = { + EBT_VLAN_MATCH, +- sizeof (struct ebt_vlan_info), ++ sizeof(struct ebt_vlan_info), + print_help, + init, + parse, +@@ -336,8 +318,8 @@ + opts + }; + +-static void _init (void) __attribute__ ((constructor)); +-static void _init (void) ++static void _init(void) __attribute__ ((constructor)); ++static void _init(void) + { +- register_match (&vlan_match); ++ register_match(&vlan_match); + } +--- ebtables-v2.0.1/extensions/Makefile Wed Jul 24 10:36:48 2002 ++++ ebtables-v2.0.2/extensions/Makefile Fri Nov 22 20:44:37 2002 +@@ -6,7 +6,8 @@ + EXT_OBJS+=$(foreach T,$(EXT_TABLES), extensions/ebtable_$(T).o) + + extensions/ebt_%.o: extensions/ebt_%.c include/ebtables_u.h +- $(CC) $(CFLAGS) -c -o $@ $< ++ $(CC) $(CFLAGS) $(PROGSPECS) -c -o $@ $< -I$(KERNEL_INCLUDES) ++ + extensions/ebtable_%.o: extensions/ebtable_%.c +- $(CC) $(CFLAGS) -c -o $@ $< ++ $(CC) $(CFLAGS) $(PROGSPECS) -c -o $@ $< -I$(KERNEL_INCLUDES) + +--- ebtables-v2.0.1/ChangeLog Fri Aug 30 22:33:36 2002 ++++ ebtables-v2.0.2/ChangeLog Tue Dec 3 23:00:45 2002 +@@ -1,3 +1,20 @@ ++20021203 ++ * changed the way to use the atomic operations. It's now possible ++ to use the EBTABLES_ATOMIC_FILE environment variable, so it's no ++ longer necessary to explicitly state the file name. See the man. ++20021120 ++ * changed the way of compiling. New releases will now contain their ++ own set of kernel includes. No more copying of kernel includes to ++ /usr/include/linux ++ * added getethertype.c (Nick) and use it. Removed name_to_number() ++ and number_to_name(). ++20021106 ++ * added possibility to specify a rule number interval when deleting ++ rules ++20021102 ++ * added ! - option possibility, which is equivalent to - ! option ++20021102 ++ * since last entry: added byte counters and udp/tcp port matching + 20020830 + * updated the kernel files for 2.4.20-pre5 and 2.5.32 + * last big cleanup of kernel and userspace code just finished +--- ebtables-v2.0.1/ebtables.8 Thu Oct 17 23:20:57 2002 ++++ ebtables-v2.0.2/ebtables.8 Sat Dec 7 13:42:58 2002 +@@ -1,6 +1,6 @@ +-.TH EBTABLES 8 "11 August 2002" ++.TH EBTABLES 8 "03 December 2002" + .\" +-.\" Man page written by Bart De Schuymer ++.\" Man page written by Bart De Schuymer + .\" It is based on the iptables man page. + .\" + .\" Iptables page by Herve Eychenne March 2000. +@@ -35,11 +35,11 @@ + .br + .BR "ebtables --init-table" + .br +-.BR "ebtables --atomic-init " file ++.BR "ebtables --atomic-init " + .br +-.BR "ebtables --atomic-save " file ++.BR "ebtables --atomic-save " + .br +-.BR "ebtables --atomic-commit " file ++.BR "ebtables --atomic-commit " + .br + .SH DESCRIPTION + .B ebtables +@@ -133,9 +133,10 @@ + Append a rule to the end of the selected chain. + .TP + .B "-D, --delete" +-Delete the specified rule from the selected chain. There are two versions +-of this command. A rule number (starting at 1) or the complete rule can be +-specified. ++Delete the specified rule from the selected chain. There are two ways to ++use this command. The first is by specifying an interval of rule numbers ++to delete, syntax: start_nr[:end_nr]. The second usage is by specifying ++the complete rule as it would have been specified when it was added. + .TP + .B "-I, --insert" + Insert the specified rule into the selected chain at the specified rule number (1 meaning +@@ -178,10 +179,8 @@ + 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 +-, either +-.BR DROP . ++Set the policy for the chain to the given target. The policy can be ++.BR ACCEPT ", " DROP " or " RETURN . + .TP + .B "-N, --new-chain" + Create a new user-defined chain by the given name. The number of +@@ -202,26 +201,34 @@ + .B "--atomic-init" + Copy the kernel's initial data of the table to the specified + file. This can be used as the first action, after which rules are added +-to the file. ++to the file. The file can be specified using the ++.B --atomic-file ++option or through the ++.IR EBTABLES_ATOMIC_FILE " environment variable." + .TP + .B "--atomic-save" + Copy the kernel's current data of the table to the specified + file. This can be used as the first action, after which rules are added +-to the file. ++to the file. The file can be specified using the ++.B --atomic-file ++option or through the ++.IR EBTABLES_ATOMIC_FILE " environment variable." + .TP + .B "--atomic-commit" + Replace the kernel table data with the data contained in the specified + file. This is a useful command that allows you to put all your rules of a + certain table into the kernel at once, saving the kernel a lot of precious +-time. The file which contains the table data is constructed by using +-either the ++time and allowing atomic updates of the tables. The file which contains ++the table data is constructed by using either the + .B "--atomic-init" + or the + .B "--atomic-save" + command to get a starting file. After that, using the +-.B "--atomic" +-option when constructing rules allows you to extend the file and build up +-the complete wanted table. ++.B "--atomic-file" ++option when constructing rules or setting the ++.IR EBTABLES_ATOMIC_FILE " environment variable" ++allows you to extend the file and build the complete table before ++commiting it to the kernel. + .SS + PARAMETERS + The following parameters make up a rule specification (as used in the add +@@ -334,11 +341,13 @@ + .BR "TARGET EXTENSIONS" ")" + or a user defined chain name. + .TP +-.B --atomic file ++.B --atomic-file file + Let the command operate on the specified file. The data of the table to + operate on will be extracted from the file and the result of the operation + will be saved back into the file. If specified, this option should come +-before the command specification. ++before the command specification. An alternative that should be preferred, ++is setting the ++.BR EBTABLES_ATOMIC_FILE "environment variable." + .TP + .B -M, --modprobe program + When talking to the kernel, use this program to try to automatically load +@@ -560,9 +569,11 @@ + .br + .SH FILES + .I /etc/ethertypes ++.SH ENVIRONMENT VARIABLES ++.I EBTABLES_ATOMIC_FILE + .SH BUGS + This won't work on an architecture with a user32/kernel64 situation like the Sparc64. + .SH AUTHOR +-.IR "" "Bart De Schuymer <" bart.de.schuymer@pandora.be > ++.IR "" "Bart De Schuymer <" bdschuym@pandora.be > + .SH SEE ALSO + .BR iptables "(8), " brctl (8) +--- ebtables-v2.0.1/ethertypes Sun Aug 11 18:49:14 2002 ++++ ebtables-v2.0.2/ethertypes Wed Nov 20 20:44:45 2002 +@@ -1,32 +1,37 @@ +-# 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 +-# anything on a line after the protocol number is ignored +-# programs using this file should not be case sensitive +-IPv4 0800 ++# ++# Ethernet frame types ++# This file describes some of the various Ethernet ++# protocol types that are used on Ethernet networks. ++# ++# This list could be found on: ++# http://www.iana.org/assignments/ethernet-numbers ++# ++# ... #Comment ++# ++IPv4 0800 ip ip4 # Internet IP (IPv4) + X25 0805 +-ARP 0806 +-802_1Q 8100 802.1Q Virtual LAN tagged frame +-IPX 8137 +-IPv6 86DD +-NetBEUI 8191 +-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 +-LOOP 9000 ++ARP 0806 ether-arp # ++FR_ARP 0808 # Frame Relay ARP [RFC1701] ++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 ++TEB 6558 # Trans Ether Bridging [RFC1701] ++RAW_FR 6559 # Raw Frame Relay [RFC1701] ++AARP 80F3 # Appletalk AARP ++ATALK 809B # Appletalk ++802_1Q 8100 8021q 1q 802.1q dot1q # 802.1Q Virtual LAN tagged frame ++IPX 8137 # Novell IPX ++NetBEUI 8191 # NetBEUI ++IPv6 86DD ip6 # IP version 6 ++PPP 880B # PPP ++ATMMPOA 884C # MultiProtocol over ATM ++PPP_DISC 8863 # PPPoE discovery messages ++PPP_SES 8864 # PPPoE session messages ++ATMFATE 8884 # Frame-based ATM Transport over Ethernet ++LOOP 9000 loopback # loop proto +--- ebtables-v2.0.1/include/ebtables_u.h Thu Aug 29 18:52:36 2002 ++++ ebtables-v2.0.2/include/ebtables_u.h Wed Nov 20 22:05:39 2002 +@@ -198,14 +198,12 @@ + struct ebt_u_table *find_table(char *name); + void deliver_counters(struct ebt_u_replace *repl); + void deliver_table(struct ebt_u_replace *repl); +-int name_to_number(char *name, uint16_t *proto); +-int number_to_name(unsigned short proto, char *name); + void check_option(unsigned int *flags, unsigned int mask); + int check_inverse(const char option[]); + void __print_bug(char *file, int line, char *format, ...); + #define print_bug(format, args...) \ + __print_bug(__FILE__, __LINE__, format, ##args) +-#define print_error(format, args...) {printf(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);} + +--- /dev/null Thu Aug 24 11:00:32 2000 ++++ ebtables-v2.0.2/include/ethernetdb.h Fri Nov 22 20:44:03 2002 +@@ -0,0 +1,58 @@ ++/* ++* This program is free software; you can redistribute it and/or modify ++* it under the terms of the GNU General Public License as published by ++* the Free Software Foundation; either version 2 of the License, or ++* (at your option) any later version. ++* ++* This program is distributed in the hope that it will be useful, ++* but WITHOUT ANY WARRANTY; without even the implied warranty of ++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++* GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License ++* along with this program; if not, write to the Free Software ++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++*/ ++ ++/* All data returned by the network data base library are supplied in ++ host order and returned in network order (suitable for use in ++ system calls). */ ++ ++#ifndef _ETHERNETDB_H ++#define _ETHERNETDB_H 1 ++ ++#include ++#include ++#include ++ ++/* Absolute file name for network data base files. */ ++#ifndef _PATH_ETHERTYPES ++#define _PATH_ETHERTYPES "/etc/ethertypes" ++#endif /* _PATH_ETHERTYPES */ ++ ++struct ethertypeent { ++ char *e_name; /* Official ethernet type name. */ ++ char **e_aliases; /* Alias list. */ ++ int e_ethertype; /* Ethernet type number. */ ++}; ++ ++/* Open ethertype data base files and mark them as staying open even ++ after a later search if STAY_OPEN is non-zero. */ ++extern void setethertypeent(int __stay_open) __THROW; ++ ++/* Close ethertype data base files and clear `stay open' flag. */ ++extern void endethertypeent(void) __THROW; ++ ++/* Get next entry from ethertype data base file. Open data base if ++ necessary. */ ++extern struct ethertypeent *getethertypeent(void) __THROW; ++ ++/* Return entry from ethertype data base for network with NAME. */ ++extern struct ethertypeent *getethertypebyname(__const char *__name) ++ __THROW; ++ ++/* Return entry from ethertype data base which number is PROTO. */ ++extern struct ethertypeent *getethertypebynumber(int __ethertype) __THROW; ++ ++ ++#endif /* ethernetdb.h */ diff --git a/userspace/patches/zipped/v2.0/ebtables-v2.0.2.tar.gz b/userspace/patches/zipped/v2.0/ebtables-v2.0.2.tar.gz new file mode 100644 index 0000000..25ae298 Binary files /dev/null and b/userspace/patches/zipped/v2.0/ebtables-v2.0.2.tar.gz differ -- cgit v1.2.3