/*
 * communication.c, v2.0 July 2002
 *
 * Author: Bart De Schuymer
 *
 */

/*
 * All the userspace/kernel communication is in this file.
 * The other code should not have to know anything about the way the
 * kernel likes the structure of the table data.
 * The other code works with linked lists. So, the translation is done here.
 */

#include <getopt.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/socket.h>
#include "include/ebtables_u.h"

extern char* hooknames[NF_BR_NUMHOOKS];

#ifdef KERNEL_64_USERSPACE_32
#define sparc_cast (uint64_t)
#else
#define sparc_cast
#endif

int sockfd = -1;

static int get_sockfd()
{
	int ret = 0;
	if (sockfd == -1) {
		sockfd = socket(AF_INET, SOCK_RAW, PF_INET);
		if (sockfd < 0) {
			ebt_print_error("Problem getting a socket, "
					"you probably don't have the right "
					"permissions");
			ret = -1;
		}
	}
	return ret;
}

static struct ebt_replace *translate_user2kernel(struct ebt_u_replace *u_repl)
{
	struct ebt_replace *new;
	struct ebt_u_entry *e;
	struct ebt_u_match_list *m_l;
	struct ebt_u_watcher_list *w_l;
	struct ebt_u_entries *entries;
	char *p, *base;
	int i, j;
	unsigned int entries_size = 0, *chain_offsets;

	new = (struct ebt_replace *)malloc(sizeof(struct ebt_replace));
	if (!new)
		ebt_print_memory();
	new->valid_hooks = u_repl->valid_hooks;
	strcpy(new->name, u_repl->name);
	new->nentries = u_repl->nentries;
	new->num_counters = u_repl->num_counters;
	new->counters = sparc_cast u_repl->counters;
	chain_offsets = (unsigned int *)malloc(u_repl->num_chains * sizeof(unsigned int));
	/* Determine size */
	for (i = 0; i < u_repl->num_chains; i++) {
		if (!(entries = u_repl->chains[i]))
			continue;
		chain_offsets[i] = entries_size;
		entries_size += sizeof(struct ebt_entries);
		j = 0;
		e = entries->entries->next;
		while (e != entries->entries) {
			j++;
			entries_size += sizeof(struct ebt_entry);
			m_l = e->m_list;
			while (m_l) {
				entries_size += m_l->m->match_size +
				   sizeof(struct ebt_entry_match);
				m_l = m_l->next;
			}
			w_l = e->w_list;
			while (w_l) {
				entries_size += w_l->w->watcher_size +
				   sizeof(struct ebt_entry_watcher);
				w_l = w_l->next;
			}
			entries_size += e->t->target_size +
			   sizeof(struct ebt_entry_target);
			e = e->next;
		}
		/* A little sanity check */
		if (j != entries->nentries)
			ebt_print_bug("Wrong nentries: %d != %d, hook = %s", j,
			   entries->nentries, entries->name);
	}

	new->entries_size = entries_size;
	p = (char *)malloc(entries_size);
	if (!p)
		ebt_print_memory();

