From 9c16370646dcac6ba9803ffea4c552014f7eee11 Mon Sep 17 00:00:00 2001 From: Bart De Schuymer Date: Wed, 14 Jan 2004 20:05:27 +0000 Subject: Make ebtables library functions --- userspace/ebtables2/Makefile | 9 +- userspace/ebtables2/communication.c | 43 +- userspace/ebtables2/ebtables.c | 1607 ++--------------------- userspace/ebtables2/extensions/ebt_802_3.c | 10 +- userspace/ebtables2/extensions/ebt_among.c | 14 +- userspace/ebtables2/extensions/ebt_arp.c | 46 +- userspace/ebtables2/extensions/ebt_arpreply.c | 8 +- userspace/ebtables2/extensions/ebt_ip.c | 136 +- userspace/ebtables2/extensions/ebt_limit.c | 10 +- userspace/ebtables2/extensions/ebt_log.c | 12 +- userspace/ebtables2/extensions/ebt_mark.c | 6 +- userspace/ebtables2/extensions/ebt_mark_m.c | 6 +- userspace/ebtables2/extensions/ebt_nat.c | 16 +- userspace/ebtables2/extensions/ebt_pkttype.c | 6 +- userspace/ebtables2/extensions/ebt_redirect.c | 4 +- userspace/ebtables2/extensions/ebt_standard.c | 7 +- userspace/ebtables2/extensions/ebt_stp.c | 18 +- userspace/ebtables2/extensions/ebt_vlan.c | 10 +- userspace/ebtables2/extensions/ebtable_broute.c | 4 +- userspace/ebtables2/extensions/ebtable_filter.c | 4 +- userspace/ebtables2/extensions/ebtable_nat.c | 4 +- userspace/ebtables2/include/ebtables_u.h | 155 ++- 22 files changed, 383 insertions(+), 1752 deletions(-) diff --git a/userspace/ebtables2/Makefile b/userspace/ebtables2/Makefile index 2f4fec0..3c3229f 100644 --- a/userspace/ebtables2/Makefile +++ b/userspace/ebtables2/Makefile @@ -14,7 +14,8 @@ endif include extensions/Makefile -OBJECTS:=getethertype.o ebtables.o communication.o $(EXT_OBJS) +OBJECTS:=getethertype.o ebtables.o communication.o libebtc.o \ +useful_functions.o $(EXT_OBJS) KERNEL_INCLUDES?=include/ @@ -35,6 +36,12 @@ all: ebtables communication.o: communication.c include/ebtables_u.h $(CC) $(CFLAGS) $(PROGSPECS) -c -o $@ $< -I$(KERNEL_INCLUDES) +libebtc.o: libebtc.c include/ebtables_u.h + $(CC) $(CFLAGS) $(PROGSPECS) -c -o $@ $< -I$(KERNEL_INCLUDES) + +useful_functions.o: useful_functions.c include/ebtables_u.h + $(CC) $(CFLAGS) $(PROGSPECS) -c -o $@ $< -I$(KERNEL_INCLUDES) + getethertype.o: getethertype.c include/ethernetdb.h $(CC) $(CFLAGS) $(PROGSPECS) -c -o $@ $< -Iinclude/ diff --git a/userspace/ebtables2/communication.c b/userspace/ebtables2/communication.c index 4d02b05..7f8c531 100644 --- a/userspace/ebtables2/communication.c +++ b/userspace/ebtables2/communication.c @@ -255,7 +255,7 @@ static void store_table_in_file(char *filename, struct ebt_replace *repl) free(data); } -void deliver_table(struct ebt_u_replace *u_repl) +void ebt_deliver_table(struct ebt_u_replace *u_repl) { socklen_t optlen; struct ebt_replace *repl; @@ -311,14 +311,13 @@ static void store_counters_in_file(char *filename, struct ebt_u_replace *repl) fclose(file); } -/* gets executed after deliver_table */ -void deliver_counters(struct ebt_u_replace *u_repl) +/* gets executed after ebt_deliver_table */ +void ebt_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; + struct ebt_cntchanges *cc = u_repl->counterchanges; if (u_repl->nentries == 0) return; @@ -330,9 +329,8 @@ void deliver_counters(struct ebt_u_replace *u_repl) memset(newcounters, 0, u_repl->nentries * sizeof(struct ebt_counter)); old = u_repl->counters; new = newcounters; - point = counterchanges; - while (*point != CNT_END) { - if (*point == CNT_NORM) { + while (cc) { + if (cc->type == CNT_NORM) { /* *'normal' rule, meaning we didn't do anything to it * So, we just copy @@ -343,10 +341,10 @@ void deliver_counters(struct ebt_u_replace *u_repl) old++; /* we've set a new counter */ new++; - } else if (*point == CNT_DEL) { + } else if (cc->type == CNT_DEL) { /* don't use this old counter */ old++; - } else if (*point == CNT_ADD) { + } else if (cc->type == CNT_ADD) { /* new counter, let it stay 0 */ new++; } else { @@ -354,7 +352,7 @@ void deliver_counters(struct ebt_u_replace *u_repl) old++; new++; } - point++; + cc = cc->next; } free(u_repl->counters); @@ -393,7 +391,7 @@ ebt_translate_match(struct ebt_entry_match *m, struct ebt_u_match_list ***l) new->next = NULL; **l = new; *l = &new->next; - if (find_match(new->m->u.name) == NULL) + if (ebt_find_match(new->m->u.name) == NULL) print_error("Kernel match %s unsupported by userspace tool", new->m->u.name); return 0; @@ -417,7 +415,7 @@ ebt_translate_watcher(struct ebt_entry_watcher *w, new->next = NULL; **l = new; *l = &new->next; - if (find_watcher(new->w->u.name) == NULL) + if (ebt_find_watcher(new->w->u.name) == NULL) print_error("Kernel watcher %s unsupported by userspace tool", new->w->u.name); return 0; @@ -467,7 +465,7 @@ ebt_translate_entry(struct ebt_entry *e, unsigned int *hook, int *n, int *cnt, malloc(t->target_size + sizeof(struct ebt_entry_target)); if (!new->t) print_memory(); - if (find_target(t->u.name) == NULL) + if (ebt_find_target(t->u.name) == NULL) print_error("Kernel target %s unsupported by " "userspace tool", t->u.name); memcpy(new->t, t, t->target_size + @@ -604,7 +602,7 @@ static void retrieve_from_file(char *filename, struct ebt_replace *repl, print_error("File %s contains wrong table name or is corrupt", filename); free(hlp); - } else if (!find_table(repl->name)) { + } else if (!ebt_find_table(repl->name)) { fclose(file); print_error("File %s contains invalid table name", filename); } @@ -686,11 +684,13 @@ static int retrieve_from_kernel(struct ebt_replace *repl, char command) return 0; } -int get_table(struct ebt_u_replace *u_repl) +int ebt_get_table(struct ebt_u_replace *u_repl) { int i, j, k, hook; struct ebt_replace repl; struct ebt_u_entry **u_e; + struct ebt_cntchanges *new_cc; + struct ebt_cntchanges **prev_cc = &(u_repl->counterchanges); strcpy(repl.name, u_repl->name); if (u_repl->filename != NULL) { @@ -708,6 +708,17 @@ int get_table(struct ebt_u_replace *u_repl) u_repl->num_counters = repl.num_counters; u_repl->counters = (struct ebt_counter *)repl.counters; u_repl->udc = NULL; + u_repl->counterchanges = NULL; + for (i = 0; i < repl.nentries; i++) { + new_cc = (struct ebt_cntchanges *) + malloc(sizeof(struct ebt_cntchanges)); + if (!new_cc) + print_memory(); + new_cc->type = CNT_NORM; + new_cc->next = NULL; + *prev_cc = new_cc; + prev_cc = &(new_cc->next); + } hook = -1; EBT_ENTRY_ITERATE(repl.entries, repl.entries_size, ebt_translate_chains, &hook, u_repl, u_repl->valid_hooks); diff --git a/userspace/ebtables2/ebtables.c b/userspace/ebtables2/ebtables.c index f0e0ab9..dfe4b81 100644 --- a/userspace/ebtables2/ebtables.c +++ b/userspace/ebtables2/ebtables.c @@ -33,38 +33,6 @@ #include #include -/* - * Don't use this function, use print_bug() - */ -void __print_bug(char *file, int line, char *format, ...) -{ - va_list l; - - va_start(l, format); - printf(PROGNAME" v"PROGVERSION":%s:%d:--BUG--: \n", file, line); - vprintf(format, l); - printf("\n"); - va_end(l); - exit (-1); -} - -#ifndef PROC_SYS_MODPROBE -#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe" -#endif -#define ATOMIC_ENV_VARIABLE "EBTABLES_ATOMIC_FILE" -#define PRINT_VERSION printf(PROGNAME" v"PROGVERSION" ("PROGDATE")\n") - - -char *hooknames[NF_BR_NUMHOOKS] = -{ - [NF_BR_PRE_ROUTING]"PREROUTING", - [NF_BR_LOCAL_IN]"INPUT", - [NF_BR_FORWARD]"FORWARD", - [NF_BR_LOCAL_OUT]"OUTPUT", - [NF_BR_POST_ROUTING]"POSTROUTING", - [NF_BR_BROUTING]"BROUTING" -}; - /* * default command line options * do not mess around with the already assigned numbers unless @@ -114,23 +82,6 @@ static struct option ebt_original_options[] = static struct option *ebt_options = ebt_original_options; -char* standard_targets[NUM_STANDARD_TARGETS] = -{ - "ACCEPT", - "DROP", - "CONTINUE", - "RETURN", -}; - -unsigned char mac_type_unicast[ETH_ALEN] = {0,0,0,0,0,0}; -unsigned char msk_type_unicast[ETH_ALEN] = {1,0,0,0,0,0}; -unsigned char mac_type_multicast[ETH_ALEN] = {1,0,0,0,0,0}; -unsigned char msk_type_multicast[ETH_ALEN] = {1,0,0,0,0,0}; -unsigned char mac_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255}; -unsigned char msk_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255}; -unsigned char mac_type_bridge_group[ETH_ALEN] = {0x01,0x80,0xc2,0,0,0}; -unsigned char msk_type_bridge_group[ETH_ALEN] = {255,255,255,255,255,255}; - /* * holds all the data */ @@ -140,49 +91,6 @@ static struct ebt_u_replace replace; * the chosen table */ static struct ebt_u_table *table = NULL; -/* - * 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; -static struct ebt_u_target *targets = NULL; - -struct ebt_u_target *find_target(const char *name) -{ - struct ebt_u_target *t = targets; - - while(t && strcmp(t->name, name)) - t = t->next; - return t; -} - -struct ebt_u_match *find_match(const char *name) -{ - struct ebt_u_match *m = matches; - - while(m && strcmp(m->name, name)) - m = m->next; - return m; -} - -struct ebt_u_watcher *find_watcher(const char *name) -{ - struct ebt_u_watcher *w = watchers; - - while(w && strcmp(w->name, name)) - w = w->next; - return w; -} - -struct ebt_u_table *find_table(char *name) -{ - struct ebt_u_table *t = tables; - - while (t && strcmp(t->name, name)) - t = t->next; - return t; -} /* * The pointers in here are special: @@ -195,84 +103,6 @@ struct ebt_u_table *find_table(char *name) */ struct ebt_u_entry *new_entry; -static void initialize_entry(struct ebt_u_entry *e) -{ - e->bitmask = EBT_NOPROTO; - e->invflags = 0; - e->ethproto = 0; - strcpy(e->in, ""); - strcpy(e->out, ""); - strcpy(e->logical_in, ""); - strcpy(e->logical_out, ""); - e->m_list = NULL; - e->w_list = NULL; - /* - * the init function of the standard target should have put the verdict - * on CONTINUE - */ - e->t = (struct ebt_entry_target *)find_target(EBT_STANDARD_TARGET); - if (!e->t) - print_bug("Couldn't load standard target"); -} - -/* - * 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; - struct ebt_u_watcher_list *w_l, *w_l2; - - m_l = e->m_list; - while (m_l) { - m_l2 = m_l->next; - free(m_l->m); - free(m_l); - m_l = m_l2; - } - w_l = e->w_list; - while (w_l) { - w_l2 = w_l->next; - free(w_l->w); - free(w_l); - w_l = w_l2; - } - free(e->t); -} - -/* - * the user will use the match, so put it in new_entry - */ -static void add_match(struct ebt_u_match *m) -{ - struct ebt_u_match_list **m_list, *new; - - m->used = 1; - for (m_list = &new_entry->m_list; *m_list; m_list = &(*m_list)->next); - new = (struct ebt_u_match_list *) - malloc(sizeof(struct ebt_u_match_list)); - if (!new) - print_memory(); - *m_list = new; - new->next = NULL; - new->m = (struct ebt_entry_match *)m; -} - -static void add_watcher(struct ebt_u_watcher *w) -{ - struct ebt_u_watcher_list **w_list; - struct ebt_u_watcher_list *new; - - w->used = 1; - for (w_list = &new_entry->w_list; *w_list; w_list = &(*w_list)->next); - new = (struct ebt_u_watcher_list *) - malloc(sizeof(struct ebt_u_watcher_list)); - if (!new) - print_memory(); - *w_list = new; - new->next = NULL; - new->w = (struct ebt_entry_watcher *)w; -} static int global_option_offset = 0; #define OPTION_OFFSET 256 @@ -307,162 +137,22 @@ merge_options(struct option *oldopts, const struct option *newopts, return merge; } -void register_match(struct ebt_u_match *m) +static void merge_match(struct ebt_u_match *m) { - int size = EBT_ALIGN(m->size) + sizeof(struct ebt_entry_match); - struct ebt_u_match **i; - - m->m = (struct ebt_entry_match *)malloc(size); - if (!m->m) - print_memory(); - strcpy(m->m->u.name, m->name); - m->m->match_size = EBT_ALIGN(m->size); ebt_options = merge_options (ebt_options, m->extra_ops, &(m->option_offset)); - m->init(m->m); - - for (i = &matches; *i; i = &((*i)->next)); - m->next = NULL; - *i = m; } -void register_watcher(struct ebt_u_watcher *w) +static void merge_watcher(struct ebt_u_watcher *w) { - int size = EBT_ALIGN(w->size) + sizeof(struct ebt_entry_watcher); - struct ebt_u_watcher **i; - - w->w = (struct ebt_entry_watcher *)malloc(size); - if (!w->w) - print_memory(); - strcpy(w->w->u.name, w->name); - w->w->watcher_size = EBT_ALIGN(w->size); ebt_options = merge_options (ebt_options, w->extra_ops, &(w->option_offset)); - w->init(w->w); - - for (i = &watchers; *i; i = &((*i)->next)); - w->next = NULL; - *i = w; } -void register_target(struct ebt_u_target *t) +static void merge_target(struct ebt_u_target *t) { - int size = EBT_ALIGN(t->size) + sizeof(struct ebt_entry_target); - struct ebt_u_target **i; - - t->t = (struct ebt_entry_target *)malloc(size); - if (!t->t) - print_memory(); - strcpy(t->t->u.name, t->name); - t->t->target_size = EBT_ALIGN(t->size); 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; -} - -void register_table(struct ebt_u_table *t) -{ - t->next = tables; - tables = t; -} - -const char *modprobe = NULL; -/* - * blatently stolen (again) from iptables.c userspace program - * find out where the modprobe utility is located - */ -static char *get_modprobe(void) -{ - int procfile; - char *ret; - - procfile = open(PROC_SYS_MODPROBE, O_RDONLY); - if (procfile < 0) - return NULL; - - ret = malloc(1024); - if (ret) { - switch (read(procfile, ret, 1024)) { - case -1: goto fail; - case 1024: goto fail; /* Partial read. Wierd */ - } - if (ret[strlen(ret)-1]=='\n') - ret[strlen(ret)-1]=0; - close(procfile); - return ret; - } - fail: - free(ret); - close(procfile); - return NULL; -} - -int ebtables_insmod(const char *modname) -{ - char *buf = NULL; - char *argv[3]; - - /* If they don't explicitly set it, read out of kernel */ - if (!modprobe) { - buf = get_modprobe(); - if (!buf) - return -1; - modprobe = buf; - } - - switch (fork()) { - case 0: - argv[0] = (char *)modprobe; - argv[1] = (char *)modname; - argv[2] = NULL; - execv(argv[0], argv); - - /* not usually reached */ - exit(0); - case -1: - return -1; - - default: /* parent */ - wait(NULL); - } - - free(buf); - return 0; -} - -static void list_extensions() -{ - struct ebt_u_table *tbl = tables; - struct ebt_u_target *t = targets; - struct ebt_u_match *m = matches; - struct ebt_u_watcher *w = watchers; - - PRINT_VERSION; - printf("Supported userspace extensions:\n\nSupported tables:\n"); - while(tbl) { - printf("%s\n", tbl->name); - tbl = tbl->next; - } - printf("\nSupported targets:\n"); - while(t) { - printf("%s\n", t->name); - t = t->next; - } - printf("\nSupported matches:\n"); - while(m) { - printf("%s\n", m->name); - m = m->next; - } - printf("\nSupported watchers:\n"); - while(w) { - printf("%s\n", w->name); - w = w->next; - } - exit(0); } /* @@ -474,42 +164,6 @@ static void list_extensions() #define LIST_X 0x10 #define LIST_MAC2 0x20 -void print_mac(const char *mac) -{ - if (replace.flags & LIST_MAC2) { - int j; - for (j = 0; j < ETH_ALEN; j++) - printf("%02x%s", (unsigned char)mac[j], - (j==ETH_ALEN-1) ? "" : ":"); - } else - printf("%s", ether_ntoa((struct ether_addr *) mac)); -} - -void print_mac_and_mask(const char *mac, const char *mask) -{ - char hlpmsk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - - if (!memcmp(mac, mac_type_unicast, 6) && - !memcmp(mask, msk_type_unicast, 6)) - printf("Unicast"); - else if (!memcmp(mac, mac_type_multicast, 6) && - !memcmp(mask, msk_type_multicast, 6)) - printf("Multicast"); - else if (!memcmp(mac, mac_type_broadcast, 6) && - !memcmp(mask, msk_type_broadcast, 6)) - printf("Broadcast"); - else if (!memcmp(mac, mac_type_bridge_group, 6) && - !memcmp(mask, msk_type_bridge_group, 6)) - printf("BGA"); - else { - print_mac(mac); - if (memcmp(mask, hlpmsk, 6)) { - printf("/"); - print_mac(mask); - } - } -} - /* * helper function for list_rules() */ @@ -523,14 +177,16 @@ static void list_em(struct ebt_u_entries *entries) struct ebt_u_watcher *w; struct ebt_u_target *t; + if (replace.flags & LIST_MAC2) + ebt_printstyle_mac = 2; hlp = entries->entries; if (replace.flags & LIST_X && entries->policy != EBT_ACCEPT) { printf("ebtables -t %s -P %s %s\n", replace.name, - entries->name, standard_targets[-entries->policy - 1]); + entries->name, ebt_standard_targets[-entries->policy - 1]); } else if (!(replace.flags & LIST_X)) { printf("\nBridge chain: %s, entries: %d, policy: %s\n", entries->name, entries->nentries, - standard_targets[-entries->policy - 1]); + ebt_standard_targets[-entries->policy - 1]); } i = entries->nentries; @@ -580,14 +236,14 @@ static void list_em(struct ebt_u_entries *entries) printf("-s "); if (hlp->invflags & EBT_ISOURCE) printf("! "); - print_mac_and_mask(hlp->sourcemac, hlp->sourcemsk); + ebt_print_mac_and_mask(hlp->sourcemac, hlp->sourcemsk); printf(" "); } if (hlp->bitmask & EBT_DESTMAC) { printf("-d "); if (hlp->invflags & EBT_IDEST) printf("! "); - print_mac_and_mask(hlp->destmac, hlp->destmsk); + ebt_print_mac_and_mask(hlp->destmac, hlp->destmsk); printf(" "); } if (hlp->in[0] != '\0') { @@ -617,7 +273,7 @@ static void list_em(struct ebt_u_entries *entries) m_l = hlp->m_list; while (m_l) { - m = find_match(m_l->m->u.name); + m = ebt_find_match(m_l->m->u.name); if (!m) print_bug("Match not found"); m->print(hlp, m_l->m); @@ -625,7 +281,7 @@ static void list_em(struct ebt_u_entries *entries) } w_l = hlp->w_list; while (w_l) { - w = find_watcher(w_l->w->u.name); + w = ebt_find_watcher(w_l->w->u.name); if (!w) print_bug("Watcher not found"); w->print(hlp, w_l->w); @@ -635,7 +291,7 @@ static void list_em(struct ebt_u_entries *entries) printf("-j "); if (strcmp(hlp->t->u.name, EBT_STANDARD_TARGET)) printf("%s ", hlp->t->u.name); - t = find_target(hlp->t->u.name); + t = ebt_find_target(hlp->t->u.name); if (!t) print_bug("Target not found"); t->print(hlp, hlp->t); @@ -648,158 +304,6 @@ static void list_em(struct ebt_u_entries *entries) } } -struct ebt_u_entries *nr_to_chain(int nr) -{ - if (nr == -1) - return NULL; - if (nr < NF_BR_NUMHOOKS) - return replace.hook_entry[nr]; - else { - int i; - struct ebt_u_chain_list *cl = replace.udc; - - i = nr - NF_BR_NUMHOOKS; - while (i > 0 && cl) { - cl = cl->next; - i--; - } - if (cl) - return cl->udc; - else - return NULL; - } -} - -static inline struct ebt_u_entries *to_chain() -{ - return nr_to_chain(replace.selected_hook); -} - -struct ebt_u_stack -{ - int chain_nr; - int n; - struct ebt_u_entry *e; - struct ebt_u_entries *entries; -}; - -static void check_for_loops() -{ - int chain_nr , i, j , k, sp = 0, verdict; - struct ebt_u_entries *entries, *entries2; - struct ebt_u_stack *stack = NULL; - struct ebt_u_entry *e; - - i = -1; - /* - * initialize hook_mask to 0 - */ - while (1) { - i++; - if (i < NF_BR_NUMHOOKS && !(replace.valid_hooks & (1 << i))) - continue; - entries = nr_to_chain(i); - if (!entries) - break; - entries->hook_mask = 0; - } - if (i > NF_BR_NUMHOOKS) { - stack = (struct ebt_u_stack *)malloc((i - NF_BR_NUMHOOKS) * - sizeof(struct ebt_u_stack)); - if (!stack) - print_memory(); - } - - /* - * 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) - */ - entries->hook_mask = (1 << i) | (1 << NF_BR_NUMHOOKS); - chain_nr = i; - - e = entries->entries; - for (j = 0; j < entries->nentries; j++) { - if (strcmp(e->t->u.name, EBT_STANDARD_TARGET)) - goto letscontinue; - verdict = ((struct ebt_standard_target *)(e->t))->verdict; - if (verdict < 0) - goto letscontinue; - entries2 = nr_to_chain(verdict + NF_BR_NUMHOOKS); - entries2->hook_mask |= entries->hook_mask; - /* - * 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 - */ - stack[sp].chain_nr = chain_nr; - stack[sp].n = j; - stack[sp].entries = entries; - stack[sp].e = e; - sp++; - j = -1; - e = entries2->entries; - chain_nr = verdict + NF_BR_NUMHOOKS; - entries = entries2; - continue; -letscontinue: - e = e->next; - } - /* - * we are at the end of a standard chain - */ - if (sp == 0) - continue; - /* - * go back to the chain one level higher - */ - sp--; - j = stack[sp].n; - chain_nr = stack[sp].chain_nr; - e = stack[sp].e; - entries = stack[sp].entries; - goto letscontinue; - } - free(stack); - return; -} - -/* - * parse the chain name and return the corresponding nr - * returns -1 on failure - */ -int get_hooknr(char* arg) -{ - int i; - struct ebt_u_chain_list *cl = replace.udc; - - for (i = 0; i < NF_BR_NUMHOOKS; i++) { - if (!(replace.valid_hooks & (1 << i))) - continue; - if (!strcmp(arg, replace.hook_entry[i]->name)) - return i; - } - while(cl) { - if (!strcmp(arg, cl->udc->name)) - return i; - i++; - cl = cl->next; - } - return -1; -} - static void print_help() { struct ebt_u_match_list *m_l; @@ -859,7 +363,7 @@ ATOMIC_ENV_VARIABLE " : if set (see above) will equal its value" ((struct ebt_u_target *)new_entry->t)->help(); printf("\n"); if (table->help) - table->help(hooknames); + table->help(ebt_hooknames); exit(0); } @@ -872,8 +376,8 @@ static void list_rules() if (!(replace.flags & LIST_X)) printf("Bridge table: %s\n", table->name); - if (replace.selected_hook != -1) { - list_em(to_chain()); + if (replace.selected_chain != -1) { + list_em(ebt_to_chain(&replace)); } else { struct ebt_u_chain_list *cl = replace.udc; @@ -889,9 +393,10 @@ static void list_rules() cl = replace.udc; for (i = 0; i < NF_BR_NUMHOOKS; i++) if (replace.valid_hooks & (1 << i) && - strcmp(replace.hook_entry[i]->name, hooknames[i])) + strcmp(replace.hook_entry[i]->name, + ebt_hooknames[i])) printf("ebtables -t %s -E %s %s\n", - replace.name, hooknames[i], + replace.name, ebt_hooknames[i], replace.hook_entry[i]->name); } i = 0; @@ -911,768 +416,6 @@ static void list_rules() } } -static void counters_nochange() -{ - int i; - - replace.num_counters = replace.nentries; - if (replace.nentries) { - /* - * '+ 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 - */ - for (i = 0; i < replace.nentries; i++) - replace.counterchanges[i] = CNT_NORM; - replace.counterchanges[replace.nentries] = CNT_END; - } - else - replace.counterchanges = NULL; -} - -/* - * execute command P - */ -static void change_policy(int policy) -{ - struct ebt_u_entries *entries = to_chain(); - - /* - * don't do anything if the policy is the same - */ - if (entries->policy != policy) { - entries->policy = policy; - counters_nochange(); - } else - exit(0); -} - -/* - * 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; - unsigned short *cnt; - struct ebt_u_entry *u_e, *tmp; - struct ebt_u_entries *entries = to_chain(); - - /* - * flush whole table - */ - if (!entries) { - if (replace.nentries == 0) - return -1; - replace.nentries = 0; - /* - * no need for the kernel to give us counters back - */ - replace.num_counters = 0; - - /* - * free everything and zero (n)entries - */ - i = -1; - while (1) { - i++; - entries = nr_to_chain(i); - if (!entries) { - if (i < NF_BR_NUMHOOKS) - continue; - else - break; - } - entries->nentries = 0; - entries->counter_offset = 0; - u_e = entries->entries; - entries->entries = NULL; - while (u_e) { - free_u_entry(u_e); - tmp = u_e->next; - free(u_e); - u_e = tmp; - } - } - return 0; - } - - if (entries->nentries == 0) - return -1; - oldnentries = replace.nentries; - replace.nentries -= entries->nentries; - numdel = entries->nentries; - - if (replace.nentries) { - /* - * +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 - */ - i = -1; - cnt = replace.counterchanges; - while (1) { - i++; - entries = nr_to_chain(i); - if (!entries) { - if (i < NF_BR_NUMHOOKS) - continue; - else - break; - } - if (i > replace.selected_hook) - entries->counter_offset -= numdel; - if (replace.nentries) { - for (j = 0; j < entries->nentries; j++) { - if (i == replace.selected_hook) - *cnt = CNT_DEL; - else - *cnt = CNT_NORM; - cnt++; - } - } - } - - if (replace.nentries) { - *cnt = CNT_END; - replace.num_counters = oldnentries; - } else - replace.num_counters = 0; - - entries = to_chain(); - entries->nentries = 0; - u_e = entries->entries; - while (u_e) { - free_u_entry(u_e); - tmp = u_e->next; - free(u_e); - u_e = tmp; - } - entries->entries = NULL; - return 0; -} - -/* - * -1 == no match - */ -static int check_rule_exists(int rule_nr) -{ - struct ebt_u_entry *u_e; - struct ebt_u_match_list *m_l, *m_l2; - struct ebt_u_match *m; - struct ebt_u_watcher_list *w_l, *w_l2; - struct ebt_u_watcher *w; - struct ebt_u_target *t = (struct ebt_u_target *)new_entry->t; - struct ebt_u_entries *entries = to_chain(); - int i, j, k; - - /* - * handle '-D chain rulenr' command - */ - if (rule_nr != 0) { - if (rule_nr > entries->nentries) - return -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) - */ - 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) - 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; -letscontinue: - } - return -1; -} - -/* execute command A or I */ -static void add_rule(int rule_nr) -{ - int i, j; - struct ebt_u_entry **u_e; - unsigned short *cnt; - struct ebt_u_match_list *m_l; - struct ebt_u_watcher_list *w_l; - struct ebt_u_entries *entries = to_chain(), *entries2; - - if (rule_nr <= 0) - rule_nr += entries->nentries; - else - rule_nr--; - if (rule_nr > entries->nentries || rule_nr < 0) - print_error("The specified rule number is incorrect"); - /* - * we're adding one rule - */ - replace.num_counters = replace.nentries; - replace.nentries++; - entries->nentries++; - - /* - * handle counter stuff - * +1 for CNT_END - */ - if ( !(replace.counterchanges = (unsigned short *) - malloc((replace.nentries + 1) * sizeof(unsigned short))) ) - print_memory(); - cnt = replace.counterchanges; - for (i = 0; i < replace.selected_hook; i++) { - if (i < NF_BR_NUMHOOKS && !(replace.valid_hooks & (1 << i))) - continue; - entries2 = nr_to_chain(i); - for (j = 0; j < entries2->nentries; j++) { - *cnt = CNT_NORM; - cnt++; - } - } - for (i = 0; i < rule_nr; i++) { - *cnt = CNT_NORM; - cnt++; - } - *cnt = CNT_ADD; - cnt++; - while (cnt != replace.counterchanges + replace.nentries) { - *cnt = CNT_NORM; - cnt++; - } - *cnt = CNT_END; - - /* - * 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 - */ - new_entry->next = *u_e; - *u_e = new_entry; - - /* - * 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; - m_l = m_l->next; - } - w_l = new_entry->w_list; - while (w_l) { - w_l->w = ((struct ebt_u_watcher *)w_l->w)->w; - w_l = w_l->next; - } - new_entry->t = ((struct ebt_u_target *)new_entry->t)->t; - - /* - * update the counter_offset of chains behind this one - */ - i = replace.selected_hook; - while (1) { - i++; - entries = nr_to_chain(i); - if (!entries) { - if (i < NF_BR_NUMHOOKS) - continue; - else - break; - } else - entries->counter_offset++; - } -} - -/* - * execute command D - */ -static void delete_rule(int begin, int end) -{ - 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 (begin < 0) - begin += entries->nentries + 1; - if (end < 0) - end += entries->nentries + 1; - - if (begin < 0 || begin > end || end > entries->nentries) - print_error("Sorry, wrong rule numbers"); - - if ((begin = check_rule_exists(begin)) == -1 || - (end = check_rule_exists(end)) == -1) - print_error("Sorry, rule does not exist"); - - /* - * we're deleting rules - */ - replace.num_counters = replace.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++) { - if (j < NF_BR_NUMHOOKS && - !(replace.valid_hooks & (1 << j))) - continue; - entries2 = nr_to_chain(j); - lentmp += entries2->nentries; - } - 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++, cnt++) - *cnt = CNT_NORM; - 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_END; - } - else - replace.num_counters = 0; - - /* - * go to the right position in the chain - */ - u_e = &entries->entries; - for (j = 0; j < begin; j++) - u_e = &(*u_e)->next; - /* - * 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) { - j++; - entries = nr_to_chain(j); - if (!entries) { - if (j < NF_BR_NUMHOOKS) - continue; - else - break; - } else - entries->counter_offset -= nr_deletes; - } -} - -/* - * 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 - */ - replace.counterchanges = NULL; - replace.num_counters = 0; - } else { - int i, j; - unsigned short *cnt; - struct ebt_u_entries *entries = nr_to_chain(zerochain), *e2; - - if (entries->nentries == 0) - exit(0); - replace.counterchanges = (unsigned short *) - malloc((replace.nentries + 1) * sizeof(unsigned short)); - if (!replace.counterchanges) - print_memory(); - cnt = replace.counterchanges; - for (i = 0; i < zerochain; i++) { - if (i < NF_BR_NUMHOOKS && - !(replace.valid_hooks & (1 << i))) - continue; - e2 = nr_to_chain(i); - for (j = 0; j < e2->nentries; j++) { - *cnt = CNT_NORM; - cnt++; - } - } - for (i = 0; i < entries->nentries; i++) { - *cnt = CNT_ZERO; - cnt++; - } - while (cnt != replace.counterchanges + replace.nentries) { - *cnt = CNT_NORM; - cnt++; - } - *cnt = CNT_END; - } -} - -/* - * 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 - * returns 0 on success - */ -int get_mac_and_mask(char *from, char *to, char *mask) -{ - char *p; - int i; - struct ether_addr *addr; - - if (strcasecmp(from, "Unicast") == 0) { - memcpy(to, mac_type_unicast, ETH_ALEN); - memcpy(mask, msk_type_unicast, ETH_ALEN); - return 0; - } - if (strcasecmp(from, "Multicast") == 0) { - memcpy(to, mac_type_multicast, ETH_ALEN); - memcpy(mask, msk_type_multicast, ETH_ALEN); - return 0; - } - if (strcasecmp(from, "Broadcast") == 0) { - memcpy(to, mac_type_broadcast, ETH_ALEN); - memcpy(mask, msk_type_broadcast, ETH_ALEN); - return 0; - } - if (strcasecmp(from, "BGA") == 0) { - memcpy(to, mac_type_bridge_group, ETH_ALEN); - memcpy(mask, msk_type_bridge_group, ETH_ALEN); - return 0; - } - if ( (p = strrchr(from, '/')) != NULL) { - *p = '\0'; - if (!(addr = ether_aton(p + 1))) - return -1; - memcpy(mask, addr, ETH_ALEN); - } else - memset(mask, 0xff, ETH_ALEN); - if (!(addr = ether_aton(from))) - return -1; - memcpy(to, addr, ETH_ALEN); - for (i = 0; i < ETH_ALEN; i++) - to[i] &= mask[i]; - return 0; -} - -/* - * 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; - struct ebt_u_watcher_list *w_l; - struct ebt_u_target *t; - struct ebt_u_match *m; - struct ebt_u_watcher *w; - - m_l = e->m_list; - w_l = e->w_list; - while (m_l) { - m = find_match(m_l->m->u.name); - m->final_check(e, m_l->m, replace.name, - entries->hook_mask, 1); - m_l = m_l->next; - } - while (w_l) { - w = find_watcher(w_l->w->u.name); - w->final_check(e, w_l->w, replace.name, - entries->hook_mask, 1); - w_l = w_l->next; - } - t = find_target(e->t->u.name); - t->final_check(e, e->t, replace.name, - entries->hook_mask, 1); -} - -/* - * used for the -X command - * type = 0 => update chain jumps - * type = 1 => check for reference - */ -static int iterate_entries(int chain_nr, int silent, int type) -{ - int i = -1, j; - struct ebt_u_entries *entries; - struct ebt_u_entry *e; - - while (1) { - i++; - entries = nr_to_chain(i); - if (!entries) { - if (i < NF_BR_NUMHOOKS) - continue; - else - break; - } - e = entries->entries; - j = 0; - while (e) { - int chain_jmp; - - j++; - if (strcmp(e->t->u.name, EBT_STANDARD_TARGET)) { - e = e->next; - continue; - } - chain_jmp = ((struct ebt_standard_target *)e->t)->verdict; - switch (type) { - case 1: - if (chain_jmp == chain_nr) { - if (silent) - return 1; - print_error("Can't delete the chain, it's referenced " - "in chain %s, rule %d", entries->name, j); - } - break; - case 0: - /* adjust the chain jumps when necessary */ - if (chain_jmp > chain_nr) - ((struct ebt_standard_target *)e->t)->verdict--; - break; - } /* end switch */ - e = e->next; - } - } - return 0; -} - -static void decrease_chain_jumps(int chain_nr) -{ - iterate_entries(chain_nr, 1, 0); -} - -static int check_for_references(int chain_nr, int silent) -{ - return iterate_entries(chain_nr, silent, 1); -} - -static int *determine_referenced_chains(int *n) -{ - int *nrs, i = 0, j = 0; - - *n = 0; - while (nr_to_chain(i + NF_BR_NUMHOOKS)) { - if (check_for_references(i, 1)) - (*n)++; - i++; - } - if (*n == 0) - return NULL; - nrs = malloc(*n * sizeof(int)); - i = 0; - while (nr_to_chain(i + NF_BR_NUMHOOKS)) { - if (check_for_references(i, 1)) { - nrs[j] = i; - j++; - } - i++; - } - return nrs; -} - -static void remove_udc(int udc_nr) -{ - struct ebt_u_chain_list *cl, **cl2; - struct ebt_u_entries *entries; - struct ebt_u_entry *u_e, *tmp; - - /* first free the rules */ - entries = nr_to_chain(udc_nr + NF_BR_NUMHOOKS); - u_e = entries->entries; - while (u_e) { - free_u_entry(u_e); - tmp = u_e->next; - free(u_e); - u_e = tmp; - } - - /* next, remove the chain */ - cl2 = &(replace.udc); - while ((*cl2)->udc != entries) - cl2 = &((*cl2)->next); - cl = (*cl2); - (*cl2) = (*cl2)->next; - free(cl->udc); - free(cl); -} - -/* Removes all udc that aren't referenced at the time of execution */ -static void delete_all_user_chains() -{ - struct ebt_u_chain_list *chain; - int *ref, nr_ref, chain_nr = 0, counter_offset, i; - struct ebt_u_entries *entries; - - /* initialize counterchanges */ - counters_nochange(); - - ref = determine_referenced_chains(&nr_ref); - - chain = replace.udc; - counter_offset = 0; - /* skip the standard chains */ - for (i = 0; i < NF_BR_NUMHOOKS; i++) - if ((entries = nr_to_chain(i)) != NULL) - counter_offset += entries->nentries; - - /* first update chain jumps and counterchanges */ - while (chain) { - int nentries; - - nentries = chain->udc->nentries; - for (i = 0; i < nr_ref; i++) - if (ref[i] == chain_nr) - goto letscontinue; - decrease_chain_jumps(chain_nr); - for (i = counter_offset; i < counter_offset + nentries; i++) - replace.counterchanges[i] = CNT_DEL; - replace.nentries -= nentries; -letscontinue: - counter_offset += nentries; - chain = chain->next; - chain_nr++; - } - chain = replace.udc; - chain_nr = -1; - /* next, remove the chains, update the counter offset of - * non-removed chains */ - counter_offset = 0; - while (chain) { - int real_cn = 0; - - chain_nr++; - for (i = 0; i < nr_ref; i++) - if (ref[i] == chain_nr) - break; - if (i != nr_ref) { - real_cn++; - chain->udc->counter_offset -= counter_offset; - chain = chain->next; - continue; - } - counter_offset += chain->udc->nentries; - chain = chain->next; - remove_udc(real_cn); - } -} - static int parse_delete_rule(const char *argv, int *rule_nr, int *rule_nr_end) { char *colon = strchr(argv, ':'), *buffer; @@ -1699,47 +442,6 @@ static int parse_delete_rule(const char *argv, int *rule_nr, int *rule_nr_end) 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 invert; -} - -void check_option(unsigned int *flags, unsigned int mask) -{ - if (*flags & mask) - print_error("Multiple use of same option not allowed"); - *flags |= mask; -} - -static void get_kernel_table() -{ - if ( !(table = find_table(replace.name)) ) - print_error("Bad table name"); - /* - * get the kernel's information - */ - if (get_table(&replace)) { - ebtables_insmod("ebtables"); - 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 demand that - * the user knows the table's name - */ - if ( !(table = find_table(replace.name)) ) - print_error("Bad table name"); -} - #define print_if_l_error print_error("Interface name length must be less " \ "than %d", IFNAMSIZ) #define OPT_COMMAND 0x01 @@ -1774,13 +476,17 @@ int main(int argc, char *argv[]) opterr = 0; + ebt_iterate_matches(merge_match); + ebt_iterate_watchers(merge_watcher); + ebt_iterate_targets(merge_target); + 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.selected_chain = -1; replace.command = 'h'; replace.counterchanges = NULL; @@ -1790,7 +496,8 @@ int main(int argc, char *argv[]) /* * put some sane values in our new entry */ - initialize_entry(new_entry); + ebt_initialize_entry(new_entry); + new_entry->replace = &replace; /* * The scenario induced by this loop makes that: @@ -1816,56 +523,22 @@ int main(int argc, char *argv[]) if (replace.flags & OPT_COMMAND) print_error("Multiple commands not allowed"); replace.flags |= OPT_COMMAND; - get_kernel_table(); + ebt_get_kernel_table(&replace, table); if (optarg && (optarg[0] == '-' || !strcmp(optarg, "!"))) print_error("No chain name specified"); if (c == 'N') { - struct ebt_u_chain_list *cl, **cl2; - - if (get_hooknr(optarg) != -1) - print_error("Chain %s already exists", - optarg); - if (find_target(optarg)) - print_error("Target with name %s exists" - , optarg); - if (strlen(optarg) >= EBT_CHAIN_MAXNAMELEN) - print_error("Chain name length can't exceed %d", - EBT_CHAIN_MAXNAMELEN - 1); - cl = (struct ebt_u_chain_list *) - malloc(sizeof(struct ebt_u_chain_list)); - if (!cl) - print_memory(); - cl->next = NULL; - cl->udc = (struct ebt_u_entries *) - malloc(sizeof(struct ebt_u_entries)); - if (!cl->udc) - print_memory(); - cl->udc->nentries = 0; - cl->udc->policy = EBT_ACCEPT; - cl->udc->counter_offset = replace.nentries; - cl->udc->hook_mask = 0; - strcpy(cl->udc->name, optarg); - cl->udc->entries = NULL; - cl->kernel_start = NULL; - /* - * put the new chain at the end - */ - cl2 = &replace.udc; - while (*cl2) - cl2 = &((*cl2)->next); - *cl2 = cl; - counters_nochange(); + ebt_new_chain(&replace, optarg, EBT_ACCEPT); break; } if (c == 'X') { char *opt; - int udc_nr; if (!optarg && (optind >= argc || (argv[optind][0] == '-' && strcmp(argv[optind], "!")))) { - delete_all_user_chains(); + replace.selected_chain = -1; + ebt_delete_chain(&replace); break; } if (optarg) @@ -1874,25 +547,15 @@ int main(int argc, char *argv[]) opt = argv[optind]; optind++; } - if ((replace.selected_hook = get_hooknr(opt)) == -1) + if ((replace.selected_chain = + ebt_get_chainnr(&replace, opt)) == -1) print_error("Chain %s doesn't exist", optarg); - 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, - * also decrement jumps to a chain behind the - * one we're deleting - */ - udc_nr=replace.selected_hook-NF_BR_NUMHOOKS; - check_for_references(udc_nr, 0); - decrease_chain_jumps(udc_nr); - if (flush_chains() == -1) - counters_nochange(); - remove_udc(udc_nr); + ebt_delete_chain(&replace); break; } - if ((replace.selected_hook = get_hooknr(optarg)) == -1) + if ((replace.selected_chain = + ebt_get_chainnr(&replace, optarg)) == -1) print_error("Chain %s doesn't exist", optarg); if (c == 'E') { if (optind >= argc || argv[optind][0] == '-' || @@ -1901,15 +564,13 @@ int main(int argc, char *argv[]) if (strlen(argv[optind]) >= EBT_CHAIN_MAXNAMELEN) print_error("Chain name len can't exceed %d", EBT_CHAIN_MAXNAMELEN - 1); - if (get_hooknr(argv[optind]) != -1) + if (ebt_get_chainnr(&replace, argv[optind]) != -1) print_error("Chain %s already exists", argv[optind]); - if (find_target(argv[optind])) + if (ebt_find_target(argv[optind])) print_error("Target with name %s exists" , argv[optind]); - entries = to_chain(); - strcpy(entries->name, argv[optind]); - counters_nochange(); + ebt_rename_chain(&replace, argv[optind]); optind++; break; } @@ -1940,7 +601,7 @@ int main(int argc, char *argv[]) policy = 0; for (i = 0; i < NUM_STANDARD_TARGETS; i++) if (!strcmp(argv[optind], - standard_targets[i])) { + ebt_standard_targets[i])) { policy = -i -1; if (policy == EBT_CONTINUE) policy = 0; @@ -1971,14 +632,15 @@ int main(int argc, char *argv[]) " not allowed"); replace.flags |= OPT_COMMAND; } - get_kernel_table(); + ebt_get_kernel_table(&replace, table); i = -1; if (optarg) { - if ( (i = get_hooknr(optarg)) == -1 ) + if ( (i = ebt_get_chainnr(&replace, optarg)) == -1 ) print_error("Bad chain"); } else if (optind < argc && argv[optind][0] != '-') { - if ((i = get_hooknr(argv[optind])) == -1) + if ((i = ebt_get_chainnr(&replace, + argv[optind])) == -1) print_error("Bad chain"); optind++; } @@ -1986,7 +648,7 @@ int main(int argc, char *argv[]) if (c == 'Z') zerochain = i; else - replace.selected_hook = i; + replace.selected_chain = i; } break; @@ -2000,7 +662,7 @@ int main(int argc, char *argv[]) case 'M': /* modprobe */ if (replace.command != 'h') print_error("Please put the -M option earlier"); - modprobe = optarg; + ebt_modprobe = optarg; break; case 'h': /* help */ @@ -2016,14 +678,14 @@ int main(int argc, char *argv[]) if (!strcasecmp("list_extensions", argv[optind])) - list_extensions(); + ebt_list_extensions(); - if ((m = find_match(argv[optind]))) - add_match(m); - else if ((w = find_watcher(argv[optind]))) - add_watcher(w); + if ((m = ebt_find_match(argv[optind]))) + ebt_add_match(new_entry, m); + else if ((w = ebt_find_watcher(argv[optind]))) + ebt_add_watcher(new_entry, w); else { - if (!(t = find_target(argv[optind]))) + if (!(t = ebt_find_target(argv[optind]))) print_error("Extension %s " "not found", argv[optind]); if (replace.flags & OPT_JUMP) @@ -2041,7 +703,7 @@ int main(int argc, char *argv[]) case 't': /* table */ if (replace.command != 'h') print_error("Please put the -t option first"); - check_option(&replace.flags, OPT_TABLE); + ebt_check_option(&replace.flags, OPT_TABLE); if (strlen(optarg) > EBT_TABLE_MAXNAMELEN - 1) print_error("Table name too long"); strcpy(replace.name, optarg); @@ -2061,13 +723,13 @@ int main(int argc, char *argv[]) replace.command != 'D' && replace.command != 'I') print_error("Command and option do not match"); if (c == 'i') { - check_option(&replace.flags, OPT_IN); - if (replace.selected_hook > 2 && - replace.selected_hook < NF_BR_BROUTING) + ebt_check_option(&replace.flags, OPT_IN); + if (replace.selected_chain > 2 && + replace.selected_chain < NF_BR_BROUTING) print_error("Use in-interface only in " "INPUT, FORWARD, PREROUTING and" "BROUTING chains"); - if (check_inverse(optarg)) + if (ebt_check_inverse(optarg)) new_entry->invflags |= EBT_IIN; if (optind > argc) @@ -2079,13 +741,13 @@ int main(int argc, char *argv[]) break; } if (c == 2) { - check_option(&replace.flags, OPT_LOGICALIN); - if (replace.selected_hook > 2 && - replace.selected_hook < NF_BR_BROUTING) + ebt_check_option(&replace.flags, OPT_LOGICALIN); + if (replace.selected_chain > 2 && + replace.selected_chain < NF_BR_BROUTING) print_error("Use logical in-interface " "only in INPUT, FORWARD, " "PREROUTING and BROUTING chains"); - if (check_inverse(optarg)) + if (ebt_check_inverse(optarg)) new_entry->invflags |= EBT_ILOGICALIN; if (optind > argc) @@ -2097,12 +759,12 @@ int main(int argc, char *argv[]) break; } if (c == 'o') { - check_option(&replace.flags, OPT_OUT); - if (replace.selected_hook < 2) + ebt_check_option(&replace.flags, OPT_OUT); + if (replace.selected_chain < 2) print_error("Use out-interface only" " in OUTPUT, FORWARD and " "POSTROUTING chains"); - if (check_inverse(optarg)) + if (ebt_check_inverse(optarg)) new_entry->invflags |= EBT_IOUT; if (optind > argc) @@ -2115,12 +777,12 @@ int main(int argc, char *argv[]) break; } if (c == 3) { - check_option(&replace.flags, OPT_LOGICALOUT); - if (replace.selected_hook < 2) + ebt_check_option(&replace.flags, OPT_LOGICALOUT); + if (replace.selected_chain < 2) print_error("Use logical out-interface " "only in OUTPUT, FORWARD and " "POSTROUTING chains"); - if (check_inverse(optarg)) + if (ebt_check_inverse(optarg)) new_entry->invflags |= EBT_ILOGICALOUT; if (optind > argc) @@ -2134,40 +796,38 @@ int main(int argc, char *argv[]) break; } if (c == 'j') { - check_option(&replace.flags, OPT_JUMP); + ebt_check_option(&replace.flags, OPT_JUMP); for (i = 0; i < NUM_STANDARD_TARGETS; i++) if (!strcmp(optarg, - standard_targets[i])) { - t = find_target( + ebt_standard_targets[i])) { + t = ebt_find_target( EBT_STANDARD_TARGET); ((struct ebt_standard_target *) t->t)->verdict = -i - 1; break; } if (-i - 1 == EBT_RETURN) { - if (replace.selected_hook < NF_BR_NUMHOOKS) + if (replace.selected_chain < NF_BR_NUMHOOKS) print_error("Return target" " only for user defined chains"); } if (i != NUM_STANDARD_TARGETS) break; - if ((i = get_hooknr(optarg)) != -1) { - if (i < NF_BR_NUMHOOKS) - print_error("don't jump" - " to a standard chain"); - t = find_target( - EBT_STANDARD_TARGET); - ((struct ebt_standard_target *) - t->t)->verdict = i - NF_BR_NUMHOOKS; - break; - } - else { + if ((i = ebt_get_chainnr(&replace, optarg)) != -1) { + if (i < NF_BR_NUMHOOKS) + print_error("don't jump" + " to a standard chain"); + t = ebt_find_target(EBT_STANDARD_TARGET); + ((struct ebt_standard_target *) + t->t)->verdict = i - NF_BR_NUMHOOKS; + break; + } else { /* * must be an extension then */ struct ebt_u_target *t; - t = find_target(optarg); + t = ebt_find_target(optarg); /* * -j standard not allowed either */ @@ -2181,14 +841,14 @@ int main(int argc, char *argv[]) break; } if (c == 's') { - check_option(&replace.flags, OPT_SOURCE); - if (check_inverse(optarg)) + ebt_check_option(&replace.flags, OPT_SOURCE); + if (ebt_check_inverse(optarg)) new_entry->invflags |= EBT_ISOURCE; if (optind > argc) print_error("No source mac " "specified"); - if (get_mac_and_mask(argv[optind - 1], + if (ebt_get_mac_and_mask(argv[optind - 1], new_entry->sourcemac, new_entry->sourcemsk)) print_error("Problem with specified " "source mac"); @@ -2196,22 +856,22 @@ int main(int argc, char *argv[]) break; } if (c == 'd') { - check_option(&replace.flags, OPT_DEST); - if (check_inverse(optarg)) + ebt_check_option(&replace.flags, OPT_DEST); + if (ebt_check_inverse(optarg)) new_entry->invflags |= EBT_IDEST; if (optind > argc) print_error("No destination mac " "specified"); - if (get_mac_and_mask(argv[optind - 1], + if (ebt_get_mac_and_mask(argv[optind - 1], new_entry->destmac, new_entry->destmsk)) print_error("Problem with specified " "destination mac"); new_entry->bitmask |= EBT_DESTMAC; break; } - check_option(&replace.flags, OPT_PROTOCOL); - if (check_inverse(optarg)) + ebt_check_option(&replace.flags, OPT_PROTOCOL); + if (ebt_check_inverse(optarg)) new_entry->invflags |= EBT_IPROTO; if (optind > argc) @@ -2242,7 +902,7 @@ int main(int argc, char *argv[]) break; case 4 : /* Lc */ - check_option(&replace.flags, LIST_C); + ebt_check_option(&replace.flags, LIST_C); if (replace.command != 'L') print_error("Use --Lc with -L"); if (replace.flags & LIST_X) @@ -2250,7 +910,7 @@ int main(int argc, char *argv[]) replace.flags |= LIST_C; break; case 5 : /* Ln */ - check_option(&replace.flags, LIST_N); + ebt_check_option(&replace.flags, LIST_N); if (replace.command != 'L') print_error("Use --Ln with -L"); if (replace.flags & LIST_X) @@ -2258,7 +918,7 @@ int main(int argc, char *argv[]) replace.flags |= LIST_N; break; case 6 : /* Lx */ - check_option(&replace.flags, LIST_X); + ebt_check_option(&replace.flags, LIST_X); if (replace.command != 'L') print_error("Use --Lx with -L"); if (replace.flags & LIST_C) @@ -2268,7 +928,7 @@ int main(int argc, char *argv[]) replace.flags |= LIST_X; break; case 12 : /* Lmac2 */ - check_option(&replace.flags, LIST_MAC2); + ebt_check_option(&replace.flags, LIST_MAC2); if (replace.command != 'L') print_error("Use --Lmac2 with -L"); replace.flags |= LIST_MAC2; @@ -2283,14 +943,7 @@ int main(int argc, char *argv[]) /* * get the information from the file */ - get_table(&replace); - if (replace.nentries) { - replace.counterchanges = (unsigned short *) - malloc(sizeof(unsigned short) * (replace.nentries + 1)); - for (i = 0; i < replace.nentries; i++) - replace.counterchanges[i] = CNT_NORM; - replace.counterchanges[i] = CNT_END; - } + ebt_get_table(&replace); /* * we don't want the kernel giving us its counters, they would * overwrite the counters extracted from the file @@ -2317,16 +970,9 @@ int main(int argc, char *argv[]) tmp = replace.filename; /* get the kernel table */ replace.filename = NULL; - get_kernel_table(); + ebt_get_kernel_table(&replace, table); replace.filename = tmp; } - if (replace.nentries) { - replace.counterchanges = (unsigned short *) - malloc(sizeof(unsigned short) * (replace.nentries + 1)); - for (i = 0; i < replace.nentries; i++) - replace.counterchanges[i] = CNT_NORM; - replace.counterchanges[i] = CNT_END; - } break; case 9 : /* atomic */ if (replace.flags & OPT_COMMAND) @@ -2338,11 +984,11 @@ int main(int argc, char *argv[]) break; case 1 : if (!strcmp(optarg, "!")) - check_inverse(optarg); + ebt_check_inverse(optarg); else print_error("Bad argument : %s", optarg); /* - * check_inverse() did optind++ + * ebt_check_inverse() did optind++ */ optind--; continue; @@ -2358,38 +1004,42 @@ int main(int argc, char *argv[]) /* * is it a match_option? */ - for (m = matches; m; m = m->next) + for (m = ebt_matches; m; m = m->next) if (m->parse(c - m->option_offset, argv, argc, new_entry, &m->flags, &m->m)) break; if (m != NULL) { - if (m->used == 0) - add_match(m); + if (m->used == 0) { + ebt_add_match(new_entry, m); + m->used = 1; + } goto check_extension; } /* * is it a watcher option? */ - for (w = watchers; w; w = w->next) + for (w = ebt_watchers; w; w = w->next) if (w->parse(c-w->option_offset, argv, argc, new_entry, &w->flags, &w->w)) break; if (w == NULL) print_error("Unknown argument"); - if (w->used == 0) - add_watcher(w); + if (w->used == 0) { + ebt_add_watcher(new_entry, w); + w->used = 1; + } check_extension: if (replace.command != 'A' && replace.command != 'I' && replace.command != 'D') print_error("Extensions only for -A, -I and -D"); } - invert = 0; + ebt_invert = 0; } - if ( !table && !(table = find_table(replace.name)) ) + if ( !table && !(table = ebt_find_table(replace.name)) ) print_error("Bad table name"); if ( (replace.flags & OPT_COMMAND) && replace.command != 'L' && @@ -2410,8 +1060,8 @@ check_extension: /* * this will put the hook_mask right for the chains */ - check_for_loops(); - entries = to_chain(); + ebt_check_for_loops(&replace); + entries = ebt_to_chain(&replace); m_l = new_entry->m_list; w_l = new_entry->w_list; t = (struct ebt_u_target *)new_entry->t; @@ -2432,31 +1082,32 @@ check_extension: } /* * so, the extensions can work with the host endian - * the kernel does not have to do this ofcourse + * the kernel does not have to do this of course */ new_entry->ethproto = htons(new_entry->ethproto); if (replace.command == 'P') { - if (replace.selected_hook < NF_BR_NUMHOOKS && + if (replace.selected_chain < NF_BR_NUMHOOKS && policy == EBT_RETURN) print_error("Policy RETURN only allowed for user " "defined chains"); - change_policy(policy); + ebt_change_policy(&replace, policy); } else if (replace.command == 'L') { list_rules(); - if (replace.flags & OPT_ZERO) - zero_counters(zerochain); - else + if (replace.flags & OPT_ZERO) { + replace.selected_chain = zerochain; + ebt_zero_counters(&replace); + } else exit(0); } - if (replace.flags & OPT_ZERO) - zero_counters(zerochain); - else if (replace.command == 'F') { - if (flush_chains() == -1) - exit(0); - } else if (replace.command == 'A' || replace.command == 'I') { - add_rule(rule_nr); - check_for_loops(); + if (replace.flags & OPT_ZERO) { + replace.selected_chain = zerochain; + ebt_zero_counters(&replace); + } else if (replace.command == 'F') + ebt_flush_chains(&replace); + else if (replace.command == 'A' || replace.command == 'I') { + ebt_add_rule(&replace, new_entry, rule_nr); + ebt_check_for_loops(&replace); /* * do the final_check(), for all entries * needed when adding a rule that has a chain target @@ -2466,7 +1117,7 @@ check_extension: struct ebt_u_entry *e; i++; - entries = nr_to_chain(i); + entries = ebt_nr_to_chain(&replace, i); if (!entries) { if (i < NF_BR_NUMHOOKS) continue; @@ -2479,13 +1130,13 @@ check_extension: * userspace extensions use host endian */ e->ethproto = ntohs(e->ethproto); - do_final_checks(e, entries); + ebt_do_final_checks(&replace, e, entries); e->ethproto = htons(e->ethproto); e = e->next; } } } else if (replace.command == 'D') - delete_rule(rule_nr, rule_nr_end); + ebt_delete_rule(&replace, new_entry, rule_nr, rule_nr_end); /* * commands -N, -E, -X, --atomic-commit, --atomic-commit, --atomic-save, * --init-table fall through @@ -2494,9 +1145,9 @@ check_extension: if (table->check) table->check(&replace); - deliver_table(&replace); + ebt_deliver_table(&replace); if (replace.counterchanges) - deliver_counters(&replace); + ebt_deliver_counters(&replace); return 0; } diff --git a/userspace/ebtables2/extensions/ebt_802_3.c b/userspace/ebtables2/extensions/ebt_802_3.c index 52b05aa..f76b20a 100644 --- a/userspace/ebtables2/extensions/ebt_802_3.c +++ b/userspace/ebtables2/extensions/ebt_802_3.c @@ -43,8 +43,8 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, switch (c) { case _802_3_SAP: - check_option(flags, _802_3_SAP); - if (check_inverse(optarg)) + ebt_check_option(flags, _802_3_SAP); + if (ebt_check_inverse(optarg)) info->invflags |= EBT_802_3_SAP; if (optind > argc) @@ -57,8 +57,8 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, info->bitmask |= EBT_802_3_SAP; break; case _802_3_TYPE: - check_option(flags, _802_3_TYPE); - if (check_inverse(optarg)) + ebt_check_option(flags, _802_3_TYPE); + if (ebt_check_inverse(optarg)) info->invflags |= EBT_802_3_TYPE; if (optind > argc) print_error("Missing 802.3-type argument"); @@ -141,5 +141,5 @@ static struct ebt_u_match _802_3_match = static void _init(void) __attribute__ ((constructor)); static void _init(void) { - register_match(&_802_3_match); + ebt_register_match(&_802_3_match); } diff --git a/userspace/ebtables2/extensions/ebt_among.c b/userspace/ebtables2/extensions/ebt_among.c index b865ca2..9427038 100644 --- a/userspace/ebtables2/extensions/ebt_among.c +++ b/userspace/ebtables2/extensions/ebt_among.c @@ -41,8 +41,8 @@ static void print_help() { printf( "`among' options:\n" -"--among-dst [!] list : matches if ether dst is in list\n" -"--among-src [!] list : matches if ether src is in list\n" +"--among-dst [!] list : matches if ether dst is in list\n" +"--among-src [!] list : matches if ether src is in list\n" "list has form:\n" " xx:xx:xx:xx:xx:xx[=ip.ip.ip.ip],yy:yy:yy:yy:yy:yy[=ip.ip.ip.ip]" ",...,zz:zz:zz:zz:zz:zz[=ip.ip.ip.ip][,]\n" @@ -295,7 +295,7 @@ static int parse(int c, char **argv, int argc, switch (c) { case AMONG_DST: case AMONG_SRC: - if (check_inverse(optarg)) { + if (ebt_check_inverse(optarg)) { if (c == AMONG_DST) info->bitmask |= EBT_AMONG_DST_NEG; else @@ -314,11 +314,11 @@ static int parse(int c, char **argv, int argc, h->match_size = new_size - sizeof(struct ebt_entry_match); info = (struct ebt_among_info *) h->data; if (c == AMONG_DST) { - check_option(flags, OPT_DST); + ebt_check_option(flags, OPT_DST); info->wh_dst_ofs = old_size - sizeof(struct ebt_entry_match); } else { - check_option(flags, OPT_SRC); + ebt_check_option(flags, OPT_SRC); info->wh_src_ofs = old_size - sizeof(struct ebt_entry_match); } @@ -364,7 +364,7 @@ static void wormhash_printout(const struct ebt_mac_wormhash *wh) const struct ebt_mac_wormhash_tuple *p; p = (const struct ebt_mac_wormhash_tuple *)(&wh->pool[i]); - print_mac(((const char *) &p->cmp[0]) + 2); + ebt_print_mac(((const char *) &p->cmp[0]) + 2); if (p->ip) { ip = (unsigned char *) &p->ip; printf("=%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); @@ -439,5 +439,5 @@ static struct ebt_u_match among_match = { static void _init(void) __attribute__ ((constructor)); static void _init(void) { - register_match(&among_match); + ebt_register_match(&among_match); } diff --git a/userspace/ebtables2/extensions/ebt_arp.c b/userspace/ebtables2/extensions/ebt_arp.c index 7b00b78..a60d6a7 100644 --- a/userspace/ebtables2/extensions/ebt_arp.c +++ b/userspace/ebtables2/extensions/ebt_arp.c @@ -71,11 +71,6 @@ static void init(struct ebt_entry_match *match) arpinfo->bitmask = 0; } -/* defined in ebt_ip.c */ -void parse_ip_address(char *address, uint32_t *addr, uint32_t *msk); - -/* defined in ebtables.c */ -int get_mac_and_mask(char *from, char *to, char *mask); #define OPT_OPCODE 0x01 #define OPT_HTYPE 0x02 @@ -97,8 +92,8 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, switch (c) { case ARP_OPCODE: - check_option(flags, OPT_OPCODE); - if (check_inverse(optarg)) + ebt_check_option(flags, OPT_OPCODE); + if (ebt_check_inverse(optarg)) arpinfo->invflags |= EBT_ARP_OPCODE; if (optind > argc) @@ -118,8 +113,8 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, break; case ARP_HTYPE: - check_option(flags, OPT_HTYPE); - if (check_inverse(optarg)) + ebt_check_option(flags, OPT_HTYPE); + if (ebt_check_inverse(optarg)) arpinfo->invflags |= EBT_ARP_HTYPE; if (optind > argc) @@ -140,8 +135,8 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, { uint16_t proto; - check_option(flags, OPT_PTYPE); - if (check_inverse(optarg)) + ebt_check_option(flags, OPT_PTYPE); + if (ebt_check_inverse(optarg)) arpinfo->invflags |= EBT_ARP_PTYPE; if (optind > argc) @@ -166,17 +161,17 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, case ARP_IP_S: case ARP_IP_D: if (c == ARP_IP_S) { - check_option(flags, OPT_IP_S); + ebt_check_option(flags, OPT_IP_S); addr = &arpinfo->saddr; mask = &arpinfo->smsk; arpinfo->bitmask |= EBT_ARP_SRC_IP; } else { - check_option(flags, OPT_IP_D); + ebt_check_option(flags, OPT_IP_D); addr = &arpinfo->daddr; mask = &arpinfo->dmsk; arpinfo->bitmask |= EBT_ARP_DST_IP; } - if (check_inverse(optarg)) { + if (ebt_check_inverse(optarg)) { if (c == ARP_IP_S) arpinfo->invflags |= EBT_ARP_SRC_IP; else @@ -184,23 +179,23 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, } if (optind > argc) print_error("Missing ARP IP address argument"); - parse_ip_address(argv[optind - 1], addr, mask); + ebt_parse_ip_address(argv[optind - 1], addr, mask); break; case ARP_MAC_S: case ARP_MAC_D: if (c == ARP_MAC_S) { - check_option(flags, OPT_MAC_S); + ebt_check_option(flags, OPT_MAC_S); maddr = arpinfo->smaddr; mmask = arpinfo->smmsk; arpinfo->bitmask |= EBT_ARP_SRC_MAC; } else { - check_option(flags, OPT_MAC_D); + ebt_check_option(flags, OPT_MAC_D); maddr = arpinfo->dmaddr; mmask = arpinfo->dmmsk; arpinfo->bitmask |= EBT_ARP_DST_MAC; } - if (check_inverse(optarg)) { + if (ebt_check_inverse(optarg)) { if (c == ARP_MAC_S) arpinfo->invflags |= EBT_ARP_SRC_MAC; else @@ -208,7 +203,7 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, } if (optind > argc) print_error("Missing ARP MAC address argument"); - if (get_mac_and_mask(argv[optind - 1], maddr, mmask)) + if (ebt_get_mac_and_mask(argv[optind - 1], maddr, mmask)) print_error("Problem with ARP MAC address argument"); break; @@ -228,9 +223,6 @@ static void final_check(const struct ebt_u_entry *entry, "specified as ARP or RARP"); } -/* defined in the ebt_ip.c */ -char *mask_to_dotted(uint32_t mask); - static void print(const struct ebt_u_entry *entry, const struct ebt_entry_match *match) { @@ -272,7 +264,7 @@ static void print(const struct ebt_u_entry *entry, for (i = 0; i < 4; i++) printf("%d%s", ((unsigned char *)&arpinfo->saddr)[i], (i == 3) ? "" : "."); - printf("%s ", mask_to_dotted(arpinfo->smsk)); + printf("%s ", ebt_mask_to_dotted(arpinfo->smsk)); } if (arpinfo->bitmask & EBT_ARP_DST_IP) { printf("--arp-ip-dst "); @@ -281,20 +273,20 @@ static void print(const struct ebt_u_entry *entry, for (i = 0; i < 4; i++) printf("%d%s", ((unsigned char *)&arpinfo->daddr)[i], (i == 3) ? "" : "."); - printf("%s ", mask_to_dotted(arpinfo->dmsk)); + printf("%s ", ebt_mask_to_dotted(arpinfo->dmsk)); } if (arpinfo->bitmask & EBT_ARP_SRC_MAC) { printf("--arp-mac-src "); if (arpinfo->invflags & EBT_ARP_SRC_MAC) printf("! "); - print_mac_and_mask(arpinfo->smaddr, arpinfo->smmsk); + ebt_print_mac_and_mask(arpinfo->smaddr, arpinfo->smmsk); printf(" "); } if (arpinfo->bitmask & EBT_ARP_DST_MAC) { printf("--arp-mac-dst "); if (arpinfo->invflags & EBT_ARP_DST_MAC) printf("! "); - print_mac_and_mask(arpinfo->dmaddr, arpinfo->dmmsk); + ebt_print_mac_and_mask(arpinfo->dmaddr, arpinfo->dmmsk); printf(" "); } } @@ -364,5 +356,5 @@ static struct ebt_u_match arp_match = static void _init(void) __attribute__ ((constructor)); static void _init(void) { - register_match(&arp_match); + ebt_register_match(&arp_match); } diff --git a/userspace/ebtables2/extensions/ebt_arpreply.c b/userspace/ebtables2/extensions/ebt_arpreply.c index 7e5f113..d524253 100644 --- a/userspace/ebtables2/extensions/ebt_arpreply.c +++ b/userspace/ebtables2/extensions/ebt_arpreply.c @@ -48,7 +48,7 @@ static int parse(int c, char **argv, int argc, switch (c) { case REPLY_MAC: - check_option(flags, OPT_REPLY_MAC); + ebt_check_option(flags, OPT_REPLY_MAC); if (!(addr = ether_aton(optarg))) print_error("Problem with specified " "--arpreply-mac mac"); @@ -56,7 +56,7 @@ static int parse(int c, char **argv, int argc, mac_supplied = 1; break; case REPLY_TARGET: - check_option(flags, OPT_REPLY_TARGET); + ebt_check_option(flags, OPT_REPLY_TARGET); if (FILL_TARGET(optarg, replyinfo->target)) print_error("Illegal --arpreply-target target"); break; @@ -94,7 +94,7 @@ static void print(const struct ebt_u_entry *entry, (struct ebt_arpreply_info *)target->data; printf("--arpreply-mac "); - print_mac(replyinfo->mac); + ebt_print_mac(replyinfo->mac); if (replyinfo->target == EBT_DROP) return; printf(" --arpreply-target %s", TARGET_NAME(replyinfo->target)); @@ -128,5 +128,5 @@ static struct ebt_u_target arpreply_target = static void _init(void) __attribute__ ((constructor)); static void _init(void) { - register_target(&arpreply_target); + ebt_register_target(&arpreply_target); } diff --git a/userspace/ebtables2/extensions/ebt_ip.c b/userspace/ebtables2/extensions/ebt_ip.c index b836bae..f93b8b9 100644 --- a/userspace/ebtables2/extensions/ebt_ip.c +++ b/userspace/ebtables2/extensions/ebt_ip.c @@ -57,111 +57,7 @@ static struct option opts[] = { 0 } }; -/* put the ip string into 4 bytes */ -static int undot_ip(char *ip, unsigned char *ip2) -{ - char *p, *q, *end; - long int onebyte; - int i; - char buf[20]; - - strncpy(buf, ip, sizeof(buf) - 1); - - p = buf; - for (i = 0; i < 3; i++) { - if ((q = strchr(p, '.')) == NULL) - return -1; - *q = '\0'; - onebyte = strtol(p, &end, 10); - if (*end != '\0' || onebyte > 255 || onebyte < 0) - return -1; - ip2[i] = (unsigned char)onebyte; - p = q + 1; - } - - onebyte = strtol(p, &end, 10); - if (*end != '\0' || onebyte > 255 || onebyte < 0) - return -1; - ip2[3] = (unsigned char)onebyte; - - return 0; -} - /* put the mask into 4 bytes */ -static int ip_mask(char *mask, unsigned char *mask2) -{ - char *end; - long int bits; - uint32_t mask22; - - if (undot_ip(mask, mask2)) { - /* not the /a.b.c.e format, maybe the /x format */ - bits = strtol(mask, &end, 10); - if (*end != '\0' || bits > 32 || bits < 0) - return -1; - if (bits != 0) { - mask22 = htonl(0xFFFFFFFF << (32 - bits)); - memcpy(mask2, &mask22, 4); - } else { - mask22 = 0xFFFFFFFF; - memcpy(mask2, &mask22, 4); - } - } - return 0; -} - -/* set the ip mask and ip address */ -void parse_ip_address(char *address, uint32_t *addr, uint32_t *msk) -{ - char *p; - - /* first the mask */ - if ((p = strrchr(address, '/')) != NULL) { - *p = '\0'; - if (ip_mask(p + 1, (unsigned char *)msk)) - print_error("Problem with the IP mask"); - } - else - *msk = 0xFFFFFFFF; - - if (undot_ip(address, (unsigned char *)addr)) - print_error("Problem with the IP address"); - *addr = *addr & *msk; -} - -/* transform the ip mask into a string ready for output */ -char *mask_to_dotted(uint32_t mask) -{ - int i; - static char buf[20]; - uint32_t maskaddr, bits; - - maskaddr = ntohl(mask); - - /* don't print /32 */ - if (mask == 0xFFFFFFFFL) { - *buf = '\0'; - return buf; - } - - i = 32; - bits = 0xFFFFFFFEL; /* case 0xFFFFFFFF has just been dealt with */ - while (--i >= 0 && maskaddr != bits) - bits <<= 1; - - if (i > 0) - sprintf(buf, "/%d", i); - else if (!i) - *buf = '\0'; - else - /* mask was not a decent combination of 1's and 0's */ - sprintf(buf, "/%d.%d.%d.%d", ((unsigned char *)&mask)[0], - ((unsigned char *)&mask)[1], ((unsigned char *)&mask)[2], - ((unsigned char *)&mask)[3]); - - return buf; -} - /* transform a protocol and service name into a port number */ static uint16_t parse_port(const char *protocol, const char *name) { @@ -247,15 +143,15 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, switch (c) { case IP_SOURCE: - check_option(flags, OPT_SOURCE); + ebt_check_option(flags, OPT_SOURCE); ipinfo->bitmask |= EBT_IP_SOURCE; case IP_DEST: if (c == IP_DEST) { - check_option(flags, OPT_DEST); + ebt_check_option(flags, OPT_DEST); ipinfo->bitmask |= EBT_IP_DEST; } - if (check_inverse(optarg)) { + if (ebt_check_inverse(optarg)) { if (c == IP_SOURCE) ipinfo->invflags |= EBT_IP_SOURCE; else @@ -265,24 +161,24 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, if (optind > argc) print_error("Missing IP address argument"); if (c == IP_SOURCE) - parse_ip_address(argv[optind - 1], &ipinfo->saddr, + ebt_parse_ip_address(argv[optind - 1], &ipinfo->saddr, &ipinfo->smsk); else - parse_ip_address(argv[optind - 1], &ipinfo->daddr, + ebt_parse_ip_address(argv[optind - 1], &ipinfo->daddr, &ipinfo->dmsk); break; case IP_SPORT: case IP_DPORT: if (c == IP_SPORT) { - check_option(flags, OPT_SPORT); + ebt_check_option(flags, OPT_SPORT); ipinfo->bitmask |= EBT_IP_SPORT; - if (check_inverse(optarg)) + if (ebt_check_inverse(optarg)) ipinfo->invflags |= EBT_IP_SPORT; } else { - check_option(flags, OPT_DPORT); + ebt_check_option(flags, OPT_DPORT); ipinfo->bitmask |= EBT_IP_DPORT; - if (check_inverse(optarg)) + if (ebt_check_inverse(optarg)) ipinfo->invflags |= EBT_IP_DPORT; } if (optind > argc) @@ -294,8 +190,8 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, break; case IP_myTOS: - check_option(flags, OPT_TOS); - if (check_inverse(optarg)) + ebt_check_option(flags, OPT_TOS); + if (ebt_check_inverse(optarg)) ipinfo->invflags |= EBT_IP_TOS; if (optind > argc) @@ -308,8 +204,8 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, break; case IP_PROTO: - check_option(flags, OPT_PROTO); - if (check_inverse(optarg)) + ebt_check_option(flags, OPT_PROTO); + if (ebt_check_inverse(optarg)) ipinfo->invflags |= EBT_IP_PROTO; if (optind > argc) print_error("Missing IP protocol argument"); @@ -366,7 +262,7 @@ static void print(const struct ebt_u_entry *entry, for (j = 0; j < 4; j++) printf("%d%s",((unsigned char *)&ipinfo->saddr)[j], (j == 3) ? "" : "."); - printf("%s ", mask_to_dotted(ipinfo->smsk)); + printf("%s ", ebt_mask_to_dotted(ipinfo->smsk)); } if (ipinfo->bitmask & EBT_IP_DEST) { printf("--ip-dst "); @@ -375,7 +271,7 @@ static void print(const struct ebt_u_entry *entry, for (j = 0; j < 4; j++) printf("%d%s", ((unsigned char *)&ipinfo->daddr)[j], (j == 3) ? "" : "."); - printf("%s ", mask_to_dotted(ipinfo->dmsk)); + printf("%s ", ebt_mask_to_dotted(ipinfo->dmsk)); } if (ipinfo->bitmask & EBT_IP_TOS) { printf("--ip-tos "); @@ -471,5 +367,5 @@ static struct ebt_u_match ip_match = static void _init(void) __attribute((constructor)); static void _init(void) { - register_match(&ip_match); + ebt_register_match(&ip_match); } diff --git a/userspace/ebtables2/extensions/ebt_limit.c b/userspace/ebtables2/extensions/ebt_limit.c index bf322b8..490686d 100644 --- a/userspace/ebtables2/extensions/ebt_limit.c +++ b/userspace/ebtables2/extensions/ebt_limit.c @@ -120,16 +120,16 @@ static int parse(int c, char **argv, int argc, switch(c) { case ARG_LIMIT: - check_option(flags, FLAG_LIMIT); - if (check_inverse(optarg)) + ebt_check_option(flags, FLAG_LIMIT); + if (ebt_check_inverse(optarg)) print_error("Unexpected `!' after --limit"); if (!parse_rate(optarg, &r->avg)) print_error("bad rate `%s'", optarg); break; case ARG_LIMIT_BURST: - check_option(flags, FLAG_LIMIT_BURST); - if (check_inverse(optarg)) + ebt_check_option(flags, FLAG_LIMIT_BURST); + if (ebt_check_inverse(optarg)) print_error("Unexpected `!' after --limit-burst"); if (string_to_number(optarg, 0, 10000, &num) == -1) @@ -217,5 +217,5 @@ static struct ebt_u_match limit_match = static void _init(void) __attribute((constructor)); static void _init(void) { - register_match(&limit_match); + ebt_register_match(&limit_match); } diff --git a/userspace/ebtables2/extensions/ebt_log.c b/userspace/ebtables2/extensions/ebt_log.c index 2892348..953211e 100644 --- a/userspace/ebtables2/extensions/ebt_log.c +++ b/userspace/ebtables2/extensions/ebt_log.c @@ -103,14 +103,14 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, switch (c) { case LOG_PREFIX: - check_option(flags, OPT_PREFIX); + ebt_check_option(flags, OPT_PREFIX); if (strlen(optarg) > sizeof(loginfo->prefix) - 1) print_error("Prefix too long"); strcpy(loginfo->prefix, optarg); break; case LOG_LEVEL: - check_option(flags, OPT_LEVEL); + ebt_check_option(flags, OPT_LEVEL); i = strtol(optarg, &end, 16); if (*end != '\0' || i < 0 || i > 7) loginfo->loglevel = name_to_loglevel(optarg); @@ -121,17 +121,17 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, break; case LOG_IP: - check_option(flags, OPT_IP); + ebt_check_option(flags, OPT_IP); loginfo->bitmask |= EBT_LOG_IP; break; case LOG_ARP: - check_option(flags, OPT_ARP); + ebt_check_option(flags, OPT_ARP); loginfo->bitmask |= EBT_LOG_ARP; break; case LOG_LOG: - check_option(flags, OPT_LOG); + ebt_check_option(flags, OPT_LOG); break; default: return 0; @@ -190,5 +190,5 @@ static struct ebt_u_watcher log_watcher = static void _init(void) __attribute__ ((constructor)); static void _init(void) { - register_watcher(&log_watcher); + ebt_register_watcher(&log_watcher); } diff --git a/userspace/ebtables2/extensions/ebt_mark.c b/userspace/ebtables2/extensions/ebt_mark.c index 6fa26f8..c40b9fd 100644 --- a/userspace/ebtables2/extensions/ebt_mark.c +++ b/userspace/ebtables2/extensions/ebt_mark.c @@ -46,12 +46,12 @@ static int parse(int c, char **argv, int argc, switch (c) { case MARK_TARGET: - check_option(flags, OPT_MARK_TARGET); + ebt_check_option(flags, OPT_MARK_TARGET); if (FILL_TARGET(optarg, markinfo->target)) print_error("Illegal --mark-target target"); break; case MARK_SETMARK: - check_option(flags, OPT_MARK_SETMARK); + ebt_check_option(flags, OPT_MARK_SETMARK); markinfo->mark = strtoul(optarg, &end, 0); if (*end != '\0' || end == optarg) print_error("Bad MARK value '%s'", optarg); @@ -116,5 +116,5 @@ static struct ebt_u_target mark_target = static void _init(void) __attribute__ ((constructor)); static void _init(void) { - register_target(&mark_target); + ebt_register_target(&mark_target); } diff --git a/userspace/ebtables2/extensions/ebt_mark_m.c b/userspace/ebtables2/extensions/ebt_mark_m.c index 0d14d76..1c18d9e 100644 --- a/userspace/ebtables2/extensions/ebt_mark_m.c +++ b/userspace/ebtables2/extensions/ebt_mark_m.c @@ -40,8 +40,8 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, switch (c) { case MARK: - check_option(flags, MARK); - if (check_inverse(optarg)) + ebt_check_option(flags, MARK); + if (ebt_check_inverse(optarg)) markinfo->invert = 1; if (optind > argc) print_error("No mark specified"); @@ -118,5 +118,5 @@ static struct ebt_u_match mark_match = static void _init(void) __attribute((constructor)); static void _init(void) { - register_match(&mark_match); + ebt_register_match(&mark_match); } diff --git a/userspace/ebtables2/extensions/ebt_nat.c b/userspace/ebtables2/extensions/ebt_nat.c index 04c6f0f..16e1842 100644 --- a/userspace/ebtables2/extensions/ebt_nat.c +++ b/userspace/ebtables2/extensions/ebt_nat.c @@ -73,14 +73,14 @@ static int parse_s(int c, char **argv, int argc, switch (c) { case NAT_S: - check_option(flags, OPT_SNAT); + ebt_check_option(flags, OPT_SNAT); to_source_supplied = 1; if (!(addr = ether_aton(optarg))) print_error("Problem with specified --to-source mac"); memcpy(natinfo->mac, addr, ETH_ALEN); break; case NAT_S_TARGET: - check_option(flags, OPT_SNAT_TARGET); + ebt_check_option(flags, OPT_SNAT_TARGET); if (FILL_TARGET(optarg, natinfo->target)) print_error("Illegal --snat-target target"); break; @@ -101,7 +101,7 @@ static int parse_d(int c, char **argv, int argc, switch (c) { case NAT_D: - check_option(flags, OPT_DNAT); + ebt_check_option(flags, OPT_DNAT); to_dest_supplied = 1; if (!(addr = ether_aton(optarg))) print_error("Problem with specified " @@ -109,7 +109,7 @@ static int parse_d(int c, char **argv, int argc, memcpy(natinfo->mac, addr, ETH_ALEN); break; case NAT_D_TARGET: - check_option(flags, OPT_DNAT_TARGET); + ebt_check_option(flags, OPT_DNAT_TARGET); if (FILL_TARGET(optarg, natinfo->target)) print_error("Illegal --dnat-target target"); break; @@ -157,7 +157,7 @@ static void print_s(const struct ebt_u_entry *entry, struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data; printf("--to-src "); - print_mac(natinfo->mac); + ebt_print_mac(natinfo->mac); printf(" --snat-target %s", TARGET_NAME(natinfo->target)); } @@ -167,7 +167,7 @@ static void print_d(const struct ebt_u_entry *entry, struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data; printf("--to-dst "); - print_mac(natinfo->mac); + ebt_print_mac(natinfo->mac); printf(" --dnat-target %s", TARGET_NAME(natinfo->target)); } @@ -210,6 +210,6 @@ static struct ebt_u_target dnat_target = static void _init(void) __attribute__ ((constructor)); static void _init(void) { - register_target(&snat_target); - register_target(&dnat_target); + ebt_register_target(&snat_target); + ebt_register_target(&dnat_target); } diff --git a/userspace/ebtables2/extensions/ebt_pkttype.c b/userspace/ebtables2/extensions/ebt_pkttype.c index 73f6e62..35bac29 100644 --- a/userspace/ebtables2/extensions/ebt_pkttype.c +++ b/userspace/ebtables2/extensions/ebt_pkttype.c @@ -57,8 +57,8 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, switch (c) { case '1': - check_option(flags, 1); - if (check_inverse(optarg)) + ebt_check_option(flags, 1); + if (ebt_check_inverse(optarg)) ptinfo->invert = 1; if (optind > argc) print_error("Missing pkttype class specification"); @@ -132,5 +132,5 @@ static struct ebt_u_match pkttype_match = static void _init(void) __attribute((constructor)); static void _init(void) { - register_match(&pkttype_match); + ebt_register_match(&pkttype_match); } diff --git a/userspace/ebtables2/extensions/ebt_redirect.c b/userspace/ebtables2/extensions/ebt_redirect.c index 432e58d..82feaa9 100644 --- a/userspace/ebtables2/extensions/ebt_redirect.c +++ b/userspace/ebtables2/extensions/ebt_redirect.c @@ -38,7 +38,7 @@ static int parse(int c, char **argv, int argc, switch (c) { case REDIRECT_TARGET: - check_option(flags, OPT_REDIRECT_TARGET); + ebt_check_option(flags, OPT_REDIRECT_TARGET); if (FILL_TARGET(optarg, redirectinfo->target)) print_error("Illegal --redirect-target target"); break; @@ -102,5 +102,5 @@ static struct ebt_u_target redirect_target = static void _init(void) __attribute__ ((constructor)); static void _init(void) { - register_target(&redirect_target); + ebt_register_target(&redirect_target); } diff --git a/userspace/ebtables2/extensions/ebt_standard.c b/userspace/ebtables2/extensions/ebt_standard.c index 6a260eb..7ee454b 100644 --- a/userspace/ebtables2/extensions/ebt_standard.c +++ b/userspace/ebtables2/extensions/ebt_standard.c @@ -31,8 +31,6 @@ static void final_check(const struct ebt_u_entry *entry, { } -struct ebt_u_entries *nr_to_chain(int nr); - static void print(const struct ebt_u_entry *entry, const struct ebt_entry_target *target) { @@ -41,7 +39,8 @@ static void print(const struct ebt_u_entry *entry, if (verdict >= 0) { struct ebt_u_entries *entries; - entries = nr_to_chain(verdict + NF_BR_NUMHOOKS); + entries = ebt_nr_to_chain(entry->replace, + verdict + NF_BR_NUMHOOKS); printf("%s", entries->name); return; } @@ -81,5 +80,5 @@ static struct ebt_u_target standard = static void _init(void) __attribute__ ((constructor)); static void _init(void) { - register_target(&standard); + ebt_register_target(&standard); } diff --git a/userspace/ebtables2/extensions/ebt_stp.c b/userspace/ebtables2/extensions/ebt_stp.c index 391b89e..60f2cc8 100644 --- a/userspace/ebtables2/extensions/ebt_stp.c +++ b/userspace/ebtables2/extensions/ebt_stp.c @@ -78,10 +78,6 @@ static void init(struct ebt_entry_match *match) stpinfo->bitmask = 0; } -/* defined in ebtables.c */ -int get_mac_and_mask(char *from, char *to, char *mask); -void print_mac_and_mask(const char *mac, const char *mask); - #define determine_value(p,s) \ { \ uint32_t _tmp2; \ @@ -135,8 +131,8 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, if (c < 'a' || c > ('a' + STP_NUMOPS - 1)) return 0; flag = 1 << (c - 'a'); - check_option(flags, flag); - if (check_inverse(optarg)) + ebt_check_option(flags, flag); + if (ebt_check_inverse(optarg)) stpinfo->invflags |= flag; if (optind > argc) print_error("Missing argument for --%s", opts[c-'a'].name); @@ -211,12 +207,12 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, print_error("Bad STP config forward delay range"); break; case EBT_STP_ROOTADDR: - if (get_mac_and_mask(argv[optind-1], + if (ebt_get_mac_and_mask(argv[optind-1], stpinfo->config.root_addr, stpinfo->config.root_addrmsk)) print_error("Bad STP config root address"); break; case EBT_STP_SENDERADDR: - if (get_mac_and_mask(argv[optind-1], stpinfo->config.sender_addr, + if (ebt_get_mac_and_mask(argv[optind-1], stpinfo->config.sender_addr, stpinfo->config.sender_addrmsk)) print_error("Bad STP config sender address"); break; @@ -269,13 +265,13 @@ static void print(const struct ebt_u_entry *entry, } else if (EBT_STP_ROOTPRIO == (1 << i)) print_range(c->root_priol, c->root_priou); else if (EBT_STP_ROOTADDR == (1 << i)) - print_mac_and_mask(c->root_addr, c->root_addrmsk); + ebt_print_mac_and_mask(c->root_addr, c->root_addrmsk); else if (EBT_STP_ROOTCOST == (1 << i)) print_range(c->root_costl, c->root_costu); else if (EBT_STP_SENDERPRIO == (1 << i)) print_range(c->sender_priol, c->sender_priou); else if (EBT_STP_SENDERADDR == (1 << i)) - print_mac_and_mask(c->sender_addr, c->sender_addrmsk); + ebt_print_mac_and_mask(c->sender_addr, c->sender_addrmsk); else if (EBT_STP_PORT == (1 << i)) print_range(c->portl, c->portu); else if (EBT_STP_MSGAGE == (1 << i)) @@ -312,5 +308,5 @@ static struct ebt_u_match stp_match = static void _init(void) __attribute__ ((constructor)); static void _init(void) { - register_match(&stp_match); + ebt_register_match(&stp_match); } diff --git a/userspace/ebtables2/extensions/ebt_vlan.c b/userspace/ebtables2/extensions/ebt_vlan.c index 198f537..5a8a912 100644 --- a/userspace/ebtables2/extensions/ebt_vlan.c +++ b/userspace/ebtables2/extensions/ebt_vlan.c @@ -45,7 +45,7 @@ #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_INV_FLAG(_INDEX_) if (ebt_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" @@ -138,7 +138,7 @@ parse(int c, switch (c) { case VLAN_ID: - check_option(flags, OPT_VLAN_ID); + ebt_check_option(flags, OPT_VLAN_ID); CHECK_INV_FLAG(EBT_VLAN_ID); CHECK_IF_MISSING_VALUE; (unsigned short) local.id = @@ -149,7 +149,7 @@ parse(int c, break; case VLAN_PRIO: - check_option(flags, OPT_VLAN_PRIO); + ebt_check_option(flags, OPT_VLAN_PRIO); CHECK_INV_FLAG(EBT_VLAN_PRIO); CHECK_IF_MISSING_VALUE; (unsigned char) local.prio = @@ -160,7 +160,7 @@ parse(int c, break; case VLAN_ENCAP: - check_option(flags, OPT_VLAN_ENCAP); + ebt_check_option(flags, OPT_VLAN_ENCAP); CHECK_INV_FLAG(EBT_VLAN_ENCAP); CHECK_IF_MISSING_VALUE; (unsigned short) local.encap = @@ -321,5 +321,5 @@ static struct ebt_u_match vlan_match = { static void _init(void) __attribute__ ((constructor)); static void _init(void) { - register_match(&vlan_match); + ebt_register_match(&vlan_match); } diff --git a/userspace/ebtables2/extensions/ebtable_broute.c b/userspace/ebtables2/extensions/ebtable_broute.c index 155d9ce..362183a 100644 --- a/userspace/ebtables2/extensions/ebtable_broute.c +++ b/userspace/ebtables2/extensions/ebtable_broute.c @@ -2,7 +2,7 @@ #include "../include/ebtables_u.h" -static void print_help(char **hn) +static void print_help(const char **hn) { printf("Supported chain for the broute table:\n"); printf("%s\n",hn[NF_BR_BROUTING]); @@ -18,5 +18,5 @@ ebt_u_table table = static void _init(void) __attribute__ ((constructor)); static void _init(void) { - register_table(&table); + ebt_register_table(&table); } diff --git a/userspace/ebtables2/extensions/ebtable_filter.c b/userspace/ebtables2/extensions/ebtable_filter.c index 724198c..904a857 100644 --- a/userspace/ebtables2/extensions/ebtable_filter.c +++ b/userspace/ebtables2/extensions/ebtable_filter.c @@ -4,7 +4,7 @@ #define FILTER_VALID_HOOKS ((1 << NF_BR_LOCAL_IN) | (1 << NF_BR_FORWARD) | \ (1 << NF_BR_LOCAL_OUT)) -static void print_help(char **hn) +static void print_help(const char **hn) { int i; @@ -24,5 +24,5 @@ static struct ebt_u_table table = static void _init(void) __attribute__ ((constructor)); static void _init(void) { - register_table(&table); + ebt_register_table(&table); } diff --git a/userspace/ebtables2/extensions/ebtable_nat.c b/userspace/ebtables2/extensions/ebtable_nat.c index 7998e7d..b151dc5 100644 --- a/userspace/ebtables2/extensions/ebtable_nat.c +++ b/userspace/ebtables2/extensions/ebtable_nat.c @@ -4,7 +4,7 @@ #define NAT_VALID_HOOKS ((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT) | \ (1 << NF_BR_POST_ROUTING)) -static void print_help(char **hn) +static void print_help(const char **hn) { int i; @@ -25,5 +25,5 @@ ebt_u_table table = static void _init(void) __attribute__ ((constructor)); static void _init(void) { - register_table(&table); + ebt_register_table(&table); } diff --git a/userspace/ebtables2/include/ebtables_u.h b/userspace/ebtables2/include/ebtables_u.h index 914a0f9..77d1e50 100644 --- a/userspace/ebtables2/include/ebtables_u.h +++ b/userspace/ebtables2/include/ebtables_u.h @@ -30,6 +30,7 @@ #define EBT_MIN_ALIGN (__alignof__(struct ebt_entry_target)) #endif #define EBT_ALIGN(s) (((s) + (EBT_MIN_ALIGN-1)) & ~(EBT_MIN_ALIGN-1)) +#define ERRORMSG_MAXLEN 128 struct ebt_u_entries { @@ -51,6 +52,13 @@ struct ebt_u_chain_list char *kernel_start; }; +struct ebt_cntchanges; +struct ebt_cntchanges +{ + unsigned short type; + struct ebt_cntchanges *next; +}; + struct ebt_u_replace { char name[EBT_TABLE_MAXNAMELEN]; @@ -72,20 +80,20 @@ struct ebt_u_replace /* we stick the specified command (e.g. -A) in here */ char command; /* - * here we stick the hook to do our thing on (can be -1 if unspecified) + * here we stick the chain to do our thing on (can be -1 if unspecified) */ - int selected_hook; + int selected_chain; /* used for the atomic option */ char *filename; /* tells what happened to the old rules */ - unsigned short *counterchanges; + struct ebt_cntchanges *counterchanges; }; struct ebt_u_table { char name[EBT_TABLE_MAXNAMELEN]; void (*check)(struct ebt_u_replace *repl); - void (*help)(char **); + void (*help)(const char **); struct ebt_u_table *next; }; @@ -118,6 +126,8 @@ struct ebt_u_entry struct ebt_u_watcher_list *w_list; struct ebt_entry_target *t; struct ebt_u_entry *next; + /* needed f.e. to find out the name of the udc when listing -j */ + struct ebt_u_replace *replace; }; struct ebt_u_match @@ -147,6 +157,7 @@ struct ebt_u_match /* * if used == 1 we no longer have to add it to * the match chain of the new entry + * be sure to put it back on 0 when finished */ unsigned int used; struct ebt_u_match *next; @@ -200,60 +211,128 @@ struct ebt_u_target struct ebt_u_target *next; }; -void register_table(struct ebt_u_table *); -void register_match(struct ebt_u_match *); -void register_watcher(struct ebt_u_watcher *); -void register_target(struct ebt_u_target *t); -int get_table(struct ebt_u_replace *repl); -struct ebt_u_target *find_target(const char *name); -struct ebt_u_match *find_match(const char *name); -struct ebt_u_watcher *find_watcher(const char *name); -struct ebt_u_table *find_table(char *name); -void deliver_counters(struct ebt_u_replace *repl); -void deliver_table(struct ebt_u_replace *repl); -void check_option(unsigned int *flags, unsigned int mask); -int check_inverse(const char option[]); -void print_mac(const char *mac); -void print_mac_and_mask(const char *mac, const char *mask); +/* libebtc.c */ + +extern struct ebt_u_table *ebt_tables; +extern struct ebt_u_match *ebt_matches; +extern struct ebt_u_watcher *ebt_watchers; +extern struct ebt_u_target *ebt_targets; + +void ebt_register_table(struct ebt_u_table *); +void ebt_register_match(struct ebt_u_match *); +void ebt_register_watcher(struct ebt_u_watcher *); +void ebt_register_target(struct ebt_u_target *t); +void ebt_get_kernel_table(struct ebt_u_replace *replace, + struct ebt_u_table *table); +struct ebt_u_target *ebt_find_target(const char *name); +struct ebt_u_match *ebt_find_match(const char *name); +struct ebt_u_watcher *ebt_find_watcher(const char *name); +struct ebt_u_table *ebt_find_table(const char *name); int ebtables_insmod(const char *modname); +void ebt_list_extensions(); +void ebt_initialize_entry(struct ebt_u_entry *e); +void ebt_free_u_entry(struct ebt_u_entry *e); +struct ebt_u_entries *ebt_name_to_chain(const struct ebt_u_replace *replace, + const char* arg); +struct ebt_u_entries *ebt_nr_to_chain(const struct ebt_u_replace *replace, + int nr); +struct ebt_u_entries *ebt_to_chain(const struct ebt_u_replace *replace); +struct ebt_u_entries *ebt_name_to_chain(const struct ebt_u_replace *replace, + const char* arg); +int ebt_get_chainnr(const struct ebt_u_replace *replace, const char* arg); +/**/ +void ebt_change_policy(struct ebt_u_replace *replace, int policy); +void ebt_flush_chains(struct ebt_u_replace *replace); +int ebt_check_rule_exists(struct ebt_u_replace *replace, + struct ebt_u_entry *new_entry); +void ebt_add_rule(struct ebt_u_replace *replace, struct ebt_u_entry *new_entry, + int rule_nr); +void ebt_delete_rule(struct ebt_u_replace *replace, + struct ebt_u_entry *new_entry, int begin, int end); +void ebt_zero_counters(struct ebt_u_replace *replace); +void ebt_new_chain(struct ebt_u_replace *replace, const char *name, int policy); +void ebt_delete_chain(struct ebt_u_replace *replace); +void ebt_rename_chain(struct ebt_u_replace *replace, const char *name); +/**/ +void ebt_do_final_checks(struct ebt_u_replace *replace, struct ebt_u_entry *e, + struct ebt_u_entries *entries); +int ebt_check_for_references(struct ebt_u_replace *replace); +int ebt_check_for_references2(struct ebt_u_replace *replace, int chain_nr); +void ebt_check_for_loops(struct ebt_u_replace *replace); +void ebt_add_match(struct ebt_u_entry *new_entry, struct ebt_u_match *m); +void ebt_add_watcher(struct ebt_u_entry *new_entry, struct ebt_u_watcher *w); +void ebt_iterate_matches(void (*f)(struct ebt_u_match *)); +void ebt_iterate_watchers(void (*f)(struct ebt_u_watcher *)); +void ebt_iterate_targets(void (*f)(struct ebt_u_target *)); void __print_bug(char *file, int line, char *format, ...); +void __print_error(char *format, ...); + +/* communication.c */ + +int ebt_get_table(struct ebt_u_replace *repl); +void ebt_deliver_counters(struct ebt_u_replace *repl); +void ebt_deliver_table(struct ebt_u_replace *repl); + +/* useful_functions.c */ + +extern int ebt_invert; +void ebt_check_option(unsigned int *flags, unsigned int mask); +int ebt_check_inverse(const char option[]); +void ebt_print_mac(const char *mac); +void ebt_print_mac_and_mask(const char *mac, const char *mask); +int ebt_get_mac_and_mask(char *from, char *to, char *mask); +void ebt_parse_ip_address(char *address, uint32_t *addr, uint32_t *msk); +char *ebt_mask_to_dotted(uint32_t mask); + +struct ethertypeent *parseethertypebynumber(int type); + #define print_bug(format, args...) \ __print_bug(__FILE__, __LINE__, format, ##args) -#define print_error(format,args...) {printf(format,##args);\ - printf(".\n");exit(-1);} +#define print_error(format,args...) __print_error(format, ##args); #define print_memory() {printf("Ebtables: " __FILE__ \ " %s %d :Out of memory.\n", __FUNCTION__, __LINE__); exit(-1);} /* used for keeping the rule counters right during rule adds or deletes */ -#define CNT_NORM 0 -#define CNT_DEL 1 -#define CNT_ADD 2 -#define CNT_END 3 -#define CNT_ZERO 4 +#define CNT_NORM 0 +#define CNT_DEL 1 +#define CNT_ADD 2 +#define CNT_OWRITE 3 +#define CNT_ZERO 4 + +extern const char *ebt_hooknames[NF_BR_NUMHOOKS]; +extern const char *ebt_standard_targets[NUM_STANDARD_TARGETS]; +extern char ebt_errormsg[ERRORMSG_MAXLEN]; +extern char *ebt_modprobe; +extern int ebt_silent; +extern int ebt_printstyle_mac; -extern char *standard_targets[NUM_STANDARD_TARGETS]; /* * Transforms a target string into the right integer, * returns 0 on success. */ -#define FILL_TARGET(_str, _pos) ({ \ - int _i, _ret = 0; \ - for (_i = 0; _i < NUM_STANDARD_TARGETS; _i++) \ - if (!strcmp(_str, standard_targets[_i])) {\ - _pos = -_i - 1; \ - break; \ - } \ - if (_i == NUM_STANDARD_TARGETS) \ - _ret = 1; \ - _ret; \ +#define FILL_TARGET(_str, _pos) ({ \ + int _i, _ret = 0; \ + for (_i = 0; _i < NUM_STANDARD_TARGETS; _i++) \ + if (!strcmp(_str, ebt_standard_targets[_i])) {\ + _pos = -_i - 1; \ + break; \ + } \ + if (_i == NUM_STANDARD_TARGETS) \ + _ret = 1; \ + _ret; \ }) /* Transforms the target value to an index into standard_targets[] */ #define TARGET_INDEX(_value) (-_value - 1) /* Returns a target string corresponding to the value */ -#define TARGET_NAME(_value) (standard_targets[TARGET_INDEX(_value)]) +#define TARGET_NAME(_value) (ebt_standard_targets[TARGET_INDEX(_value)]) /* True if the hook mask denotes that the rule is in a base chain */ #define BASE_CHAIN (hookmask & (1 << NF_BR_NUMHOOKS)) /* Clear the bit in the hook_mask that tells if the rule is on a base chain */ #define CLEAR_BASE_CHAIN_BIT (hookmask &= ~(1 << NF_BR_NUMHOOKS)) +#define PRINT_VERSION printf(PROGNAME" v"PROGVERSION" ("PROGDATE")\n") +#ifndef PROC_SYS_MODPROBE +#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe" +#endif +#define ATOMIC_ENV_VARIABLE "EBTABLES_ATOMIC_FILE" #endif /* EBTABLES_U_H */ -- cgit v1.2.3