aboutsummaryrefslogtreecommitdiffstats
path: root/tools/remus/imqebt/communication.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/remus/imqebt/communication.c')
-rw-r--r--tools/remus/imqebt/communication.c762
1 files changed, 0 insertions, 762 deletions
diff --git a/tools/remus/imqebt/communication.c b/tools/remus/imqebt/communication.c
deleted file mode 100644
index 0c58c8fbe4..0000000000
--- a/tools/remus/imqebt/communication.c
+++ /dev/null
@@ -1,762 +0,0 @@
-/*
- * 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(void)
-{
- 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 = NULL;
- 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-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)
- || 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, *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;
-}