/*
 * 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 *)calloc(u_repl->num_chains, sizeof(unsigned int));
	if (!chain_offsets)
		ebt_print_memory();
	/* 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 the correct priviliges */
	if ((fd = creat(filename, 0600)) == -1) {
		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("Unable to update the kernel. Two possible causes:\n"
			"1. Multiple ebtables programs were executing simultaneously. The ebtables\n"
			"   userspace tool doesn't by default support multiple ebtables programs running\n"
			"   concurrently. The ebtables option --concurrent or a tool like flock can be\n"
			"   used to support concurrent scripts that update the ebtables kernel tables.\n"
			"2. The kernel doesn't support a certain ebtables extension, consider\n"
			"   recompiling your kernel or insmod the extension.\n");
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 ret;
}

/* 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 = NULL;
	struct ebt_u_entry *next = NULL;
	int i, chainnr = -1;

	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) {
			chainnr++;
			while (chainnr < u_repl->num_chains && (!(entries = u_repl->chains[chainnr]) ||
			       (next = entries->entries->next) == entries->entries))
				chainnr++;
			if (chainnr == u_repl->num_chains)
				break;
		}
		if (next == NULL)
			ebt_print_bug("next == NULL");
		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-NF_BR_NUMHOOKS;
			}
		}

		(*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)
	   || (repl->counters && 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 = NULL;
	struct ebt_cntchanges *new_cc = NULL, *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;
}
