/* Library which manipulates firewall rules.  Version 0.1. */

/* Architecture of firewall rules is as follows:
 *
 * Chains go INPUT, FORWARD, OUTPUT then user chains.
 * Each user chain starts with an ERROR node.
 * Every chain ends with an unconditional jump: a RETURN for user chains,
 * and a POLICY for built-ins.
 */

/* (C)1999 Paul ``Rusty'' Russell - Placed under the GNU GPL (See
   COPYING for details). */

#include <assert.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>

#if !defined(__GLIBC__) || (__GLIBC__ < 2)
typedef unsigned int socklen_t;
#endif

#include <libiptc/libiptc.h>

#define IP_VERSION	4
#define IP_OFFSET	0x1FFF

#ifndef IPT_LIB_DIR
#define IPT_LIB_DIR "/usr/local/lib/iptables"
#endif

static int sockfd = -1;
static void *iptc_fn = NULL;

static const char *hooknames[]
= { [NF_IP_PRE_ROUTING]  "PREROUTING",
    [NF_IP_LOCAL_IN]     "INPUT",
    [NF_IP_FORWARD]      "FORWARD",
    [NF_IP_LOCAL_OUT]    "OUTPUT",
    [NF_IP_POST_ROUTING] "POSTROUTING"
};

struct counter_map
{
	enum {
		COUNTER_MAP_NOMAP,
		COUNTER_MAP_NORMAL_MAP,
		COUNTER_MAP_ZEROED
	} maptype;
	unsigned int mappos;
};

/* Convenience structures */
struct ipt_error_target
{
	struct ipt_entry_target t;
	char error[IPT_TABLE_MAXNAMELEN];
};

struct iptc_handle
{
	/* Have changes been made? */
	int changed;
	/* Size in here reflects original state. */
	struct ipt_getinfo info;

	struct counter_map *counter_map;
	/* Array of hook names */
	const char **hooknames;

	/* Number in here reflects current state. */
	unsigned int new_number;
	struct ipt_get_entries entries;
};

static void do_check(iptc_handle_t h, unsigned int line);
#define CHECK(h) do_check((h), __LINE__)

static inline int
get_number(const struct ipt_entry *i,
	   const struct ipt_entry *seek,
	   unsigned int *pos)
{
	if (i == seek)
		return 1;
	(*pos)++;
	return 0;
}

static unsigned int
entry2index(const iptc_handle_t h, const struct ipt_entry *seek)
{
	unsigned int pos = 0;

	if (IPT_ENTRY_ITERATE(h->entries.entries, h->entries.size,
			      get_number, seek, &pos) == 0) {
		fprintf(stderr, "ERROR: offset %i not an entry!\n",
			(unsigned char *)seek - h->entries.entries);
		abort();
	}
	return pos;
}

static inline int
get_entry_n(struct ipt_entry *i,
	    unsigned int number,
	    unsigned int *pos,
	    struct ipt_entry **pe)
{
	if (*pos == number) {
		*pe = i;
		return 1;
	}
	(*pos)++;
	return 0;
}

static struct ipt_entry *
index2entry(iptc_handle_t h, unsigned int index)
{
	unsigned int pos = 0;
	struct ipt_entry *ret = NULL;

	IPT_ENTRY_ITERATE(h->entries.entries, h->entries.size,
			  get_entry_n, index, &pos, &ret);

	return ret;
}

static inline struct ipt_entry *
get_entry(iptc_handle_t h, unsigned int offset)
{
	return (struct ipt_entry *)(h->entries.entries + offset);
}

static inline unsigned long
entry2offset(const iptc_handle_t h, const struct ipt_entry *e)
{
	return (unsigned char *)e - h->entries.entries;
}

static unsigned long
index2offset(iptc_handle_t h, unsigned int index)
{
	return entry2offset(h, index2entry(h, index));
}

static const char *
get_errorlabel(iptc_handle_t h, unsigned int offset)
{
	struct ipt_entry *e;

	e = get_entry(h, offset);
	if (strcmp(ipt_get_target(e)->u.name, IPT_ERROR_TARGET) != 0) {
		fprintf(stderr, "ERROR: offset %u not an error node!\n",
			offset);
		abort();
	}

	return (const char *)ipt_get_target(e)->data;
}

/* Allocate handle of given size */
static iptc_handle_t
alloc_handle(const char *tablename, unsigned int size, unsigned int num_rules)
{
	size_t len;
	iptc_handle_t h;

	len = sizeof(struct iptc_handle)
		+ size
		+ num_rules * sizeof(struct counter_map);

	if ((h = malloc(len)) == NULL) {
		errno = ENOMEM;
		return NULL;
	}

	h->changed = 0;
	h->counter_map = (void *)h
		+ sizeof(struct iptc_handle)
		+ size;
	strcpy(h->info.name, tablename);
	strcpy(h->entries.name, tablename);

	return h;
}

iptc_handle_t
iptc_init(const char *tablename)
{
	iptc_handle_t h;
	struct ipt_getinfo info;
	unsigned int i;
	int tmp;
	socklen_t s;

	iptc_fn = iptc_init;

	sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
	if (sockfd < 0)
		return NULL;

	s = sizeof(info);
	if (strlen(tablename) >= IPT_TABLE_MAXNAMELEN) {
		errno = EINVAL;
		return NULL;
	}
	strcpy(info.name, tablename);
	if (getsockopt(sockfd, IPPROTO_IP, IPT_SO_GET_INFO, &info, &s) < 0)
		return NULL;

	if ((h = alloc_handle(info.name, info.size, info.num_entries))
	    == NULL)
		return NULL;

/* Too hard --RR */
#if 0
	sprintf(pathname, "%s/%s", IPT_LIB_DIR, info.name);
	dynlib = dlopen(pathname, RTLD_NOW);
	if (!dynlib) {
		errno = ENOENT;
		return NULL;
	}
	h->hooknames = dlsym(dynlib, "hooknames");
	if (!h->hooknames) {
		errno = ENOENT;
		return NULL;
	}
#else
	h->hooknames = hooknames;
#endif

	/* Initialize current state */
	h->info = info;
	h->new_number = h->info.num_entries;
	for (i = 0; i < h->info.num_entries; i++)
		h->counter_map[i]
			= ((struct counter_map){COUNTER_MAP_NORMAL_MAP, i});

	h->entries.size = h->info.size;

	tmp = sizeof(struct ipt_get_entries) + h->info.size;

	if (getsockopt(sockfd, IPPROTO_IP, IPT_SO_GET_ENTRIES, &h->entries,
		       &tmp) < 0) {
		free(h);
		return NULL;
	}

	CHECK(h);
	return h;
}

#define IP_PARTS_NATIVE(n)			\
(unsigned int)((n)>>24)&0xFF,			\
(unsigned int)((n)>>16)&0xFF,			\
(unsigned int)((n)>>8)&0xFF,			\
(unsigned int)((n)&0xFF)

#define IP_PARTS(n) IP_PARTS_NATIVE(ntohl(n))

static inline int
print_match(const struct ipt_entry_match *m)
{
	printf("Match name: `%s'\n", m->u.name);
	return 0;
}

