From 86b37a9c99511d7ae157e63b6e566c717b722a30 Mon Sep 17 00:00:00 2001 From: Bart De Schuymer Date: Wed, 31 Jul 2002 19:55:34 +0000 Subject: *** empty log message *** --- kernel/scripts/Makediff | 15 +- kernel/scripts/Makeincrdiff | 13 +- .../incremental-patches/ebtables-v2.0-rc1.001.diff | 1764 ++++++++++++++++++++ userspace/patches/zipped/ebtables-v2.0-rc1.tar.gz | Bin 0 -> 45600 bytes userspace/scripts/Make_userspace_diff | 9 +- 5 files changed, 1791 insertions(+), 10 deletions(-) create mode 100644 userspace/patches/incremental-patches/ebtables-v2.0-rc1.001.diff create mode 100644 userspace/patches/zipped/ebtables-v2.0-rc1.tar.gz diff --git a/kernel/scripts/Makediff b/kernel/scripts/Makediff index 04326e8..486762d 100755 --- a/kernel/scripts/Makediff +++ b/kernel/scripts/Makediff @@ -4,12 +4,14 @@ # br-nf patch. # 6 June 2002: added ebt_snat.c, ebt_dnat.c files, removed ebt_nat.c file +# 31 July 2002: added mark match/target, bridge/br.c, bridge/Makefile; +# deleted netsyms export FROM=linux -export TO=ebt2.0pre8 -export FILE=ebtables-v2.0pre8_vs_2.4.18.diff +export TO=ebt2.0-rc1 +export FILE=ebtables-v2.0-rc1_vs_2.4.18.diff -echo "ebtables-v2.0pre8 - 06 June" >$FILE +echo "ebtables-v2.0-rc1 - 31 July" >$FILE echo >>$FILE echo "*** modifications for brouter support ***" >>$FILE echo >>$FILE @@ -18,7 +20,8 @@ diff -urN $FROM/net/bridge/br_private.h $TO/net/bridge/br_private.h >> $FILE diff -urN $FROM/include/linux/if_bridge.h $TO/include/linux/if_bridge.h >> $FILE diff -urN $FROM/net/core/dev.c $TO/net/core/dev.c >> $FILE diff -urN $FROM/net/bridge/br_input.c $TO/net/bridge/br_input.c >> $FILE -diff -urN $FROM/net/netsyms.c $TO/net/netsyms.c >> $FILE +diff -urN $FROM/net/bridge/br.c $TO/net/bridge/br.c >> $FILE +diff -urN $FROM/net/bridge/Makefile $TO/net/bridge/Makefile >> $FILE diff -urN $FROM/include/linux/netfilter_bridge.h $TO/include/linux/netfilter_bridge.h >> $FILE echo >>$FILE @@ -38,6 +41,8 @@ diff -urN /dev/null $TO/net/bridge/netfilter/br_db.c >> $FILE diff -urN /dev/null $TO/net/bridge/netfilter/ebtable_filter.c >> $FILE diff -urN /dev/null $TO/net/bridge/netfilter/ebtable_nat.c >> $FILE diff -urN /dev/null $TO/net/bridge/netfilter/ebtable_broute.c >> $FILE +diff -urN /dev/null $TO/net/bridge/netfilter/ebt_mark.c >> $FILE +diff -urN /dev/null $TO/net/bridge/netfilter/ebt_mark_m.c >> $FILE diff -urN /dev/null $TO/net/bridge/netfilter/ebt_redirect.c >> $FILE diff -urN /dev/null $TO/net/bridge/netfilter/ebt_arp.c >> $FILE diff -urN /dev/null $TO/net/bridge/netfilter/ebt_ip.c >> $FILE @@ -53,4 +58,6 @@ diff -urN /dev/null $TO/include/linux/netfilter_bridge/ebt_vlan.h >> $FILE diff -urN /dev/null $TO/include/linux/netfilter_bridge/ebt_log.h >> $FILE diff -urN /dev/null $TO/include/linux/netfilter_bridge/ebt_nat.h >> $FILE diff -urN /dev/null $TO/include/linux/netfilter_bridge/ebt_redirect.h >> $FILE +diff -urN /dev/null $TO/include/linux/netfilter_bridge/ebt_mark_m.h >> $FILE +diff -urN /dev/null $TO/include/linux/netfilter_bridge/ebt_mark_t.h >> $FILE diff -urN /dev/null $TO/include/linux/br_db.h >> $FILE diff --git a/kernel/scripts/Makeincrdiff b/kernel/scripts/Makeincrdiff index 3665fac..0b36755 100755 --- a/kernel/scripts/Makeincrdiff +++ b/kernel/scripts/Makeincrdiff @@ -1,9 +1,11 @@ #!/bin/bash # used for making the incremental kernel diffs +# 31 July 2002: added mark match/target, bridge/br.c, bridge/Makefile; +# deleted netsyms export FROM=linux -export TO=ebt2.0pre9.001 -export FILE=ebtables-v2.0_vs_2.4.18.pre9.001.diff +export TO=ebt2.0-rc1 +export FILE=ebtables-v2.0_vs_2.4.18-rc1.001.diff # brouter support @@ -11,7 +13,8 @@ diff -urN $FROM/net/bridge/br_private.h $TO/net/bridge/br_private.h > $FILE diff -urN $FROM/include/linux/if_bridge.h $TO/include/linux/if_bridge.h >> $FILE diff -urN $FROM/net/core/dev.c $TO/net/core/dev.c >> $FILE diff -urN $FROM/net/bridge/br_input.c $TO/net/bridge/br_input.c >> $FILE -diff -urN $FROM/net/netsyms.c $TO/net/netsyms.c >> $FILE +diff -urN $FROM/net/bridge/br.c $TO/net/bridge/br.c >> $FILE +diff -urN $FROM/net/bridge/Makefile $TO/net/bridge/Makefile >> $FILE diff -urN $FROM/include/linux/netfilter_bridge.h $TO/include/linux/netfilter_bridge.h >> $FILE # getting ebtables compilable @@ -32,6 +35,8 @@ diff -urN $FROM/net/bridge/netfilter/ebt_arp.c $TO/net/bridge/netfilter/ebt_arp. diff -urN $FROM/net/bridge/netfilter/ebt_ip.c $TO/net/bridge/netfilter/ebt_ip.c >> $FILE diff -urN $FROM/net/bridge/netfilter/ebt_vlan.c $TO/net/bridge/netfilter/ebt_vlan.c >> $FILE diff -urN $FROM/net/bridge/netfilter/ebt_log.c $TO/net/bridge/netfilter/ebt_log.c >> $FILE +diff -urN $FROM/net/bridge/netfilter/ebt_mark.c $TO/net/bridge/netfilter/ebt_mark.c >> $FILE +diff -urN $FROM/net/bridge/netfilter/ebt_mark_m.c $TO/net/bridge/netfilter/ebt_mark_m.c >> $FILE diff -urN $FROM/net/bridge/netfilter/ebt_snat.c $TO/net/bridge/netfilter/ebt_snat.c >> $FILE diff -urN $FROM/net/bridge/netfilter/ebt_dnat.c $TO/net/bridge/netfilter/ebt_dnat.c >> $FILE diff -urN $FROM/net/bridge/netfilter/ebtables.c $TO/net/bridge/netfilter/ebtables.c >> $FILE @@ -40,6 +45,8 @@ diff -urN $FROM/include/linux/netfilter_bridge/ebt_arp.h $TO/include/linux/netfi diff -urN $FROM/include/linux/netfilter_bridge/ebt_ip.h $TO/include/linux/netfilter_bridge/ebt_ip.h >> $FILE diff -urN $FROM/include/linux/netfilter_bridge/ebt_vlan.h $TO/include/linux/netfilter_bridge/ebt_vlan.h >> $FILE diff -urN $FROM/include/linux/netfilter_bridge/ebt_log.h $TO/include/linux/netfilter_bridge/ebt_log.h >> $FILE +diff -urN $FROM/include/linux/netfilter_bridge/ebt_mark_t.h $TO/include/linux/netfilter_bridge/ebt_mark_t.h >> $FILE +diff -urN $FROM/include/linux/netfilter_bridge/ebt_mark_m.h $TO/include/linux/netfilter_bridge/ebt_mark_m.h >> $FILE diff -urN $FROM/include/linux/netfilter_bridge/ebt_nat.h $TO/include/linux/netfilter_bridge/ebt_nat.h >> $FILE diff -urN $FROM/include/linux/netfilter_bridge/ebt_redirect.h $TO/include/linux/netfilter_bridge/ebt_redirect.h >> $FILE diff -urN $FROM/include/linux/br_db.h $TO/include/linux/br_db.h >> $FILE diff --git a/userspace/patches/incremental-patches/ebtables-v2.0-rc1.001.diff b/userspace/patches/incremental-patches/ebtables-v2.0-rc1.001.diff new file mode 100644 index 0000000..b6ee40f --- /dev/null +++ b/userspace/patches/incremental-patches/ebtables-v2.0-rc1.001.diff @@ -0,0 +1,1764 @@ +--- ebtables-v2.0pre10/Makefile Wed Jul 10 22:12:36 2002 ++++ ebtables-v2.0-rc1.001/Makefile Wed Jul 31 19:48:25 2002 +@@ -2,7 +2,7 @@ + + KERNEL_DIR?=/usr/src/linux + PROGNAME:=ebtables +-PROGVERSION:="2.0pre10 (July 2002)" ++PROGVERSION:="2.0-rc1 (July 2002)" + + MANDIR?=/usr/local/man + CFLAGS:=-Wall -Wunused +--- ebtables-v2.0pre10/ebtables.c Tue Jul 16 20:36:50 2002 ++++ ebtables-v2.0-rc1.001/ebtables.c Thu Jul 25 16:02:43 2002 +@@ -1,5 +1,5 @@ + /* +- * ebtables.c, v2.0 April 2002 ++ * ebtables.c, v2.0 July 2002 + * + * Author: Bart De Schuymer + * +@@ -32,13 +32,12 @@ + #include // the database + #include + #include +-#include + #include "include/ebtables_u.h" + #include + #include + #include + +-// here are the number-name correspondences kept for the ethernet ++// here are the number-name correspondences kept for the Ethernet + // frame type field + #define PROTOCOLFILE "/etc/ethertypes" + +@@ -123,8 +122,6 @@ + unsigned char mac_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255}; + unsigned char msk_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255}; + +-// tells what happened to the old rules +-static unsigned short *counterchanges; + // holds all the data + static struct ebt_u_replace replace; + +@@ -228,8 +225,7 @@ + struct ebt_u_match_list **m_list, *new; + + m->used = 1; +- for (m_list = &new_entry->m_list; +- *m_list; m_list = &(*m_list)->next); ++ for (m_list = &new_entry->m_list; *m_list; m_list = &(*m_list)->next); + new = (struct ebt_u_match_list *) + malloc(sizeof(struct ebt_u_match_list)); + if (!new) +@@ -245,8 +241,7 @@ + struct ebt_u_watcher_list *new; + + w->used = 1; +- for (w_list = &new_entry->w_list; +- *w_list; w_list = &(*w_list)->next); ++ for (w_list = &new_entry->w_list; *w_list; w_list = &(*w_list)->next); + new = (struct ebt_u_watcher_list *) + malloc(sizeof(struct ebt_u_watcher_list)); + if (!new) +@@ -340,6 +335,7 @@ + ebt_options = merge_options + (ebt_options, t->extra_ops, &(t->option_offset)); + t->init(t->t); ++ + for (i = &targets; *i; i = &((*i)->next)); + t->next = NULL; + *i = t; +@@ -379,7 +375,6 @@ + return NULL; + } + +-// I hate stealing, really... Lets call it a tribute. + int ebtables_insmod(const char *modname, const char *modprobe) + { + char *buf = NULL; +@@ -413,86 +408,26 @@ + return 0; + } + +- +-// used to parse /etc/ethertypes +-static int disregard_whitespace(char *buffer, FILE *ifp) +-{ +- int hlp; +- +- buffer[0] = '\t'; +- while (buffer[0] == '\t' || buffer[0] == '\n' || buffer[0] == ' ') { +- hlp = fscanf(ifp, "%c", buffer); +- if (hlp == EOF || hlp == 0) return -1; +- } +- return 0; +-} +- +-// used to parse /etc/ethertypes +-static int disregard_tabspace(char *buffer, FILE *ifp) +-{ +- int hlp; +- +- buffer[0] = '\t'; +- while (buffer[0] == '\t' || buffer[0] == ' ') { +- hlp = fscanf(ifp, "%c", buffer); +- if (hlp == EOF || hlp == 0) return -1; +- } +- 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) + { +- int i, hlp; +- char anotherhlp; ++ char line[80], *p; ++ const char delim[] = " \t\n"; + +- // discard comment lines and whitespace +- while (1) { +- if (disregard_whitespace(buffer, ifp)) +- return -1; +- if (buffer[0] == '#') +- while (1) { +- hlp = fscanf(ifp, "%c", &anotherhlp); +- if (!hlp || hlp == EOF) +- return -1; +- if (anotherhlp == '\n') +- break; +- } +- else +- break; +- } +- +- // buffer[0] already contains the first letter +- for (i = 1; i < 21; i++) { +- hlp = fscanf(ifp, "%c", buffer + i); +- if (hlp == EOF || hlp == 0) +- return -1; +- if (buffer[i] == '\t' || buffer[i] == ' ') +- break; +- } +- if (i == 21) +- return -1; +- buffer[i] = '\0'; +- if (disregard_tabspace(value, ifp)) +- return -1; +- // maybe I should allow 0x0800 instead of 0800, but I'm feeling lazy +- // buffer[0] already contains the first letter +- for (i = 1; i < 5; i++) { +- hlp = fscanf(ifp, "%c", value+i); +- if (value[i] == '\n' || value[i] == '\t' || +- value[i] == ' ' || hlp == EOF) +- break; ++ 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; + } +- if (i == 5) return -1; +- // discard comments at the end of a line +- if (value[i] == '\t' || value[i] == ' ') +- while (1) { +- hlp = fscanf(ifp, "%c", &anotherhlp); +- if (!hlp || hlp == EOF || anotherhlp == '\n') +- break; +- } +- value[i] = '\0'; +- return 0; ++ return -1; + } + + // translate a hexadecimal number to a protocol name, parsing /etc/ethertypes +@@ -500,7 +435,7 @@ + int number_to_name(unsigned short proto, char *name) + { + FILE *ifp; +- char buffer[21], value[5], *bfr; ++ char buffer[21], value[11], *bfr; + unsigned short i; + + if ( !(ifp = fopen(PROTOCOLFILE, "r")) ) +@@ -768,7 +703,9 @@ + if (!(replace.valid_hooks & (1 << i))) + continue; + entries = nr_to_chain(i); +- entries->hook_mask = (1 << i); ++ // (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; + + e = entries->entries; +@@ -784,7 +721,8 @@ + 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); ++ 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 + stack[sp].chain_nr = chain_nr; + stack[sp].n = j; +@@ -960,16 +898,16 @@ + replace.num_counters = replace.nentries; + if (replace.nentries) { + // '+ 1' for the CNT_END +- if (!(counterchanges = (unsigned short *) malloc( ++ if (!(replace.counterchanges = (unsigned short *) malloc( + (replace.nentries + 1) * sizeof(unsigned short)))) + print_memory(); + // done nothing special to the rules + for (i = 0; i < replace.nentries; i++) +- counterchanges[i] = CNT_NORM; +- counterchanges[replace.nentries] = CNT_END; ++ replace.counterchanges[i] = CNT_NORM; ++ replace.counterchanges[replace.nentries] = CNT_END; + } + else +- counterchanges = NULL; ++ replace.counterchanges = NULL; + } + else + exit(0); +@@ -1026,14 +964,14 @@ + + if (replace.nentries) { + // +1 for CNT_END +- if ( !(counterchanges = (unsigned short *) ++ if ( !(replace.counterchanges = (unsigned short *) + malloc((oldnentries + 1) * sizeof(unsigned short))) ) + print_memory(); + } + // delete the counters belonging to the specified chain, + // update counter_offset + i = -1; +- cnt = counterchanges; ++ cnt = replace.counterchanges; + while (1) { + i++; + entries = nr_to_chain(i); +@@ -1101,73 +1039,74 @@ + for (i = 0; i < entries->nentries; i++, u_e = u_e->next) { + if (!u_e) + print_bug("Hmm, trouble"); +- if ( u_e->ethproto == new_entry->ethproto +- && !strcmp(u_e->in, new_entry->in) +- && !strcmp(u_e->out, new_entry->out)) { +- if (strcmp(u_e->logical_in, new_entry->logical_in) || +- strcmp(u_e->logical_out, new_entry->logical_out)) +- continue; +- if (new_entry->bitmask & EBT_SOURCEMAC && +- memcmp(u_e->sourcemac, new_entry->sourcemac, ETH_ALEN)) +- continue; +- if (new_entry->bitmask & EBT_DESTMAC && +- memcmp(u_e->destmac, new_entry->destmac, ETH_ALEN)) +- continue; +- if (new_entry->bitmask != u_e->bitmask || +- new_entry->invflags != u_e->invflags) +- continue; +- // compare all matches +- m_l = new_entry->m_list; +- j = 0; +- while (m_l) { +- m = (struct ebt_u_match *)(m_l->m); +- m_l2 = u_e->m_list; +- while (m_l2 && +- strcmp(m_l2->m->u.name, m->m->u.name)) +- m_l2 = m_l2->next; +- if (!m_l2 || !m->compare(m->m, m_l2->m)) +- goto letscontinue; +- j++; +- m_l = m_l->next; +- } +- // now be sure they have the same nr of matches +- k = 0; +- m_l = u_e->m_list; +- while (m_l) { +- k++; +- m_l = m_l->next; +- } +- if (j != k) +- continue; ++ if (u_e->ethproto != new_entry->ethproto) ++ continue; ++ if (strcmp(u_e->in, new_entry->in)) ++ continue; ++ if (strcmp(u_e->out, new_entry->out)) ++ continue; ++ if (strcmp(u_e->logical_in, new_entry->logical_in)) ++ continue; ++ if (strcmp(u_e->logical_out, new_entry->logical_out)) ++ continue; ++ if (new_entry->bitmask & EBT_SOURCEMAC && ++ memcmp(u_e->sourcemac, new_entry->sourcemac, ETH_ALEN)) ++ continue; ++ if (new_entry->bitmask & EBT_DESTMAC && ++ memcmp(u_e->destmac, new_entry->destmac, ETH_ALEN)) ++ continue; ++ if (new_entry->bitmask != u_e->bitmask || ++ new_entry->invflags != u_e->invflags) ++ continue; ++ // compare all matches ++ m_l = new_entry->m_list; ++ j = 0; ++ while (m_l) { ++ m = (struct ebt_u_match *)(m_l->m); ++ m_l2 = u_e->m_list; ++ while (m_l2 && strcmp(m_l2->m->u.name, m->m->u.name)) ++ m_l2 = m_l2->next; ++ if (!m_l2 || !m->compare(m->m, m_l2->m)) ++ goto letscontinue; ++ j++; ++ m_l = m_l->next; ++ } ++ // now be sure they have the same nr of matches ++ k = 0; ++ m_l = u_e->m_list; ++ while (m_l) { ++ k++; ++ m_l = m_l->next; ++ } ++ if (j != k) ++ continue; + +- // compare all watchers +- w_l = new_entry->w_list; +- j = 0; +- while (w_l) { +- w = (struct ebt_u_watcher *)(w_l->w); +- w_l2 = u_e->w_list; +- while (w_l2 && +- strcmp(w_l2->w->u.name, w->w->u.name)) +- w_l2 = w_l2->next; +- if (!w_l2 || !w->compare(w->w, w_l2->w)) +- goto letscontinue; +- j++; +- w_l = w_l->next; +- } +- k = 0; +- w_l = u_e->w_list; +- while (w_l) { +- k++; +- w_l = w_l->next; +- } +- if (j != k) +- continue; +- if (strcmp(t->t->u.name, u_e->t->u.name)) +- continue; +- if (!t->compare(t->t, u_e->t)) +- continue; +- return i; ++ // compare all watchers ++ w_l = new_entry->w_list; ++ j = 0; ++ while (w_l) { ++ w = (struct ebt_u_watcher *)(w_l->w); ++ w_l2 = u_e->w_list; ++ while (w_l2 && strcmp(w_l2->w->u.name, w->w->u.name)) ++ w_l2 = w_l2->next; ++ if (!w_l2 || !w->compare(w->w, w_l2->w)) ++ goto letscontinue; ++ j++; ++ w_l = w_l->next; ++ } ++ k = 0; ++ w_l = u_e->w_list; ++ while (w_l) { ++ k++; ++ w_l = w_l->next; + } ++ if (j != k) ++ continue; ++ if (strcmp(t->t->u.name, u_e->t->u.name)) ++ continue; ++ if (!t->compare(t->t, u_e->t)) ++ continue; ++ return i; + letscontinue: + } + return -1; +@@ -1177,7 +1116,7 @@ + static void add_rule(int rule_nr) + { + int i, j; +- struct ebt_u_entry *u_e, *u_e2; ++ struct ebt_u_entry **u_e; + unsigned short *cnt; + struct ebt_u_match_list *m_l; + struct ebt_u_watcher_list *w_l; +@@ -1196,10 +1135,10 @@ + + // handle counter stuff + // +1 for CNT_END +- if ( !(counterchanges = (unsigned short *) ++ if ( !(replace.counterchanges = (unsigned short *) + malloc((replace.nentries + 1) * sizeof(unsigned short))) ) + print_memory(); +- cnt = counterchanges; ++ cnt = replace.counterchanges; + for (i = 0; i < replace.selected_hook; i++) { + if (i < NF_BR_NUMHOOKS && !(replace.valid_hooks & (1 << i))) + continue; +@@ -1215,25 +1154,19 @@ + } + *cnt = CNT_ADD; + cnt++; +- while (cnt != counterchanges + replace.nentries) { ++ while (cnt != replace.counterchanges + replace.nentries) { + *cnt = CNT_NORM; + cnt++; + } + *cnt = CNT_END; + + // go to the right position in the chain +- u_e2 = NULL; +- u_e = entries->entries; +- for (i = 0; i < rule_nr; i++) { +- u_e2 = u_e; +- u_e = u_e->next; +- } ++ u_e = &entries->entries; ++ for (i = 0; i < rule_nr; i++) ++ u_e = &(*u_e)->next; + // insert the rule +- if (u_e2) +- u_e2->next = new_entry; +- else +- entries->entries = new_entry; +- new_entry->next = u_e; ++ new_entry->next = *u_e; ++ *u_e = new_entry; + + // put the ebt_[match, watcher, target] pointers in place + m_l = new_entry->m_list; +@@ -1268,7 +1201,7 @@ + { + int i, j, lentmp = 0; + unsigned short *cnt; +- struct ebt_u_entry *u_e, *u_e2; ++ struct ebt_u_entry **u_e, *u_e2; + struct ebt_u_entries *entries = to_chain(), *entries2; + + if ( (i = check_rule_exists(rule_nr)) == -1 ) +@@ -1277,6 +1210,7 @@ + // we're deleting a rule + replace.num_counters = replace.nentries; + replace.nentries--; ++ entries->nentries--; + + if (replace.nentries) { + for (j = 0; j < replace.selected_hook; j++) { +@@ -1288,10 +1222,10 @@ + } + lentmp += i; + // +1 for CNT_END +- if ( !(counterchanges = (unsigned short *)malloc( ++ if ( !(replace.counterchanges = (unsigned short *)malloc( + (replace.num_counters + 1) * sizeof(unsigned short))) ) + print_memory(); +- cnt = counterchanges; ++ cnt = replace.counterchanges; + for (j = 0; j < lentmp; j++) { + *cnt = CNT_NORM; + cnt++; +@@ -1308,23 +1242,16 @@ + replace.num_counters = 0; + + // go to the right position in the chain +- u_e2 = NULL; +- u_e = entries->entries; +- for (j = 0; j < i; j++) { +- u_e2 = u_e; +- u_e = u_e->next; +- } +- +- // remove from the chain +- if (u_e2) +- u_e2->next = u_e->next; +- else +- entries->entries = u_e->next; +- +- entries->nentries--; ++ u_e = &entries->entries; ++ for (j = 0; j < i; j++) ++ u_e = &(*u_e)->next; ++ // remove the rule ++ u_e2 = *u_e; ++ *u_e = (*u_e)->next; + // free everything +- free_u_entry(u_e); +- free(u_e); ++ free_u_entry(u_e2); ++ free(u_e2); ++ + // update the counter_offset of chains behind this one + i = replace.selected_hook; + while (1) { +@@ -1348,7 +1275,7 @@ + // 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 +- counterchanges = NULL; ++ replace.counterchanges = NULL; + replace.num_counters = 0; + } else { + int i, j; +@@ -1357,11 +1284,11 @@ + + if (entries->nentries == 0) + exit(0); +- counterchanges = (unsigned short *) ++ replace.counterchanges = (unsigned short *) + malloc((replace.nentries + 1) * sizeof(unsigned short)); +- if (!counterchanges) ++ if (!replace.counterchanges) + print_memory(); +- cnt = counterchanges; ++ cnt = replace.counterchanges; + for (i = 0; i < zerochain; i++) { + if (i < NF_BR_NUMHOOKS && + !(replace.valid_hooks & (1 << i))) +@@ -1376,7 +1303,7 @@ + *cnt = CNT_ZERO; + cnt++; + } +- while (cnt != counterchanges + replace.nentries) { ++ while (cnt != replace.counterchanges + replace.nentries) { + *cnt = CNT_NORM; + cnt++; + } +@@ -1450,7 +1377,7 @@ + int name_to_number(char *name, __u16 *proto) + { + FILE *ifp; +- char buffer[21], value[5], *bfr; ++ char buffer[21], value[11], *bfr; + unsigned short i; + + if (!strcasecmp("LENGTH", name)) { +@@ -1461,14 +1388,15 @@ + if ( !(ifp = fopen(PROTOCOLFILE, "r")) ) + return -1; + while (1) { +- if (get_a_line(buffer, value, ifp)) return -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; +- fclose(ifp); + return 0; + } + return -1; +@@ -1587,6 +1515,19 @@ + *flags |= mask; + } + ++static void get_kernel_table(const char *modprobe) ++{ ++ if ( !(table = find_table(replace.name)) ) ++ print_error("Bad table name"); ++ // 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); ++ } ++} ++ + #define OPT_COMMAND 0x01 + #define OPT_TABLE 0x02 + #define OPT_IN 0x04 +@@ -1606,7 +1547,7 @@ + // 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 chain number ++ int rule_nr = -1;// used for -[D,I] chain number + struct ebt_u_target *t; + struct ebt_u_match *m; + struct ebt_u_watcher *w; +@@ -1621,6 +1562,7 @@ + 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) +@@ -1648,16 +1590,8 @@ + if (replace.flags & OPT_COMMAND) + print_error("Multiple commands not allowed"); + replace.flags |= OPT_COMMAND; +- if ( !(table = find_table(replace.name)) ) +- print_error("Bad table name"); +- // get the kernel's information +- if (get_table(&replace)) { +- ebtables_insmod("ebtables", modprobe); +- if (get_table(&replace)) +- print_error("can't initialize ebtables " +- "table %s", replace.name); +- } +- if (optarg[0] == '-') ++ get_kernel_table(modprobe); ++ if (optarg[0] == '-' || !strcmp(optarg, "!")) + print_error("No chain name specified"); + if (c == 'N') { + struct ebt_u_chain_list *cl, **cl2; +@@ -1697,7 +1631,8 @@ + if ((replace.selected_hook = get_hooknr(optarg)) == -1) + print_error("Chain %s doesn't exist", optarg); + if (c == 'E') { +- if (optind >= argc || argv[optind][0] == '-') ++ if (optind >= argc || argv[optind][0] == '-' || ++ !strcmp(argv[optind], "!")) + print_error("No new chain name specified"); + if (strlen(argv[optind]) >= EBT_CHAIN_MAXNAMELEN) + print_error("Chain name len can't exceed %d", +@@ -1705,6 +1640,9 @@ + if (get_hooknr(argv[optind]) != -1) + print_error("Chain %s already exists", + argv[optind]); ++ if (find_target(argv[optind])) ++ print_error("Target with name %s exists" ++ , argv[optind]); + entries = to_chain(); + strcpy(entries->name, argv[optind]); + optind++; +@@ -1719,25 +1657,21 @@ + check_for_references(replace.selected_hook - NF_BR_NUMHOOKS); + flush_chains(); + entries = to_chain(); +- if (replace.udc->udc == entries) { +- cl = replace.udc; +- replace.udc = replace.udc->next; +- free(cl->udc); +- free(cl); +- break; +- } + cl2 = &(replace.udc); +- while ((*cl2)->next->udc != entries) ++ while ((*cl2)->udc != entries) + cl2 = &((*cl2)->next); +- cl = (*cl2)->next; +- (*cl2)->next = (*cl2)->next->next; ++ cl = (*cl2); ++ (*cl2) = (*cl2)->next; + free(cl->udc); + free(cl); + break; + } + +- if (c == 'D' && optind < argc && +- argv[optind][0] != '-') { ++ if ( (c == 'D' && optind < argc && ++ argv[optind][0] != '-') || c == 'I') { ++ if (optind >= argc || argv[optind][0] == '-') ++ print_error("No rulenr for -I" ++ " specified"); + rule_nr = strtol(argv[optind], &buffer, 10); + if (*buffer != '\0' || rule_nr < 0) + print_error("Problem with the " +@@ -1760,16 +1694,6 @@ + print_error("Wrong policy"); + optind++; + } +- if (c == 'I') { +- if (optind >= argc) +- print_error("No rulenr for -I" +- " specified"); +- rule_nr = strtol(argv[optind], &buffer, 10); +- if (*buffer != '\0' || rule_nr < 0) +- print_error("Problem with the specified" +- " rule number"); +- optind++; +- } + break; + + case 'L': // list +@@ -1791,23 +1715,14 @@ + " not allowed"); + replace.flags |= OPT_COMMAND; + } +- if ( !(table = find_table(replace.name)) ) +- print_error("Bad table name"); +- // get the kernel's information +- if (get_table(&replace)) { +- ebtables_insmod("ebtables", modprobe); +- if (get_table(&replace)) +- print_error("can't initialize ebtables " +- "table %s", replace.name); +- } ++ get_kernel_table(modprobe); + i = -1; + if (optarg) { + if ( (i = get_hooknr(optarg)) == -1 ) + print_error("Bad chain"); + } else + if (optind < argc && argv[optind][0] != '-') { +- if ((i = get_hooknr(argv[optind])) +- == -1) ++ if ((i = get_hooknr(argv[optind])) == -1) + print_error("Bad chain"); + optind++; + } +@@ -2054,7 +1969,7 @@ + if (new_entry->ethproto < 1536 && + !(new_entry->bitmask & EBT_802_3)) + print_error("Sorry, protocols have values above" +- " or equal to 1536 (0x0600)"); ++ " or equal to 0x0600"); + break; + + case 'b': // allow database? +@@ -2104,17 +2019,24 @@ + 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 + get_table(&replace); + if (replace.nentries) { +- counterchanges = (unsigned short *) ++ replace.counterchanges = (unsigned short *) + malloc(sizeof(unsigned short) * (replace.nentries + 1)); + for (i = 0; i < replace.nentries; i++) +- counterchanges[i] = CNT_NORM; +- counterchanges[i] = CNT_END; ++ 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 ++ replace.num_counters = 0; ++ // make sure the table will be written to the kernel + free(replace.filename); + replace.filename = NULL; + break; +@@ -2125,24 +2047,23 @@ + if (replace.flags & OPT_COMMAND) + print_error("Multiple commands not allowed"); + replace.flags |= OPT_COMMAND; +- if ( !(table = find_table(replace.name)) ) +- print_error("Bad table name"); +- if (get_table(&replace)) { +- ebtables_insmod("ebtables", modprobe); +- if (get_table(&replace)) +- print_error("can't initialize ebtables " +- "table %s", replace.name); +- } ++ if (replace.filename) ++ print_error("--atomic incompatible with " ++ "command"); ++ get_kernel_table(modprobe); + if (replace.nentries) { +- counterchanges = (unsigned short *) ++ replace.counterchanges = (unsigned short *) + malloc(sizeof(unsigned short) * (replace.nentries + 1)); + for (i = 0; i < replace.nentries; i++) +- counterchanges[i] = CNT_NORM; +- counterchanges[i] = CNT_END; ++ replace.counterchanges[i] = CNT_NORM; ++ replace.counterchanges[i] = CNT_END; + } + if (c == 11) + break; + case 9 : // atomic ++ if (c == 9 && (replace.flags & OPT_COMMAND)) ++ print_error("--atomic has to come before" ++ " the command"); + replace.filename = (char *)malloc(strlen(optarg) + 1); + strcpy(replace.filename, optarg); + break; +@@ -2179,7 +2100,7 @@ + check_extension: + if (replace.command != 'A' && replace.command != 'I' && + replace.command != 'D') +- print_error("extensions only for -A, -I and -D"); ++ print_error("Extensions only for -A, -I and -D"); + } + } + +@@ -2195,12 +2116,6 @@ + replace.flags & OPT_ZERO ) + print_error("Command -Z only allowed together with command -L"); + +- if (replace.command == 'A' || replace.command == 'I' || +- replace.command == 'D') { +- if (replace.selected_hook == -1) +- print_error("Not enough information"); +- } +- + // do this after parsing everything, so we can print specific info + if (replace.command == 'h' && !(replace.flags & OPT_ZERO)) + print_help(); +@@ -2283,7 +2198,7 @@ + + deliver_table(&replace); + +- if (counterchanges) +- deliver_counters(&replace, counterchanges); ++ if (replace.counterchanges) ++ deliver_counters(&replace); + return 0; + } +--- ebtables-v2.0pre10/communication.c Mon Jul 15 22:35:14 2002 ++++ ebtables-v2.0-rc1.001/communication.c Fri Jul 26 13:33:02 2002 +@@ -1,5 +1,5 @@ + /* +- * communication.c, v2.0 April 2002 ++ * communication.c, v2.0 July 2002 + * + * Author: Bart De Schuymer + * +@@ -18,9 +18,8 @@ + #include + #include + #include +-#include // the database ++#include + #include // IPPROTO_IP +-#include + #include "include/ebtables_u.h" + + extern char* hooknames[NF_BR_NUMHOOKS]; +@@ -32,7 +31,8 @@ + if (sockfd == -1) { + sockfd = socket(AF_INET, SOCK_RAW, PF_INET); + if (sockfd < 0) +- print_error("Problem getting a socket"); ++ print_error("Problem getting a socket, " ++ "do you have the right permissions?"); + } + } + +@@ -52,7 +52,7 @@ + if (!new) + print_memory(); + new->valid_hooks = u_repl->valid_hooks; +- memcpy(new->name, u_repl->name, sizeof(new->name)); ++ strcpy(new->name, u_repl->name); + new->nentries = u_repl->nentries; + new->num_counters = u_repl->num_counters; + new->counters = u_repl->counters; +@@ -150,12 +150,10 @@ + tmp->bitmask = e->bitmask | EBT_ENTRY_OR_ENTRIES; + tmp->invflags = e->invflags; + tmp->ethproto = e->ethproto; +- memcpy(tmp->in, e->in, sizeof(tmp->in)); +- memcpy(tmp->out, e->out, sizeof(tmp->out)); +- memcpy(tmp->logical_in, e->logical_in, +- sizeof(tmp->logical_in)); +- memcpy(tmp->logical_out, e->logical_out, +- sizeof(tmp->logical_out)); ++ strcpy(tmp->in, e->in); ++ strcpy(tmp->out, e->out); ++ strcpy(tmp->logical_in, e->logical_in); ++ strcpy(tmp->logical_out, e->logical_out); + memcpy(tmp->sourcemac, e->sourcemac, + sizeof(tmp->sourcemac)); + memcpy(tmp->sourcemsk, e->sourcemsk, +@@ -190,7 +188,8 @@ + (struct ebt_standard_target *)p; + // translate the jump to a udc + if (st->verdict >= 0) +- st->verdict = chain_offsets[st->verdict + NF_BR_NUMHOOKS]; ++ st->verdict = chain_offsets ++ [st->verdict + NF_BR_NUMHOOKS]; + } + p += e->t->target_size + + sizeof(struct ebt_entry_target); +@@ -257,23 +256,23 @@ + + // translate the struct ebt_u_replace to a struct ebt_replace + repl = translate_user2kernel(u_repl); +- // give the data to the kernel +- optlen = sizeof(struct ebt_replace) + repl->entries_size; + if (u_repl->filename != NULL) { + store_table_in_file(u_repl->filename, repl); + return; + } ++ // give the data to the kernel ++ optlen = sizeof(struct ebt_replace) + repl->entries_size; + get_sockfd(); + if (setsockopt(sockfd, IPPROTO_IP, EBT_SO_SET_ENTRIES, repl, optlen)) + print_error("The kernel doesn't support a certain ebtables" + " extension, consider recompiling your kernel or insmod" +- " the extension"); ++ " the extension"); + } + + static void store_counters_in_file(char *filename, struct ebt_u_replace *repl) + { + int size = repl->nentries * sizeof(struct ebt_counter); +- int entries_size; ++ unsigned int entries_size; + struct ebt_replace hlp; + FILE *file; + +@@ -296,12 +295,13 @@ + + // gets executed after deliver_table + void +-deliver_counters(struct ebt_u_replace *u_repl, unsigned short *counterchanges) ++deliver_counters(struct ebt_u_replace *u_repl) + { + unsigned short *point; + struct ebt_counter *old, *new, *newcounters; + socklen_t optlen; + struct ebt_replace repl; ++ unsigned short *counterchanges = u_repl->counterchanges; + + if (u_repl->nentries == 0) + return; +@@ -323,16 +323,14 @@ + old++; + // we've set a new counter + new++; +- } else +- if (*point == CNT_DEL) { ++ } else if (*point == CNT_DEL) { + // don't use this old counter + old++; + } else if (*point == CNT_ADD) { + // new counter, let it stay 0 + new++; + } else { +- // zero it +- new->pcnt = 0; ++ // zero it (let it stay 0) + old++; + new++; + } +@@ -355,7 +353,7 @@ + + get_sockfd(); + if (setsockopt(sockfd, IPPROTO_IP, EBT_SO_SET_COUNTERS, &repl, optlen)) +- print_bug("couldn't update kernel counters"); ++ print_bug("Couldn't update kernel counters"); + } + + static int +@@ -425,12 +423,10 @@ + new->bitmask &= ~EBT_ENTRY_OR_ENTRIES; + new->invflags = e->invflags; + new->ethproto = e->ethproto; +- memcpy(new->in, e->in, sizeof(new->in)); +- memcpy(new->out, e->out, sizeof(new->out)); +- memcpy(new->logical_in, e->logical_in, +- sizeof(new->logical_in)); +- memcpy(new->logical_out, e->logical_out, +- sizeof(new->logical_out)); ++ strcpy(new->in, e->in); ++ strcpy(new->out, e->out); ++ strcpy(new->logical_in, e->logical_in); ++ strcpy(new->logical_out, e->logical_out); + memcpy(new->sourcemac, e->sourcemac, sizeof(new->sourcemac)); + memcpy(new->sourcemsk, e->sourcemsk, sizeof(new->sourcemsk)); + memcpy(new->destmac, e->destmac, sizeof(new->destmac)); +@@ -500,9 +496,8 @@ + while (i-- > 0) + cl = cl->next; + *u_e = &(cl->udc->entries); +- } else { ++ } else + *u_e = &(u_repl->hook_entry[*hook]->entries); +- } + return 0; + } + } +@@ -568,7 +563,7 @@ + print_error("Could not open file %s", filename); + // make sure table name is right if command isn't -L or --atomic-commit + if (command != 'L' && command != 8) { +- hlp = (char *)malloc(strlen(repl->name)); ++ hlp = (char *)malloc(strlen(repl->name) + 1); + if (!hlp) + print_memory(); + strcpy(hlp, repl->name); +@@ -580,12 +575,11 @@ + fclose(file); + print_error("File %s contains wrong table name or is corrupt", + filename); +- } else +- if (!find_table(repl->name)) { +- fclose(file); +- print_error("File %s contains invalid table name", +- filename); +- } ++ free(hlp); ++ } else if (!find_table(repl->name)) { ++ fclose(file); ++ print_error("File %s contains invalid table name", filename); ++ } + + size = sizeof(struct ebt_replace) + + repl->nentries * sizeof(struct ebt_counter) + repl->entries_size; +@@ -633,7 +627,7 @@ + if (getsockopt(sockfd, IPPROTO_IP, optname, repl, &optlen)) + return -1; + +- if ( !(repl->entries = (char *) malloc(repl->entries_size)) ) ++ if ( !(repl->entries = (char *)malloc(repl->entries_size)) ) + print_memory(); + if (repl->nentries) { + if (!(repl->counters = (struct ebt_counter *) +@@ -657,7 +651,6 @@ + return 0; + } + +-// talk with kernel to receive the kernel's table + int get_table(struct ebt_u_replace *u_repl) + { + int i, j, k, hook; +@@ -667,12 +660,10 @@ + strcpy(repl.name, u_repl->name); + if (u_repl->filename != NULL) + retrieve_from_file(u_repl->filename, &repl, u_repl->command); +- else +- if (retrieve_from_kernel(&repl, u_repl->command) == -1) +- return -1; ++ else if (retrieve_from_kernel(&repl, u_repl->command) == -1) ++ return -1; + + // translate the struct ebt_replace to a struct ebt_u_replace +- memcpy(u_repl->name, repl.name, sizeof(u_repl->name)); + u_repl->valid_hooks = repl.valid_hooks; + u_repl->nentries = repl.nentries; + u_repl->num_counters = repl.num_counters; +--- ebtables-v2.0pre10/extensions/ebt_redirect.c Thu Jun 27 18:53:55 2002 ++++ ebtables-v2.0-rc1.001/extensions/ebt_redirect.c Thu Jul 25 19:28:52 2002 +@@ -12,7 +12,7 @@ + #define REDIRECT_TARGET '1' + static struct option opts[] = + { +- { "redirect-target" , required_argument, 0, REDIRECT_TARGET }, ++ { "redirect-target", required_argument, 0, REDIRECT_TARGET }, + { 0 } + }; + +@@ -20,7 +20,7 @@ + { + printf( + "redirect option:\n" +- " --redirect-target target : ACCEPT, DROP or CONTINUE\n"); ++ " --redirect-target target : ACCEPT, DROP, RETURN or CONTINUE\n"); + } + + static void init(struct ebt_entry_target *target) +@@ -62,6 +62,13 @@ + const struct ebt_entry_target *target, const char *name, + unsigned int hook_mask, unsigned int time) + { ++ struct ebt_redirect_info *redirectinfo = ++ (struct ebt_redirect_info *)target->data; ++ ++ if ((hook_mask & (1 << NF_BR_NUMHOOKS)) && ++ redirectinfo->target == EBT_RETURN) ++ print_error("--redirect-target RETURN not allowed on base chain"); ++ hook_mask &= ~(1 << NF_BR_NUMHOOKS); + if ( ((hook_mask & ~(1 << NF_BR_PRE_ROUTING)) || strcmp(name, "nat")) && + ((hook_mask & ~(1 << NF_BR_BROUTING)) || strcmp(name, "broute")) ) + print_error("Wrong chain for redirect"); +--- ebtables-v2.0pre10/extensions/ebtable_broute.c Thu Jun 27 18:53:55 2002 ++++ ebtables-v2.0-rc1.001/extensions/ebtable_broute.c Wed Jul 24 20:44:43 2002 +@@ -5,7 +5,7 @@ + + static void print_help(char **hn) + { +- printf("Supported chain for the nat table:\n"); ++ printf("Supported chain for the broute table:\n"); + printf("%s\n",hn[NF_BR_BROUTING]); + } + +--- ebtables-v2.0pre10/extensions/ebt_nat.c Thu Jun 27 18:53:55 2002 ++++ ebtables-v2.0-rc1.001/extensions/ebt_nat.c Thu Jul 25 16:31:01 2002 +@@ -37,7 +37,7 @@ + printf( + "snat options:\n" + " --to-src address : MAC address to map source to\n" +- " --snat-target target : ACCEPT, DROP or CONTINUE\n"); ++ " --snat-target target : ACCEPT, DROP, RETURN or CONTINUE\n"); + } + + static void print_help_d() +@@ -45,7 +45,7 @@ + printf( + "dnat options:\n" + " --to-dst address : MAC address to map destination to\n" +- " --dnat-target target : ACCEPT, DROP or CONTINUE\n"); ++ " --dnat-target target : ACCEPT, DROP, RETURN or CONTINUE\n"); + } + + static void init_s(struct ebt_entry_target *target) +@@ -81,7 +81,7 @@ + check_option(flags, OPT_SNAT); + to_source_supplied = 1; + if (!(addr = ether_aton(optarg))) +- print_error("Problem with specified to-source mac"); ++ print_error("Problem with specified --to-source mac"); + memcpy(natinfo->mac, addr, ETH_ALEN); + break; + case NAT_S_TARGET: +@@ -116,7 +116,7 @@ + to_dest_supplied = 1; + if (!(addr = ether_aton(optarg))) + print_error("Problem with specified " +- "to-destination mac"); ++ "--to-destination mac"); + memcpy(natinfo->mac, addr, ETH_ALEN); + break; + case NAT_D_TARGET: +@@ -139,6 +139,11 @@ + const struct ebt_entry_target *target, const char *name, + unsigned int hook_mask, unsigned int time) + { ++ struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data; ++ ++ if ((hook_mask & (1 << NF_BR_NUMHOOKS)) && natinfo->target == EBT_RETURN) ++ print_error("--snat-target RETURN not allowed on base chain"); ++ hook_mask &= ~(1 << NF_BR_NUMHOOKS); + if (!(hook_mask & (1 << NF_BR_POST_ROUTING)) || strcmp(name, "nat")) + print_error("Wrong chain for snat"); + if (time == 0 && to_source_supplied == 0) +@@ -149,6 +154,11 @@ + const struct ebt_entry_target *target, const char *name, + unsigned int hook_mask, unsigned int time) + { ++ struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data; ++ ++ if ((hook_mask & (1 << NF_BR_NUMHOOKS)) && natinfo->target == EBT_RETURN) ++ print_error("--dnat-target RETURN not allowed on base chain"); ++ hook_mask &= ~(1 << NF_BR_NUMHOOKS); + if (((hook_mask & ~((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT))) || + strcmp(name, "nat")) && + ((hook_mask & ~(1 << NF_BR_BROUTING)) || strcmp(name, "broute"))) +--- ebtables-v2.0pre10/extensions/ebt_vlan.c Thu Jun 27 18:53:55 2002 ++++ ebtables-v2.0-rc1.001/extensions/ebt_vlan.c Wed Jul 24 12:18:25 2002 +@@ -41,7 +41,7 @@ + + #define GET_BITMASK(_MASK_) vlaninfo->bitmask & _MASK_ + #define SET_BITMASK(_MASK_) vlaninfo->bitmask |= _MASK_ +-#define INV_FLAG(_inv_flag_) (vlaninfo->invflags & _inv_flag_) ? "!" : "" ++#define INV_FLAG(_inv_flag_) (vlaninfo->invflags & _inv_flag_) ? "! " : "" + + #define VLAN_ID 0 + #define VLAN_PRIO 1 +@@ -60,9 +60,9 @@ + 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"); ++ "--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"); + } + + /* +@@ -124,7 +124,7 @@ + * Check arg value presence + */ + if (optind > argc) +- print_error ("Missing VLAN ID argument value\n"); ++ print_error ("Missing VLAN ID argument value"); + /* + * Convert argv to long int, + * set *end to end of argv string, +@@ -136,7 +136,7 @@ + */ + if (i > 4094 || *end != '\0') + print_error +- ("Specified VLAN ID is out of range (0-4094)\n"); ++ ("Specified VLAN ID is out of range (0-4094)"); + /* + * Set up parameter value + */ +@@ -153,7 +153,7 @@ + vlaninfo->invflags |= EBT_VLAN_PRIO; + if (optind > argc) + print_error +- ("Missing user_priority argument value\n"); ++ ("Missing user_priority argument value"); + /* + * Convert argv to long int, + * set *end to end of argv string, +@@ -165,7 +165,7 @@ + */ + if (i >= 8 || *end != '\0') + print_error +- ("Specified user_priority is out of range (0-7)\n"); ++ ("Specified user_priority is out of range (0-7)"); + /* + * Set up parameter value + */ +@@ -182,7 +182,7 @@ + vlaninfo->invflags |= EBT_VLAN_ENCAP; + if (optind > argc) + print_error +- ("Missing encapsulated frame type argument value\n"); ++ ("Missing encapsulated frame type argument value"); + /* + * Parameter can be decimal, hexadecimal, or string. + * Check arg val range (still raw area) +@@ -190,12 +190,12 @@ + (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\n"); ++ ("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\n"); ++ "protocol"); + /* + * Set up parameter value (network notation) + */ +@@ -227,7 +227,7 @@ + */ + if (entry->bitmask & EBT_NOPROTO || entry->ethproto != ETH_P_8021Q) + print_error +- ("For use 802.1Q extension the protocol must be specified as 802_1Q\n"); ++ ("For use 802.1Q extension the protocol must be specified as 802_1Q"); + /* + * Check if specified vlan-id=0 (priority-tagged frame condition) + * when vlan-prio was specified. +@@ -235,7 +235,7 @@ + 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\n"); ++ ("For use user_priority the specified vlan-id must be 0"); + } + } + +--- /dev/null Thu Aug 24 11:00:32 2000 ++++ ebtables-v2.0-rc1.001/extensions/ebt_mark.c Thu Jul 25 16:51:14 2002 +@@ -0,0 +1,132 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "../include/ebtables_u.h" ++#include ++ ++extern char *standard_targets[NUM_STANDARD_TARGETS]; ++ ++int mark_supplied; ++ ++#define MARK_TARGET '1' ++#define MARK_SETMARK '2' ++static struct option opts[] = ++{ ++ { "mark-target" , required_argument, 0, MARK_TARGET }, ++ { "set-mark" , required_argument, 0, MARK_SETMARK }, ++ { 0 } ++}; ++ ++static void print_help() ++{ ++ printf( ++ "mark target options:\n" ++ " --set-mark value : Set nfmark value\n" ++ " --mark-target target : ACCEPT, DROP, RETURN or CONTINUE\n"); ++} ++ ++static void init(struct ebt_entry_target *target) ++{ ++ struct ebt_mark_t_info *markinfo = ++ (struct ebt_mark_t_info *)target->data; ++ ++ markinfo->target = EBT_ACCEPT; ++ markinfo->mark = 0; ++ mark_supplied = 0; ++ return; ++} ++ ++#define OPT_MARK_TARGET 0x01 ++#define OPT_MARK_SETMARK 0x02 ++static int parse(int c, char **argv, int argc, ++ const struct ebt_u_entry *entry, unsigned int *flags, ++ struct ebt_entry_target **target) ++{ ++ int i; ++ struct ebt_mark_t_info *markinfo = ++ (struct ebt_mark_t_info *)(*target)->data; ++ char *end; ++ ++ switch (c) { ++ case MARK_TARGET: ++ check_option(flags, OPT_MARK_TARGET); ++ for (i = 0; i < NUM_STANDARD_TARGETS; i++) ++ if (!strcmp(optarg, standard_targets[i])) { ++ markinfo->target = -i - 1; ++ break; ++ } ++ if (i == NUM_STANDARD_TARGETS) ++ print_error("Illegal --mark-target target"); ++ break; ++ case MARK_SETMARK: ++ check_option(flags, OPT_MARK_SETMARK); ++ markinfo->mark = strtoul(optarg, &end, 0); ++ if (*end != '\0' || end == optarg) ++ print_error("Bad MARK value '%s'", optarg); ++ mark_supplied = 1; ++ break; ++ default: ++ return 0; ++ } ++ return 1; ++} ++ ++static void final_check(const struct ebt_u_entry *entry, ++ const struct ebt_entry_target *target, const char *name, ++ unsigned int hook_mask, unsigned int time) ++{ ++ struct ebt_mark_t_info *markinfo = ++ (struct ebt_mark_t_info *)target->data; ++ ++ if (time == 0 && mark_supplied == 0) ++ print_error("No mark value supplied"); ++ if ((hook_mask & (1 << NF_BR_NUMHOOKS)) && markinfo->target == EBT_RETURN) ++ print_error("--mark-target RETURN not allowed on base chain"); ++} ++ ++static void print(const struct ebt_u_entry *entry, ++ const struct ebt_entry_target *target) ++{ ++ struct ebt_mark_t_info *markinfo = ++ (struct ebt_mark_t_info *)target->data; ++ ++ printf("--set-mark 0x%lx", markinfo->mark); ++ if (markinfo->target == EBT_ACCEPT) ++ return; ++ printf(" --mark-target %s", ++ standard_targets[-markinfo->target - 1]); ++} ++ ++static int compare(const struct ebt_entry_target *t1, ++ const struct ebt_entry_target *t2) ++{ ++ struct ebt_mark_t_info *markinfo1 = ++ (struct ebt_mark_t_info *)t1->data; ++ struct ebt_mark_t_info *markinfo2 = ++ (struct ebt_mark_t_info *)t2->data; ++ ++ return markinfo1->target == markinfo2->target && ++ markinfo1->mark == markinfo2->mark; ++} ++ ++static struct ebt_u_target mark_target = ++{ ++ EBT_MARK_TARGET, ++ sizeof(struct ebt_mark_t_info), ++ print_help, ++ init, ++ parse, ++ final_check, ++ print, ++ compare, ++ opts, ++}; ++ ++static void _init(void) __attribute__ ((constructor)); ++static void _init(void) ++{ ++ register_target(&mark_target); ++} +--- /dev/null Thu Aug 24 11:00:32 2000 ++++ ebtables-v2.0-rc1.001/extensions/ebt_mark_m.c Sun Jul 21 17:12:04 2002 +@@ -0,0 +1,123 @@ ++#include ++#include ++#include ++#include ++#include ++#include "../include/ebtables_u.h" ++#include ++ ++#define MARK '1' ++ ++static struct option opts[] = ++{ ++ { "mark" , required_argument, 0, MARK }, ++ { 0 } ++}; ++ ++static void print_help() ++{ ++ printf( ++"mark option:\n" ++"--mark [!] [value][/mask]: Match nfmask value (see man page)\n"); ++} ++ ++static void init(struct ebt_entry_match *match) ++{ ++ struct ebt_mark_m_info *markinfo = (struct ebt_mark_m_info *)match->data; ++ ++ markinfo->mark = 0; ++ markinfo->mask = 0; ++ markinfo->invert = 0; ++ markinfo->bitmask = 0; ++} ++ ++#define OPT_MARK 0x01 ++static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, ++ unsigned int *flags, struct ebt_entry_match **match) ++{ ++ struct ebt_mark_m_info *markinfo = (struct ebt_mark_m_info *) ++ (*match)->data; ++ char *end; ++ ++ switch (c) { ++ case MARK: ++ check_option(flags, MARK); ++ if (check_inverse(optarg)) ++ markinfo->invert = 1; ++ if (optind > argc) ++ print_error("No mark specified"); ++ markinfo->mark = strtoul(argv[optind - 1], &end, 0); ++ markinfo->bitmask = EBT_MARK_AND; ++ if (*end == '/') { ++ if (end == argv[optind - 1]) ++ markinfo->bitmask = EBT_MARK_OR; ++ markinfo->mask = strtoul(end+1, &end, 0); ++ } else ++ markinfo->mask = 0xffffffff; ++ if ( *end != '\0' || end == argv[optind - 1]) ++ print_error("Bad mark value '%s'", argv[optind - 1]); ++ break; ++ default: ++ return 0; ++ } ++ return 1; ++} ++ ++static void final_check(const struct ebt_u_entry *entry, ++ const struct ebt_entry_match *match, const char *name, ++ unsigned int hook_mask, unsigned int time) ++{ ++} ++ ++static void print(const struct ebt_u_entry *entry, ++ const struct ebt_entry_match *match) ++{ ++ struct ebt_mark_m_info *markinfo = ++ (struct ebt_mark_m_info *)match->data; ++ ++ printf("--mark "); ++ if (markinfo->invert) ++ printf("! "); ++ if (markinfo->bitmask == EBT_MARK_OR) ++ printf("/0x%lx ", markinfo->mask); ++ else if(markinfo->mask != 0xffffffff) ++ printf("0x%lx/0x%lx ", markinfo->mark, markinfo->mask); ++ else ++ printf("0x%lx ", markinfo->mark); ++} ++ ++static int compare(const struct ebt_entry_match *m1, ++ const struct ebt_entry_match *m2) ++{ ++ struct ebt_mark_m_info *markinfo1 = (struct ebt_mark_m_info *)m1->data; ++ struct ebt_mark_m_info *markinfo2 = (struct ebt_mark_m_info *)m2->data; ++ ++ if (markinfo1->invert != markinfo2->invert) ++ return 0; ++ if (markinfo1->mark != markinfo2->mark) ++ return 0; ++ if (markinfo1->mask != markinfo2->mask) ++ return 0; ++ if (markinfo1->bitmask != markinfo2->bitmask) ++ return 0; ++ return 1; ++} ++ ++static struct ebt_u_match mark_match = ++{ ++ EBT_MARK_MATCH, ++ sizeof(struct ebt_mark_m_info), ++ print_help, ++ init, ++ parse, ++ final_check, ++ print, ++ compare, ++ opts, ++}; ++ ++static void _init(void) __attribute((constructor)); ++static void _init(void) ++{ ++ register_match(&mark_match); ++} +--- ebtables-v2.0pre10/extensions/Makefile Thu Jun 27 18:53:55 2002 ++++ ebtables-v2.0-rc1.001/extensions/Makefile Sat Jul 20 15:34:51 2002 +@@ -1,6 +1,6 @@ + #! /usr/bin/make + +-EXT_FUNC+=nat arp ip standard log redirect vlan ++EXT_FUNC+=nat arp ip standard log redirect vlan mark_m mark + EXT_TABLES+=filter nat broute + EXT_OBJS+=$(foreach T,$(EXT_FUNC), extensions/ebt_$(T).o) + EXT_OBJS+=$(foreach T,$(EXT_TABLES), extensions/ebtable_$(T).o) +--- ebtables-v2.0pre10/ChangeLog Sun Jul 14 21:30:18 2002 ++++ ebtables-v2.0-rc1.001/ChangeLog Tue Jul 30 23:05:30 2002 +@@ -1,3 +1,16 @@ ++20020730 ++ * other things done before 2.0-rc1 that I can think of, ++ including kernel: ++ * cache align counters for better smp performance ++ * simplify snat code ++ * check for --xxxx-target RETURN on base chain ++ * cleanup code ++ * minor bugfixes ++20020724 ++ * code cleanup ++ * bugfix for --atomic-commit ++20020720 ++ * added mark target+match + 20020714 + * added --atomic options + 20020710 +--- ebtables-v2.0pre10/ebtables.8 Mon Jul 15 21:45:55 2002 ++++ ebtables-v2.0-rc1.001/ebtables.8 Thu Jul 25 17:01:17 2002 +@@ -1,4 +1,4 @@ +-.TH EBTABLES 8 "26 June 2002" ++.TH EBTABLES 8 "23 July 2002" + .\" + .\" Man page written by Bart De Schuymer + .\" It is based on the iptables man page. +@@ -21,7 +21,7 @@ + .\" + .\" + .SH NAME +-ebtables (v.2.0) \- ethernet bridge packet table administration ++ebtables (v.2.0) \- Ethernet bridge packet table administration + .SH SYNOPSIS + .BR "ebtables -[ADI] " "chain rule-specification " [ options ] + .br +@@ -335,7 +335,7 @@ + .B ebtables + will try to write help about those extensions. E.g. ebtables -h snat log ip arp. + .TP +-.BR "-b --db [" "y/n" "]" ++.BR "-b --db " [ "y/n" ] + Enable (y) or disable (n) the database. + .TP + .BR "-j, --jump " "\fItarget\fP" +@@ -346,13 +346,13 @@ + or a target extension, see + .BR "TARGET EXTENSIONS" . + .TP +-.BR "--atomic " file ++.B --atomic 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. + .TP +-.BR "-M, --modprobe " "program" ++.B -M, --modprobe program + When talking to the kernel, use this program to try to automatically load + missing kernel modules. + .SH MATCH EXTENSIONS +@@ -390,7 +390,8 @@ + .BR ARP " or " RARP . + .TP + .BR "--arp-opcode " "[!] \fIopcode\fP" +-The (r)arp opcode (decimal or a string, for more details see ebtables -h arp). ++The (r)arp opcode (decimal or a string, for more details see ++.BR "ebtables -h arp" ). + .TP + .BR "--arp-htype " "[!] \fIhardware type\fP" + The hardware type, this can be a decimal or the string "Ethernet". This +@@ -419,13 +420,24 @@ + Required VID to be 0 (null VID) or not specified vlan-id parameter (in this case VID deliberately be set to 0). + .TP + .BR "--vlan-encap " "[!] \fItype\fP" +-The encapsulated ethernet frame type/length, this can be a hexadecimal number from 0x0000 to 0xFFFF. ++The encapsulated Ethernet frame type/length, this can be a hexadecimal ++number from 0x0000 to 0xFFFF. + Usually it's 0x0800 (IPv4). See also + .B /etc/ethertypes + file. ++.SS mark_m ++.TP ++.BR "--mark " "[!] [\fIvalue\fP][/\fImask\fP]" ++Matches frames with the given unsigned mark value. If a mark value and ++mask is specified, the logical AND of the mark value of the frame and ++the user specified mask is taken before comparing with the user specified ++mark value. If only a mask is specified (start with '/') the logical AND ++of the mark value of the frame and the user specified mark is taken and ++the result is compared with zero. ++ + .SH WATCHER EXTENSION(S) +-Watchers are things that only look at frames passing by. These watchers only see the +-frame if the frame passes all the matches of the rule. ++Watchers are things that only look at frames passing by. These watchers only ++see the frame if the frame passes all the matches of the rule. + .SS log + The fact that the log module is a watcher lets us log stuff while giving a target + by choice. Note that the log module therefore is not a target. +@@ -478,7 +490,7 @@ + The default target is ACCEPT. Making it CONTINUE could let you use + multiple target extensions on the same frame. Making it DROP doesn't + make sense, but you could do that too. RETURN is also allowed. Note +-that using RETURN in a base chain will result in the CONTINUE behaviour. ++that using RETURN in a base chain is not allowed. + .TP + .B dnat + The +@@ -504,7 +516,7 @@ + multiple target extensions on the same frame. Making it DROP only makes + sense in the BROUTING chain but using the redirect target is more logical + there. RETURN is also allowed. Note +-that using RETURN in a base chain will result in the CONTINUE behaviour. ++that using RETURN in a base chain is not allowed. + .TP + .B redirect + The +@@ -523,7 +535,28 @@ + The default target is ACCEPT. Making it CONTINUE could let you use + multiple target extensions on the same frame. Making it DROP in the + BROUTING chain will let the frames be routed. RETURN is also allowed. Note +-that using RETURN in a base chain will result in the CONTINUE behaviour. ++that using RETURN in a base chain is not allowed. ++.TP ++.B mark ++The mark target can be used in every chain of every table. It is possible ++to use the marking of a frame/packet in both ebtables and iptables, ++if the br-nf code is compiled into the kernel. Both put the marking at the ++same place. So, you can consider this fact as a feature, or as something to ++watch out for. ++.br ++.BR "--mark-target " "\fItarget\fP" ++.br ++Specifies the standard target. After marking the frame, the rule ++still has to give a standard target so ++.B ebtables ++knows what to do. ++The default target is ACCEPT. Making it CONTINUE can let you do other ++things with the frame in other rules of the chain. ++.br ++.BR "--set-mark " "\fIvalue\fP" ++.br ++Mark the frame with the specified unsigned value. ++.br + .SH FILES + .I /etc/ethertypes + .SH BUGS +--- ebtables-v2.0pre10/ethertypes Thu Jun 27 18:53:55 2002 ++++ ebtables-v2.0-rc1.001/ethertypes Fri Jul 19 20:44:25 2002 +@@ -3,15 +3,14 @@ + # all protocol numbers are in hexadecimal form + # maximum namesize = 20 characters + # always put tabs or spaces between the name and the protocol number +-# don't use more than 4 digits for the protocol number ++# anything on a line after the protocol number is ignored + # programs using this file should not be case sensitive +-# that's all :-)) +-IPV4 0800 put your comments behind, on the same line, after a tab +-X25 0805 or whitespace ++IPv4 0800 ++X25 0805 + ARP 0806 + 802_1Q 8100 802.1Q Virtual LAN tagged frame + IPX 8137 +-IPV6 86DD ++IPv6 86DD + NetBEUI 8191 + BPQ 08FF G8BPQ AX.25 Ethernet Packet + DEC 6000 DEC Assigned proto +--- ebtables-v2.0pre10/include/ebtables_u.h Sat Jul 13 21:13:46 2002 ++++ ebtables-v2.0-rc1.001/include/ebtables_u.h Fri Jul 26 14:03:04 2002 +@@ -29,7 +29,7 @@ + struct ebt_u_entries + { + int policy; +- __u32 nentries; ++ unsigned int nentries; + // counter offset for this chain + unsigned int counter_offset; + // used for udc +@@ -42,7 +42,7 @@ + { + struct ebt_u_entries *udc; + struct ebt_u_chain_list *next; +- // this is only used internally, in communications.c ++ // this is only used internally, in communication.c + char *kernel_start; + }; + +@@ -68,6 +68,8 @@ + int selected_hook; + // used for the atomic option + char *filename; ++ // tells what happened to the old rules ++ unsigned short *counterchanges; + }; + + struct ebt_u_table +@@ -92,17 +94,17 @@ + + struct ebt_u_entry + { +- __u32 bitmask; +- __u32 invflags; ++ unsigned int bitmask; ++ unsigned int invflags; + __u16 ethproto; +- __u8 in[IFNAMSIZ]; +- __u8 logical_in[IFNAMSIZ]; +- __u8 out[IFNAMSIZ]; +- __u8 logical_out[IFNAMSIZ]; +- __u8 sourcemac[ETH_ALEN]; +- __u8 sourcemsk[ETH_ALEN]; +- __u8 destmac[ETH_ALEN]; +- __u8 destmsk[ETH_ALEN]; ++ char in[IFNAMSIZ]; ++ char logical_in[IFNAMSIZ]; ++ char out[IFNAMSIZ]; ++ char logical_out[IFNAMSIZ]; ++ unsigned char sourcemac[ETH_ALEN]; ++ unsigned char sourcemsk[ETH_ALEN]; ++ unsigned char destmac[ETH_ALEN]; ++ unsigned char destmsk[ETH_ALEN]; + struct ebt_u_match_list *m_list; + struct ebt_u_watcher_list *w_list; + struct ebt_entry_target *t; +@@ -194,8 +196,7 @@ + struct ebt_u_match *find_match(const char *name); + struct ebt_u_watcher *find_watcher(const char *name); + struct ebt_u_table *find_table(char *name); +-void deliver_counters(struct ebt_u_replace *repl, +- unsigned short * counterchanges); ++void deliver_counters(struct ebt_u_replace *repl); + void deliver_table(struct ebt_u_replace *repl); + void get_dbinfo(struct brdb_dbinfo *nr); + void get_db(int len, struct brdb_dbentry *db); diff --git a/userspace/patches/zipped/ebtables-v2.0-rc1.tar.gz b/userspace/patches/zipped/ebtables-v2.0-rc1.tar.gz new file mode 100644 index 0000000..030c57e Binary files /dev/null and b/userspace/patches/zipped/ebtables-v2.0-rc1.tar.gz differ diff --git a/userspace/scripts/Make_userspace_diff b/userspace/scripts/Make_userspace_diff index 9262465..d877954 100755 --- a/userspace/scripts/Make_userspace_diff +++ b/userspace/scripts/Make_userspace_diff @@ -1,9 +1,10 @@ #!/bin/bash # Used to make incremental diffs for ebtables userspace +# 31 July 2002, added mark match/target -export FROM=ebtables-v2.0pre6 -export TO=ebtables-v2.0pre7.001 -export FILE=ebtables-v2.0pre7.001.diff +export FROM=ebtables-v2.0pre10 +export TO=ebtables-v2.0-rc1.001 +export FILE=ebtables-v2.0-rc1.001.diff diff -urN $FROM/Makefile $TO/Makefile > $FILE diff -urN $FROM/ebtables.c $TO/ebtables.c >> $FILE @@ -18,6 +19,8 @@ diff -urN $FROM/extensions/ebt_log.c $TO/extensions/ebt_log.c >> $FILE diff -urN $FROM/extensions/ebt_standard.c $TO/extensions/ebt_standard.c >> $FILE diff -urN $FROM/extensions/ebtable_filter.c $TO/extensions/ebtable_filter.c >> $FILE diff -urN $FROM/extensions/ebtable_nat.c $TO/extensions/ebtable_nat.c >> $FILE +diff -urN $FROM/extensions/ebt_mark.c $TO/extensions/ebt_mark.c >> $FILE +diff -urN $FROM/extensions/ebt_mark_m.c $TO/extensions/ebt_mark_m.c >> $FILE diff -urN $FROM/extensions/Makefile $TO/extensions/Makefile >> $FILE diff -urN $FROM/COPYING $TO/COPYING >> $FILE diff -urN $FROM/THANKS $TO/THANKS >> $FILE -- cgit v1.2.3