	/* Put everything in one block */
	new->entries = sparc_cast p;
	for (i = 0; i < u_repl->num_chains; i++) {
		struct ebt_entries *hlp;

		hlp = (struct ebt_entries *)p;
		if (!(entries = u_repl->chains[i]))
			continue;
		if (i < NF_BR_NUMHOOKS)
			new->hook_entry[i] = sparc_cast hlp;
		hlp->nentries = entries->nentries;
		hlp->policy = entries->policy;
		strcpy(hlp->name, entries->name);
		hlp->counter_offset = entries->counter_offset;
		hlp->distinguisher = 0; /* Make the kernel see the light */
		p += sizeof(struct ebt_entries);
		e = entries->entries->next;
		while (e != entries->entries) {
			struct ebt_entry *tmp = (struct ebt_entry *)p;

			tmp->bitmask = e->bitmask | EBT_ENTRY_OR_ENTRIES;
			tmp->invflags = e->invflags;
			tmp->ethproto = e->ethproto;
			strcpy(tmp->in, e->in);
			strcpy(tmp->out, e->out);
			strcpy(tmp->logical_in, e->logical_in);
			strcpy(tmp->logical_out, e->logical_out);
			memcpy(tmp->sourcemac, e->sourcemac,
			   sizeof(tmp->sourcemac));
			memcpy(tmp->sourcemsk, e->sourcemsk,
			   sizeof(tmp->sourcemsk));
			memcpy(tmp->destmac, e->destmac, sizeof(tmp->destmac));
			memcpy(tmp->destmsk, e->destmsk, sizeof(tmp->destmsk));

			base = p;
			p += sizeof(struct ebt_entry);
			m_l = e->m_list;
			while (m_l) {
				memcpy(p, m_l->m, m_l->m->match_size +
				   sizeof(struct ebt_entry_match));
				p += m_l->m->match_size +
				   sizeof(struct ebt_entry_match);
				m_l = m_l->next;
			}
			tmp->watchers_offset = p - base;
			w_l = e->w_list;
			while (w_l) {
				memcpy(p, w_l->w, w_l->w->watcher_size +
				   sizeof(struct ebt_entry_watcher));
				p += w_l->w->watcher_size +
				   sizeof(struct ebt_entry_watcher);
				w_l = w_l->next;
			}
			tmp->target_offset = p - base;
			memcpy(p, e->t, e->t->target_size +
			   sizeof(struct ebt_entry_target));
			if (!strcmp(e->t->u.name, EBT_STANDARD_TARGET)) {
				struct ebt_standard_target *st =
				   (struct ebt_standard_target *)p;
				/* Translate the jump to a udc */
				if (st->verdict >= 0)
					st->verdict = chain_offsets
					   [st->verdict + NF_BR_NUMHOOKS];
			}
			p += e->t->target_size +
			   sizeof(struct ebt_entry_target);
			tmp->next_offset = p - base;
			e = e->next;
		}
	}

	/* Sanity check */
	if (p - (char *)new->entries != new->entries_size)
		ebt_print_bug("Entries_size bug");
	free(chain_offsets);
	return new;
}

static void store_table_in_file(char *filename, struct ebt_replace *repl)
{
	char *data;
	int size;
	int fd;

	/* Start from an empty file with right priviliges */
	if (!(fd = creat(filename, 0600))) {
		ebt_print_error("Couldn't create file %s", filename);
		return;
	}

	size = sizeof(struct ebt_replace) + repl->entries_size +
	   repl->nentries * sizeof(struct ebt_counter);
	data = (char *)malloc(size);
	if (!data)
		ebt_print_memory();
	memcpy(data, repl, sizeof(struct ebt_replace));
	memcpy(data + sizeof(struct ebt_replace), (char *)repl->entries,
	   repl->entries_size);
	/* Initialize counters to zero, deliver_counters() can update them */
	memset(data + sizeof(struct ebt_replace) + repl->entries_size,
	   0, repl->nentries * sizeof(struct ebt_counter));
	if (write(fd, data, size) != size)
		ebt_print_error("Couldn't write everything to file %s",
				filename);
	close(fd);
	free(data);
}

void ebt_deliver_table(struct ebt_u_replace *u_repl)
{
	socklen_t optlen;
	struct ebt_replace *repl;

	/* Translate the struct ebt_u_replace to a struct ebt_replace */
	repl = translate_user2kernel(u_repl);
	if (u_repl->filename != NULL) {
		store_table_in_file(u_repl->filename, repl);
		goto free_repl;
	}
	/* Give the data to the kernel */
	optlen = sizeof(struct ebt_replace) + repl->entries_size;
	if (get_sockfd())
		goto free_repl;
	if (!setsockopt(sockfd, IPPROTO_IP, EBT_SO_SET_ENTRIES, repl, optlen))
		goto free_repl;
	if (u_repl->command == 8) { /* The ebtables module may not
	                             * yet be loaded with --atomic-commit */
		ebtables_insmod("ebtables");
		if (!setsockopt(sockfd, IPPROTO_IP, EBT_SO_SET_ENTRIES,
		    repl, optlen))
			goto free_repl;
	}

	ebt_print_error("The kernel doesn't support a certain ebtables"
		    " extension, consider recompiling your kernel or insmod"
		    " the extension");
free_repl:
	if (repl) {
		free(repl->entries);
		free(repl);
	}
}