int
dump_entry(struct ipt_entry *e, const iptc_handle_t handle)
{
	size_t i;
	struct ipt_entry_target *t;

	printf("Entry %u (%lu):\n", entry2index(handle, e),
	       entry2offset(handle, e));
	printf("SRC IP: %u.%u.%u.%u/%u.%u.%u.%u\n",
	       IP_PARTS(e->ip.src.s_addr),IP_PARTS(e->ip.smsk.s_addr));
	printf("DST IP: %u.%u.%u.%u/%u.%u.%u.%u\n",
	       IP_PARTS(e->ip.dst.s_addr),IP_PARTS(e->ip.dmsk.s_addr));
	printf("Interface: `%s'/", e->ip.iniface);
	for (i = 0; i < IFNAMSIZ; i++)
		printf("%c", e->ip.iniface_mask[i] ? 'X' : '.');
	printf("to `%s'/", e->ip.outiface);
	for (i = 0; i < IFNAMSIZ; i++)
		printf("%c", e->ip.outiface_mask[i] ? 'X' : '.');
	printf("\nProtocol: %u\n", e->ip.proto);
	printf("Flags: %02X\n", e->ip.flags);
	printf("Invflags: %02X\n", e->ip.invflags);
	printf("Counters: %llu packets, %llu bytes\n",
	       e->counters.pcnt, e->counters.bcnt);
	printf("Cache: %08X ", e->nfcache);
	if (e->nfcache & NFC_ALTERED) printf("ALTERED ");
	if (e->nfcache & NFC_UNKNOWN) printf("UNKNOWN ");
	if (e->nfcache & NFC_IP_SRC) printf("IP_SRC ");
	if (e->nfcache & NFC_IP_DST) printf("IP_DST ");
	if (e->nfcache & NFC_IP_IF_IN) printf("IP_IF_IN ");
	if (e->nfcache & NFC_IP_IF_OUT) printf("IP_IF_OUT ");
	if (e->nfcache & NFC_IP_TOS) printf("IP_TOS ");
	if (e->nfcache & NFC_IP_PROTO) printf("IP_PROTO ");
	if (e->nfcache & NFC_IP_OPTIONS) printf("IP_OPTIONS ");
	if (e->nfcache & NFC_IP_TCPFLAGS) printf("IP_TCPFLAGS ");
	if (e->nfcache & NFC_IP_SRC_PT) printf("IP_SRC_PT ");
	if (e->nfcache & NFC_IP_DST_PT) printf("IP_DST_PT ");
	if (e->nfcache & NFC_IP_PROTO_UNKNOWN) printf("IP_PROTO_UNKNOWN ");
	printf("\n");

	IPT_MATCH_ITERATE(e, print_match);

	t = ipt_get_target(e);
	printf("Target name: `%s' [%u]\n", t->u.name, t->target_size);
	if (strcmp(t->u.name, IPT_STANDARD_TARGET) == 0) {
		int pos = *(int *)t->data;
		if (pos < 0)
			printf("verdict=%s\n",
			       pos == -NF_ACCEPT-1 ? "NF_ACCEPT"
			       : pos == -NF_DROP-1 ? "NF_DROP"
			       : pos == -NF_QUEUE-1 ? "NF_QUEUE"
			       : pos == IPT_RETURN ? "RETURN"
			       : "UNKNOWN");
		else
			printf("verdict=%u\n", pos);
	} else if (strcmp(t->u.name, IPT_ERROR_TARGET) == 0)
		printf("error=`%s'\n", t->data);

	printf("\n");
	return 0;
}

void
dump_entries(const iptc_handle_t handle)
{
	CHECK(handle);

	printf("libiptc v%s.  %u entries, %u bytes.\n",
	       NETFILTER_VERSION,
	       handle->new_number, handle->entries.size);
	printf("Table `%s'\n", handle->info.name);
	printf("Hooks: pre/in/fwd/out/post = %u/%u/%u/%u/%u\n",
	       handle->info.hook_entry[NF_IP_PRE_ROUTING],
	       handle->info.hook_entry[NF_IP_LOCAL_IN],
	       handle->info.hook_entry[NF_IP_FORWARD],
	       handle->info.hook_entry[NF_IP_LOCAL_OUT],
	       handle->info.hook_entry[NF_IP_POST_ROUTING]);
	printf("Underflows: pre/in/fwd/out/post = %u/%u/%u/%u/%u\n",
	       handle->info.underflow[NF_IP_PRE_ROUTING],
	       handle->info.underflow[NF_IP_LOCAL_IN],
	       handle->info.underflow[NF_IP_FORWARD],
	       handle->info.underflow[NF_IP_LOCAL_OUT],
	       handle->info.underflow[NF_IP_POST_ROUTING]);

	IPT_ENTRY_ITERATE(handle->entries.entries, handle->entries.size,
			  dump_entry, handle);
}

static inline int
find_user_label(struct ipt_entry *e, unsigned int *off, const char *name)
{
	/* Increment first: they want offset of entry AFTER label */
	(*off) += e->next_offset;

	if (strcmp(ipt_get_target(e)->u.name, IPT_ERROR_TARGET) == 0
	    && strcmp(ipt_get_target(e)->data, name) == 0)
		return 1;

	return 0;
}

/* Returns offset of label. */
static int
find_label(unsigned int *off,
	   const char *name,
	   const iptc_handle_t handle)
{
	unsigned int i;

	/* Builtin chain name? */
	i = iptc_builtin(name, handle);
	if (i != 0) {
		*off = handle->info.hook_entry[i-1];
		return 1;
	}

	/* User chain name? */
	*off = 0;
	if (IPT_ENTRY_ITERATE(handle->entries.entries, handle->entries.size,
			      find_user_label, off, name) != 0) {
		/* last error node doesn't count */
		if (*off != handle->entries.size)
			return 1;
	}

	return 0;
}

/* Does this chain exist? */
int iptc_is_chain(const char *chain, const iptc_handle_t handle)
{
	unsigned int dummy;

	/* avoid infinite recursion */
#if 0
	CHECK(handle);
#endif

	return find_label(&dummy, chain, handle);
}

/* Returns the position of the final (ie. unconditional) element. */
static unsigned int
get_chain_end(const iptc_handle_t handle, unsigned int start)
{
	unsigned int last_off, off;
	struct ipt_entry *e;

	last_off = start;
	e = get_entry(handle, start);

	/* Terminate when we meet a error label or a hook entry. */
	for (off = start + e->next_offset;
	     off < handle->entries.size;
	     last_off = off, off += e->next_offset) {
		struct ipt_entry_target *t;
		unsigned int i;

		e = get_entry(handle, off);

		/* We hit an entry point. */
		for (i = 0; i < NF_IP_NUMHOOKS; i++) {
			if ((handle->info.valid_hooks & (1 << i))
			    && off == handle->info.hook_entry[i])
				return last_off;
		}

		/* We hit a user chain label */
		t = ipt_get_target(e);
		if (strcmp(t->u.name, IPT_ERROR_TARGET) == 0)
			return last_off;
	}
	/* SHOULD NEVER HAPPEN */
	fprintf(stderr, "ERROR: Off end (%u) of chain from %u!\n",
		handle->entries.size, off);
	abort();
}

