| --- 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 <stdarg.h> |
| #include <netinet/ether.h> |
| #include "include/ebtables_u.h" |
| +#include "include/ethernetdb.h" |
| #include <unistd.h> |
| #include <fcntl.h> |
| #include <sys/wait.h> |
| |
| -// 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 <FILE>\n" |
| +"--atomic-init : put the initial kernel table into <FILE>\n" |
| +"--atomic-save : put the current kernel table into <FILE>\n" |
| +"--atomic file : set <FILE> 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 <FILE> (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 <this> -L <that>) |
| + /* |
| + * this special one for the -Z option (we can have -Z <this> -L <that>) |
| + */ |
| 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 <fnm@ukrsat.com> |
| +* Checker: Bart De Schuymer <bdschuym@pandora.be> |
| +* Origin: uClibc-0.9.16/libc/inet/getproto.c |
| +* Created at: Mon Nov 11 12:20:11 EET 2002 |
| +********************************************************************/ |
| + |
| + |
| +#include <ctype.h> |
| +#include <features.h> |
| +#include <sys/types.h> |
| +#include <sys/socket.h> |
| +#include <netdb.h> |
| +#include <stdio.h> |
| +#include <stdlib.h> |
| +#include <string.h> |
| +#include <netinet/ether.h> |
| +#include <net/ethernet.h> |
| + |
| +#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 <stdlib.h> |
| #include <getopt.h> |
| #include "../include/ebtables_u.h" |
| +#include "../include/ethernetdb.h" |
| #include <linux/netfilter_bridge/ebt_arp.h> |
| |
| #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 <stdlib.h> |
| #include <string.h> |
| #include <getopt.h> |
| +#include <ctype.h> |
| #include "../include/ebtables_u.h" |
| +#include "../include/ethernetdb.h" |
| #include <linux/netfilter_bridge/ebt_vlan.h> |
| +#include <linux/if_ether.h> |
| + |
| |
| #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 <match name>" |
| */ |
| -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 <bart.de.schuymer@pandora.be> |
| +.\" Man page written by Bart De Schuymer <bdschuym@pandora.be> |
| .\" 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 |
| +# |
| +# <name> <hexnumber> <alias1>...<alias35> #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 <features.h> |
| +#include <netinet/in.h> |
| +#include <stdint.h> |
| + |
| +/* 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 */ |