static int store_counters_in_file(char *filename, struct ebt_u_replace *repl)
{
	int size = repl->nentries * sizeof(struct ebt_counter), ret = 0;
	unsigned int entries_size;
	struct ebt_replace hlp;
	FILE *file;

	if (!(file = fopen(filename, "r+b"))) {
		ebt_print_error("Could not open file %s", filename);
		return -1;
	}
	/* Find out entries_size and then set the file pointer to the
	 * counters */
	if (fseek(file, (char *)(&hlp.entries_size) - (char *)(&hlp), SEEK_SET)
	   || fread(&entries_size, sizeof(char), sizeof(unsigned int), file) !=
	   sizeof(unsigned int) ||
	   fseek(file, entries_size + sizeof(struct ebt_replace), SEEK_SET)) {
		ebt_print_error("File %s is corrupt", filename);
		ret = -1;
		goto close_file;
	}
	if (fwrite(repl->counters, sizeof(char), size, file) != size) {
		ebt_print_error("Could not write everything to file %s",
				filename);
		ret = -1;
	}
close_file:
	fclose(file);
	return 0;
}

/* Gets executed after ebt_deliver_table. Delivers the counters to the kernel
 * and resets the counterchanges to CNT_NORM */
void ebt_deliver_counters(struct ebt_u_replace *u_repl)
{
	struct ebt_counter *old, *new, *newcounters;
	socklen_t optlen;
	struct ebt_replace repl;
	struct ebt_cntchanges *cc = u_repl->cc->next, *cc2;
	struct ebt_u_entries *entries;
	struct ebt_u_entry *next = NULL;
	int i, chainnr = 0;

	if (u_repl->nentries == 0)
		return;

	newcounters = (struct ebt_counter *)
	   malloc(u_repl->nentries * sizeof(struct ebt_counter));
	if (!newcounters)
		ebt_print_memory();
	memset(newcounters, 0, u_repl->nentries * sizeof(struct ebt_counter));
	old = u_repl->counters;
	new = newcounters;
	while (cc != u_repl->cc) {
		if (!next || next == entries->entries) {
			while (chainnr < u_repl->num_chains && (!(entries = u_repl->chains[chainnr++]) ||
			       (next = entries->entries->next) == entries->entries));
			if (chainnr == u_repl->num_chains)
				break;
		}
		if (cc->type == CNT_NORM) {
			/* 'Normal' rule, meaning we didn't do anything to it
			 * So, we just copy */
			*new = *old;
			next->cnt = *new;
			next->cnt_surplus.pcnt = next->cnt_surplus.bcnt = 0;
			old++; /* We've used an old counter */
			new++; /* We've set a new counter */
			next = next->next;
		} else if (cc->type == CNT_DEL) {
			old++; /* Don't use this old counter */
		} else {
			if (cc->type == CNT_CHANGE) {
				if (cc->change % 3 == 1)
					new->pcnt = old->pcnt + next->cnt_surplus.pcnt;
				else if (cc->change % 3 == 2)
					new->pcnt = old->pcnt - next->cnt_surplus.pcnt;
				else
					new->pcnt = next->cnt.pcnt;
				if (cc->change / 3 == 1)
					new->bcnt = old->bcnt + next->cnt_surplus.bcnt;
				else if (cc->change / 3 == 2)
					new->bcnt = old->bcnt - next->cnt_surplus.bcnt;
				else
					new->bcnt = next->cnt.bcnt;
			} else
				*new = next->cnt;
			next->cnt = *new;
			next->cnt_surplus.pcnt = next->cnt_surplus.bcnt = 0;
			if (cc->type == CNT_ADD)
				new++;
			else {
				old++;
				new++;
			}
			next = next->next;
		}
		cc = cc->next;
	}

	free(u_repl->counters);
	u_repl->counters = newcounters;
	u_repl->num_counters = u_repl->nentries;
	/* Reset the counterchanges to CNT_NORM and delete the unused cc */
	i = 0;
	cc = u_repl->cc->next;
	while (cc != u_repl->cc) {
		if (cc->type == CNT_DEL) {
			cc->prev->next = cc->next;
			cc->next->prev = cc->prev;
			cc2 = cc->next;
			free(cc);
			cc = cc2;
		} else {
			cc->type = CNT_NORM;
			cc->change = 0;
			i++;
			cc = cc->next;
		}
	}
	if (i != u_repl->nentries)
		ebt_print_bug("i != u_repl->nentries");
	if (u_repl->filename != NULL) {
		store_counters_in_file(u_repl->filename, u_repl);
		return;
	}
	optlen = u_repl->nentries * sizeof(struct ebt_counter) +
	   sizeof(struct ebt_replace);
	/* Now put the stuff in the kernel's struct ebt_replace */
	repl.counters = sparc_cast u_repl->counters;
	repl.num_counters = u_repl->num_counters;
	memcpy(repl.name, u_repl->name, sizeof(repl.name));

	if (get_sockfd())
		return;
	if (setsockopt(sockfd, IPPROTO_IP, EBT_SO_SET_COUNTERS, &repl, optlen))
		ebt_print_bug("Couldn't update kernel counters");
}