/* 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)
{
	unsigned int pos;
	unsigned int i;
	struct ipt_entry *e;

	CHECK(*handle);
	if (!prev)
		pos = 0;
	else {
		if (!find_label(&pos, prev, *handle)) {
			errno = ENOENT;
			return NULL;
		}
		pos = get_chain_end(*handle, pos);
		/* Next entry. */
		e = get_entry(*handle, pos);
		pos += e->next_offset;
	}
	e = get_entry(*handle, pos);

	/* Return names of entry points if it is one. */
	for (i = 0; i < NF_IP_NUMHOOKS; i++) {
		if (((*handle)->info.valid_hooks & (1 << i))
		    && pos == (*handle)->info.hook_entry[i])
			return (*handle)->hooknames[i];
	}
	/* If this is the last element, iteration finished */
	if (pos + e->next_offset == (*handle)->entries.size)
		return NULL;

	if (strcmp(ipt_get_target(e)->u.name, IPT_ERROR_TARGET) != 0) {
		/* SHOULD NEVER HAPPEN */
		fprintf(stderr, "ERROR: position %u/%u not an error label\n",
			pos, (*handle)->entries.size);
		abort();
	}

	return (const char *)ipt_get_target(e)->data;
}

/* How many rules in this chain? */
unsigned int
iptc_num_rules(const char *chain, iptc_handle_t *handle)
{
	unsigned int off = 0;
	struct ipt_entry *start, *end;

	CHECK(*handle);
	if (!find_label(&off, chain, *handle)) {
		errno = ENOENT;
		return (unsigned int)-1;
	}

	start = get_entry(*handle, off);
	end = get_entry(*handle, get_chain_end(*handle, off));

	return entry2index(*handle, end) - entry2index(*handle, start);
}

/* Get n'th rule in this chain. */
const struct ipt_entry *iptc_get_rule(const char *chain,
				      unsigned int n,
				      iptc_handle_t *handle)
{
	unsigned int pos = 0, chainindex;

	CHECK(*handle);
	if (!find_label(&pos, chain, *handle)) {
		errno = ENOENT;
		return NULL;
	}

	chainindex = entry2index(*handle, get_entry(*handle, pos));

	return index2entry(*handle, chainindex + n);
}

static const char *target_name(iptc_handle_t handle, struct ipt_entry *e)
{
	int spos;
	unsigned int labelidx;
	struct ipt_entry *jumpto;

	if (strcmp(ipt_get_target(e)->u.name, IPT_STANDARD_TARGET) != 0)
		return ipt_get_target(e)->u.name;

	/* Standard target: evaluate */
	spos = *(int *)ipt_get_target(e)->data;
	if (spos < 0) {
		if (spos == IPT_RETURN)
			return IPTC_LABEL_RETURN;
		else if (spos == -NF_ACCEPT-1)
			return IPTC_LABEL_ACCEPT;
		else if (spos == -NF_DROP-1)
			return IPTC_LABEL_DROP;
		else if (spos == -NF_ACCEPT-1)
			return IPTC_LABEL_QUEUE;

		fprintf(stderr, "ERROR: off %lu/%u not a valid target (%i)\n",
			entry2offset(handle, e), handle->entries.size,
			spos);
		abort();
	}

	jumpto = get_entry(handle, spos);

	/* Fall through rule */
	if (jumpto == (void *)e + e->next_offset)
		return "";

	/* Must point to head of a chain: ie. after error rule */
	labelidx = entry2index(handle, jumpto) - 1;
	return get_errorlabel(handle, index2offset(handle, labelidx));
}

/* Returns a pointer to the target name of this position. */
const char *iptc_get_target(const char *chain,
			    unsigned int n,
			    iptc_handle_t *handle)
{
	unsigned int pos = 0, chainindex;
	struct ipt_entry *e;

	CHECK(*handle);
	if (!find_label(&pos, chain, *handle)) {
		errno = ENOENT;
		return NULL;
	}

	chainindex = entry2index(*handle, get_entry(*handle, pos));
	e = index2entry(*handle, chainindex + n);

	return target_name(*handle, e);
}

/* Is this a built-in chain?  Actually returns hook + 1. */
int
iptc_builtin(const char *chain, const iptc_handle_t handle)
{
	unsigned int i;

	for (i = 0; i < NF_IP_NUMHOOKS; i++) {
		if ((handle->info.valid_hooks & (1 << i))
		    && handle->hooknames[i]
		    && strcmp(handle->hooknames[i], chain) == 0)
			return i+1;
	}
	return 0;
}

/* Get the policy of a given built-in chain */
const char *
iptc_get_policy(const char *chain,
		struct ipt_counters *counters,
		iptc_handle_t *handle)
{
	unsigned int start;
	struct ipt_entry *e;
	int hook;

	CHECK(*handle);
	hook = iptc_builtin(chain, *handle);
	if (hook != 0)
		start = (*handle)->info.hook_entry[hook-1];
	else
		return NULL;

	e = get_entry(*handle, get_chain_end(*handle, start));
	*counters = e->counters;

	return target_name(*handle, e);
}

static int
correct_verdict(struct ipt_entry *e,
		unsigned char *base,
		unsigned int offset, int delta_offset)
{
	struct ipt_standard_target *t = (void *)ipt_get_target(e);
	unsigned int curr = (unsigned char *)e - base;

	/* Trap: insert of fall-through rule.  Don't change fall-through
	   verdict to jump-over-next-rule. */
	if (strcmp(t->target.u.name, IPT_STANDARD_TARGET) == 0
	    && t->verdict > (int)offset
	    && !(curr == offset &&
		 t->verdict == curr + e->next_offset)) {
		t->verdict += delta_offset;
	}

	return 0;
}

/* Adjusts standard verdict jump positions after an insertion/deletion. */
static int
set_verdict(unsigned int offset, int delta_offset, iptc_handle_t *handle)
{
	IPT_ENTRY_ITERATE((*handle)->entries.entries,
			  (*handle)->entries.size,
			  correct_verdict, (*handle)->entries.entries,
			  offset, delta_offset);

	(*handle)->changed = 1;
	return 1;
}

/* If prepend is set, then we are prepending to a chain: if the
 * insertion position is an entry point, keep the entry point. */
