diff options
Diffstat (limited to 'libiptc')
-rw-r--r-- | libiptc/libip4tc.c | 5 | ||||
-rw-r--r-- | libiptc/libip6tc.c | 123 | ||||
-rw-r--r-- | libiptc/libiptc.c | 16 |
3 files changed, 132 insertions, 12 deletions
diff --git a/libiptc/libip4tc.c b/libiptc/libip4tc.c index 57a6fb65..e1d7f8f4 100644 --- a/libiptc/libip4tc.c +++ b/libiptc/libip4tc.c @@ -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 diff --git a/libiptc/libip6tc.c b/libiptc/libip6tc.c index 10bcf5a5..dae85eb5 100644 --- a/libiptc/libip6tc.c +++ b/libiptc/libip6tc.c @@ -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*/ diff --git a/libiptc/libiptc.c b/libiptc/libiptc.c index 141a5849..ddbea747 100644 --- a/libiptc/libiptc.c +++ b/libiptc/libiptc.c @@ -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 */ |