static int
ebt_translate_match(struct ebt_entry_match *m, struct ebt_u_match_list ***l)
{
	struct ebt_u_match_list *new;
	int ret = 0;

	new = (struct ebt_u_match_list *)
	   malloc(sizeof(struct ebt_u_match_list));
	if (!new)
		ebt_print_memory();
	new->m = (struct ebt_entry_match *)
	   malloc(m->match_size + sizeof(struct ebt_entry_match));
	if (!new->m)
		ebt_print_memory();
	memcpy(new->m, m, m->match_size + sizeof(struct ebt_entry_match));
	new->next = NULL;
	**l = new;
	*l = &new->next;
	if (ebt_find_match(new->m->u.name) == NULL) {
		ebt_print_error("Kernel match %s unsupported by userspace tool",
				new->m->u.name);
		ret = -1;
	}
	return ret;
}

static int
ebt_translate_watcher(struct ebt_entry_watcher *w,
   struct ebt_u_watcher_list ***l)
{
	struct ebt_u_watcher_list *new;
	int ret = 0;

	new = (struct ebt_u_watcher_list *)
	   malloc(sizeof(struct ebt_u_watcher_list));
	if (!new)
		ebt_print_memory();
	new->w = (struct ebt_entry_watcher *)
	   malloc(w->watcher_size + sizeof(struct ebt_entry_watcher));
	if (!new->w)
		ebt_print_memory();
	memcpy(new->w, w, w->watcher_size + sizeof(struct ebt_entry_watcher));
	new->next = NULL;
	**l = new;
	*l = &new->next;
	if (ebt_find_watcher(new->w->u.name) == NULL) {
		ebt_print_error("Kernel watcher %s unsupported by userspace "
				"tool", new->w->u.name);
		ret = -1;
	}
	return ret;
}