static int
insert_rules(unsigned int num_rules, unsigned int rules_size,
	     const struct ipt_entry *insert,
	     unsigned int offset, unsigned int num_rules_offset,
	     int prepend,
	     iptc_handle_t *handle)
{
	iptc_handle_t newh;
	struct ipt_getinfo newinfo;
	unsigned int i;

	if (offset >= (*handle)->entries.size) {
		errno = EINVAL;
		return 0;
	}

	newinfo = (*handle)->info;

	/* Fix up entry points. */
	for (i = 0; i < NF_IP_NUMHOOKS; i++) {
		/* Entry points to START of chain, so keep same if
                   inserting on at that point. */
		if ((*handle)->info.hook_entry[i] > offset)
			newinfo.hook_entry[i] += rules_size;

		/* Underflow always points to END of chain (policy),
		   so if something is inserted at same point, it
		   should be advanced. */
		if ((*handle)->info.underflow[i] >= offset)
			newinfo.underflow[i] += rules_size;
	}

	newh = alloc_handle((*handle)->info.name,
			    (*handle)->info.size + rules_size,
			    (*handle)->info.num_entries + num_rules);
	if (!newh)
		return 0;
	newh->info = newinfo;

	/* Copy pre... */
	memcpy(newh->entries.entries, (*handle)->entries.entries, offset);
	/* ... Insert new ... */
	memcpy(newh->entries.entries + offset, insert, rules_size);
	/* ... copy post */
	memcpy(newh->entries.entries + offset + rules_size,
	       (*handle)->entries.entries + offset,
	       (*handle)->entries.size - offset);

	/* Move counter map. */
	/* Copy pre... */
	memcpy(newh->counter_map, (*handle)->counter_map,
	       sizeof(struct counter_map) * num_rules_offset);
	/* ... copy post */
	memcpy(newh->counter_map + num_rules_offset + num_rules,
	       (*handle)->counter_map + num_rules_offset,
	       sizeof(struct counter_map) * ((*handle)->new_number
					     - num_rules_offset));
	/* Set intermediates to no counter copy */
	for (i = 0; i < num_rules; i++)
		newh->counter_map[num_rules_offset+i]
			= ((struct counter_map){ COUNTER_MAP_NOMAP, 0 });

	newh->new_number = (*handle)->new_number + num_rules;
	newh->entries.size = (*handle)->entries.size + rules_size;
	newh->hooknames = (*handle)->hooknames;

	free(*handle);
	*handle = newh;

	return set_verdict(offset, rules_size, handle);
}

static int
delete_rules(unsigned int num_rules, unsigned int rules_size,
	     unsigned int offset, unsigned int num_rules_offset,
	     iptc_handle_t *handle)
{
	unsigned int i;

	if (offset + rules_size > (*handle)->entries.size) {
		errno = EINVAL;
		return 0;
	}

	/* Fix up entry points. */
	for (i = 0; i < NF_IP_NUMHOOKS; i++) {
		/* In practice, we never delete up to a hook entry,
		   since the built-in chains are always first,
		   so these two are never equal */
		if ((*handle)->info.hook_entry[i] >= offset + rules_size)
			(*handle)->info.hook_entry[i] -= rules_size;
		else if ((*handle)->info.hook_entry[i] > offset) {
			fprintf(stderr, "ERROR: Deleting entry %u %u %u\n",
				i, (*handle)->info.hook_entry[i], offset);
			abort();
		}

		/* Underflow points to policy (terminal) rule in
                   built-in, so sequality is valid here (when deleting
                   the last rule). */
		if ((*handle)->info.underflow[i] >= offset + rules_size)
			(*handle)->info.underflow[i] -= rules_size;
		else if ((*handle)->info.underflow[i] > offset) {
			fprintf(stderr, "ERROR: Deleting uflow %u %u %u\n",
				i, (*handle)->info.underflow[i], offset);
			abort();
		}
	}

	/* Move the rules down. */
	memmove((*handle)->entries.entries + offset,
		(*handle)->entries.entries + offset + rules_size,
		(*handle)->entries.size - (offset + rules_size));

	/* Move the counter map down. */
	memmove(&(*handle)->counter_map[num_rules_offset],
		&(*handle)->counter_map[num_rules_offset + num_rules],
		sizeof(struct counter_map)
		* ((*handle)->new_number - (num_rules + num_rules_offset)));

	/* Fix numbers */
	(*handle)->new_number -= num_rules;
	(*handle)->entries.size -= rules_size;

	return set_verdict(offset, -(int)rules_size, handle);
}

static int
standard_map(struct ipt_entry *e, int verdict)
{
	struct ipt_standard_target *t;

	t = (struct ipt_standard_target *)ipt_get_target(e);

	if (t->target.target_size != IPT_ALIGN(sizeof(struct ipt_standard_target))) {
		errno = EINVAL;
		return 0;
	}
	/* memset for memcmp convenience on delete/replace */
	memset(t->target.u.name, 0, IPT_FUNCTION_MAXNAMELEN);
	strcpy(t->target.u.name, IPT_STANDARD_TARGET);
	t->verdict = verdict;

	return 1;
}

static int
map_target(const iptc_handle_t handle,
	   struct ipt_entry *e,
	   unsigned int offset,
	   struct ipt_entry_target *old)
{
	struct ipt_entry_target *t = ipt_get_target(e);

	/* Save old target (except data, which we don't change, except for
	   standard case, where we don't care). */
	*old = *t;

	/* Maybe it's empty (=> fall through) */
	if (strcmp(t->u.name, "") == 0)
		return standard_map(e, offset + e->next_offset);
	/* Maybe it's a standard target name... */
	else if (strcmp(t->u.name, IPTC_LABEL_ACCEPT) == 0)
		return standard_map(e, -NF_ACCEPT - 1);
	else if (strcmp(t->u.name, IPTC_LABEL_DROP) == 0)
		return standard_map(e, -NF_DROP - 1);
	else if (strcmp(t->u.name, IPTC_LABEL_QUEUE) == 0)
		return standard_map(e, -NF_QUEUE - 1);
	else if (strcmp(t->u.name, IPTC_LABEL_RETURN) == 0)
		return standard_map(e, IPT_RETURN);
	else if (iptc_builtin(t->u.name, handle)) {
		/* Can't jump to builtins. */
		errno = EINVAL;
		return 0;
	} else {
		/* Maybe it's an existing chain name. */
		unsigned int exists;

		if (find_label(&exists, t->u.name, handle))
			return standard_map(e, exists);
	}

	/* Must be a module?  If not, kernel will reject... */
	/* memset to all 0 for your memcmp convenience. */
	memset(t->u.name + strlen(t->u.name),
	       0,
	       IPT_FUNCTION_MAXNAMELEN - strlen(t->u.name));
	return 1;
}

static void
unmap_target(struct ipt_entry *e, struct ipt_entry_target *old)
{
	struct ipt_entry_target *t = ipt_get_target(e);

	/* Save old target (except data, which we don't change, except for
	   standard case, where we don't care). */
	*t = *old;
}

/* Insert the entry `fw' in chain `chain' into position `rulenum'. */
int
iptc_insert_entry(const ipt_chainlabel chain,
		  const struct ipt_entry *e,
		  unsigned int rulenum,
		  iptc_handle_t *handle)
{
	unsigned int chainoff, chainindex, offset;
	struct ipt_entry_target old;
	int ret;

	CHECK(*handle);
	iptc_fn = iptc_insert_entry;
	if (!find_label(&chainoff, chain, *handle)) {
		errno = ENOENT;
		return 0;
	}

	chainindex = entry2index(*handle, get_entry(*handle, chainoff));

	if (index2entry(*handle, chainindex + rulenum)
	    > get_entry(*handle, get_chain_end(*handle, chainoff))) {
		errno = E2BIG;
		return 0;
	}
	offset = index2offset(*handle, chainindex + rulenum);

	/* Mapping target actually alters entry, but that's
           transparent to the caller. */
	if (!map_target(*handle, (struct ipt_entry *)e, offset, &old))
		return 0;

	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;
}

