/* Take a snapshot of the rules. Returns NULL on error. */
iptc_handle_t iptc_init(const char *tablename);
-/* Iterator functions to run through the chains; prev = NULL means
- first chain. Returns NULL at end. */
-const char *iptc_next_chain(const char *prev, iptc_handle_t *handle);
+/* Iterator functions to run through the chains. Returns NULL at end. */
+const char *iptc_first_chain(iptc_handle_t *handle);
+const char *iptc_next_chain(iptc_handle_t *handle);
-/* How many rules in this chain? */
-unsigned int iptc_num_rules(const char *chain, iptc_handle_t *handle);
+/* Get first rule in the given chain: NULL for empty chain. */
+const struct ipt_entry *iptc_first_rule(const char *chain,
+ iptc_handle_t *handle);
-/* Get n'th rule in this chain. */
-const struct ipt_entry *iptc_get_rule(const char *chain,
- unsigned int n,
- iptc_handle_t *handle);
+/* Returns NULL when rules run out. */
+const struct ipt_entry *iptc_next_rule(const struct ipt_entry *prev,
+ iptc_handle_t *handle);
-/* Returns a pointer to the target name of this position. */
-const char *iptc_get_target(const char *chain,
- unsigned int n,
+/* Returns a pointer to the target name of this entry. */
+const char *iptc_get_target(const struct ipt_entry *e,
iptc_handle_t *handle);
/* Is this a built-in chain? */
#ifndef NDEBUG
static void do_check(iptc_handle_t h, unsigned int line);
-#define CHECK(h) do_check((h), __LINE__)
+#define CHECK(h) do { if (!getenv("IPTC_NO_CHECK")) do_check((h), __LINE__); } while(0)
#else
#define CHECK(h)
#endif
return 0;
}
-
static int alphasort(const void *a, const void *b)
{
return strcmp(((struct chain_cache *)a)->name,
((struct chain_cache *)b)->name);
}
-
static int populate_cache(iptc_handle_t h)
{
unsigned int i;
IPT_ENTRY_ITERATE(h->entries.entries, h->entries.size,
add_chain, h, &prev);
- /* Sort users by alphabetical: */
qsort(h->cache_chain_heads + h->cache_num_builtins,
h->cache_num_chains - h->cache_num_builtins,
sizeof(struct chain_cache), alphasort);
static struct chain_cache *
find_label(const char *name, iptc_handle_t handle)
{
- unsigned int start, end;
+ unsigned int i;
if (handle->cache_chain_heads == NULL
&& !populate_cache(handle))
return NULL;
- /* Linear search through builtins, then binary */
- for (start = 0; start < handle->cache_num_builtins; start++) {
- if (strcmp(handle->cache_chain_heads[start].name, name) == 0)
- return &handle->cache_chain_heads[start];
+ /* FIXME: Linear search through builtins, then binary --RR */
+ for (i = 0; i < handle->cache_num_chains; i++) {
+ if (strcmp(handle->cache_chain_heads[i].name, name) == 0)
+ return &handle->cache_chain_heads[i];
}
- /* Binary search. */
- end = handle->cache_num_chains - 1;
- while (start < end) {
- struct chain_cache *mid;
- int res;
-
- mid = &handle->cache_chain_heads[(start + end) / 2];
-
- res = strcmp(name, mid->name);
- if (res == 0) {
- return mid;
- } else if (res > 0)
- start = (start + end + 1) / 2;
- else
- end = (start + end) / 2;
- }
- if (strcmp(name, handle->cache_chain_heads[start].name) == 0)
- return &handle->cache_chain_heads[start];
- else
- return NULL;
+ return NULL;
}
/* Does this chain exist? */
int iptc_is_chain(const char *chain, const iptc_handle_t handle)
{
- /* avoid infinite recursion */
-#if 0
- CHECK(handle);
-#endif
-
return find_label(chain, handle) != NULL;
}
const char *
iptc_first_chain(iptc_handle_t *handle)
{
- CHECK(*handle);
-
if ((*handle)->cache_chain_heads == NULL
&& !populate_cache(*handle))
return NULL;
const char *iptc_get_target(const struct ipt_entry *e,
iptc_handle_t *handle)
{
- CHECK(*handle);
return target_name(*handle, e);
}
struct ipt_entry *e;
int hook;
- CHECK(*handle);
hook = iptc_builtin(chain, *handle);
if (hook != 0)
start = (*handle)->info.hook_entry[hook-1];
struct chain_cache *c;
int ret;
- CHECK(*handle);
iptc_fn = iptc_insert_entry;
if (!(c = find_label(chain, *handle))) {
errno = ENOENT;
ret = insert_rules(1, e->next_offset, e, offset,
chainindex + rulenum, rulenum == 0, handle);
unmap_target((struct ipt_entry *)e, &old);
- CHECK(*handle);
return ret;
}
struct chain_cache *c;
int ret;
- CHECK(*handle);
iptc_fn = iptc_replace_entry;
if (!(c = find_label(chain, *handle))) {
if (!map_target(*handle, (struct ipt_entry *)e, offset, &old))
return 0;
- CHECK(*handle);
ret = insert_rules(1, e->next_offset, e, offset,
chainindex + rulenum, 1, handle);
unmap_target((struct ipt_entry *)e, &old);
- CHECK(*handle);
return ret;
}
struct ipt_entry_target old;
int ret;
- CHECK(*handle);
iptc_fn = iptc_append_entry;
if (!(c = find_label(chain, *handle))) {
errno = ENOENT;
entry2index(*handle, c->end),
0, handle);
unmap_target((struct ipt_entry *)e, &old);
- CHECK(*handle);
return ret;
}
struct chain_cache *c;
struct ipt_entry *e, *fw;
- CHECK(*handle);
iptc_fn = iptc_delete_entry;
if (!(c = find_label(chain, *handle))) {
errno = ENOENT;
offset, entry2index(*handle, e),
handle);
free(fw);
- CHECK(*handle);
return ret;
}
}
struct ipt_entry *e;
struct chain_cache *c;
- CHECK(*handle);
iptc_fn = iptc_delete_num_entry;
if (!(c = find_label(chain, *handle))) {
errno = ENOENT;
ret = delete_rules(1, e->next_offset, entry2offset(*handle, e),
index, handle);
- CHECK(*handle);
return ret;
}
struct chain_cache *c;
int ret;
- CHECK(*handle);
iptc_fn = iptc_flush_entries;
if (!(c = find_label(chain, *handle))) {
errno = ENOENT;
(char *)c->end - (char *)c->start,
entry2offset(*handle, c->start), startindex,
handle);
- CHECK(*handle);
return ret;
}
unsigned int i, end;
struct chain_cache *c;
- CHECK(*handle);
if (!(c = find_label(chain, *handle))) {
errno = ENOENT;
return 0;
}
set_changed(*handle);
- CHECK(*handle);
return 1;
}
struct ipt_standard_target target;
} newc;
- CHECK(*handle);
iptc_fn = iptc_create_chain;
/* find_label doesn't cover built-in targets: DROP, ACCEPT,
index2offset(*handle, (*handle)->new_number - 1),
(*handle)->new_number - 1,
0, handle);
- CHECK(*handle);
return ret;
}
{
struct chain_cache *c;
- CHECK(*handle);
if (!(c = find_label(chain, *handle))) {
errno = ENOENT;
return 0;
struct chain_cache *c;
int ret;
- CHECK(*handle);
if (!iptc_get_references(&references, chain, handle))
return 0;
get_entry(*handle, labeloff)->next_offset
+ c->start->next_offset,
labeloff, labelidx, handle);
- CHECK(*handle);
return ret;
}
struct chain_cache *c;
struct ipt_error_target *t;
- CHECK(*handle);
iptc_fn = iptc_rename_chain;
/* find_label doesn't cover built-in targets: DROP, ACCEPT
strcpy(t->error, newname);
set_changed(*handle);
- CHECK(*handle);
return 1;
}
struct ipt_entry *e;
struct ipt_standard_target *t;
- CHECK(*handle);
iptc_fn = iptc_set_policy;
/* Figure out which chain. */
hook = iptc_builtin(chain, *handle);
= ((struct counter_map){ COUNTER_MAP_NOMAP, 0 });
set_changed(*handle);
- CHECK(*handle);
return 1;
}