]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
Philip Blundell's IPv6 fixes.
authorPhilip Blundell <Philip.Blundell@pobox.com>
Mon, 15 May 2000 02:17:52 +0000 (02:17 +0000)
committerRusty Russell <rusty@rustcorp.com.au>
Mon, 15 May 2000 02:17:52 +0000 (02:17 +0000)
Makefile
include/ip6tables.h
include/libiptc/libip6tc.h
libiptc/libip4tc.c
libiptc/libip6tc.c
libiptc/libiptc.c

index be2e7192a3e2bb91b326c7b8acf26ab6b9d7deb8..ea219bed5e73639999895f03e928df19b4f3d115 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -11,8 +11,8 @@ LIBDIR:=/usr/local/lib
 BINDIR:=/usr/local/bin
 MANDIR:=/usr/local/man
 
-COPT_FLAGS:=-O #-O2
-CFLAGS:=$(COPT_FLAGS) -Wall -Wunused -Iinclude/ -I$(KERNEL_DIR)/include -DNETFILTER_VERSION=\"$(NETFILTER_VERSION)\" -g #-pg # -DNDEBUG
+COPT_FLAGS:=-O2
+CFLAGS:=$(COPT_FLAGS) -Wall -Wunused -Iinclude/ -I$(KERNEL_DIR)/include -DNDEBUG -DNETFILTER_VERSION=\"$(NETFILTER_VERSION)\" #-g #-pg # -DNDEBUG
 
 DEPFILES = $(SHARED_LIBS:%.so=%.d)
 SH_CFLAGS:=$(CFLAGS) -fPIC
@@ -56,6 +56,30 @@ $(DESTDIR)$(BINDIR)/iptables-restore: iptables-restore
        @[ -d $(DESTDIR)$(BINDIR) ] || mkdir -p $(DESTDIR)$(BINDIR)
        cp $< $@
 
+ip6tables.o: ip6tables.c
+       $(CC) $(CFLAGS) -DIPT_LIB_DIR=\"$(IPT_LIBDIR)\" -c -o $@ $<
+
+ip6tables: ip6tables-standalone.c ip6tables.o libiptc/libiptc.a
+       $(CC) $(CFLAGS) -DIPT_LIB_DIR=\"$(IPT_LIBDIR)\" -rdynamic -o $@ $^ -ldl
+
+$(DESTDIR)$(BINDIR)/ip6tables: ip6tables
+       @[ -d $(DESTDIR)$(BINDIR) ] || mkdir -p $(DESTDIR)$(BINDIR)
+       cp $< $@
+
+ip6tables-save: ip6tables-save.c ip6tables.o libiptc/libiptc.a
+       $(CC) $(CFLAGS) -DIPT_LIB_DIR=\"$(IPT_LIBDIR)\" -rdynamic -o $@ $^ -ldl
+
+$(DESTDIR)$(BINDIR)/ip6tables-save: ip6tables-save
+       @[ -d $(DESTDIR)$(BINDIR) ] || mkdir -p $(DESTDIR)$(BINDIR)
+       cp $< $@
+
+ip6tables-restore: ip6tables-restore.c ip6tables.o libiptc/libiptc.a
+       $(CC) $(CFLAGS) -DIPT_LIB_DIR=\"$(IPT_LIBDIR)\" -rdynamic -o $@ $^ -ldl
+
+$(DESTDIR)$(BINDIR)/ip6tables-restore: ip6tables-restore
+       @[ -d $(DESTDIR)$(BINDIR) ] || mkdir -p $(DESTDIR)$(BINDIR)
+       cp $< $@
+
 $(DESTDIR)$(MANDIR)/man8/iptables.8: iptables.8
        @[ -d $(DESTDIR)$(MANDIR)/man8 ] || mkdir -p $(DESTDIR)$(MANDIR)/man8
        cp $< $@
index 7acf800bca1a9583dd9c1fcda2fe535af96b9877..9860e62fe696b5a19c79cfbd56e61c8cc7675b5d 100644 (file)
@@ -16,6 +16,9 @@ struct ip6tables_match
        /* Size of match data. */
        size_t size;
 
+       /* Size of match data relevent for userspace comparison purposes */
+       size_t userspacesize;
+
        /* Function which prints out usage message. */
        void (*help)(void);
 
@@ -60,6 +63,9 @@ struct ip6tables_target
        /* Size of target data. */
        size_t size;
 