/* Atomically replace rule `rulenum' in `chain' with `fw'. */
int
iptc_replace_entry(const ipt_chainlabel chain,
		   const struct ipt_entry *e,
		   unsigned int rulenum,
		   iptc_handle_t *handle)
{
	unsigned int chainoff, chainindex, offset;
	struct ipt_entry_target old;
	int ret;

	CHECK(*handle);
	iptc_fn = iptc_replace_entry;

	if (!find_label(&chainoff, chain, *handle)) {
		errno = ENOENT;
		return 0;
	}

	chainindex = entry2index(*handle, get_entry(*handle, chainoff));

	if (index2entry(*handle, chainindex + rulenum)
	    >= get_entry(*handle, get_chain_end(*handle, chainoff))) {
		errno = E2BIG;
		return 0;
	}

	offset = index2offset(*handle, chainindex + rulenum);
	/* Replace = delete and insert. */
	if (!delete_rules(1, get_entry(*handle, offset)->next_offset,
			  offset, chainindex + rulenum, handle))
		return 0;

	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;
}

/* Append entry `fw' to chain `chain'.  Equivalent to insert with
   rulenum = length of chain. */
int
iptc_append_entry(const ipt_chainlabel chain,
		  const struct ipt_entry *e,
		  iptc_handle_t *handle)
{
	unsigned int startoff, endoff;
	struct ipt_entry_target old;
	int ret;

	CHECK(*handle);
	iptc_fn = iptc_append_entry;
	if (!find_label(&startoff, chain, *handle)) {
		errno = ENOENT;
		return 0;
	}

	endoff = get_chain_end(*handle, startoff);
	if (!map_target(*handle, (struct ipt_entry *)e, endoff, &old))
		return 0;

	ret = insert_rules(1, e->next_offset, e, endoff,
			   entry2index(*handle, get_entry(*handle, endoff)),
			   0, handle);
	unmap_target((struct ipt_entry *)e, &old);
	CHECK(*handle);
	return ret;
}

static inline int
match_different(const struct ipt_entry_match *a,
		const char *a_elems,
		const char *b_elems)
{
	const struct ipt_entry_match *b;

	/* Offset of b is the same as a. */
	b = (void *)b_elems + (a_elems - (char *)a);

	if (a->match_size != b->match_size)
		return 1;

	if (strcmp(a->u.name, b->u.name) != 0)
		return 1;

	/* FIXME: If kernel modifies these (eg. RATE), then we'll
           never match --RR */
	if (memcmp(a->data, b->data, a->match_size - sizeof(*a)) != 0)
		return 1;

	return 0;
}

static inline int
is_same(const struct ipt_entry *a, const struct ipt_entry *b)
{
	unsigned int i;
	struct ipt_entry_target *ta, *tb;

	if (a->ip.src.s_addr != b->ip.src.s_addr
	    || a->ip.dst.s_addr != b->ip.dst.s_addr
	    || a->ip.smsk.s_addr != b->ip.smsk.s_addr
	    || a->ip.smsk.s_addr != b->ip.smsk.s_addr
	    || a->ip.proto != b->ip.proto
	    || a->ip.flags != b->ip.flags
	    || a->ip.invflags != b->ip.invflags)
		return 0;

	for (i = 0; i < IFNAMSIZ; i++) {
		if (a->ip.iniface_mask[i] != b->ip.iniface_mask[i])
			return 0;
		if ((a->ip.iniface[i] & a->ip.iniface_mask[i])
		    != (b->ip.iniface[i] & b->ip.iniface_mask[i]))
			return 0;
		if (a->ip.outiface_mask[i] != b->ip.outiface_mask[i])
			return 0;
		if ((a->ip.outiface[i] & a->ip.outiface_mask[i])
		    != (b->ip.outiface[i] & b->ip.outiface_mask[i]))
			return 0;
	}

	if (a->nfcache != b->nfcache
	    || a->target_offset != b->target_offset
	    || a->next_offset != b->next_offset)
		return 0;

	if (IPT_MATCH_ITERATE(a, match_different, a->elems, b->elems))
		return 0;

	ta = ipt_get_target((struct ipt_entry *)a);
	tb = ipt_get_target((struct ipt_entry *)b);
	if (ta->target_size != tb->target_size)
		return 0;
	if (strcmp(ta->u.name, tb->u.name) != 0)
		return 0;
	/* FIXME: If kernel modifies these, then we never match --RR */
	if (memcmp(ta->data, tb->data, ta->target_size - sizeof(*ta)) != 0)
		return 0;

	return 1;
}

/* Delete the first rule in `chain' which matches `fw'. */
int
iptc_delete_entry(const ipt_chainlabel chain,
		  const struct ipt_entry *origfw,
		  iptc_handle_t *handle)
{
	unsigned int offset, lastoff;
	struct ipt_entry *e, *fw;

	CHECK(*handle);
	iptc_fn = iptc_delete_entry;
	if (!find_label(&offset, chain, *handle)) {
		errno = ENOENT;
		return 0;
	}

	fw = malloc(origfw->next_offset);
	if (fw == NULL) {
		errno = ENOMEM;
		return 0;
	}
	lastoff = get_chain_end(*handle, offset);

	for (; offset < lastoff; offset += e->next_offset) {
		struct ipt_entry_target discard;

		memcpy(fw, origfw, origfw->next_offset);

		/* FIXME: handle this in is_same --RR */
		if (!map_target(*handle, fw, offset, &discard)) {
			free(fw);
			return 0;
		}
		e = get_entry(*handle, offset);

#if 0
		printf("Deleting:\n");
		dump_entry(newe);
#endif
		if (is_same(e, fw)) {
			int ret;
			ret = delete_rules(1, e->next_offset,
					   offset, entry2index(*handle, e),
					   handle);
			free(fw);
			CHECK(*handle);
			return ret;
		}
	}

	free(fw);
	errno = ENOENT;
	return 0;
}

/* Delete the rule in position `rulenum' in `chain'. */
int
iptc_delete_num_entry(const ipt_chainlabel chain,
		      unsigned int rulenum,
		      iptc_handle_t *handle)
{
	unsigned int chainstart;
	unsigned int index;
	int ret;
	struct ipt_entry *e;

	CHECK(*handle);
	iptc_fn = iptc_delete_num_entry;
	if (!find_label(&chainstart, chain, *handle)) {
		errno = ENOENT;
		return 0;
	}

	index = entry2index(*handle, get_entry(*handle, chainstart))
		+ rulenum;

	if (index
	    >= entry2index(*handle,
			  get_entry(*handle,
				    get_chain_end(*handle, chainstart)))) {
		errno = E2BIG;
		return 0;
	}

	e = index2entry(*handle, index);
	if (e == NULL) {
		errno = EINVAL;
		return 0;
	}

	ret = delete_rules(1, e->next_offset, entry2offset(*handle, e),
			   index, handle);
	CHECK(*handle);
	return ret;
}

