add shared libraries
authorBart De Schuymer <bdschuym@pandora.be>
Wed, 21 Jan 2004 20:39:54 +0000 (20:39 +0000)
committerBart De Schuymer <bdschuym@pandora.be>
Wed, 21 Jan 2004 20:39:54 +0000 (20:39 +0000)
26 files changed:
Makefile
communication.c
ebtables.8
ebtables.c
extensions/Makefile
extensions/ebt_802_3.c
extensions/ebt_among.c
extensions/ebt_arp.c
extensions/ebt_arpreply.c
extensions/ebt_ip.c
extensions/ebt_limit.c
extensions/ebt_log.c
extensions/ebt_mark.c
extensions/ebt_mark_m.c
extensions/ebt_nat.c
extensions/ebt_pkttype.c
extensions/ebt_redirect.c
extensions/ebt_standard.c
extensions/ebt_stp.c
extensions/ebt_vlan.c
extensions/ebtable_broute.c
extensions/ebtable_filter.c
extensions/ebtable_nat.c
include/ebtables_u.h
libebtc.c
useful_functions.c

index 3c3229f..dc86a8f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,12 +1,14 @@
 # ebtables Makefile
 
 PROGNAME:=ebtables
-PROGVERSION:=2.0.5
-PROGDATE:=July\ 2003
+PROGVERSION:=2.0.7
+PROGDATE:=January\ 2004
 
+LIBDIR?=/usr/lib/
 MANDIR?=$(DESTDIR)/usr/local/man
 CFLAGS:=-Wall -Wunused
 CC:=gcc
+LD:=ld
 
 ifeq ($(shell uname -m),sparc64)
 CFLAGS+=-DEBT_MIN_ALIGN=8 -DKERNEL_64_USERSPACE_32
@@ -14,8 +16,10 @@ endif
 
 include extensions/Makefile
 
-OBJECTS:=getethertype.o ebtables.o communication.o libebtc.o \
-useful_functions.o $(EXT_OBJS)
+OBJECTS2:=getethertype.o communication.o libebtc.o \
+useful_functions.o
+
+OBJECTS:=$(OBJECTS2) ebtables.o $(EXT_OBJS) $(EXT_LIBS)
 
 KERNEL_INCLUDES?=include/
 
@@ -49,7 +53,10 @@ ebtables.o: ebtables.c include/ebtables_u.h
        $(CC) $(CFLAGS) $(PROGSPECS) -c -o $@ $< -I$(KERNEL_INCLUDES)
 
 ebtables: $(OBJECTS)
-       $(CC) $(CFLAGS) -o $@ $^ -I$(KERNEL_INCLUDES)
+       ld -shared -soname libebtc.so -o libebtc.so -lc $(OBJECTS2)
+       $(CC) $(CFLAGS) -o $@ ebtables.o -I$(KERNEL_INCLUDES) -L/root/ \
+       -L. -Lextensions/ -lebtc $(EXT_LIBSI)
+       
 
 $(MANDIR)/man8/ebtables.8: ebtables.8
        mkdir -p $(@D)
@@ -65,12 +72,14 @@ exec: ebtables
 
 .PHONY: install
 install: $(MANDIR)/man8/ebtables.8 $(ETHERTYPESFILE) exec
+       install -m 0755 extensions/*.so $(LIBDIR)
+       install -m 0755 *.so $(LIBDIR)
 
 .PHONY: clean
 clean:
        rm -f ebtables
-       rm -f *.o *.c~
-       rm -f extensions/*.o extensions/*.c~
+       rm -f *.o *.c~ *.so
+       rm -f extensions/*.o extensions/*.c~ extensions/*.so
 
 DIR:=$(PROGNAME)-v$(PROGVERSION)
 # This is used to make a new userspace release
index 7f8c531..af00fa2 100644 (file)
@@ -36,9 +36,9 @@ static void get_sockfd()
        if (sockfd == -1) {
                sockfd = socket(AF_INET, SOCK_RAW, PF_INET);
                if (sockfd < 0)
-                       print_error("Problem getting a socket, "
-                          "you probably don't have the right "
-                          "permissions");
+                       ebt_print_error("Problem getting a socket, "
+                                       "you probably don't have the right "
+                                       "permissions");
        }
 }
 
@@ -56,7 +56,7 @@ static struct ebt_replace * translate_user2kernel(struct ebt_u_replace *u_repl)
 
        new = (struct ebt_replace *)malloc(sizeof(struct ebt_replace));
        if (!new)
-               print_memory();
+               ebt_print_memory();
        new->valid_hooks = u_repl->valid_hooks;
        strcpy(new->name, u_repl->name);
        new->nentries = u_repl->nentries;
@@ -111,7 +111,7 @@ static struct ebt_replace * translate_user2kernel(struct ebt_u_replace *u_repl)
                }
                /* a little sanity check */
                if (j != entries->nentries)
-                       print_bug("Wrong nentries: %d != %d, hook = %s", j,
+                       ebt_print_bug("Wrong nentries: %d != %d, hook = %s", j,
                           entries->nentries, entries->name);
                if (i >= NF_BR_NUMHOOKS)
                        cl = cl->next;
@@ -121,7 +121,7 @@ static struct ebt_replace * translate_user2kernel(struct ebt_u_replace *u_repl)
        new->entries_size = entries_size;
        p = (char *)malloc(entries_size);
        if (!p)
-               print_memory();
+               ebt_print_memory();
 
        /* put everything in one block */
        new->entries = sparc_cast p;
@@ -209,7 +209,7 @@ static struct ebt_replace * translate_user2kernel(struct ebt_u_replace *u_repl)
 
        /* sanity check */
        if (p - (char *)new->entries != new->entries_size)
-               print_bug("Entries_size bug");
+               ebt_print_bug("Entries_size bug");
        free(chain_offsets);
        return new;
 }
@@ -223,22 +223,22 @@ static void store_table_in_file(char *filename, struct ebt_replace *repl)
        /* start from an empty file with right priviliges */
        command = (char *)malloc(strlen(filename) + 15);
        if (!command)
-               print_memory();
+               ebt_print_memory();
        strcpy(command, "cat /dev/null>");
        strcpy(command + 14, filename);
        if (system(command))
-               print_error("Couldn't create file %s", filename);
+               ebt_print_error("Couldn't create file %s", filename);
        strcpy(command, "chmod 600 ");
        strcpy(command + 10, filename);
        if (system(command))
-               print_error("Couldn't chmod file %s", filename);
+               ebt_print_error("Couldn't chmod file %s", filename);
        free(command);
 
        size = sizeof(struct ebt_replace) + repl->entries_size +
           repl->nentries * sizeof(struct ebt_counter);
        data = (char *)malloc(size);
        if (!data)
-               print_memory();
+               ebt_print_memory();
        memcpy(data, repl, sizeof(struct ebt_replace));
        memcpy(data + sizeof(struct ebt_replace), (char *)repl->entries,
           repl->entries_size);
@@ -246,10 +246,11 @@ static void store_table_in_file(char *filename, struct ebt_replace *repl)
        memset(data + sizeof(struct ebt_replace) + repl->entries_size,
           0, repl->nentries * sizeof(struct ebt_counter));
        if (!(file = fopen(filename, "wb")))
-               print_error("Couldn't open file %s", filename);
+               ebt_print_error("Couldn't open file %s", filename);
        if (fwrite(data, sizeof(char), size, file) != size) {
                fclose(file);
-               print_error("Couldn't write everything to file %s", filename);
+               ebt_print_error("Couldn't write everything to file %s",
+                               filename);
        }
        fclose(file);
        free(data);
@@ -279,7 +280,7 @@ void ebt_deliver_table(struct ebt_u_replace *u_repl)
                        return;
        }
 
-       print_error("The kernel doesn't support a certain ebtables"
+       ebt_print_error("The kernel doesn't support a certain ebtables"
                    " extension, consider recompiling your kernel or insmod"
                    " the extension");
 }
@@ -292,7 +293,7 @@ static void store_counters_in_file(char *filename, struct ebt_u_replace *repl)
        FILE *file;
 
        if (!(file = fopen(filename, "r+b")))
-               print_error("Could not open file %s", filename);
+               ebt_print_error("Could not open file %s", filename);
        /* 
         * find out entries_size and then set the file pointer to the
         * counters
@@ -302,11 +303,12 @@ static void store_counters_in_file(char *filename, struct ebt_u_replace *repl)
           sizeof(unsigned int) ||
           fseek(file, entries_size + sizeof(struct ebt_replace), SEEK_SET)) {
                fclose(file);
-               print_error("File %s is corrupt", filename);
+               ebt_print_error("File %s is corrupt", filename);
        }
        if (fwrite(repl->counters, sizeof(char), size, file) != size) {
                fclose(file);
-               print_error("Could not write everything to file %s", filename);
+               ebt_print_error("Could not write everything to file %s",
+                               filename);
        }
        fclose(file);
 }
@@ -325,7 +327,7 @@ void ebt_deliver_counters(struct ebt_u_replace *u_repl)
        newcounters = (struct ebt_counter *)
           malloc(u_repl->nentries * sizeof(struct ebt_counter));
        if (!newcounters)
-               print_memory();
+               ebt_print_memory();
        memset(newcounters, 0, u_repl->nentries * sizeof(struct ebt_counter));
        old = u_repl->counters;
        new = newcounters;
@@ -371,7 +373,7 @@ void ebt_deliver_counters(struct ebt_u_replace *u_repl)
 
        get_sockfd();
        if (setsockopt(sockfd, IPPROTO_IP, EBT_SO_SET_COUNTERS, &repl, optlen))
-               print_bug("Couldn't update kernel counters");
+               ebt_print_bug("Couldn't update kernel counters");
 }
 
 static int
@@ -382,18 +384,18 @@ ebt_translate_match(struct ebt_entry_match *m, struct ebt_u_match_list ***l)
        new = (struct ebt_u_match_list *)
           malloc(sizeof(struct ebt_u_match_list));
        if (!new)
-               print_memory();
+               ebt_print_memory();
        new->m = (struct ebt_entry_match *)
           malloc(m->match_size + sizeof(struct ebt_entry_match));
        if (!new->m)
-               print_memory();
+               ebt_print_memory();
        memcpy(new->m, m, m->match_size + sizeof(struct ebt_entry_match));
        new->next = NULL;
        **l = new;
        *l = &new->next;
        if (ebt_find_match(new->m->u.name) == NULL)
-               print_error("Kernel match %s unsupported by userspace tool",
-                  new->m->u.name);
+               ebt_print_error("Kernel match %s unsupported by userspace tool",
+                               new->m->u.name);
        return 0;
 }
 
@@ -406,18 +408,18 @@ ebt_translate_watcher(struct ebt_entry_watcher *w,
        new = (struct ebt_u_watcher_list *)
           malloc(sizeof(struct ebt_u_watcher_list));
        if (!new)
-               print_memory();
+               ebt_print_memory();
        new->w = (struct ebt_entry_watcher *)
           malloc(w->watcher_size + sizeof(struct ebt_entry_watcher));
        if (!new->w)
-               print_memory();
+               ebt_print_memory();
        memcpy(new->w, w, w->watcher_size + sizeof(struct ebt_entry_watcher));
        new->next = NULL;
        **l = new;
        *l = &new->next;
        if (ebt_find_watcher(new->w->u.name) == NULL)
-               print_error("Kernel watcher %s unsupported by userspace tool",
-                  new->w->u.name);
+               ebt_print_error("Kernel watcher %s unsupported by userspace "
+                               "tool", new->w->u.name);
        return 0;
 }
 
@@ -435,7 +437,7 @@ ebt_translate_entry(struct ebt_entry *e, unsigned int *hook, int *n, int *cnt,
 
                new = (struct ebt_u_entry *)malloc(sizeof(struct ebt_u_entry));
                if (!new)
-                       print_memory();
+                       ebt_print_memory();
                new->bitmask = e->bitmask;
                /*
                 * plain userspace code doesn't know about
@@ -464,10 +466,10 @@ ebt_translate_entry(struct ebt_entry *e, unsigned int *hook, int *n, int *cnt,
                new->t = (struct ebt_entry_target *)
                   malloc(t->target_size + sizeof(struct ebt_entry_target));
                if (!new->t)
-                       print_memory();
+                       ebt_print_memory();
                if (ebt_find_target(t->u.name) == NULL)
-                       print_error("Kernel target %s unsupported by "
-                                   "userspace tool", t->u.name);
+                       ebt_print_error("Kernel target %s unsupported by "
+                                       "userspace tool", t->u.name);
                memcpy(new->t, t, t->target_size +
                   sizeof(struct ebt_entry_target));
                /* deal with jumps to udc */
@@ -486,7 +488,8 @@ ebt_translate_entry(struct ebt_entry *e, unsigned int *hook, int *n, int *cnt,
                                        cl = cl->next;
                                }
                                if (!cl)
-                                       print_bug("can't find udc for jump");
+                                       ebt_print_bug("can't find udc for "
+                                                     "jump");
                                ((struct ebt_standard_target *)new->t)->verdict = i;
                        }
                }