static int
ebt_translate_entry(struct ebt_entry *e, int *hook, int *n, int *cnt,
   int *totalcnt, struct ebt_u_entry **u_e, struct ebt_u_replace *u_repl,
   unsigned int valid_hooks, char *base, struct ebt_cntchanges **cc)
{
	/* An entry */
	if (e->bitmask & EBT_ENTRY_OR_ENTRIES) {
		struct ebt_u_entry *new;
		struct ebt_u_match_list **m_l;
		struct ebt_u_watcher_list **w_l;
		struct ebt_entry_target *t;

		new = (struct ebt_u_entry *)malloc(sizeof(struct ebt_u_entry));
		if (!new)
			ebt_print_memory();
		new->bitmask = e->bitmask;
		/*
		 * Plain userspace code doesn't know about
		 * EBT_ENTRY_OR_ENTRIES
		 */
		new->bitmask &= ~EBT_ENTRY_OR_ENTRIES;
		new->invflags = e->invflags;
		new->ethproto = e->ethproto;
		strcpy(new->in, e->in);
		strcpy(new->out, e->out);
		strcpy(new->logical_in, e->logical_in);
		strcpy(new->logical_out, e->logical_out);
		memcpy(new->sourcemac, e->sourcemac, sizeof(new->sourcemac));
		memcpy(new->sourcemsk, e->sourcemsk, sizeof(new->sourcemsk));
		memcpy(new->destmac, e->destmac, sizeof(new->destmac));
		memcpy(new->destmsk, e->destmsk, sizeof(new->destmsk));
		if (*totalcnt >= u_repl->nentries)
			ebt_print_bug("*totalcnt >= u_repl->nentries");
		new->cnt = u_repl->counters[*totalcnt];
		new->cnt_surplus.pcnt = new->cnt_surplus.bcnt = 0;
		new->cc = *cc;
		*cc = (*cc)->next;
		new->m_list = NULL;
		new->w_list = NULL;
		new->next = (*u_e)->next;
		new->next->prev = new;
		(*u_e)->next = new;
		new->prev = *u_e;
		*u_e = new;
		m_l = &new->m_list;
		EBT_MATCH_ITERATE(e, ebt_translate_match, &m_l);
		w_l = &new->w_list;
		EBT_WATCHER_ITERATE(e, ebt_translate_watcher, &w_l);

		t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
		new->t = (struct ebt_entry_target *)
		   malloc(t->target_size + sizeof(struct ebt_entry_target));
		if (!new->t)
			ebt_print_memory();
		if (ebt_find_target(t->u.name) == NULL) {
			ebt_print_error("Kernel target %s unsupported by "
					"userspace tool", t->u.name);
			return -1;
		}
		memcpy(new->t, t, t->target_size +
		   sizeof(struct ebt_entry_target));
		/* Deal with jumps to udc */
		if (!strcmp(t->u.name, EBT_STANDARD_TARGET)) {
			char *tmp = base;
			int verdict = ((struct ebt_standard_target *)t)->verdict;
			int i;

			if (verdict >= 0) {
				tmp += verdict;
				for (i = NF_BR_NUMHOOKS; i < u_repl->num_chains; i++)
					if (u_repl->chains[i]->kernel_start == tmp)
						break;
				if (i == u_repl->num_chains)
					ebt_print_bug("Can't find udc for jump");
				((struct ebt_standard_target *)new->t)->verdict = i;
			}
		}

		(*cnt)++;
		(*totalcnt)++;
		return 0;
	} else { /* A new chain */
		int i;
		struct ebt_entries *entries = (struct ebt_entries *)e;

		if (*n != *cnt)
			ebt_print_bug("Nr of entries in the chain is wrong");
		*n = entries->nentries;
		*cnt = 0;
		for (i = *hook + 1; i < NF_BR_NUMHOOKS; i++)
			if (valid_hooks & (1 << i))
				break;
		*hook = i;
		*u_e = u_repl->chains[*hook]->entries;
		return 0;
	}
}

/* Initialize all chain headers */
static int
ebt_translate_chains(struct ebt_entry *e, int *hook,
   struct ebt_u_replace *u_repl, unsigned int valid_hooks)
{
	int i;
	struct ebt_entries *entries = (struct ebt_entries *)e;
	struct ebt_u_entries *new;