/* Check the packet `fw' on chain `chain'.  Returns the verdict, or
   NULL and sets errno. */
const char *
iptc_check_packet(const ipt_chainlabel chain,
			      struct ipt_entry *entry,
			      iptc_handle_t *handle)
{
	errno = ENOSYS;
	return NULL;
}

/* Flushes the entries in the given chain (ie. empties chain). */
int
iptc_flush_entries(const ipt_chainlabel chain, iptc_handle_t *handle)
{
	unsigned int startoff, endoff, startindex, endindex;
	int ret;

	CHECK(*handle);
	iptc_fn = iptc_flush_entries;
	if (!find_label(&startoff, chain, *handle)) {
		errno = ENOENT;
		return 0;
	}
	endoff = get_chain_end(*handle, startoff);
	startindex = entry2index(*handle, get_entry(*handle, startoff));
	endindex = entry2index(*handle, get_entry(*handle, endoff));

	ret = delete_rules(endindex - startindex,
			   endoff - startoff, startoff, startindex,
			   handle);
	CHECK(*handle);
	return ret;
}

/* Zeroes the counters in a chain. */
int
iptc_zero_entries(const ipt_chainlabel chain, iptc_handle_t *handle)
{
	unsigned int i, end;

	CHECK(*handle);
	if (!find_label(&i, chain, *handle)) {
		errno = ENOENT;
		return 0;
	}
	end = get_chain_end(*handle, i);

	i = entry2index(*handle, get_entry(*handle, i));
	end = entry2index(*handle, get_entry(*handle, end));

	for (; i <= end; i++) {
		if ((*handle)->counter_map[i].maptype ==COUNTER_MAP_NORMAL_MAP)
			(*handle)->counter_map[i].maptype = COUNTER_MAP_ZEROED;
	}
	(*handle)->changed = 1;

	CHECK(*handle);
	return 1;
}

/* Creates a new chain. */
/* To create a chain, create two rules: error node and unconditional
 * return. */
int
iptc_create_chain(const ipt_chainlabel chain, iptc_handle_t *handle)
{
	unsigned int pos;
	int ret;
	struct {
		struct ipt_entry head;
		struct ipt_error_target name;
		struct ipt_entry ret;
		struct ipt_standard_target target;
	} newc;

	CHECK(*handle);
	iptc_fn = iptc_create_chain;

	/* find_label doesn't cover built-in targets: DROP, ACCEPT,
           QUEUE, RETURN. */
	if (find_label(&pos, chain, *handle)
	    || strcmp(chain, IPTC_LABEL_DROP) == 0
	    || strcmp(chain, IPTC_LABEL_ACCEPT) == 0
	    || strcmp(chain, IPTC_LABEL_QUEUE) == 0
	    || strcmp(chain, IPTC_LABEL_RETURN) == 0) {
		errno = EEXIST;
		return 0;
	}

	if (strlen(chain)+1 > sizeof(ipt_chainlabel)) {
		errno = EINVAL;
		return 0;
	}

	memset(&newc, 0, sizeof(newc));
	newc.head.target_offset = sizeof(struct ipt_entry);
	newc.head.next_offset
		= sizeof(struct ipt_entry) + sizeof(struct ipt_error_target);
	strcpy(newc.name.t.u.name, IPT_ERROR_TARGET);
	newc.name.t.target_size = sizeof(struct ipt_error_target);
	strcpy(newc.name.error, chain);

	newc.ret.target_offset = sizeof(struct ipt_entry);
	newc.ret.next_offset
		= sizeof(struct ipt_entry)+sizeof(struct ipt_standard_target);
	strcpy(newc.target.target.u.name, IPT_STANDARD_TARGET);
	newc.target.target.target_size = sizeof(struct ipt_standard_target);
	newc.target.verdict = IPT_RETURN;

	/* Add just before terminal entry */
	ret = insert_rules(2, sizeof(newc), &newc.head,
			   index2offset(*handle, (*handle)->new_number - 1),
			   (*handle)->new_number - 1,
			   0, handle);
	CHECK(*handle);
	return ret;
}

static int
count_ref(struct ipt_entry *e, unsigned int offset, unsigned int *ref)
{
	struct ipt_standard_target *t;

	if (strcmp(ipt_get_target(e)->u.name, IPT_STANDARD_TARGET) == 0) {
		t = (struct ipt_standard_target *)ipt_get_target(e);

		if (t->verdict == offset)
			(*ref)++;
	}

	return 0;
}

/* Get the number of references to this chain. */
int
iptc_get_references(unsigned int *ref, const ipt_chainlabel chain,
		    iptc_handle_t *handle)
{
	unsigned int offset;

	CHECK(*handle);
	if (!find_label(&offset, chain, *handle)) {
		errno = ENOENT;
		return 0;
	}

	*ref = 0;
	IPT_ENTRY_ITERATE((*handle)->entries.entries,
			  (*handle)->entries.size,
			  count_ref, offset, ref);
	return 1;
}

/* Deletes a chain. */
int
iptc_delete_chain(const ipt_chainlabel chain, iptc_handle_t *handle)
{
	unsigned int chainoff, labelidx, labeloff;
	unsigned int references;
	struct ipt_entry *e;
	int ret;

	CHECK(*handle);
	if (!iptc_get_references(&references, chain, handle))
		return 0;

	iptc_fn = iptc_delete_chain;

	if (iptc_builtin(chain, *handle)) {
		errno = EINVAL;
		return 0;
	}

	if (references > 0) {
		errno = EMLINK;
		return 0;
	}

	if (!find_label(&chainoff, chain, *handle)) {
		errno = ENOENT;
		return 0;
	}

	e = get_entry(*handle, chainoff);
	if (get_chain_end(*handle, chainoff) != chainoff) {
		errno = ENOTEMPTY;
		return 0;
	}

	/* Need label index: preceeds chain start */
	labelidx = entry2index(*handle, e) - 1;
	labeloff = index2offset(*handle, labelidx);

	ret = delete_rules(2,
			   get_entry(*handle, labeloff)->next_offset
			   + e->next_offset,
			   labeloff, labelidx, handle);
	CHECK(*handle);
	return ret;
}

