summaryrefslogtreecommitdiffstats
path: root/libiptc
diff options
context:
space:
mode:
Diffstat (limited to 'libiptc')
-rw-r--r--libiptc/libip4tc.c5
-rw-r--r--libiptc/libip6tc.c123
-rw-r--r--libiptc/libiptc.c16
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 */