	if (!(e->bitmask & EBT_ENTRY_OR_ENTRIES)) {
		for (i = *hook + 1; i < NF_BR_NUMHOOKS; i++)
			if (valid_hooks & (1 << i))
				break;
		new = (struct ebt_u_entries *)malloc(sizeof(struct ebt_u_entries));
		if (!new)
			ebt_print_memory();
		if (i == u_repl->max_chains)
			ebt_double_chains(u_repl);
		u_repl->chains[i] = new;
		if (i >= NF_BR_NUMHOOKS)
			new->kernel_start = (char *)e;
		*hook = i;
		new->nentries = entries->nentries;
		new->policy = entries->policy;
		new->entries = (struct ebt_u_entry *)malloc(sizeof(struct ebt_u_entry));
		if (!new->entries)
			ebt_print_memory();
		new->entries->next = new->entries->prev = new->entries;
		new->counter_offset = entries->counter_offset;
		strcpy(new->name, entries->name);
	}
	return 0;
}

static int retrieve_from_file(char *filename, struct ebt_replace *repl,
   char command)
{
	FILE *file;
	char *hlp = NULL, *entries;
	struct ebt_counter *counters;
	int size, ret = 0;

	if (!(file = fopen(filename, "r+b"))) {
		ebt_print_error("Could not open file %s", filename);
		return -1;
	}
	/* Make sure table name is right if command isn't -L or --atomic-commit */
	if (command != 'L' && command != 8) {
		hlp = (char *)malloc(strlen(repl->name) + 1);
		if (!hlp)
			ebt_print_memory();
		strcpy(hlp, repl->name);
	}
	if (fread(repl, sizeof(char), sizeof(struct ebt_replace), file)
	   != sizeof(struct ebt_replace)) {
		ebt_print_error("File %s is corrupt", filename);
		ret = -1;
		goto close_file;
	}
	if (command != 'L' && command != 8 && strcmp(hlp, repl->name)) {
		ebt_print_error("File %s contains wrong table name or is "
				"corrupt", filename);
		ret = -1;
		goto close_file;
	} else if (!ebt_find_table(repl->name)) {
		ebt_print_error("File %s contains invalid table name",
				filename);
		ret = -1;
		goto close_file;
	}

	size = sizeof(struct ebt_replace) +
	   repl->nentries * sizeof(struct ebt_counter) + repl->entries_size;
	fseek(file, 0, SEEK_END);
	if (size != ftell(file)) {
		ebt_print_error("File %s has wrong size", filename);
		ret = -1;
		goto close_file;
	}
	entries = (char *)malloc(repl->entries_size);
	if (!entries)
		ebt_print_memory();
	repl->entries = sparc_cast entries;
	if (repl->nentries) {
		counters = (struct ebt_counter *)
		   malloc(repl->nentries * sizeof(struct ebt_counter));
		repl->counters = sparc_cast counters;
		if (!repl->counters)
			ebt_print_memory();
	} else
		repl->counters = sparc_cast NULL;
	/* Copy entries and counters */
	if (fseek(file, sizeof(struct ebt_replace), SEEK_SET) ||
	   fread((char *)repl->entries, sizeof(char), repl->entries_size, file)
	   != repl->entries_size ||
	   fseek(file, sizeof(struct ebt_replace) + repl->entries_size,
		 SEEK_SET)
	   || fread((char *)repl->counters, sizeof(char),
	   repl->nentries * sizeof(struct ebt_counter), file)
	   != repl->nentries * sizeof(struct ebt_counter)) {
		ebt_print_error("File %s is corrupt", filename);
		free(entries);
		repl->entries = NULL;
		ret = -1;
	}
close_file:
	fclose(file);
	free(hlp);
	return ret;
}