/* Renames a chain. */
int iptc_rename_chain(const ipt_chainlabel oldname,
		      const ipt_chainlabel newname,
		      iptc_handle_t *handle)
{
	unsigned int chainoff, labeloff, labelidx;
	struct ipt_error_target *t;

	CHECK(*handle);
	iptc_fn = iptc_rename_chain;

	/* find_label doesn't cover built-in targets: DROP, ACCEPT
           RETURN. */
	if (find_label(&chainoff, newname, *handle)
	    || strcmp(newname, IPTC_LABEL_DROP) == 0
	    || strcmp(newname, IPTC_LABEL_ACCEPT) == 0
	    || strcmp(newname, IPTC_LABEL_RETURN) == 0) {
		errno = EEXIST;
		return 0;
	}

	if (!find_label(&chainoff, oldname, *handle)
	    || iptc_builtin(oldname, *handle)) {
		errno = ENOENT;
		return 0;
	}

	if (strlen(newname)+1 > sizeof(ipt_chainlabel)) {
		errno = EINVAL;
		return 0;
	}

	/* Need label index: preceeds chain start */
	labelidx = entry2index(*handle, get_entry(*handle, chainoff)) - 1;
	labeloff = index2offset(*handle, labelidx);

	t = (struct ipt_error_target *)
		ipt_get_target(get_entry(*handle, labeloff));

	memset(t->error, 0, sizeof(t->error));
	strcpy(t->error, newname);
	(*handle)->changed = 1;

	CHECK(*handle);
	return 1;
}

/* Sets the policy on a built-in chain. */
int
iptc_set_policy(const ipt_chainlabel chain,
		const ipt_chainlabel policy,
		iptc_handle_t *handle)
{
	unsigned int hook;
	unsigned int policyoff;
	struct ipt_entry *e;
	struct ipt_standard_target *t;

	CHECK(*handle);
	/* Figure out which chain. */
	hook = iptc_builtin(chain, *handle);
	if (hook == 0) {
		errno = EINVAL;
		return 0;
	} else
		hook--;

	policyoff = get_chain_end(*handle, (*handle)->info.hook_entry[hook]);
	if (policyoff != (*handle)->info.underflow[hook]) {
		printf("ERROR: Policy for `%s' offset %u != underflow %u\n",
		       chain, policyoff, (*handle)->info.underflow[hook]);
		return 0;
	}

	e = get_entry(*handle, policyoff);
	t = (struct ipt_standard_target *)ipt_get_target(e);

	if (strcmp(policy, IPTC_LABEL_ACCEPT) == 0)
		t->verdict = -NF_ACCEPT - 1;
	else if (strcmp(policy, IPTC_LABEL_DROP) == 0)
		t->verdict = -NF_DROP - 1;
	else {
		errno = EINVAL;
		return 0;
	}
	(*handle)->counter_map[entry2index(*handle, e)]
		= ((struct counter_map){ COUNTER_MAP_NOMAP, 0 });
	(*handle)->changed = 1;

	CHECK(*handle);
	return 1;
}

/* Without this, on gcc 2.7.2.3, we get:
   libiptc.c: In function `iptc_commit':
   libiptc.c:833: fixed or forbidden register was spilled.
   This may be due to a compiler bug or to impossible asm
   statements or clauses.
*/
static void
subtract_counters(struct ipt_counters *answer,
		  const struct ipt_counters *a,
		  const struct ipt_counters *b)
{
	answer->pcnt = a->pcnt - b->pcnt;
	answer->bcnt = a->bcnt - b->bcnt;
}

int
iptc_commit(iptc_handle_t *handle)
{
	/* Replace, then map back the counters. */
	struct ipt_replace *repl;
	struct ipt_counters_info *newcounters;
	unsigned int i;
	size_t counterlen
		= sizeof(struct ipt_counters_info)
		+ sizeof(struct ipt_counters) * (*handle)->new_number;

	CHECK(*handle);
#if 0
	dump_entries(*handle);
#endif

	/* Don't commit if nothing changed. */
	if (!(*handle)->changed)
		goto finished;

	repl = malloc(sizeof(*repl) + (*handle)->entries.size);
	if (!repl) {
		errno = ENOMEM;
		return 0;
	}

	/* These are the old counters we will get from kernel */
	repl->counters = malloc(sizeof(struct ipt_counters)
				* (*handle)->info.num_entries);
	if (!repl->counters) {
		free(repl);
		errno = ENOMEM;
		return 0;
	}

	/* These are the counters we're going to put back, later. */
	newcounters = malloc(counterlen);
	if (!newcounters) {
		free(repl->counters);
		free(repl);
		errno = ENOMEM;
		return 0;
	}

	strcpy(repl->name, (*handle)->info.name);
	repl->num_entries = (*handle)->new_number;
	repl->size = (*handle)->entries.size;
	memcpy(repl->hook_entry, (*handle)->info.hook_entry,
	       sizeof(repl->hook_entry));
	memcpy(repl->underflow, (*handle)->info.underflow,
	       sizeof(repl->underflow));
	repl->num_counters = (*handle)->info.num_entries;
	repl->valid_hooks = (*handle)->info.valid_hooks;
	memcpy(repl->entries, (*handle)->entries.entries,
	       (*handle)->entries.size);

	if (setsockopt(sockfd, IPPROTO_IP, IPT_SO_SET_REPLACE, repl,
		       sizeof(*repl) + (*handle)->entries.size) < 0) {
		free(repl->counters);
		free(repl);
		free(newcounters);
		return 0;
	}

	/* Put counters back. */
	strcpy(newcounters->name, (*handle)->info.name);
	newcounters->num_counters = (*handle)->new_number;
	for (i = 0; i < (*handle)->new_number; i++) {
		unsigned int mappos = (*handle)->counter_map[i].mappos;
		switch ((*handle)->counter_map[i].maptype) {
		case COUNTER_MAP_NOMAP:
			newcounters->counters[i]
				= ((struct ipt_counters){ 0, 0 });
			break;

		case COUNTER_MAP_NORMAL_MAP:
			/* Original read: X.
			 * Atomic read on replacement: X + Y.
			 * Currently in kernel: Z.
			 * Want in kernel: X + Y + Z.
			 * => Add in X + Y
			 * => Add in replacement read.
			 */
			newcounters->counters[i] = repl->counters[mappos];
			break;

		case COUNTER_MAP_ZEROED:
			/* Original read: X.
			 * Atomic read on replacement: X + Y.
			 * Currently in kernel: Z.
			 * Want in kernel: Y + Z.
			 * => Add in Y.
			 * => Add in (replacement read - original read).
			 */
			subtract_counters(&newcounters->counters[i],
					  &repl->counters[mappos],
					  &index2entry(*handle, i)->counters);
			break;
		}
	}

	if (setsockopt(sockfd, IPPROTO_IP, IPT_SO_SET_ADD_COUNTERS,
	       newcounters, counterlen) < 0) {
		free(repl->counters);
		free(repl);
		free(newcounters);
		return 0;
	}

	free(repl->counters);
	free(repl);
	free(newcounters);

 finished:
	free(*handle);
	*handle = NULL;
	return 1;
}

/* Get raw socket. */
int
iptc_get_raw_socket()
{
	return sockfd;
}

