/* 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);
}