static int retrieve_from_kernel(struct ebt_replace *repl, char command,
				int init)
{
	socklen_t optlen;
	int optname;
	char *entries;

	optlen = sizeof(struct ebt_replace);
	if (get_sockfd())
		return -1;
	/* --atomic-init || --init-table */
	if (init)
		optname = EBT_SO_GET_INIT_INFO;
	else
		optname = EBT_SO_GET_INFO;
	if (getsockopt(sockfd, IPPROTO_IP, optname, repl, &optlen))
		return -1;

	if ( !(entries = (char *)malloc(repl->entries_size)) )
		ebt_print_memory();
	repl->entries = sparc_cast entries;
	if (repl->nentries) {
		struct ebt_counter *counters;

		if (!(counters = (struct ebt_counter *)
		   malloc(repl->nentries * sizeof(struct ebt_counter))) )
			ebt_print_memory();
		repl->counters = sparc_cast counters;
	}
	else
		repl->counters = sparc_cast NULL;

	/* We want to receive the counters */
	repl->num_counters = repl->nentries;
	optlen += repl->entries_size + repl->num_counters *
	   sizeof(struct ebt_counter);
	if (init)
		optname = EBT_SO_GET_INIT_ENTRIES;
	else
		optname = EBT_SO_GET_ENTRIES;
	if (getsockopt(sockfd, IPPROTO_IP, optname, repl, &optlen))
		ebt_print_bug("Hmm, what is wrong??? bug#1");

	return 0;
}

int ebt_get_table(struct ebt_u_replace *u_repl, int init)
{
	int i, j, k, hook;
	struct ebt_replace repl;
	struct ebt_u_entry *u_e;
	struct ebt_cntchanges *new_cc, *cc;

	strcpy(repl.name, u_repl->name);
	if (u_repl->filename != NULL) {
		if (init)
			ebt_print_bug("Getting initial table data from a file is impossible");
		if (retrieve_from_file(u_repl->filename, &repl, u_repl->command))
			return -1;
		/* -L with a wrong table name should be dealt with silently */
		strcpy(u_repl->name, repl.name);
	} else if (retrieve_from_kernel(&repl, u_repl->command, init))
		return -1;

	/* Translate the struct ebt_replace to a struct ebt_u_replace */
	u_repl->valid_hooks = repl.valid_hooks;
	u_repl->nentries = repl.nentries;
	u_repl->num_counters = repl.num_counters;
	u_repl->counters = repl.counters;
	u_repl->cc = (struct ebt_cntchanges *)malloc(sizeof(struct ebt_cntchanges));
	if (!u_repl->cc)
		ebt_print_memory();
	u_repl->cc->next = u_repl->cc->prev = u_repl->cc;
	cc = u_repl->cc;
	for (i = 0; i < repl.nentries; i++) {
		new_cc = (struct ebt_cntchanges *)malloc(sizeof(struct ebt_cntchanges));
		if (!new_cc)
			ebt_print_memory();
		new_cc->type = CNT_NORM;
		new_cc->change = 0;
		new_cc->prev = cc;
		cc->next = new_cc;
		cc = new_cc;
	}
	if (repl.nentries) {
		new_cc->next = u_repl->cc;
		u_repl->cc->prev = new_cc;
	}
	u_repl->chains = (struct ebt_u_entries **)calloc(EBT_ORI_MAX_CHAINS, sizeof(void *));
	u_repl->max_chains = EBT_ORI_MAX_CHAINS;
	hook = -1;
	/* FIXME: Clean up when an error is encountered */
	EBT_ENTRY_ITERATE(repl.entries, repl.entries_size, ebt_translate_chains,
	   &hook, u_repl, u_repl->valid_hooks);
	if (hook >= NF_BR_NUMHOOKS)
		u_repl->num_chains = hook + 1;
	else
		u_repl->num_chains = NF_BR_NUMHOOKS;
	i = 0; /* Holds the expected nr. of entries for the chain */
	j = 0; /* Holds the up to now counted entries for the chain */
	k = 0; /* Holds the total nr. of entries, should equal u_repl->nentries afterwards */
	cc = u_repl->cc->next;
	hook = -1;
	EBT_ENTRY_ITERATE((char *)repl.entries, repl.entries_size,
	   ebt_translate_entry, &hook, &i, &j, &k, &u_e, u_repl,
	   u_repl->valid_hooks, (char *)repl.entries, &cc);
	if (k != u_repl->nentries)
		ebt_print_bug("Wrong total nentries");
	free(repl.entries);
	return 0;
}