/* Translates errno numbers into more human-readable form than strerror. */
const char *
iptc_strerror(int err)
{
	unsigned int i;
	struct table_struct {
		void *fn;
		int err;
		const char *message;
	} table [] =
	  { { NULL, 0, "Incompatible with this kernel" },
	    { NULL, ENOPROTOOPT, "iptables who? (do you need to insmod?)" },
	    { NULL, ENOSYS, "Will be implemented real soon.  I promise." },
	    { NULL, ENOMEM, "Memory allocation problem" },
	    { iptc_init, EPERM, "Permission denied (you must be root)" },
	    { iptc_init, EINVAL, "Module is wrong version" },
	    { iptc_delete_chain, ENOTEMPTY, "Chain is not empty" },
	    { iptc_delete_chain, EINVAL, "Can't delete built-in chain" },
	    { iptc_delete_chain, EMLINK,
	      "Can't delete chain with references left" },
	    { iptc_create_chain, EEXIST, "Chain already exists" },
	    { iptc_insert_entry, E2BIG, "Index of insertion too big" },
	    { iptc_replace_entry, E2BIG, "Index of replacement too big" },
	    { iptc_delete_num_entry, E2BIG, "Index of deletion too big" },
	    { iptc_insert_entry, ELOOP, "Loop found in table" },
	    { iptc_insert_entry, EINVAL, "Target problem" },
	    /* EINVAL for CHECK probably means bad interface. */
	    { iptc_check_packet, EINVAL,
	      "bad arguments (does that interface exist?)" },
	    /* ENOENT for DELETE probably means no matching rule */
	    { iptc_delete_entry, ENOENT,
	      "bad rule (does a matching rule exist in that chain?)" },
	    { NULL, ENOENT, "No extended target/match by that name" }
	  };

	for (i = 0; i < sizeof(table)/sizeof(struct table_struct); i++) {
		if ((!table[i].fn || table[i].fn == iptc_fn)
		    && table[i].err == err)
			return table[i].message;
	}

	return strerror(err);
}

/***************************** DEBUGGING ********************************/
static inline int
unconditional(const struct ipt_ip *ip)
{
	unsigned int i;

	for (i = 0; i < sizeof(*ip)/sizeof(u_int32_t); i++)
		if (((u_int32_t *)ip)[i])
			return 0;

	return 1;
}

static inline int
check_match(const struct ipt_entry_match *m, unsigned int *off)
{
	assert(m->match_size >= sizeof(struct ipt_entry_match));

	(*off) += m->match_size;
	return 0;
}

static inline int
check_entry(const struct ipt_entry *e, unsigned int *i, unsigned int *off,
	    unsigned int user_offset, int *was_return,
	    iptc_handle_t h)
{
	unsigned int toff;
	struct ipt_standard_target *t;

	assert(e->target_offset >= sizeof(struct ipt_entry));
	assert(e->next_offset >= e->target_offset
	       + sizeof(struct ipt_entry_target));
	toff = sizeof(struct ipt_entry);
	IPT_MATCH_ITERATE(e, check_match, &toff);

	assert(toff == e->target_offset);

	t = (struct ipt_standard_target *)
		ipt_get_target((struct ipt_entry *)e);
	assert(t->target.target_size == e->next_offset - e->target_offset);
	assert(!iptc_is_chain(t->target.u.name, h));

	if (strcmp(t->target.u.name, IPT_STANDARD_TARGET) == 0) {
		assert(t->target.target_size
		       == IPT_ALIGN(sizeof(struct ipt_standard_target)));

		assert(t->verdict == -NF_DROP-1
		       || t->verdict == -NF_ACCEPT-1
		       || t->verdict == IPT_RETURN
		       || t->verdict < (int)h->entries.size);

		if (t->verdict >= 0) {
			struct ipt_entry *te = get_entry(h, t->verdict);
			int idx;

			idx = entry2index(h, te);
			assert(strcmp(ipt_get_target(te)->u.name,
				      IPT_ERROR_TARGET)
			       != 0);
			assert(te != e);

			/* Prior node must be error node, or this node. */
			assert(t->verdict == entry2offset(h, e)+e->next_offset
			       || strcmp(ipt_get_target(index2entry(h, idx-1))
					 ->u.name, IPT_ERROR_TARGET)
			       == 0);
		}

		if (t->verdict == IPT_RETURN
		    && unconditional(&e->ip)
		    && e->target_offset == sizeof(*e))
			*was_return = 1;
		else
			*was_return = 0;
	} else if (strcmp(t->target.u.name, IPT_ERROR_TARGET) == 0) {
		assert(t->target.target_size
		       == IPT_ALIGN(sizeof(struct ipt_error_target)));

		/* If this is in user area, previous must have been return */
		if (*off > user_offset)
			assert(*was_return);

		*was_return = 0;
	}
	else *was_return = 0;

	if (*off == user_offset)
		assert(strcmp(t->target.u.name, IPT_ERROR_TARGET) == 0);

	(*off) += e->next_offset;
	(*i)++;
	return 0;
}

/* Do every conceivable sanity check on the handle */
static void
do_check(iptc_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_IP_LOCAL_IN
			   | 1 << NF_IP_FORWARD
			   | 1 << NF_IP_LOCAL_OUT));

		/* Hooks should be first three */
		assert(h->info.hook_entry[NF_IP_LOCAL_IN] == 0);

		n = get_chain_end(h, 0);
		n += get_entry(h, n)->next_offset;
		assert(h->info.hook_entry[NF_IP_FORWARD] == n);

		n = get_chain_end(h, n);
		n += get_entry(h, n)->next_offset;
		assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n);

		user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT];
	} else if (strcmp(h->info.name, "nat") == 0) {
		assert(h->info.valid_hooks
		       == (1 << NF_IP_PRE_ROUTING
			   | 1 << NF_IP_POST_ROUTING
			   | 1 << NF_IP_LOCAL_OUT));

		assert(h->info.hook_entry[NF_IP_PRE_ROUTING] == 0);

		n = get_chain_end(h, 0);
		n += get_entry(h, n)->next_offset;
		assert(h->info.hook_entry[NF_IP_POST_ROUTING] == n);

		n = get_chain_end(h, n);
		n += get_entry(h, n)->next_offset;
		assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n);

		user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT];
	} else if (strcmp(h->info.name, "mangle") == 0) {
		assert(h->info.valid_hooks
		       == (1 << NF_IP_PRE_ROUTING
			   | 1 << NF_IP_LOCAL_OUT));

		/* Hooks should be first three */
		assert(h->info.hook_entry[NF_IP_PRE_ROUTING] == 0);

		n = get_chain_end(h, 0);
		n += get_entry(h, n)->next_offset;
		assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n);

		user_offset = h->info.hook_entry[NF_IP_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 < NF_IP_NUMHOOKS; i++) {
		struct ipt_entry *e;
		struct ipt_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->ip));
		assert(e->target_offset == sizeof(*e));
		assert(e->next_offset == sizeof(*e) + sizeof(*t));
		t = (struct ipt_standard_target *)ipt_get_target(e);

		assert(strcmp(t->target.u.name, IPT_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 ipt_entry)
					 +sizeof(struct ipt_standard_target)));

	assert(h->entries.size
	       >= (h->new_number
		   * (sizeof(struct ipt_entry)
		      + sizeof(struct ipt_standard_target))));
	assert(strcmp(h->info.name, h->entries.name) == 0);

	i = 0; n = 0;
	was_return = 0;
	/* Check all the entries. */
	IPT_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(ipt_get_target(index2entry(h, h->new_number-1))->u.name,
		      IPT_ERROR_TARGET) == 0);
}