@@ -503,7 +506,7 @@ ebt_translate_entry(struct ebt_entry *e, unsigned int *hook, int *n, int *cnt,
                struct ebt_u_chain_list *cl;
 
                if (*n != *cnt)
-                       print_bug("Nr of entries in the chain is wrong");
+                       ebt_print_bug("Nr of entries in the chain is wrong");
                *n = entries->nentries;
                *cnt = 0;
                for (i = *hook + 1; i < NF_BR_NUMHOOKS; i++)
@@ -546,12 +549,12 @@ ebt_translate_chains(struct ebt_entry *e, unsigned int *hook,
                        *chain_list = (struct ebt_u_chain_list *)
                           malloc(sizeof(struct ebt_u_chain_list));
                        if (!(*chain_list))
-                               print_memory();
+                               ebt_print_memory();
                        (*chain_list)->next = NULL;
                        (*chain_list)->udc = (struct ebt_u_entries *)
                           malloc(sizeof(struct ebt_u_entries));
                        if (!((*chain_list)->udc))
-                               print_memory();
+                               ebt_print_memory();
                        new = (*chain_list)->udc;
                        /*
                         * ebt_translate_entry depends on this for knowing
@@ -563,7 +566,7 @@ ebt_translate_chains(struct ebt_entry *e, unsigned int *hook,
                        new = (struct ebt_u_entries *)
                           malloc(sizeof(struct ebt_u_entries));
                        if (!new)
-                               print_memory();
+                               ebt_print_memory();
                        u_repl->hook_entry[*hook] = new;
                }
                new->nentries = entries->nentries;
@@ -584,27 +587,28 @@ static void retrieve_from_file(char *filename, struct ebt_replace *repl,
        int size;
 
        if (!(file = fopen(filename, "r+b")))
-               print_error("Could not open file %s", filename);
+               ebt_print_error("Could not open file %s", filename);
        /*
         * make sure table name is right if command isn't -L or --atomic-commit
         */
        if (command != 'L' && command != 8) {
                hlp = (char *)malloc(strlen(repl->name) + 1);
                if (!hlp)
-                       print_memory();
+                       ebt_print_memory();
                strcpy(hlp, repl->name);
        }
        if (fread(repl, sizeof(char), sizeof(struct ebt_replace), file)
           != sizeof(struct ebt_replace))
-               print_error("File %s is corrupt", filename);
+               ebt_print_error("File %s is corrupt", filename);
        if (command != 'L' && command != 8 && strcmp(hlp, repl->name)) {
                fclose(file);
-               print_error("File %s contains wrong table name or is corrupt",
-                  filename);
+               ebt_print_error("File %s contains wrong table name or is "
+                               "corrupt", filename);
                free(hlp);
        } else if (!ebt_find_table(repl->name)) {
                fclose(file);
-               print_error("File %s contains invalid table name", filename);
+               ebt_print_error("File %s contains invalid table name",
+                               filename);
        }
 
        size = sizeof(struct ebt_replace) +
@@ -612,35 +616,37 @@ static void retrieve_from_file(char *filename, struct ebt_replace *repl,
        fseek(file, 0, SEEK_END);
        if (size != ftell(file)) {
                fclose(file);
-               print_error("File %s has wrong size", filename);
+               ebt_print_error("File %s has wrong size", filename);
        }
        entries = (char *)malloc(repl->entries_size);
        if (!entries)
-               print_memory();
+               ebt_print_memory();
        repl->entries = sparc_cast entries;
        if (repl->nentries) {
                counters = (struct ebt_counter *)
                   malloc(repl->nentries * sizeof(struct ebt_counter));
                repl->counters = sparc_cast counters;
                if (!repl->counters)
-                       print_memory();
+                       ebt_print_memory();
        } else
                repl->counters = sparc_cast NULL;
        /* copy entries and counters */
        if (fseek(file, sizeof(struct ebt_replace), SEEK_SET) ||
           fread((char *)repl->entries, sizeof(char), repl->entries_size, file)
           != repl->entries_size ||
-          fseek(file, sizeof(struct ebt_replace) + repl->entries_size, SEEK_SET)
+          fseek(file, sizeof(struct ebt_replace) + repl->entries_size,
+                SEEK_SET)
           || fread((char *)repl->counters, sizeof(char),
           repl->nentries * sizeof(struct ebt_counter), file)
           != repl->nentries * sizeof(struct ebt_counter)) {
                fclose(file);
-               print_error("File %s is corrupt", filename);
+               ebt_print_error("File %s is corrupt", filename);
        }
        fclose(file);
 }
 
-static int retrieve_from_kernel(struct ebt_replace *repl, char command)
+static int retrieve_from_kernel(struct ebt_replace *repl, char command,
+                               int init)
 {
        socklen_t optlen;
        int optname;
@@ -649,7 +655,7 @@ static int retrieve_from_kernel(struct ebt_replace *repl, char command)
        optlen = sizeof(struct ebt_replace);
        get_sockfd();
        /* --atomic-init || --init-table */
-       if (command == 7 || command == 11)
+       if (init)
                optname = EBT_SO_GET_INIT_INFO;
        else
                optname = EBT_SO_GET_INFO;
@@ -657,14 +663,14 @@ static int retrieve_from_kernel(struct ebt_replace *repl, char command)
                return -1;
 
        if ( !(entries = (char *)malloc(repl->entries_size)) )
-               print_memory();
+               ebt_print_memory();
        repl->entries = sparc_cast entries;
        if (repl->nentries) {
                struct ebt_counter *counters;
 
                if (!(counters = (struct ebt_counter *)
                   malloc(repl->nentries * sizeof(struct ebt_counter))) )
-                       print_memory();
+                       ebt_print_memory();
                repl->counters = sparc_cast counters;
        }
        else
@@ -674,17 +680,17 @@ static int retrieve_from_kernel(struct ebt_replace *repl, char command)
        repl->num_counters = repl->nentries;
        optlen += repl->entries_size + repl->num_counters *
           sizeof(struct ebt_counter);
-       if (command == 7 || command == 11)
+       if (init)
                optname = EBT_SO_GET_INIT_ENTRIES;
        else
                optname = EBT_SO_GET_ENTRIES;
        if (getsockopt(sockfd, IPPROTO_IP, optname, repl, &optlen))
-               print_bug("hmm, what is wrong??? bug#1");
+               ebt_print_bug("hmm, what is wrong??? bug#1");
 
        return 0;
 }
 
-int ebt_get_table(struct ebt_u_replace *u_repl)
+int ebt_get_table(struct ebt_u_replace *u_repl, int init)
 {
        int i, j, k, hook;
        struct ebt_replace repl;
@@ -694,12 +700,15 @@ int ebt_get_table(struct ebt_u_replace *u_repl)
 
        strcpy(repl.name, u_repl->name);
        if (u_repl->filename != NULL) {
+               if (init)
+                       ebt_print_bug("getting initial table data from a "
+                                 "file is impossible");
                retrieve_from_file(u_repl->filename, &repl, u_repl->command);
                /*
                 * -L with a wrong table name should be dealt with silently
                 */
                strcpy(u_repl->name, repl.name);
-       } else if (retrieve_from_kernel(&repl, u_repl->command) == -1)
+       } else if (retrieve_from_kernel(&repl, u_repl->command, init) == -1)
                return -1;
 
        /* translate the struct ebt_replace to a struct ebt_u_replace */
@@ -713,7 +722,7 @@ int ebt_get_table(struct ebt_u_replace *u_repl)
                new_cc = (struct ebt_cntchanges *)
                         malloc(sizeof(struct ebt_cntchanges));
                if (!new_cc)
-                       print_memory();
+                       ebt_print_memory();
                new_cc->type = CNT_NORM;
                new_cc->next = NULL;
                *prev_cc = new_cc;
@@ -730,9 +739,10 @@ int ebt_get_table(struct ebt_u_replace *u_repl)
         */
        k = 0;
        hook = -1;
-       EBT_ENTRY_ITERATE((char *)repl.entries, repl.entries_size, ebt_translate_entry,
-          &hook, &i, &j, &k, &u_e, u_repl, u_repl->valid_hooks, (char *)repl.entries);
+       EBT_ENTRY_ITERATE((char *)repl.entries, repl.entries_size,
+          ebt_translate_entry, &hook, &i, &j, &k, &u_e, u_repl,
+          u_repl->valid_hooks, (char *)repl.entries);
        if (k != u_repl->nentries)
-               print_bug("Wrong total nentries");
+               ebt_print_bug("Wrong total nentries");
        return 0;
 }
index 7ddddb9..41829b5 100644 (file)
@@ -1,6 +1,6 @@
-.TH EBTABLES 8  "09 November 2003"
+.TH EBTABLES 8  "18 January 2004"
 .\"
-.\" Man page written and maintained by Bart De Schuymer <bdschuym@pandora.be>
+.\" Man page written by Bart De Schuymer <bdschuym@pandora.be>
 .\" It is based on the iptables man page.
 .\"
 .\" The man page was edited, February 25th 2003, by 
@@ -36,7 +36,7 @@ ebtables (v.2.0) \- Ethernet bridge frame table administration
 .br
 .BR "ebtables " [ "-t table" ] " -L " [ -Z "] [" " chain" "] [ [ [" --Ln "] [" --Lc "] ] | [" --Lx "] ] [" --Lmac2 "]"
 .br
-.BR "ebtables " [ "-t table" ] " -N chain"
+.BR "ebtables " [ "-t table" ] " -N chain " [ "-P ACCEPT " | " DROP " | " RETURN" ]
 .br
 .BR "ebtables " [ "-t table" ] " -X " [ chain ]
 .br
@@ -266,7 +266,12 @@ option.
 .B "-N, --new-chain"
 Create a new user-defined chain with the given name. The number of
 user-defined chains is unlimited. A user-defined chain name has maximum
-length of 31 characters.
+length of 31 characters. The standard policy of the user-defined chain is
+ACCEPT. You can initialize the new chain with another policy by using the
+.B -P
+option. Unlike the
+.B -P
+command, you only need to specify the policy, not the chain name.
 .TP
 .B "-X, --delete-chain"
 Delete the specified user-defined chain. There must be no remaining references
@@ -491,28 +496,6 @@ If the 802.3 DSAP and SSAP values are 0xaa then the SNAP type field must
 be consulted to determine the payload protocol.  This is a two byte
 (hexadecimal) argument.  Only 802.3 frames with DSAP/SSAP 0xaa are
 checked for type.
-.SS among
-Match a MAC address or MAC/IP address pair versus a list of MAC addresses
-and MAC/IP address pairs.
-A list entry has the following format: xx:xx:xx:xx:xx:xx[=ip.ip.ip.ip][,]. Multiple
-list entries are separated by a comma, specifying an IP address corresponding to
-the MAC address is optional. Multiple MAC/IP address pairs with the same MAC address
-but different IP address (and vice versa) can be specified. If the MAC address doesn't
-match any entry from the list, the frame doesn't match the rule (unless '!' was used).
-.TP
-.BR "--among-dst " "[!] \fIlist\fP"
-Compare the MAC destination to the given list. If the Ethernet frame has type
-.BR IPv4 " or " ARP ,
-then comparison with MAC/IP destination address pairs from the
-list is possible.
-
-.TP
-.BR "--among-src " "[!] \fIlist\fP"
-Compare the MAC source to the given list. If the Ethernet frame has type
-.BR IPv4 " or " ARP ,
-then comparison with MAC/IP source address pairs from the list
-is possible.
-
 .SS arp
 Specify arp fields. The protocol must be specified as
 .BR ARP " or " RARP .
@@ -578,22 +561,6 @@ The destination port or port range for ip protocols 6 (TCP) and
 17 (UDP). The flag
 .B --ip-dport
 is an alias for this option.
-.SS limit
-Matches at a limited rate using a token bucket filter. A rule using
-this extension will match until this limit is reached (unless the '!'
-flag is used). It can be used in combination with the log watcher to
-give limited logging, for example. The usage/implementation is completely
-similar to that of the iptables limit match.
-.TP
-.BR --limit " \fIrate"
-Maximum average matching rate: specified as a number, with an optional
-'/second', '/minute', '/hour', or '/day' suffix; the default is 3/hour.
-.TP
-.BR --limit-burst " \fInumber"
-Maximum initial number of packets to match: this number gets recharged by
-one every time the limit specified above is not reached, up to this number;
-the default is 5.
-
 .SS mark_m
 .TP
 .BR "--mark " "[!] [\fIvalue\fP][/\fImask\fP]"
index dfe4b81..58dad06 100644 (file)
@@ -114,7 +114,7 @@ merge_options(struct option *oldopts, const struct option *newopts,
        struct option *merge;
 
        if (!newopts || !oldopts || !options_offset)
-               print_bug("merge wrong");
+               ebt_print_bug("merge wrong");
        for (num_old = 0; oldopts[num_old].name; num_old++);
        for (num_new = 0; newopts[num_new].name; num_new++);
 
@@ -123,7 +123,7 @@ merge_options(struct option *oldopts, const struct option *newopts,
 
        merge = malloc(sizeof(struct option) * (num_new + num_old + 1));
        if (!merge)
-               print_memory();
+               ebt_print_memory();
        memcpy(merge, oldopts, num_old * sizeof(struct option));
        for (i = 0; i < num_new; i++) {
                merge[num_old + i] = newopts[i];
@@ -225,7 +225,8 @@ static void list_em(struct ebt_u_entries *entries)
                        else {
                                struct ethertypeent *ent;
 
-                               ent = getethertypebynumber(ntohs(hlp->ethproto));
+                               ent = getethertypebynumber
+                                     (ntohs(hlp->ethproto));
                                if (!ent)
                                        printf("0x%x ", ntohs(hlp->ethproto));
                                else
@@ -275,7 +276,7 @@ static void list_em(struct ebt_u_entries *entries)
                while (m_l) {
                        m = ebt_find_match(m_l->m->u.name);
                        if (!m)
-                               print_bug("Match not found");
+                               ebt_print_bug("Match not found");
                        m->print(hlp, m_l->m);
                        m_l = m_l->next;
                }
@@ -283,7 +284,7 @@ static void list_em(struct ebt_u_entries *entries)
                while (w_l) {
                        w = ebt_find_watcher(w_l->w->u.name);
                        if (!w)
-                               print_bug("Watcher not found");
+                               ebt_print_bug("Watcher not found");
                        w->print(hlp, w_l->w);
                        w_l = w_l->next;
                }
@@ -293,7 +294,7 @@ static void list_em(struct ebt_u_entries *entries)
                        printf("%s ", hlp->t->u.name);
                t = ebt_find_target(hlp->t->u.name);
                if (!t)
-                       print_bug("Target not found");
+                       ebt_print_bug("Target not found");
                t->print(hlp, hlp->t);
                if (replace.flags & LIST_C)
                        printf(", pcnt = %llu -- bcnt = %llu",
@@ -347,7 +348,6 @@ static void print_help()
 "Environment variable:\n"
 ATOMIC_ENV_VARIABLE "          : if set <FILE> (see above) will equal its value"
 "\n\n");
-
        m_l = new_entry->m_list;
        while (m_l) {
                ((struct ebt_u_match *)m_l->m)->help();
@@ -442,19 +442,21 @@ static int parse_delete_rule(const char *argv, int *rule_nr, int *rule_nr_end)
        return 0;
 }
 
-#define print_if_l_error print_error("Interface name length must be less " \
+#define print_if_l_error ebt_print_error("Interface name length must be less " \
    "than %d", IFNAMSIZ)
-#define OPT_COMMAND    0x01
-#define OPT_TABLE      0x02
-#define OPT_IN         0x04
-#define OPT_OUT        0x08
-#define OPT_JUMP       0x10
-#define OPT_PROTOCOL   0x20
-#define OPT_SOURCE     0x40
-#define OPT_DEST       0x80
-#define OPT_ZERO       0x100
-#define OPT_LOGICALIN  0x200
-#define OPT_LOGICALOUT 0x400
+#define OPT_COMMAND    0x01
+#define OPT_TABLE      0x02
+#define OPT_IN         0x04
+#define OPT_OUT                0x08
+#define OPT_JUMP       0x10
+#define OPT_PROTOCOL   0x20
+#define OPT_SOURCE     0x40
+#define OPT_DEST       0x80
+#define OPT_ZERO       0x100
+#define OPT_LOGICALIN  0x200
+#define OPT_LOGICALOUT 0x400
+#define OPT_KERNELDATA 0x800 /* if set, we already have loaded the table
+                              * in userspace */
 /* the main thing */
 int main(int argc, char *argv[])
 {
@@ -480,7 +482,14 @@ int main(int argc, char *argv[])
        ebt_iterate_watchers(merge_watcher);
        ebt_iterate_targets(merge_target);
 
-       replace.filename = getenv(ATOMIC_ENV_VARIABLE);
+       buffer = getenv(ATOMIC_ENV_VARIABLE);
+       if (buffer) {
+               replace.filename = malloc(strlen(buffer)+1);
+               if (!replace.filename)
+                       ebt_print_memory();
+               memcpy(replace.filename, buffer, strlen(buffer)+1);
+               buffer = NULL;
+       }
        /*
         * initialize the table name, OPT_ flags, selected hook and command
         */
@@ -492,7 +501,7 @@ int main(int argc, char *argv[])
 
        new_entry = (struct ebt_u_entry *)malloc(sizeof(struct ebt_u_entry));
        if (!new_entry)
-               print_memory();
+               ebt_print_memory();
        /*
         * put some sane values in our new entry
         */
@@ -519,16 +528,26 @@ int main(int argc, char *argv[])
                case 'N': /* make a user defined chain */
                case 'E': /* rename chain */
                case 'X': /* delete chain */
+                       /* We allow -N chainname -P policy */
+                       if (replace.command == 'N' && c == 'P') {
+                               replace.command = c;
+                               optind--;
+                               goto handle_P;
+                       }
                        replace.command = c;
-                       if (replace.flags & OPT_COMMAND)
-                               print_error("Multiple commands not allowed");
                        replace.flags |= OPT_COMMAND;
-                       ebt_get_kernel_table(&replace, table);
+                       if (!(replace.flags & OPT_KERNELDATA)) {
+                               ebt_get_kernel_table(&replace, table, 0);
+                               replace.flags |= OPT_KERNELDATA;
+                       }
                        if (optarg && (optarg[0] == '-' ||
                            !strcmp(optarg, "!")))
-                               print_error("No chain name specified");
+                               ebt_print_error("No chain name specified");
                        if (c == 'N') {
                                ebt_new_chain(&replace, optarg, EBT_ACCEPT);
+                               /* This is needed to get -N x -P y working */
+                               replace.selected_chain =
+                               ebt_get_chainnr(&replace, optarg);
                                break;
                        }
                        if (c == 'X') {
@@ -549,27 +568,32 @@ int main(int argc, char *argv[])
                                }
                                if ((replace.selected_chain =
                                     ebt_get_chainnr(&replace, opt)) == -1)
-                                       print_error("Chain %s doesn't exist", optarg);
+                                       ebt_print_error("Chain %s doesn't "
+                                                       "exist", optarg);
                                ebt_delete_chain(&replace);
                                break;
                        }
 
                        if ((replace.selected_chain =
                            ebt_get_chainnr(&replace, optarg)) == -1)
-                               print_error("Chain %s doesn't exist", optarg);
+                               ebt_print_error("Chain %s doesn't exist",
+                                               optarg);
                        if (c == 'E') {
                                if (optind >= argc || argv[optind][0] == '-' ||
                                   !strcmp(argv[optind], "!"))
-                                       print_error("No new chain name specified");
-                               if (strlen(argv[optind]) >= EBT_CHAIN_MAXNAMELEN)
-                                       print_error("Chain name len can't exceed %d",
-                                          EBT_CHAIN_MAXNAMELEN - 1);
-                               if (ebt_get_chainnr(&replace, argv[optind]) != -1)
-                                       print_error("Chain %s already exists",
-                                          argv[optind]);
+                                       ebt_print_error("No new chain name "
+                                                   "specified");
+                               if (strlen(argv[optind])>=EBT_CHAIN_MAXNAMELEN)
+                                       ebt_print_error("Chain name len can't "
+                                                   "exceed %d",
+                                                   EBT_CHAIN_MAXNAMELEN - 1);
+                               if (ebt_get_chainnr(&replace, argv[optind]) !=
+                                   -1)
+                                       ebt_print_error("Chain %s already "
+                                                       "exists", argv[optind]);
                                if (ebt_find_target(argv[optind]))
-                                       print_error("Target with name %s exists"
-                                          , argv[optind]);
+                                       ebt_print_error("Target with name %s "
+                                                       "exists", argv[optind]);
                                ebt_rename_chain(&replace, argv[optind]);
                                optind++;
                                break;
@@ -577,27 +601,31 @@ int main(int argc, char *argv[])
 
                        if (c == 'D' && optind < argc &&
                            (argv[optind][0] != '-' ||
-                           (argv[optind][1] >= '0' && argv[optind][1] <= '9'))) {
+                           (argv[optind][1] >= '0' &&
+                            argv[optind][1] <= '9'))) {
                                if (parse_delete_rule(argv[optind],
                                    &rule_nr, &rule_nr_end))
-                                       print_error("Problem with the "
+                                       ebt_print_error("Problem with the "
                                                    "specified rule number(s)");
                                optind++;
                        }
                        if (c == 'I') {
-                               if (optind >= argc || (argv[optind][0] == '-' &&
-                                   (argv[optind][1] < '0' || argv[optind][1] > '9')))
-                                       print_error("No rulenr for -I"
+                               if (optind >= argc ||
+                                   (argv[optind][0] == '-' &&
+                                   (argv[optind][1] < '0' ||
+                                   argv[optind][1] > '9')))
+                                       ebt_print_error("No rulenr for -I"
                                                    " specified");
                                rule_nr = strtol(argv[optind], &buffer, 10);
                                if (*buffer != '\0')
-                                       print_error("Problem with the "
+                                       ebt_print_error("Problem with the "
                                                    "specified rule number");
                                optind++;
                        }
                        if (c == 'P') {
+handle_P:
                                if (optind >= argc)
-                                       print_error("No policy specified");
+                                       ebt_print_error("No policy specified");
                                policy = 0;
                                for (i = 0; i < NUM_STANDARD_TARGETS; i++)
                                        if (!strcmp(argv[optind],
@@ -608,7 +636,7 @@ int main(int argc, char *argv[])
                                                break;
                                        }
                                if (policy == 0)
-                                       print_error("Wrong policy");
+                                       ebt_print_error("Wrong policy");
                                optind++;
                        }
                        break;
@@ -618,30 +646,31 @@ int main(int argc, char *argv[])
                case 'Z': /* zero counters */
                        if (c == 'Z') {
                                if (replace.flags & OPT_ZERO)
-                                       print_error("Multiple commands"
+                                       ebt_print_error("Multiple commands"
                                                    " not allowed");
                                if ( (replace.flags & OPT_COMMAND &&
                                   replace.command != 'L'))
-                                       print_error("command -Z only allowed "
-                                                   "together with command -L");
+                                       ebt_print_error("command -Z only "
+                                          "allowed together with command -L");
                                replace.flags |= OPT_ZERO;
                        } else {
                                replace.command = c;
                                if (replace.flags & OPT_COMMAND)
-                                       print_error("Multiple commands"
+                                       ebt_print_error("Multiple commands"
                                                    " not allowed");
                                replace.flags |= OPT_COMMAND;
                        }
-                       ebt_get_kernel_table(&replace, table);
+                       ebt_get_kernel_table(&replace, table, 0);
                        i = -1;
                        if (optarg) {
-                               if ( (i = ebt_get_chainnr(&replace, optarg)) == -1 )
-                                       print_error("Bad chain");
+                               if ( (i = ebt_get_chainnr(&replace, optarg)) ==
+                                     -1 )
+                                       ebt_print_error("Bad chain");
                        } else
                                if (optind < argc && argv[optind][0] != '-') {
                                        if ((i = ebt_get_chainnr(&replace,
                                            argv[optind])) == -1)
-                                               print_error("Bad chain");
+                                               ebt_print_error("Bad chain");
                                        optind++;
                                }
                        if (i != -1) {
@@ -655,19 +684,22 @@ int main(int argc, char *argv[])
                case 'V': /* version */
                        replace.command = 'V';
                        if (replace.flags & OPT_COMMAND)
-                               print_error("Multiple commands not allowed");
+                               ebt_print_error("Multiple commands not "
+                                               "allowed");
                        PRINT_VERSION;
                        exit(0);
 
                case 'M': /* modprobe */
                        if (replace.command != 'h')
-                               print_error("Please put the -M option earlier");
+                               ebt_print_error("Please put the -M option "
+                                               "earlier");
                        ebt_modprobe = optarg;
                        break;
 
                case 'h': /* help */
                        if (replace.flags & OPT_COMMAND)
-                               print_error("Multiple commands not allowed");
+                               ebt_print_error("Multiple commands not "
+                                               "allowed");
                        replace.command = 'h';
                        /*
                         * All other arguments should be extension names
@@ -686,11 +718,11 @@ int main(int argc, char *argv[])
                                        ebt_add_watcher(new_entry, w);
                                else {
                                        if (!(t = ebt_find_target(argv[optind])))
-                                               print_error("Extension %s "
+                                               ebt_print_error("Extension %s "
                                                   "not found", argv[optind]);
                                        if (replace.flags & OPT_JUMP)
-                                               print_error("Sorry, you can "
-                                                "only see help for one "
+                                               ebt_print_error("Sorry, you "
+                                                "can only see help for one "
                                                 "target extension each time");
                                        replace.flags |= OPT_JUMP;
                                        new_entry->t =
@@ -702,10 +734,11 @@ int main(int argc, char *argv[])
 
                case 't': /* table */
                        if (replace.command != 'h')
-                               print_error("Please put the -t option first");
+                               ebt_print_error("Please put the -t option "
+                                               "first");
                        ebt_check_option(&replace.flags, OPT_TABLE);
                        if (strlen(optarg) > EBT_TABLE_MAXNAMELEN - 1)
-                               print_error("Table name too long");
+                               ebt_print_error("Table name too long");
                        strcpy(replace.name, optarg);
                        break;
 
@@ -718,22 +751,24 @@ int main(int argc, char *argv[])
                case 's': /* source mac */
                case 'd': /* destination mac */
                        if ((replace.flags & OPT_COMMAND) == 0)
-                               print_error("No command specified");
+                               ebt_print_error("No command specified");
                        if ( replace.command != 'A' &&
                           replace.command != 'D' && replace.command != 'I')
-                               print_error("Command and option do not match");
+                               ebt_print_error("Command and option do not "
+                                               "match");
                        if (c == 'i') {
                                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 "
+                                       ebt_print_error("Use in-interface "
+                                          "only in "
                                           "INPUT, FORWARD, PREROUTING and"
                                           "BROUTING chains");
                                if (ebt_check_inverse(optarg))
                                        new_entry->invflags |= EBT_IIN;
 
                                if (optind > argc)
-                                       print_error("No in-interface "
+                                       ebt_print_error("No in-interface "
                                                    "specified");
                                if (strlen(argv[optind - 1]) >= IFNAMSIZ)
                                        print_if_l_error;
@@ -744,15 +779,16 @@ int main(int argc, char *argv[])
                                ebt_check_option(&replace.flags, OPT_LOGICALIN);
                                if (replace.selected_chain > 2 &&
                                   replace.selected_chain < NF_BR_BROUTING)
-                                       print_error("Use logical in-interface "
+                                       ebt_print_error("Use logical "
+                                          "in-interface "
                                           "only in INPUT, FORWARD, "
                                           "PREROUTING and BROUTING chains");
                                if (ebt_check_inverse(optarg))
                                        new_entry->invflags |= EBT_ILOGICALIN;
 
                                if (optind > argc)
-                                       print_error("No logical in-interface "
-                                                   "specified");
+                                       ebt_print_error("No logical "
+                                          "in-interface specified");
                                if (strlen(argv[optind - 1]) >= IFNAMSIZ)
                                        print_if_l_error;
                                strcpy(new_entry->logical_in, argv[optind - 1]);
@@ -761,14 +797,14 @@ int main(int argc, char *argv[])
                        if (c == 'o') {
                                ebt_check_option(&replace.flags, OPT_OUT);
                                if (replace.selected_chain < 2)
-                                       print_error("Use out-interface only"
-                                          " in OUTPUT, FORWARD and "
+                                       ebt_print_error("Use out-interface "
+                                          "only in OUTPUT, FORWARD and "
                                           "POSTROUTING chains");
                                if (ebt_check_inverse(optarg))
                                        new_entry->invflags |= EBT_IOUT;
 
                                if (optind > argc)
-                                       print_error("No out-interface "
+                                       ebt_print_error("No out-interface "
                                                    "specified");
 
                                if (strlen(argv[optind - 1]) >= IFNAMSIZ)
@@ -777,17 +813,19 @@ int main(int argc, char *argv[])
                                break;
                        }
                        if (c == 3) {
-                               ebt_check_option(&replace.flags, OPT_LOGICALOUT);
+                               ebt_check_option(&replace.flags,
+                                                OPT_LOGICALOUT);
                                if (replace.selected_chain < 2)
-                                       print_error("Use logical out-interface "
+                                       ebt_print_error("Use logical "
+                                          "out-interface "
                                           "only in OUTPUT, FORWARD and "
                                           "POSTROUTING chains");
                                if (ebt_check_inverse(optarg))
                                        new_entry->invflags |= EBT_ILOGICALOUT;
 
                                if (optind > argc)
-                                       print_error("No logical out-interface "
-                                                   "specified");
+                                       ebt_print_error("No logical "
+                                          "out-interface specified");
 
                                if (strlen(argv[optind - 1]) >= IFNAMSIZ)
                                        print_if_l_error;
@@ -807,15 +845,18 @@ int main(int argc, char *argv[])
                                                break;
                                        }
                                if (-i - 1 == EBT_RETURN) {
-                                       if (replace.selected_chain < NF_BR_NUMHOOKS)
-                                               print_error("Return target"
-                                               " only for user defined chains");
+                                       if (replace.selected_chain <
+                                           NF_BR_NUMHOOKS)
+                                               ebt_print_error("Return target"
+                                               " only for user defined "
+                                               "chains");
                                }
                                if (i != NUM_STANDARD_TARGETS)
                                        break;
-                               if ((i = ebt_get_chainnr(&replace, optarg)) != -1) {
+                               if ((i = ebt_get_chainnr(&replace, optarg)) !=
+                                    -1) {
                                        if (i < NF_BR_NUMHOOKS)
-                                               print_error("don't jump"
+                                               ebt_print_error("don't jump"
                                                  " to a standard chain");
                                        t = ebt_find_target(EBT_STANDARD_TARGET);
                                        ((struct ebt_standard_target *)
@@ -833,8 +874,8 @@ int main(int argc, char *argv[])
                                         */
                                        if (!t || t ==
                                           (struct ebt_u_target *)new_entry->t)
-                                               print_error("Illegal target "
-                                                           "name");
+                                               ebt_print_error("Illegal "
+                                                  "target name");
                                        new_entry->t =
                                           (struct ebt_entry_target *)t;
                                }
@@ -846,12 +887,12 @@ int main(int argc, char *argv[])
                                        new_entry->invflags |= EBT_ISOURCE;
 
                                if (optind > argc)
-                                       print_error("No source mac "
+                                       ebt_print_error("No source mac "
                                                    "specified");
                                if (ebt_get_mac_and_mask(argv[optind - 1],
                                   new_entry->sourcemac, new_entry->sourcemsk))
-                                       print_error("Problem with specified "
-                                                   "source mac");
+                                       ebt_print_error("Problem with "
+                                          "specified source mac");
                                new_entry->bitmask |= EBT_SOURCEMAC;
                                break;
                        }
@@ -861,12 +902,12 @@ int main(int argc, char *argv[])
                                        new_entry->invflags |= EBT_IDEST;
 
                                if (optind > argc)
-                                       print_error("No destination mac "
+                                       ebt_print_error("No destination mac "
                                                    "specified");
                                if (ebt_get_mac_and_mask(argv[optind - 1],
                                   new_entry->destmac, new_entry->destmsk))
-                                       print_error("Problem with specified "
-                                                   "destination mac");
+                                       ebt_print_error("Problem with "
+                                          "specified destination mac");
                                new_entry->bitmask |= EBT_DESTMAC;
                                break;
                        }
@@ -875,11 +916,11 @@ int main(int argc, char *argv[])
                                new_entry->invflags |= EBT_IPROTO;
 
                        if (optind > argc)
-                               print_error("No protocol specified");
+                               ebt_print_error("No protocol specified");
                        new_entry->bitmask &= ~((unsigned int)EBT_NOPROTO);
                        i = strtol(argv[optind - 1], &buffer, 16);
                        if (*buffer == '\0' && (i < 0 || i > 0xFFFF))
-                               print_error("Problem with the specified "
+                               ebt_print_error("Problem with the specified "
                                            "protocol");
                        new_entry->ethproto = i;
                        if (*buffer != '\0') {
@@ -891,68 +932,74 @@ int main(int argc, char *argv[])
                                }
                                ent = getethertypebyname(argv[optind - 1]);
                                if (!ent)
-                                       print_error("Problem with the specified"
-                                                   " protocol");
+                                       ebt_print_error("Problem with the "
+                                                       "specified protocol");
                                new_entry->ethproto = ent->e_ethertype;
                        }
                        if (new_entry->ethproto < 1536 &&
                           !(new_entry->bitmask & EBT_802_3))
-                               print_error("Sorry, protocols have values above"
-                                           " or equal to 0x0600");
+                               ebt_print_error("Sorry, protocols have values "
+                                               "above or equal to 0x0600");
                        break;
 
                case 4  : /* Lc */
                        ebt_check_option(&replace.flags, LIST_C);
                        if (replace.command != 'L')
-                               print_error("Use --Lc with -L");
+                               ebt_print_error("Use --Lc with -L");
                        if (replace.flags & LIST_X)
-                               print_error("--Lx not compatible with --Lc");
+                               ebt_print_error("--Lx not compatible with "
+                                               "--Lc");
                        replace.flags |= LIST_C;
                        break;
                case 5  : /* Ln */
                        ebt_check_option(&replace.flags, LIST_N);
                        if (replace.command != 'L')
-                               print_error("Use --Ln with -L");
+                               ebt_print_error("Use --Ln with -L");
                        if (replace.flags & LIST_X)
-                               print_error("--Lx not compatible with --Ln");
+                               ebt_print_error("--Lx not compatible with "
+                                               "--Ln");
                        replace.flags |= LIST_N;
                        break;
                case 6  : /* Lx */
                        ebt_check_option(&replace.flags, LIST_X);
                        if (replace.command != 'L')
-                               print_error("Use --Lx with -L");
+                               ebt_print_error("Use --Lx with -L");
                        if (replace.flags & LIST_C)
-                               print_error("--Lx not compatible with --Lc");
+                               ebt_print_error("--Lx not compatible with "
+                                               "--Lc");
                        if (replace.flags & LIST_N)
-                               print_error("--Lx not compatible with --Ln");
+                               ebt_print_error("--Lx not compatible with "
+                                               "--Ln");
                        replace.flags |= LIST_X;
                        break;
                case 12 : /* Lmac2 */
                        ebt_check_option(&replace.flags, LIST_MAC2);
                        if (replace.command != 'L')
-                               print_error("Use --Lmac2 with -L");
+                               ebt_print_error("Use --Lmac2 with -L");
                        replace.flags |= LIST_MAC2;
                        break;
                case 8 : /* atomic-commit */
                        replace.command = c;
                        if (replace.flags & OPT_COMMAND)
-                               print_error("Multiple commands not allowed");
+                               ebt_print_error("Multiple commands not "
+                                               "allowed");
                        replace.flags |= OPT_COMMAND;
                        if (!replace.filename)
-                               print_error("No atomic file specified");
+                               ebt_print_error("No atomic file specified");
                        /*
                         * get the information from the file
                         */
-                       ebt_get_table(&replace);
+                       ebt_get_table(&replace, 0);
                        /*
-                        * we don't want the kernel giving us its counters, they would
-                        * overwrite the counters extracted from the file
+                        * we don't want the kernel giving us its counters,
+                        * they would overwrite the counters extracted from
+                        * the file
                         */
                        replace.num_counters = 0;
                        /*
                         * make sure the table will be written to the kernel
-                        * possible memory leak here
                         */
+                       free(replace.filename);
                        replace.filename = NULL;
                        break;
                case 7 : /* atomic-init */
@@ -960,24 +1007,28 @@ int main(int argc, char *argv[])
                case 11: /* init-table */
                        replace.command = c;
                        if (replace.flags & OPT_COMMAND)
-                               print_error("Multiple commands not allowed");
+                               ebt_print_error("Multiple commands not "
+                                               "allowed");
                        if (c != 11 && !replace.filename)
-                               print_error("No atomic file specified");
+                               ebt_print_error("No atomic file specified");
                        replace.flags |= OPT_COMMAND;
                        {
                                char *tmp = replace.filename;
+                               int init = 1;
 
+                               if (c == 10)
+                                       init = 0;
                                tmp = replace.filename;
                                /* get the kernel table */
                                replace.filename = NULL;
-                               ebt_get_kernel_table(&replace, table);
+                               ebt_get_kernel_table(&replace, table, init);
                                replace.filename = tmp;
                        }
                        break;
                case 9 : /* atomic */
                        if (replace.flags & OPT_COMMAND)
-                               print_error("--atomic has to come before"
-                               " the command");
+                               ebt_print_error("--atomic has to come before"
+                                               " the command");
                        /* another possible memory leak here */
                        replace.filename = (char *)malloc(strlen(optarg) + 1);
                        strcpy(replace.filename, optarg);
@@ -986,7 +1037,7 @@ int main(int argc, char *argv[])
                        if (!strcmp(optarg, "!"))
                                ebt_check_inverse(optarg);
                        else
-                               print_error("Bad argument : %s", optarg);
+                               ebt_print_error("Bad argument : %s", optarg);
                        /*
                         * ebt_check_inverse() did optind++
                         */
@@ -1026,7 +1077,7 @@ int main(int argc, char *argv[])
                                        break;
 
                        if (w == NULL)
-                               print_error("Unknown argument");
+                               ebt_print_error("Unknown argument");
                        if (w->used == 0) {
                                ebt_add_watcher(new_entry, w);
                                w->used = 1;
@@ -1034,17 +1085,19 @@ int main(int argc, char *argv[])
 check_extension:
                        if (replace.command != 'A' && replace.command != 'I' &&
                           replace.command != 'D')
-                               print_error("Extensions only for -A, -I and -D");
+                               ebt_print_error("Extensions only for -A, "
+                                               "-I and -D");
                }
                ebt_invert = 0;
        }
 
        if ( !table && !(table = ebt_find_table(replace.name)) )
-               print_error("Bad table name");
+               ebt_print_error("Bad table name");
 
        if ( (replace.flags & OPT_COMMAND) && replace.command != 'L' &&
           replace.flags & OPT_ZERO )
-               print_error("Command -Z only allowed together with command -L");
+               ebt_print_error("Command -Z only allowed together with "
+                               "command -L");
 
        /*
         * do this after parsing everything, so we can print specific info
@@ -1089,8 +1142,8 @@ check_extension:
        if (replace.command == 'P') {
                if (replace.selected_chain < NF_BR_NUMHOOKS &&
                   policy == EBT_RETURN)
-                       print_error("Policy RETURN only allowed for user "
-                                   "defined chains");
+                       ebt_print_error("Policy RETURN only allowed for user "
+                                       "defined chains");
                ebt_change_policy(&replace, policy);
        } else if (replace.command == 'L') {
                list_rules();
index ec54f7d..21558f4 100644 (file)
@@ -5,6 +5,22 @@ EXT_FUNC+=802_3 nat arp arpreply ip standard log redirect vlan mark_m mark \
 EXT_TABLES+=filter nat broute
 EXT_OBJS+=$(foreach T,$(EXT_FUNC), extensions/ebt_$(T).o)
 EXT_OBJS+=$(foreach T,$(EXT_TABLES), extensions/ebtable_$(T).o)
+EXT_LIBS+=$(foreach T,$(EXT_FUNC), extensions/libebt_$(T).so)
+EXT_LIBS+=$(foreach T,$(EXT_TABLES), extensions/libebtable_$(T).so)
+EXT_LIBSI+=$(foreach T,$(EXT_FUNC), -lebt_$(T))
+EXT_LIBSI+=$(foreach T,$(EXT_TABLES), -lebtable_$(T))
+
+extensions/ebt_%.so: extensions/ebt_%.o
+       $(LD) -shared -o $@ -lc $<
+
+extensions/libebt_%.so: extensions/ebt_%.so
+       mv $< $@
+
+extensions/ebtable_%.so: extensions/ebtable_%.o
+       $(LD) -shared -o $@ -lc $<
+
+extensions/libebtable_%.so: extensions/ebtable_%.so
+       mv $< $@
 
 extensions/ebt_%.o: extensions/ebt_%.c include/ebtables_u.h
        $(CC) $(CFLAGS) $(PROGSPECS) -c -o $@ $< -I$(KERNEL_INCLUDES)
index f76b20a..e0b65ee 100644 (file)
@@ -48,11 +48,11 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
                                info->invflags |= EBT_802_3_SAP;
 
                        if (optind > argc)
-                               print_error("Missing 802.3-sap argument");
+                               ebt_print_error("Missing 802.3-sap argument");
                        i = strtoul(argv[optind - 1], &end, 16);
                        if (i > 255 || *end != '\0') 
-                               print_error("Problem with specified "
-                                           "sap hex value, %x",i);
+                               ebt_print_error("Problem with specified "
+                                               "sap hex value, %x",i);
                        info->sap = i; /* one byte, so no byte order worries */
                        info->bitmask |= EBT_802_3_SAP;
                        break;
@@ -61,11 +61,11 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
                        if (ebt_check_inverse(optarg))
                                info->invflags |= EBT_802_3_TYPE;
                        if (optind > argc)
-                               print_error("Missing 802.3-type argument");
+                               ebt_print_error("Missing 802.3-type argument");
                        i = strtoul(argv[optind - 1], &end, 16);
                        if (i > 65535 || *end != '\0') {
-                               print_error("Problem with the specified "
-                                           "type hex value, %x",i);
+                               ebt_print_error("Problem with the specified "
+                                               "type hex value, %x",i);
                        }
                        info->type = htons(i);
                        info->bitmask |= EBT_802_3_TYPE;
@@ -81,8 +81,8 @@ static void final_check(const struct ebt_u_entry *entry,
    unsigned int hookmask, unsigned int time)
 {
        if (!(entry->bitmask & EBT_802_3))
-               print_error("For 802.3 DSAP/SSAP filtering the protocol "
-                           "must be LENGTH");
+               ebt_print_error("For 802.3 DSAP/SSAP filtering the protocol "
+                               "must be LENGTH");
 }
 
 static void print(const struct ebt_u_entry *entry,
@@ -138,8 +138,7 @@ static struct ebt_u_match _802_3_match =
        .extra_ops      = opts,
 };
 
-static void _init(void) __attribute__ ((constructor));
-static void _init(void)
+void _init(void)
 {
        ebt_register_match(&_802_3_match);
 }
index 9427038..1756e44 100644 (file)
@@ -169,7 +169,7 @@ static struct ebt_mac_wormhash *create_wormhash(const char *arg)
        char token[4];
 
        if (!(workcopy = new_wormhash(1024))) {
-               print_memory();
+               ebt_print_memory();
        }
        while (1) {
                /* remember current position, we'll need it on error */
@@ -181,22 +181,22 @@ static struct ebt_mac_wormhash *create_wormhash(const char *arg)
                for (i = 0; i < 5; i++) {
                        if (read_until(&pc, ":", token, 2) < 0
                            || token[0] == 0) {
-                               print_error("MAC parse error: %.20s",
-                                           anchor);
+                               ebt_print_error("MAC parse error: %.20s",
+                                               anchor);
                        }
                        mac[i] = strtol(token, &endptr, 16);
                        if (*endptr) {
-                               print_error("MAC parse error: %.20s",
-                                           anchor);
+                               ebt_print_error("MAC parse error: %.20s",
+                                               anchor);
                        }
                        pc++;
                }
                if (read_until(&pc, "=,", token, 2) == -2 || token[0] == 0) {
-                       print_error("MAC parse error: %.20s", anchor);
+                       ebt_print_error("MAC parse error: %.20s", anchor);
                }
                mac[i] = strtol(token, &endptr, 16);
                if (*endptr) {
-                       print_error("MAC parse error: %.20s", anchor);
+                       ebt_print_error("MAC parse error: %.20s", anchor);
                }
                if (*pc == '=') {
                        /* an IP follows the MAC; collect similarly to MAC */
@@ -205,13 +205,13 @@ static struct ebt_mac_wormhash *create_wormhash(const char *arg)
                        for (i = 0; i < 3; i++) {
                                if (read_until(&pc, ".", token, 3) < 0
                                    || token[0] == 0) {
-                                       print_error
+                                       ebt_print_error
                                            ("IP parse error: %.20s",
                                             anchor);
                                }
                                ip[i] = strtol(token, &endptr, 10);
                                if (*endptr) {
-                                       print_error
+                                       ebt_print_error
                                            ("IP parse error: %.20s",
                                             anchor);
                                }
@@ -219,16 +219,16 @@ static struct ebt_mac_wormhash *create_wormhash(const char *arg)
                        }
                        if (read_until(&pc, ",", token, 3) == -2
                            || token[0] == 0) {
-                               print_error("IP parse error: %.20s",
+                               ebt_print_error("IP parse error: %.20s",
                                            anchor);
                        }
                        ip[3] = strtol(token, &endptr, 10);
                        if (*endptr) {
-                               print_error("IP parse error: %.20s",
+                               ebt_print_error("IP parse error: %.20s",
                                            anchor);
                        }
                        if (*(uint32_t*)ip == 0) {
-                               print_error("Illegal IP 0.0.0.0");
+                               ebt_print_error("Illegal IP 0.0.0.0");
                        }
                } else {
                        /* no IP, we set it to 0.0.0.0 */
@@ -243,7 +243,7 @@ static struct ebt_mac_wormhash *create_wormhash(const char *arg)
                /* re-allocate memory if needed */
                if (*pc && nmacs >= workcopy->poolsize) {
                        if (!(h = new_wormhash(nmacs * 2))) {
-                               print_memory();
+                               ebt_print_memory();
                        }
                        copy_wormhash(h, workcopy);
                        free(workcopy);
@@ -259,7 +259,7 @@ static struct ebt_mac_wormhash *create_wormhash(const char *arg)
                /* increment this to the next char */
                /* but first assert :-> */
                if (*pc != ',') {
-                       print_error("Something went wrong; no comma...\n");
+                       ebt_print_error("Something went wrong; no comma...\n");
                }
                pc++;
 
@@ -270,7 +270,7 @@ static struct ebt_mac_wormhash *create_wormhash(const char *arg)
                }
        }
        if (!(result = new_wormhash(nmacs))) {
-               print_memory();
+               ebt_print_memory();
        }
        copy_wormhash(result, workcopy);
        free(workcopy);
@@ -302,7 +302,7 @@ static int parse(int c, char **argv, int argc,
                                info->bitmask |= EBT_AMONG_SRC_NEG;
                }
                if (optind > argc)
-                       print_error("No MAC list specified\n");
+                       ebt_print_error("No MAC list specified\n");
                wh = create_wormhash(argv[optind - 1]);
                old_size = sizeof(struct ebt_entry_match) +
                                (**match).match_size;
@@ -436,8 +436,7 @@ static struct ebt_u_match among_match = {
        .extra_ops      = opts,
 };
 
-static void _init(void) __attribute__ ((constructor));
-static void _init(void)
+void _init(void)
 {
        ebt_register_match(&among_match);
 }
index a60d6a7..6323fc4 100644 (file)
@@ -97,15 +97,15 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
                        arpinfo->invflags |= EBT_ARP_OPCODE;
 
                if (optind > argc)
-                       print_error("Missing ARP opcode argument");
+                       ebt_print_error("Missing ARP opcode argument");
                i = strtol(argv[optind - 1], &end, 10);
                if (i < 0 || i >= (0x1 << 16) || *end !='\0') {
                        for (i = 0; i < NUMOPCODES; i++)
                                if (!strcasecmp(opcodes[i], optarg))
                                        break;
                        if (i == NUMOPCODES)
-                               print_error("Problem with specified "
-                                           "ARP opcode");
+                               ebt_print_error("Problem with specified "
+                                               "ARP opcode");
                        i++;
                }
                arpinfo->opcode = htons(i);
@@ -118,14 +118,14 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
                        arpinfo->invflags |= EBT_ARP_HTYPE;
 
                if (optind > argc)
-                       print_error("Missing ARP hardware type argument");
+                       ebt_print_error("Missing ARP hardware type argument");
                i = strtol(argv[optind - 1], &end, 10);
                if (i < 0 || i >= (0x1 << 16) || *end !='\0') {
                        if (!strcasecmp("Ethernet", argv[optind - 1]))
                                i = 1;
                        else
-                               print_error("Problem with specified ARP "
-                                           "hardware type");
+                               ebt_print_error("Problem with specified ARP "
+                                               "hardware type");
                }
                arpinfo->htype = htons(i);
                arpinfo->bitmask |= EBT_ARP_HTYPE;
@@ -140,15 +140,15 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
                        arpinfo->invflags |= EBT_ARP_PTYPE;
 
                if (optind > argc)
-                       print_error("Missing ARP protocol type argument");
+                       ebt_print_error("Missing ARP protocol type argument");
                i = strtol(argv[optind - 1], &end, 16);
                if (i < 0 || i >= (0x1 << 16) || *end !='\0') {
                        struct ethertypeent *ent;
 
                        ent = getethertypebyname(argv[optind - 1]);
                        if (!ent)
-                               print_error("Problem with specified ARP "
-                                           "protocol type");
+                               ebt_print_error("Problem with specified ARP "
+                                               "protocol type");
                        proto = ent->e_ethertype;
 
                } else
@@ -178,7 +178,7 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
                                arpinfo->invflags |= EBT_ARP_DST_IP;
                }
                if (optind > argc)
-                       print_error("Missing ARP IP address argument");
+                       ebt_print_error("Missing ARP IP address argument");
                ebt_parse_ip_address(argv[optind - 1], addr, mask);
                break;
 
@@ -202,9 +202,10 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
                                arpinfo->invflags |= EBT_ARP_DST_MAC;
                }
                if (optind > argc)
-                       print_error("Missing ARP MAC address argument");
+                       ebt_print_error("Missing ARP MAC address argument");
                if (ebt_get_mac_and_mask(argv[optind - 1], maddr, mmask))
-                       print_error("Problem with ARP MAC address argument");
+                       ebt_print_error("Problem with ARP MAC address "
+                                       "argument");
                break;
 
        default:
@@ -219,8 +220,8 @@ static void final_check(const struct ebt_u_entry *entry,
 {
        if ((entry->ethproto != ETH_P_ARP && entry->ethproto != ETH_P_RARP) ||
            entry->invflags & EBT_IPROTO)
-               print_error("For (R)ARP filtering the protocol must be "
-                           "specified as ARP or RARP");
+               ebt_print_error("For (R)ARP filtering the protocol must be "
+                               "specified as ARP or RARP");
 }
 
 static void print(const struct ebt_u_entry *entry,
@@ -353,8 +354,7 @@ static struct ebt_u_match arp_match =
        .extra_ops      = opts,
 };
 
-static void _init(void) __attribute__ ((constructor));
-static void _init(void)
+void _init(void)
 {
        ebt_register_match(&arp_match);
 }
index d524253..9c50519 100644 (file)
@@ -50,15 +50,15 @@ static int parse(int c, char **argv, int argc,
        case REPLY_MAC:
                ebt_check_option(flags, OPT_REPLY_MAC);
                if (!(addr = ether_aton(optarg)))
-                       print_error("Problem with specified "
-                                   "--arpreply-mac mac");
+                       ebt_print_error("Problem with specified "
+                                       "--arpreply-mac mac");
                memcpy(replyinfo->mac, addr, ETH_ALEN);
                mac_supplied = 1;
                break;
        case REPLY_TARGET:
                ebt_check_option(flags, OPT_REPLY_TARGET);
                if (FILL_TARGET(optarg, replyinfo->target))
-                       print_error("Illegal --arpreply-target target");
+                       ebt_print_error("Illegal --arpreply-target target");
                break;
 
        default:
@@ -75,16 +75,16 @@ static void final_check(const struct ebt_u_entry *entry,
           (struct ebt_arpreply_info *)target->data;
 
        if (entry->ethproto != ETH_P_ARP || entry->invflags & EBT_IPROTO)
-               print_error("For ARP replying the protocol must be "
-                           "specified as ARP");
+               ebt_print_error("For ARP replying the protocol must be "
+                               "specified as ARP");
        if (time == 0 && mac_supplied == 0)
-               print_error("No arpreply mac supplied");
+               ebt_print_error("No arpreply mac supplied");
        if (BASE_CHAIN && replyinfo->target == EBT_RETURN)
-               print_error("--arpreply-target RETURN not allowed on "
-                           "base chain");
+               ebt_print_error("--arpreply-target RETURN not allowed on "
+                               "base chain");
        CLEAR_BASE_CHAIN_BIT;
        if (strcmp(name, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING))
-               print_error("arpreply only allowed in PREROUTING");
+               ebt_print_error("arpreply only allowed in PREROUTING");
 }
 
 static void print(const struct ebt_u_entry *entry,
@@ -125,8 +125,7 @@ static struct ebt_u_target arpreply_target =
        .extra_ops      = opts,
 };
 
-static void _init(void) __attribute__ ((constructor));
-static void _init(void)
+void _init(void)
 {
        ebt_register_target(&arpreply_target);
 }
index f93b8b9..6d9233e 100644 (file)
@@ -74,8 +74,8 @@ static uint16_t parse_port(const char *protocol, const char *name)
        else if (port >= 0 || port <= 0xFFFF) {
                return port;
        }
-       print_error("Problem with specified %s port '%s'", 
-                   protocol?protocol:"", name);
+       ebt_print_error("Problem with specified %s port '%s'", 
+                       protocol?protocol:"", name);
        return 0; /* never reached */
 }
 
@@ -95,7 +95,7 @@ parse_port_range(const char *protocol, const char *portstring, uint16_t *ports)
                ports[1] = cp[0] ? parse_port(protocol, cp) : 0xFFFF;
                
                if (ports[0] > ports[1])
-                       print_error("Invalid portrange (min > max)");
+                       ebt_print_error("Invalid portrange (min > max)");
        }
        free(buffer);
 }
@@ -159,7 +159,7 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
                }
 
                if (optind > argc)
-                       print_error("Missing IP address argument");
+                       ebt_print_error("Missing IP address argument");
                if (c == IP_SOURCE)
                        ebt_parse_ip_address(argv[optind - 1], &ipinfo->saddr,
                           &ipinfo->smsk);
@@ -182,7 +182,7 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
                                ipinfo->invflags |= EBT_IP_DPORT;
                }
                if (optind > argc)
-                       print_error("Missing port argument");
+                       ebt_print_error("Missing port argument");
                if (c == IP_SPORT)
                        parse_port_range(NULL, argv[optind - 1], ipinfo->sport);
                else
@@ -195,10 +195,10 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
                        ipinfo->invflags |= EBT_IP_TOS;
 
                if (optind > argc)
-                       print_error("Missing IP tos argument");
+                       ebt_print_error("Missing IP tos argument");
                i = strtol(argv[optind - 1], &end, 16);
                if (i < 0 || i > 255 || *end != '\0')
-                       print_error("Problem with specified IP tos");
+                       ebt_print_error("Problem with specified IP tos");
                ipinfo->tos = i;
                ipinfo->bitmask |= EBT_IP_TOS;
                break;
@@ -208,14 +208,14 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
                if (ebt_check_inverse(optarg))
                        ipinfo->invflags |= EBT_IP_PROTO;
                if (optind > argc)
-                       print_error("Missing IP protocol argument");
+                       ebt_print_error("Missing IP protocol argument");
                (unsigned char) i = strtoul(argv[optind - 1], &end, 10);
                if (*end != '\0') {
                        struct protoent *pe;
 
                        pe = getprotobyname(argv[optind - 1]);
                        if (pe == NULL)
-                               print_error
+                               ebt_print_error
                                    ("Unknown specified IP protocol - %s",
                                     argv[optind - 1]);
                        ipinfo->protocol = pe->p_proto;
@@ -237,7 +237,7 @@ static void final_check(const struct ebt_u_entry *entry,
        struct ebt_ip_info *ipinfo = (struct ebt_ip_info *)match->data;
 
        if (entry->ethproto != ETH_P_IP || entry->invflags & EBT_IPROTO)
-               print_error("For IP filtering the protocol must be "
+               ebt_print_error("For IP filtering the protocol must be "
                            "specified as IPv4");
 
        if (ipinfo->bitmask & (EBT_IP_SPORT|EBT_IP_DPORT) &&
@@ -245,8 +245,8 @@ static void final_check(const struct ebt_u_entry *entry,
                ipinfo->invflags & EBT_IP_PROTO ||
                (ipinfo->protocol!=IPPROTO_TCP && 
                        ipinfo->protocol!=IPPROTO_UDP)))
-               print_error("For port filtering the IP protocol must be "
-                           "either 6 (tcp) or 17 (udp)");
+               ebt_print_error("For port filtering the IP protocol must be "
+                               "either 6 (tcp) or 17 (udp)");
 }
 
 static void print(const struct ebt_u_entry *entry,
@@ -364,8 +364,7 @@ static struct ebt_u_match ip_match =
        .extra_ops      = opts,
 };
 
-static void _init(void) __attribute((constructor));
-static void _init(void)
+void _init(void)
 {
        ebt_register_match(&ip_match);
 }
index 490686d..1c5c32b 100644 (file)
@@ -122,18 +122,18 @@ static int parse(int c, char **argv, int argc,
        case ARG_LIMIT:
                ebt_check_option(flags, FLAG_LIMIT);
                if (ebt_check_inverse(optarg))
-                       print_error("Unexpected `!' after --limit");
+                       ebt_print_error("Unexpected `!' after --limit");
                if (!parse_rate(optarg, &r->avg))
-                       print_error("bad rate `%s'", optarg);
+                       ebt_print_error("bad rate `%s'", optarg);
                break;
 
        case ARG_LIMIT_BURST:
                ebt_check_option(flags, FLAG_LIMIT_BURST);
                if (ebt_check_inverse(optarg))
-                       print_error("Unexpected `!' after --limit-burst");
+                       ebt_print_error("Unexpected `!' after --limit-burst");
 
                if (string_to_number(optarg, 0, 10000, &num) == -1)
-                       print_error("bad --limit-burst `%s'", optarg);
+                       ebt_print_error("bad --limit-burst `%s'", optarg);
                r->burst = num;
                break;
 
@@ -214,8 +214,7 @@ static struct ebt_u_match limit_match =
        .extra_ops      opts,
 };
 
-static void _init(void) __attribute((constructor));
-static void _init(void)
+void _init(void)
 {
        ebt_register_match(&limit_match);
 }
index 953211e..f455f9f 100644 (file)
@@ -105,7 +105,7 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
        case LOG_PREFIX:
                ebt_check_option(flags, OPT_PREFIX);
                if (strlen(optarg) > sizeof(loginfo->prefix) - 1)
-                       print_error("Prefix too long");
+                       ebt_print_error("Prefix too long");
                strcpy(loginfo->prefix, optarg);
                break;
 
@@ -117,7 +117,7 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
                else
                        loginfo->loglevel = i;
                if (loginfo->loglevel == 9)
-                       print_error("Problem with the log-level");
+                       ebt_print_error("Problem with the log-level");
                break;
 
        case LOG_IP:
@@ -187,8 +187,7 @@ static struct ebt_u_watcher log_watcher =
        .extra_ops      = opts,
 };
 
-static void _init(void) __attribute__ ((constructor));
-static void _init(void)
+void _init(void)
 {
        ebt_register_watcher(&log_watcher);
 }
index c40b9fd..bf23a03 100644 (file)
@@ -48,13 +48,13 @@ static int parse(int c, char **argv, int argc,
        case MARK_TARGET:
                ebt_check_option(flags, OPT_MARK_TARGET);
                if (FILL_TARGET(optarg, markinfo->target))
-                       print_error("Illegal --mark-target target");
+                       ebt_print_error("Illegal --mark-target target");
                break;
        case 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);
+                       ebt_print_error("Bad MARK value '%s'", optarg);
                mark_supplied = 1;
                 break;
         default:
@@ -71,9 +71,10 @@ static void final_check(const struct ebt_u_entry *entry,
           (struct ebt_mark_t_info *)target->data;
 
        if (time == 0 && mark_supplied == 0)
-               print_error("No mark value supplied");
+               ebt_print_error("No mark value supplied");
        if (BASE_CHAIN && markinfo->target == EBT_RETURN)
-               print_error("--mark-target RETURN not allowed on base chain");
+               ebt_print_error("--mark-target RETURN not allowed on base "
+                               "chain");
 }
 
 static void print(const struct ebt_u_entry *entry,
@@ -113,8 +114,7 @@ static struct ebt_u_target mark_target =
        .extra_ops      = opts,
 };
 
-static void _init(void) __attribute__ ((constructor));
-static void _init(void)
+void _init(void)
 {
        ebt_register_target(&mark_target);
 }
index 1c18d9e..2cc371a 100644 (file)
@@ -44,7 +44,7 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
                if (ebt_check_inverse(optarg))
                        markinfo->invert = 1;
                if (optind > argc)
-                       print_error("No mark specified");
+                       ebt_print_error("No mark specified");
                markinfo->mark = strtoul(argv[optind - 1], &end, 0);
                markinfo->bitmask = EBT_MARK_AND;
                if (*end == '/') {
@@ -54,7 +54,8 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
                } else
                        markinfo->mask = 0xffffffff;
                if ( *end != '\0' || end == argv[optind - 1])
-                       print_error("Bad mark value '%s'", argv[optind - 1]);
+                       ebt_print_error("Bad mark value '%s'",
+                                       argv[optind - 1]);
                break;
        default:
                return 0;
@@ -115,8 +116,7 @@ static struct ebt_u_match mark_match =
        .extra_ops      = opts,
 };
 
-static void _init(void) __attribute((constructor));
-static void _init(void)
+void _init(void)
 {
        ebt_register_match(&mark_match);
 }
index 16e1842..f2e79ca 100644 (file)
@@ -76,13 +76,14 @@ static int parse_s(int c, char **argv, int argc,
                ebt_check_option(flags, OPT_SNAT);
                to_source_supplied = 1;
                if (!(addr = ether_aton(optarg)))
-                       print_error("Problem with specified --to-source mac");
+                       ebt_print_error("Problem with specified --to-source "
+                                       "mac");
                memcpy(natinfo->mac, addr, ETH_ALEN);
                break;
        case NAT_S_TARGET:
                ebt_check_option(flags, OPT_SNAT_TARGET);
                if (FILL_TARGET(optarg, natinfo->target))
-                       print_error("Illegal --snat-target target");
+                       ebt_print_error("Illegal --snat-target target");
                break;
        default:
                return 0;
@@ -104,14 +105,14 @@ static int parse_d(int c, char **argv, int argc,
                ebt_check_option(flags, OPT_DNAT);
                to_dest_supplied = 1;
                if (!(addr = ether_aton(optarg)))
-                       print_error("Problem with specified "
-                                   "--to-destination mac");
+                       ebt_print_error("Problem with specified "
+                                       "--to-destination mac");
                memcpy(natinfo->mac, addr, ETH_ALEN);
                break;
        case NAT_D_TARGET:
                ebt_check_option(flags, OPT_DNAT_TARGET);
                if (FILL_TARGET(optarg, natinfo->target))
-                       print_error("Illegal --dnat-target target");
+                       ebt_print_error("Illegal --dnat-target target");
                break;
        default:
                return 0;
@@ -126,12 +127,13 @@ static void final_check_s(const struct ebt_u_entry *entry,
        struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
 
        if (BASE_CHAIN && natinfo->target == EBT_RETURN)
-               print_error("--snat-target RETURN not allowed on base chain");
+               ebt_print_error("--snat-target RETURN not allowed on base "
+                               "chain");
        CLEAR_BASE_CHAIN_BIT;
        if ((hookmask & ~(1 << NF_BR_POST_ROUTING)) || strcmp(name, "nat"))
-               print_error("Wrong chain for snat");
+               ebt_print_error("Wrong chain for snat");
        if (time == 0 && to_source_supplied == 0)
-               print_error("No snat address supplied");
+               ebt_print_error("No snat address supplied");
 }
 
 static void final_check_d(const struct ebt_u_entry *entry,
@@ -141,14 +143,15 @@ static void final_check_d(const struct ebt_u_entry *entry,
        struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
 
        if (BASE_CHAIN && natinfo->target == EBT_RETURN)
-               print_error("--dnat-target RETURN not allowed on base chain");
+               ebt_print_error("--dnat-target RETURN not allowed on base "
+                               "chain");
        CLEAR_BASE_CHAIN_BIT;
        if (((hookmask & ~((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT)))
           || strcmp(name, "nat")) &&
           ((hookmask & ~(1 << NF_BR_BROUTING)) || strcmp(name, "broute")))
-               print_error("Wrong chain for dnat");
+               ebt_print_error("Wrong chain for dnat");
        if (time == 0 && to_dest_supplied == 0)
-               print_error("No dnat address supplied");
+               ebt_print_error("No dnat address supplied");
 }
 
 static void print_s(const struct ebt_u_entry *entry,
@@ -207,8 +210,7 @@ static struct ebt_u_target dnat_target =
        .extra_ops      = opts_d,
 };
 
-static void _init(void) __attribute__ ((constructor));
-static void _init(void)
+void _init(void)
 {
        ebt_register_target(&snat_target);
        ebt_register_target(&dnat_target);
index 35bac29..f7893bb 100644 (file)
@@ -61,7 +61,7 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
                if (ebt_check_inverse(optarg))
                        ptinfo->invert = 1;
                if (optind > argc)
-                       print_error("Missing pkttype class specification");
+                       ebt_print_error("Missing pkttype class specification");
 
                i = strtol(argv[optind - 1], &end, 16);
                if (*end != '\0') {
@@ -74,7 +74,7 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
                                }
                }
                if (i < 0 || i > 255)
-                       print_error("Problem with specified pkttype class");
+                       ebt_print_error("Problem with specified pkttype class");
                ptinfo->pkt_type = (uint8_t)i;
 
                break;
@@ -129,8 +129,7 @@ static struct ebt_u_match pkttype_match =
        .extra_ops      = opts,
 };
 
-static void _init(void) __attribute((constructor));
-static void _init(void)
+void _init(void)
 {
        ebt_register_match(&pkttype_match);
 }
index 82feaa9..ba7f6b1 100644 (file)
@@ -40,7 +40,7 @@ static int parse(int c, char **argv, int argc,
        case REDIRECT_TARGET:
                ebt_check_option(flags, OPT_REDIRECT_TARGET);
                if (FILL_TARGET(optarg, redirectinfo->target))
-                       print_error("Illegal --redirect-target target");
+                       ebt_print_error("Illegal --redirect-target target");
                break;
        default:
                return 0;
@@ -56,12 +56,12 @@ static void final_check(const struct ebt_u_entry *entry,
           (struct ebt_redirect_info *)target->data;
 
        if (BASE_CHAIN && redirectinfo->target == EBT_RETURN)
-               print_error("--redirect-target RETURN not allowed on "
-                           "base chain");
+               ebt_print_error("--redirect-target RETURN not allowed on "
+                               "base chain");
        CLEAR_BASE_CHAIN_BIT;
        if ( ((hookmask & ~(1 << NF_BR_PRE_ROUTING)) || strcmp(name, "nat")) &&
           ((hookmask & ~(1 << NF_BR_BROUTING)) || strcmp(name, "broute")) )
-               print_error("Wrong chain for redirect");
+               ebt_print_error("Wrong chain for redirect");
 }
 
 static void print(const struct ebt_u_entry *entry,
@@ -99,8 +99,7 @@ static struct ebt_u_target redirect_target =
        .extra_ops      = opts,
 };
 
-static void _init(void) __attribute__ ((constructor));
-static void _init(void)
+void _init(void)
 {
        ebt_register_target(&redirect_target);
 }
index 7ee454b..4ac3dc0 100644 (file)
@@ -53,7 +53,7 @@ static void print(const struct ebt_u_entry *entry,
        else if (verdict == EBT_RETURN)
                printf("RETURN ");
        else
-               print_bug("Bad standard target");
+               ebt_print_bug("Bad standard target");
 }
 
 static int compare(const struct ebt_entry_target *t1,
@@ -77,8 +77,7 @@ static struct ebt_u_target standard =
        .extra_ops      = opts,
 };
 
-static void _init(void) __attribute__ ((constructor));
-static void _init(void)
+void _init(void)
 {
        ebt_register_target(&standard);
 }
index 60f2cc8..b458c40 100644 (file)
@@ -135,7 +135,7 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
        if (ebt_check_inverse(optarg))
                stpinfo->invflags |= flag;
        if (optind > argc)
-               print_error("Missing argument for --%s", opts[c-'a'].name);
+               ebt_print_error("Missing argument for --%s", opts[c-'a'].name);
        stpinfo->bitmask |= flag;
        switch (flag) {
        case EBT_STP_TYPE:
@@ -148,7 +148,7 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
                                   BPDU_TYPE_TCN_STRING))
                                stpinfo->type = BPDU_TYPE_TCN;
                        else
-                               print_error("Bad STP type argument");
+                               ebt_print_error("Bad STP type argument");
                } else
                        stpinfo->type = i;
                break;
@@ -162,62 +162,63 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
                                   FLAG_TC_ACK_STRING))
                                stpinfo->config.flags = FLAG_TC_ACK;
                        else
-                               print_error("Bad STP config flags argument");
+                               ebt_print_error("Bad STP config flags "
+                                               "argument");
                } else
                        stpinfo->config.flags = i;
                break;
        case EBT_STP_ROOTPRIO:
                if (parse_range(argv[optind-1], &(stpinfo->config.root_priol),
                    &(stpinfo->config.root_priou), 2))
-                       print_error("Bad STP config root priority range");
+                       ebt_print_error("Bad STP config root priority range");
                break;
        case EBT_STP_ROOTCOST:
                if (parse_range(argv[optind-1], &(stpinfo->config.root_costl),
                    &(stpinfo->config.root_costu), 4))
-                       print_error("Bad STP config root cost range");
+                       ebt_print_error("Bad STP config root cost range");
                break;
        case EBT_STP_SENDERPRIO:
                if (parse_range(argv[optind-1], &(stpinfo->config.sender_priol),
                    &(stpinfo->config.sender_priou), 2))
-                       print_error("Bad STP config sender priority range");
+                       ebt_print_error("Bad STP config sender priority range");
                break;
        case EBT_STP_PORT:
                if (parse_range(argv[optind-1], &(stpinfo->config.portl),
                    &(stpinfo->config.portu), 2))
-                       print_error("Bad STP config port range");
+                       ebt_print_error("Bad STP config port range");
                break;
        case EBT_STP_MSGAGE:
                if (parse_range(argv[optind-1], &(stpinfo->config.msg_agel),
                    &(stpinfo->config.msg_ageu), 2))
-                       print_error("Bad STP config message age range");
+                       ebt_print_error("Bad STP config message age range");
                break;
        case EBT_STP_MAXAGE:
                if (parse_range(argv[optind-1], &(stpinfo->config.max_agel),
                    &(stpinfo->config.max_ageu), 2))
-                       print_error("Bad STP config maximum age range");
+                       ebt_print_error("Bad STP config maximum age range");
                break;
        case EBT_STP_HELLOTIME:
                if (parse_range(argv[optind-1], &(stpinfo->config.hello_timel),
                    &(stpinfo->config.hello_timeu), 2))
-                       print_error("Bad STP config hello time range");
+                       ebt_print_error("Bad STP config hello time range");
                break;
        case EBT_STP_FWDD:
                if (parse_range(argv[optind-1], &(stpinfo->config.forward_delayl),
                    &(stpinfo->config.forward_delayu), 2))
-                       print_error("Bad STP config forward delay range");
+                       ebt_print_error("Bad STP config forward delay range");
                break;
        case EBT_STP_ROOTADDR:
                if (ebt_get_mac_and_mask(argv[optind-1],
                    stpinfo->config.root_addr, stpinfo->config.root_addrmsk))
-                       print_error("Bad STP config root address");
+                       ebt_print_error("Bad STP config root address");
                break;
        case EBT_STP_SENDERADDR:
                if (ebt_get_mac_and_mask(argv[optind-1], stpinfo->config.sender_addr,
                    stpinfo->config.sender_addrmsk))
-                       print_error("Bad STP config sender address");
+                       ebt_print_error("Bad STP config sender address");
                break;
        default:
-               print_error("stp match: this shouldn't happen");
+               ebt_print_error("stp match: this shouldn't happen");
        }
        return 1;
 }
@@ -231,9 +232,9 @@ static void final_check(const struct ebt_u_entry *entry,
 
        if (memcmp(entry->destmac, bridge_ula, 6) ||
            memcmp(entry->destmsk, msk, 6))
-               print_error("STP matching is only valid when the destination"
-                           " MAC address is the bridge group address (BGA)"
-                           " 01:80:c2:00:00:00");
+               ebt_print_error("STP matching is only valid when the "
+                               "destination MAC address is the bridge group "
+                               "address (BGA) 01:80:c2:00:00:00");
 }
 
 static void print(const struct ebt_u_entry *entry,
@@ -305,8 +306,7 @@ static struct ebt_u_match stp_match =
        .extra_ops      = opts,
 };
 
-static void _init(void) __attribute__ ((constructor));
-static void _init(void)
+void _init(void)
 {
        ebt_register_match(&stp_match);
 }
index 5a8a912..b4e1d38 100644 (file)
@@ -44,9 +44,9 @@
 #define GET_BITMASK(_MASK_) vlaninfo->bitmask & _MASK_
 #define SET_BITMASK(_MASK_) vlaninfo->bitmask |= _MASK_
 #define INV_FLAG(_inv_flag_) (vlaninfo->invflags & _inv_flag_) ? "! " : ""
-#define CHECK_IF_MISSING_VALUE if (optind > argc) print_error ("Missing %s value", opts[c].name);
+#define CHECK_IF_MISSING_VALUE if (optind > argc) ebt_print_error ("Missing %s value", opts[c].name);
 #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 CHECK_RANGE(_RANGE_) if (_RANGE_) ebt_print_error ("Invalid %s range", opts[c].name);
 
 #define NAME_VLAN_ID    "id"
 #define NAME_VLAN_PRIO  "prio"
@@ -168,8 +168,8 @@ parse(int c,
                if (*end != '\0') {
                        ethent = getethertypebyname(argv[optind - 1]);
                        if (ethent == NULL)
-                               print_error("Unknown %s encap",
-                                           opts[c].name);
+                               ebt_print_error("Unknown %s encap",
+                                               opts[c].name);
                        local.encap = ethent->e_ethertype;
                }
                CHECK_RANGE(local.encap < ETH_ZLEN);
@@ -199,16 +199,16 @@ final_check(const struct ebt_u_entry *entry,
         * Specified proto isn't 802.1Q?
         */
        if (entry->ethproto != ETH_P_8021Q || entry->invflags & EBT_IPROTO)
-               print_error
-                   ("For use 802.1Q extension the protocol must be specified as 802_1Q");
+               ebt_print_error("For use 802.1Q extension the protocol "
+                               "must be specified as 802_1Q");
        /*
         * Check if specified vlan-encap=0x8100 (802.1Q Frame) 
         * when vlan-encap specified.
         */
        if (GET_BITMASK(EBT_VLAN_ENCAP)) {
                if (vlaninfo->encap == htons(0x8100))
-                       print_error
-                           ("Encapsulated frame type can not be 802.1Q (0x8100)");
+                       ebt_print_error("Encapsulated frame type can not be "
+                               "802.1Q (0x8100)");
        }
 
        /*
@@ -217,8 +217,8 @@ final_check(const struct ebt_u_entry *entry,
         */
        if (GET_BITMASK(EBT_VLAN_PRIO)) {
                if (vlaninfo->id && GET_BITMASK(EBT_VLAN_ID))
-                       print_error
-                           ("For use user_priority the specified vlan-id must be 0");
+                       ebt_print_error("For use user_priority the specified "
+                                       "vlan-id must be 0");
        }
 }
 
@@ -318,8 +318,7 @@ static struct ebt_u_match vlan_match = {
        .extra_ops      = opts,
 };
 
-static void _init(void) __attribute__ ((constructor));
-static void _init(void)
+void _init(void)
 {
        ebt_register_match(&vlan_match);
 }
index 362183a..3c00962 100644 (file)
@@ -15,8 +15,7 @@ ebt_u_table table =
        .help           = print_help,
 };
 
-static void _init(void) __attribute__ ((constructor));
-static void _init(void)
+void _init(void)
 {
        ebt_register_table(&table);
 }
index 904a857..08f5033 100644 (file)
@@ -21,8 +21,7 @@ static struct ebt_u_table table =
        .help           = print_help,
 };
 
-static void _init(void) __attribute__ ((constructor));
-static void _init(void)
+void _init(void)
 {
        ebt_register_table(&table);
 }
index b151dc5..d64e21d 100644 (file)
@@ -22,8 +22,7 @@ ebt_u_table table =
        .help           = print_help,
 };
 
-static void _init(void) __attribute__ ((constructor));
-static void _init(void)
+void _init(void)
 {
        ebt_register_table(&table);
 }
index 77d1e50..5b040d2 100644 (file)
@@ -126,7 +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 */
+       /* the standard target needs this to know the name of a udc when
+        * printing out rules. */
        struct ebt_u_replace *replace;
 };
 
@@ -223,7 +224,7 @@ 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_table *table, int init);
 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);
@@ -264,12 +265,12 @@ 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, ...);
+void __ebt_print_bug(char *file, int line, char *format, ...);
+void __ebt_print_error(char *format, ...);
 
 /* communication.c */
 
-int ebt_get_table(struct ebt_u_replace *repl);
+int ebt_get_table(struct ebt_u_replace *repl, int init);
 void ebt_deliver_counters(struct ebt_u_replace *repl);
 void ebt_deliver_table(struct ebt_u_replace *repl);
 
@@ -286,10 +287,10 @@ 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...) __print_error(format, ##args);
-#define print_memory() {printf("Ebtables: " __FILE__ \
+#define ebt_print_bug(format, args...) \
+   __ebt_print_bug(__FILE__, __LINE__, format, ##args)
+#define ebt_print_error(format,args...) __ebt_print_error(format, ##args);
+#define ebt_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 */
index 843a6a5..11d1880 100644 (file)
--- a/libebtc.c
+++ b/libebtc.c
@@ -147,27 +147,30 @@ void ebt_list_extensions()
 
 /*
  * Get the table from the kernel or from a binary file
+ * init: 1 = ask the kernel for the initial contents of a table, i.e. the
+ *           way it looks when the table is insmod'ed
+ *       0 = get the current data in the table
  */
 void ebt_get_kernel_table(struct ebt_u_replace *replace,
-                         struct ebt_u_table *table)
+                         struct ebt_u_table *table, int init)
 {
        if ( !(table = ebt_find_table(replace->name)) )
-               print_error("Bad table name");
+               ebt_print_error("Bad table name");
        /*
         * get the kernel's information
         */
-       if (ebt_get_table(replace)) {
+       if (ebt_get_table(replace, init)) {
                ebtables_insmod("ebtables");
-               if (ebt_get_table(replace))
-                       print_error("The kernel doesn't support the ebtables "
-                                   "%s table", replace->name);
+               if (ebt_get_table(replace, init))
+                       ebt_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
+        * the user knows the table's name, so we update table if necessary
         */
        if ( !(table = ebt_find_table(replace->name)) )
-               print_error("Bad table name");
+               ebt_print_error("Bad table name");
 }
 
 /*
@@ -185,9 +188,11 @@ void ebt_initialize_entry(struct ebt_u_entry *e)
        e->m_list = NULL;
        e->w_list = NULL;
        e->t = (struct ebt_entry_target *)ebt_find_target(EBT_STANDARD_TARGET);
+
        if (!e->t)
-               print_bug("Couldn't load standard target");
-       ((struct ebt_standard_target *)e->t)->verdict = EBT_CONTINUE;
+               ebt_print_bug("Couldn't load standard target");
+       ((struct ebt_standard_target *)
+       ((struct ebt_u_target *)e->t)->t)->verdict = EBT_CONTINUE;
 }
 
 /*
@@ -262,20 +267,39 @@ void ebt_reinit_extensions(struct ebt_u_replace *replace)
        struct ebt_u_match *m;
        struct ebt_u_watcher *w;
        struct ebt_u_target *t;
+       int size;
 
        /* The init functions should determine by themselves whether they are
         * called for the first time or not (when necessary). */
        for (m = ebt_matches; m; m = m->next) {
+               size = EBT_ALIGN(m->size) + sizeof(struct ebt_entry_match);
+               if (m->m)
+                       free(m->m);
+               m->m = (struct ebt_entry_match *)malloc(size);
+               if (!m->m)
+                       ebt_print_memory();
                m->used = 0;
                m->flags = 0;
                m->init(m->m);
        }
        for (w = ebt_watchers; w; w = w->next) {
+               size = EBT_ALIGN(w->size) + sizeof(struct ebt_entry_watcher);
+               if (w->w)
+                       free(w->w);
+               w->w = (struct ebt_entry_watcher *)malloc(size);
+               if (!w->w)
+                       ebt_print_memory();
                w->used = 0;
                w->flags = 0;
                w->init(w->w);
        }
        for (t = ebt_targets; m; t = t->next) {
+               size = EBT_ALIGN(t->size) + sizeof(struct ebt_entry_target);
+               if (t->t)
+                       free(t->t);
+               t->t = (struct ebt_entry_target *)malloc(size);
+               if (!t->t)
+                       ebt_print_memory();
                t->used = 0;
                t->flags = 0;
                t->init(t->t);
@@ -475,7 +499,7 @@ void ebt_change_policy(struct ebt_u_replace *replace, int policy)
        struct ebt_u_entries *entries = ebt_to_chain(replace);
 
        if (policy < -NUM_STANDARD_TARGETS || policy == EBT_CONTINUE)
-               print_bug("wrong policy: %d", policy);
+               ebt_print_bug("wrong policy: %d", policy);
        entries->policy = policy;
 }
 
@@ -623,7 +647,7 @@ int ebt_check_rule_exists(struct ebt_u_replace *replace,
         */
        for (i = 0; i < entries->nentries; i++, u_e = u_e->next) {
                if (!u_e)
-                       print_bug("Hmm, trouble");
+                       ebt_print_bug("Hmm, trouble");
                if (u_e->ethproto != new_entry->ethproto)
                        continue;
                if (strcmp(u_e->in, new_entry->in))
@@ -731,7 +755,7 @@ void ebt_add_rule(struct ebt_u_replace *replace, struct ebt_u_entry *new_entry,
        else
                rule_nr--;
        if (rule_nr > entries->nentries || rule_nr < 0)
-               print_error("The specified rule number is incorrect");
+               ebt_print_error("The specified rule number is incorrect");
        /*
         * we're adding one rule
         */
@@ -763,7 +787,8 @@ void ebt_add_rule(struct ebt_u_replace *replace, struct ebt_u_entry *new_entry,
                                        * the delete */
                cc->type = CNT_OWRITE;
        else {
-               new_cc = (struct ebt_cntchanges *)malloc(sizeof(struct ebt_cntchanges));
+               new_cc = (struct ebt_cntchanges *)
+                        malloc(sizeof(struct ebt_cntchanges));
                new_cc->type = CNT_ADD;
                new_cc->next = cc;
                *prev_cc = new_cc;
@@ -836,11 +861,11 @@ void ebt_delete_rule(struct ebt_u_replace *replace,
                end += entries->nentries + 1;
 
        if (begin < 0 || begin > end || end > entries->nentries)
-               print_error("Sorry, wrong rule numbers");
+               ebt_print_error("Sorry, wrong rule numbers");
 
        if ((begin * end == 0) && (begin + end != 0))
-               print_bug("begin and end should be either both zero, either"
-                         " both non-zero");
+               ebt_print_bug("begin and end should be either both zero, "
+                             "either both non-zero");
        if (begin != 0 && end != 0) {
                begin--;
                end--;
@@ -848,7 +873,7 @@ void ebt_delete_rule(struct ebt_u_replace *replace,
                begin = ebt_check_rule_exists(replace, new_entry);
                end = begin;
                if (begin == -1)
-                       print_error("Sorry, rule does not exist");
+                       ebt_print_error("Sorry, rule does not exist");
        }
 
        /*
@@ -981,21 +1006,21 @@ void ebt_new_chain(struct ebt_u_replace *replace, const char *name, int policy)
        struct ebt_u_chain_list *cl, **cl2;
 
        if (ebt_get_chainnr(replace, name) != -1)
-               print_error("Chain %s already exists", optarg);
+               ebt_print_error("Chain %s already exists", optarg);
        if (ebt_find_target(name))
-               print_error("Target with name %s exists", optarg);
+               ebt_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);
+               ebt_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();
+               ebt_print_memory();
        cl->next = NULL;
        cl->udc = (struct ebt_u_entries *)
           malloc(sizeof(struct ebt_u_entries));
        if (!cl->udc)
-               print_memory();
+               ebt_print_memory();
        cl->udc->nentries = 0;
        cl->udc->policy = policy;
        cl->udc->counter_offset = replace->nentries;
@@ -1021,14 +1046,14 @@ void ebt_delete_chain(struct ebt_u_replace *replace)
        int chain_nr = replace->selected_chain;
 
        if (chain_nr != -1 && chain_nr < NF_BR_NUMHOOKS)
-               print_bug("You can't remove a standard chain");
+               ebt_print_bug("You can't remove a standard chain");
        if (chain_nr == -1)
                replace->selected_chain = NF_BR_NUMHOOKS;
        do {
                if (ebt_to_chain(replace) == NULL) {
                        if (chain_nr == -1)
                                break;
-                       print_bug("udc nr %d doesn't exist", chain_nr);
+                       ebt_print_bug("udc nr %d doesn't exist", chain_nr);
                }
                /*
                 * if the chain is referenced, don't delete it,
@@ -1054,7 +1079,7 @@ void ebt_rename_chain(struct ebt_u_replace *replace, const char *name)
        struct ebt_u_entries *entries = ebt_to_chain(replace);
 
        if (!entries)
-               print_bug("ebt_rename_chain: entries == NULL");
+               ebt_print_bug("ebt_rename_chain: entries == NULL");
        strcpy(entries->name, name);
 }
 
@@ -1163,7 +1188,7 @@ void ebt_check_for_loops(struct ebt_u_replace *replace)
                stack = (struct ebt_u_stack *)malloc((i - NF_BR_NUMHOOKS) *
                   sizeof(struct ebt_u_stack));
                if (!stack)
-                       print_memory();
+                       ebt_print_memory();
        }
 
        /*
@@ -1195,7 +1220,7 @@ void ebt_check_for_loops(struct ebt_u_replace *replace)
                         */
                        for (k = 0; k < sp; k++)
                                if (stack[k].chain_nr == verdict + NF_BR_NUMHOOKS)
-                                       print_error("Loop from chain %s to chain %s",
+                                       ebt_print_error("Loop from chain %s to chain %s",
                                           ebt_nr_to_chain(replace, chain_nr)->name,
                                           ebt_nr_to_chain(replace, stack[k].chain_nr)->name);
                        /*
@@ -1244,7 +1269,7 @@ void ebt_add_match(struct ebt_u_entry *new_entry, struct ebt_u_match *m)
        new = (struct ebt_u_match_list *)
           malloc(sizeof(struct ebt_u_match_list));
        if (!new)
-               print_memory();
+               ebt_print_memory();
        *m_list = new;
        new->next = NULL;
        new->m = (struct ebt_entry_match *)m;
@@ -1259,7 +1284,7 @@ void ebt_add_watcher(struct ebt_u_entry *new_entry, struct ebt_u_watcher *w)
        new = (struct ebt_u_watcher_list *)
           malloc(sizeof(struct ebt_u_watcher_list));
        if (!new)
-               print_memory();
+               ebt_print_memory();
        *w_list = new;
        new->next = NULL;
        new->w = (struct ebt_entry_watcher *)w;
@@ -1289,7 +1314,7 @@ static int iterate_entries(struct ebt_u_replace *replace, int type)
        struct ebt_u_entry *e;
 
        if (chain_nr < 0)
-               print_bug("iterate_entries: udc = %d < 0", chain_nr);
+               ebt_print_bug("iterate_entries: udc = %d < 0", chain_nr);
        while (1) {
                i++;
                entries = ebt_nr_to_chain(replace, i);
@@ -1309,11 +1334,12 @@ static int iterate_entries(struct ebt_u_replace *replace, int type)
                                e = e->next;
                                continue;
                        }
-                       chain_jmp = ((struct ebt_standard_target *)e->t)->verdict;
+                       chain_jmp = ((struct ebt_standard_target *)e->t)->
+                                   verdict;
                        switch (type) {
                        case 1:
                        if (chain_jmp == chain_nr) {
-                               print_error("Can't delete the chain, it's "
+                               ebt_print_error("Can't delete the chain, it's "
                                   "referenced in chain %s, rule %d",
                                   entries->name, j);
                                return 1;
@@ -1347,8 +1373,8 @@ static void remove_udc(struct ebt_u_replace *replace)
        int chain_nr = replace->selected_chain;
 
        if (chain_nr < NF_BR_NUMHOOKS)
-               print_bug("remove_udc: chain_nr = %d < %d", chain_nr,
-                           NF_BR_NUMHOOKS);
+               ebt_print_bug("remove_udc: chain_nr = %d < %d", chain_nr,
+                             NF_BR_NUMHOOKS);
        /* first free the rules */
        entries = ebt_nr_to_chain(replace, chain_nr);
        u_e = entries->entries;
@@ -1380,7 +1406,7 @@ void ebt_register_match(struct ebt_u_match *m)
 
        m->m = (struct ebt_entry_match *)malloc(size);
        if (!m->m)
-               print_memory();
+               ebt_print_memory();
        strcpy(m->m->u.name, m->name);
        m->m->match_size = EBT_ALIGN(m->size);
        m->init(m->m);
@@ -1397,7 +1423,7 @@ void ebt_register_watcher(struct ebt_u_watcher *w)
 
        w->w = (struct ebt_entry_watcher *)malloc(size);
        if (!w->w)
-               print_memory();
+               ebt_print_memory();
        strcpy(w->w->u.name, w->name);
        w->w->watcher_size = EBT_ALIGN(w->size);
        w->init(w->w);
@@ -1414,7 +1440,7 @@ void ebt_register_target(struct ebt_u_target *t)
 
        t->t = (struct ebt_entry_target *)malloc(size);
        if (!t->t)
-               print_memory();
+               ebt_print_memory();
        strcpy(t->t->u.name, t->name);
        t->t->target_size = EBT_ALIGN(t->size);
        t->init(t->t);
@@ -1455,9 +1481,9 @@ void ebt_iterate_targets(void (*f)(struct ebt_u_target *))
 }
 
 /*
- * Don't use this function, use print_bug()
+ * Don't use this function, use ebt_print_bug()
  */
-void __print_bug(char *file, int line, char *format, ...)
+void __ebt_print_bug(char *file, int line, char *format, ...)
 {
        va_list l;
 
@@ -1480,9 +1506,9 @@ char ebt_errormsg[ERRORMSG_MAXLEN];
  */
 int ebt_silent;
 /*
- * Don't use this function, use print_error()
+ * Don't use this function, use ebt_print_error()
  */
-void __print_error(char *format, ...)
+void __ebt_print_error(char *format, ...)
 {
        va_list l;
 
index cec0cc4..5c45cb9 100644 (file)
@@ -85,9 +85,9 @@ void ebt_print_mac_and_mask(const char *mac, const char *mask)
 struct ethertypeent *parseethertypebynumber(int type)
 {
        if (type < 1536)
-               print_error("Ethernet protocols have values >= 0x0600");
+               ebt_print_error("Ethernet protocols have values >= 0x0600");
        if (type > 0xffff)
-               print_error("Ethernet protocols have values <= 0xffff");
+               ebt_print_error("Ethernet protocols have values <= 0xffff");
        return getethertypebynumber(type);
 }
 
@@ -141,7 +141,7 @@ int ebt_check_inverse(const char option[])
 {
        if (strcmp(option, "!") == 0) {
                if (ebt_invert == 1)
-                       print_error("double use of '!' not allowed");
+                       ebt_print_error("double use of '!' not allowed");
                optind++;
                ebt_invert = 1;
                return 1;
@@ -152,7 +152,7 @@ int ebt_check_inverse(const char option[])
 void ebt_check_option(unsigned int *flags, unsigned int mask)
 {
        if (*flags & mask)
-               print_error("Multiple use of same option not allowed");
+               ebt_print_error("Multiple use of same option not allowed");
        *flags |= mask;
 }
 
@@ -218,12 +218,12 @@ void ebt_parse_ip_address(char *address, uint32_t *addr, uint32_t *msk)
        if ((p = strrchr(address, '/')) != NULL) {
                *p = '\0';
                if (ip_mask(p + 1, (unsigned char *)msk))
-                       print_error("Problem with the IP mask");
+                       ebt_print_error("Problem with the IP mask");
        } else
                *msk = 0xFFFFFFFF;
 
        if (undot_ip(address, (unsigned char *)addr))
-               print_error("Problem with the IP address");
+               ebt_print_error("Problem with the IP address");
        *addr = *addr & *msk;
 }