+       /* Size of target data relevent for userspace comparison purposes */
+       size_t userspacesize;
+
        /* Function which prints out usage message. */
        void (*help)(void);
 
@@ -102,6 +108,12 @@ extern int do_command6(int argc, char *argv[], char **table,
 extern struct ip6tables_match *ip6tables_matches;
 extern struct ip6tables_target *ip6tables_targets;
 
-extern struct ip6tables_target *find_target6(const char *name, int tryload);
-extern struct ip6tables_match *find_match6(const char *name, int tryload);
+enum ip6t_tryload {
+       DONT_LOAD,
+       TRY_LOAD,
+       LOAD_MUST_SUCCEED
+};
+
+extern struct ip6tables_target *find_target6(const char *name, enum ip6t_tryload);
+extern struct ip6tables_match *find_match6(const char *name, enum ip6t_tryload);
 #endif /*_IP6TABLES_USER_H*/
index ad507c8d4f1b55d07e5bbb191f499afd0790468a..599e0db69b9471304eb8e5a18694c307089057fc 100644 (file)
@@ -27,16 +27,16 @@ int ip6tc_is_chain(const char *chain, const ip6tc_handle_t handle);
 ip6tc_handle_t ip6tc_init(const char *tablename);
 
 /* Iterator functions to run through the chains.  Returns NULL at end. */
-const char *iptc_first_chain(ip6tc_handle_t *handle);
+const char *ip6tc_first_chain(ip6tc_handle_t *handle);
 const char *ip6tc_next_chain(ip6tc_handle_t *handle);
 
-/* How many rules in this chain? */
-unsigned int ip6tc_num_rules(const char *chain, ip6tc_handle_t *handle);
+/* Get first rule in the given chain: NULL for empty chain. */
+const struct ip6t_entry *ip6tc_first_rule(const char *chain,
+                                         ip6tc_handle_t *handle);
 
-/* Get n'th rule in this chain. */
-const struct ip6t_entry *ip6tc_get_rule(const char *chain,
-                                       unsigned int n,
-                                       ip6tc_handle_t *handle);
+/* Returns NULL when rules run out. */
+const struct ip6t_entry *ip6tc_next_rule(const struct ip6t_entry *prev,
+                                        ip6tc_handle_t *handle);
 
 /* Returns a pointer to the target name of this position. */
 const char *ip6tc_get_target(const struct ip6t_entry *e,
index 57a6fb65431dadff3f806553472dd43f4c487055..e1d7f8f412393de06a555c79d2769fe9b45dc95d 100644 (file)
@@ -62,9 +62,10 @@ typedef unsigned int socklen_t;
 
 #define TC_DUMP_ENTRIES                dump_entries
 #define TC_IS_CHAIN            iptc_is_chain
+#define TC_FIRST_CHAIN         iptc_first_chain
 #define TC_NEXT_CHAIN          iptc_next_chain
-#define TC_NUM_RULES           iptc_num_rules
-#define TC_GET_RULE            iptc_get_rule
+#define TC_FIRST_RULE          iptc_first_rule
+#define TC_NEXT_RULE           iptc_next_rule
 #define TC_GET_TARGET          iptc_get_target
 #define TC_BUILTIN             iptc_builtin
 #define TC_GET_POLICY          iptc_get_policy
index 10bcf5a53c4bee252924eaa068fd77f3164e7f38..dae85eb5829a95bd5433c0646c3b76aed8aafa5e 100644 (file)
@@ -60,9 +60,10 @@ typedef unsigned int socklen_t;
 
 #define TC_DUMP_ENTRIES                dump_entries6
 #define TC_IS_CHAIN            ip6tc_is_chain
+#define TC_FIRST_CHAIN         ip6tc_first_chain
 #define TC_NEXT_CHAIN          ip6tc_next_chain
-#define TC_NUM_RULES           ip6tc_num_rules
-#define TC_GET_RULE            ip6tc_get_rule
+#define TC_FIRST_RULE          ip6tc_first_rule
+#define TC_NEXT_RULE           ip6tc_next_rule
 #define TC_GET_TARGET          ip6tc_get_target
 #define TC_BUILTIN             ip6tc_builtin
 #define TC_GET_POLICY          ip6tc_get_policy
@@ -263,3 +264,121 @@ is_same(const STRUCT_ENTRY *a, const STRUCT_ENTRY *b,
 
        return 1;
 }
+
+#ifndef NDEBUG
+/* Do every conceivable sanity check on the handle */
+static void
+do_check(TC_HANDLE_T h, unsigned int line)
+{
+       unsigned int i, n;
+       unsigned int user_offset; /* Offset of first user chain */
+       int was_return;
+
+       assert(h->changed == 0 || h->changed == 1);
+       if (strcmp(h->info.name, "filter") == 0) {
+               assert(h->info.valid_hooks
+                      == (1 << NF_IP6_LOCAL_IN
+                          | 1 << NF_IP6_FORWARD
+                          | 1 << NF_IP6_LOCAL_OUT));
+
+               /* Hooks should be first three */
+               assert(h->info.hook_entry[NF_IP6_LOCAL_IN] == 0);
+
+               n = get_chain_end(h, 0);
+               n += get_entry(h, n)->next_offset;
+               assert(h->info.hook_entry[NF_IP6_FORWARD] == n);
+
+               n = get_chain_end(h, n);
+               n += get_entry(h, n)->next_offset;
+               assert(h->info.hook_entry[NF_IP6_LOCAL_OUT] == n);
+
+               user_offset = h->info.hook_entry[NF_IP6_LOCAL_OUT];
+       } else if (strcmp(h->info.name, "nat") == 0) {
+               assert(h->info.valid_hooks
+                      == (1 << NF_IP6_PRE_ROUTING
+                          | 1 << NF_IP6_POST_ROUTING
+                          | 1 << NF_IP6_LOCAL_OUT));
+
+               assert(h->info.hook_entry[NF_IP6_PRE_ROUTING] == 0);
+
+               n = get_chain_end(h, 0);
+               n += get_entry(h, n)->next_offset;
+               assert(h->info.hook_entry[NF_IP6_POST_ROUTING] == n);
+
+               n = get_chain_end(h, n);
+               n += get_entry(h, n)->next_offset;
+               assert(h->info.hook_entry[NF_IP6_LOCAL_OUT] == n);
+
+               user_offset = h->info.hook_entry[NF_IP6_LOCAL_OUT];
+       } else if (strcmp(h->info.name, "mangle") == 0) {
+               assert(h->info.valid_hooks
+                      == (1 << NF_IP6_PRE_ROUTING
+                          | 1 << NF_IP6_LOCAL_OUT));
+
+               /* Hooks should be first three */
+               assert(h->info.hook_entry[NF_IP6_PRE_ROUTING] == 0);
+
+               n = get_chain_end(h, 0);
+               n += get_entry(h, n)->next_offset;
+               assert(h->info.hook_entry[NF_IP6_LOCAL_OUT] == n);
+
+               user_offset = h->info.hook_entry[NF_IP6_LOCAL_OUT];
+       } else
+               abort();
+
+       /* User chain == end of last builtin + policy entry */
+       user_offset = get_chain_end(h, user_offset);
+       user_offset += get_entry(h, user_offset)->next_offset;
+
+       /* Overflows should be end of entry chains, and unconditional
+           policy nodes. */
+       for (i = 0; i < NUMHOOKS; i++) {
+               STRUCT_ENTRY *e;
+               STRUCT_STANDARD_TARGET *t;
+
+               if (!(h->info.valid_hooks & (1 << i)))
+                       continue;
+               assert(h->info.underflow[i]
+                      == get_chain_end(h, h->info.hook_entry[i]));
+
+               e = get_entry(h, get_chain_end(h, h->info.hook_entry[i]));
+//             assert(unconditional(&e->ipv6));
+               assert(e->target_offset == sizeof(*e));
+               t = (STRUCT_STANDARD_TARGET *)GET_TARGET(e);
+               assert(t->target.u.target_size == ALIGN(sizeof(*t)));
+               assert(e->next_offset == sizeof(*e) + ALIGN(sizeof(*t)));
+
+               assert(strcmp(t->target.u.user.name, STANDARD_TARGET)==0);
+               assert(t->verdict == -NF_DROP-1 || t->verdict == -NF_ACCEPT-1);
+
+               /* Hooks and underflows must be valid entries */
+               entry2index(h, get_entry(h, h->info.hook_entry[i]));
+               entry2index(h, get_entry(h, h->info.underflow[i]));
+       }
+
+       assert(h->info.size
+              >= h->info.num_entries * (sizeof(STRUCT_ENTRY)
+                                        +sizeof(STRUCT_STANDARD_TARGET)));
+
+       assert(h->entries.size
+              >= (h->new_number
+                  * (sizeof(STRUCT_ENTRY)
+                     + sizeof(STRUCT_STANDARD_TARGET))));
+       assert(strcmp(h->info.name, h->entries.name) == 0);
+
+       i = 0; n = 0;
+       was_return = 0;
+
+       /* Check all the entries. */
+//     ENTRY_ITERATE(h->entries.entries, h->entries.size,
+//                   check_entry, &i, &n, user_offset, &was_return, h);
+
+       assert(i == h->new_number);
+       assert(n == h->entries.size);
+
+       /* Final entry must be error node */
+       assert(strcmp(GET_TARGET(index2entry(h, h->new_number-1))
+                     ->u.user.name,
+                     ERROR_TARGET) == 0);
+}
+#endif /*NDEBUG*/
index 141a58494c07c910a7805d7e40c0f493d62bd023..ddbea747409a3d601ae082d6da5406313538387b 100644 (file)
@@ -478,7 +478,7 @@ get_chain_end(const TC_HANDLE_T handle, unsigned int start)
 
 /* Iterator functions to run through the chains. */
 const char *
-iptc_first_chain(TC_HANDLE_T *handle)
+TC_FIRST_CHAIN(TC_HANDLE_T *handle)
 {
        if ((*handle)->cache_chain_heads == NULL
            && !populate_cache(*handle))
@@ -505,7 +505,7 @@ TC_NEXT_CHAIN(TC_HANDLE_T *handle)
 
 /* Get first rule in the given chain: NULL for empty chain. */
 const STRUCT_ENTRY *
-iptc_first_rule(const char *chain, TC_HANDLE_T *handle)
+TC_FIRST_RULE(const char *chain, TC_HANDLE_T *handle)
 {
        struct chain_cache *c;
 
@@ -525,7 +525,7 @@ iptc_first_rule(const char *chain, TC_HANDLE_T *handle)
 
 /* Returns NULL when rules run out. */
 const STRUCT_ENTRY *
-iptc_next_rule(const STRUCT_ENTRY *prev, TC_HANDLE_T *handle)
+TC_NEXT_RULE(const STRUCT_ENTRY *prev, TC_HANDLE_T *handle)
 {
        if ((void *)prev + prev->next_offset
            == (void *)(*handle)->cache_rule_end)
@@ -831,7 +831,7 @@ standard_map(STRUCT_ENTRY *e, int verdict)
        t = (STRUCT_STANDARD_TARGET *)GET_TARGET(e);
 
        if (t->target.u.target_size
-           != IPT_ALIGN(sizeof(STRUCT_STANDARD_TARGET))) {
+           != ALIGN(sizeof(STRUCT_STANDARD_TARGET))) {
                errno = EINVAL;
                return 0;
        }
@@ -1236,18 +1236,18 @@ TC_CREATE_CHAIN(const IPT_CHAINLABEL chain, TC_HANDLE_T *handle)
        newc.head.target_offset = sizeof(STRUCT_ENTRY);
        newc.head.next_offset
                = sizeof(STRUCT_ENTRY)
-               + IPT_ALIGN(sizeof(struct ipt_error_target));
+               + ALIGN(sizeof(struct ipt_error_target));
        strcpy(newc.name.t.u.user.name, ERROR_TARGET);
-       newc.name.t.u.target_size = IPT_ALIGN(sizeof(struct ipt_error_target));
+       newc.name.t.u.target_size = ALIGN(sizeof(struct ipt_error_target));
        strcpy(newc.name.error, chain);
 
        newc.ret.target_offset = sizeof(STRUCT_ENTRY);
        newc.ret.next_offset
                = sizeof(STRUCT_ENTRY)
-               + IPT_ALIGN(sizeof(STRUCT_STANDARD_TARGET));
+               + ALIGN(sizeof(STRUCT_STANDARD_TARGET));
        strcpy(newc.target.target.u.user.name, STANDARD_TARGET);
        newc.target.target.u.target_size
-               = IPT_ALIGN(sizeof(STRUCT_STANDARD_TARGET));
+               = ALIGN(sizeof(STRUCT_STANDARD_TARGET));
        newc.target.verdict = RETURN;
 
        /* Add just before terminal entry */