From 03462993f2b3428e14355ac646f0694609a8b2bf Mon Sep 17 00:00:00 2001 From: Bart De Schuymer Date: Sat, 25 Oct 2003 10:18:31 +0000 Subject: auto-detect 2.4 or 2.6 --- arptables.c | 19 +++++++++++++++++++ include/arptables.h | 2 ++ include/netfilter_arp.h | 6 +----- libarptc/libarptc.c | 3 +-- libarptc/libarptc_incl.c | 47 ++++++++++++++++++++++++++++++++++++----------- 5 files changed, 59 insertions(+), 18 deletions(-) diff --git a/arptables.c b/arptables.c index e20d370..225f36a 100644 --- a/arptables.c +++ b/arptables.c @@ -154,6 +154,8 @@ static struct option original_opts[] = { { 0 } }; +int NF_ARP_NUMHOOKS = 3; + /*#ifndef __OPTIMIZE__ struct arpt_entry_target * arpt_get_target(struct arpt_entry *e) @@ -1776,6 +1778,23 @@ int do_command(int argc, char *argv[], char **table, arptc_handle_t *handle) char *protocol = NULL; const char *modprobe = NULL; + /* first figure out if this is a 2.6 or a 2.4 kernel */ + *handle = arptc_init(*table); + + if (!*handle) { + arptables_insmod("arp_tables", modprobe); + *handle = arptc_init(*table); + if (!*handle) { + NF_ARP_NUMHOOKS = 2; + *handle = arptc_init(*table); + if (!*handle) { + exit_error(VERSION_PROBLEM, + "can't initialize arptables table `%s': %s", + *table, arptc_strerror(errno)); + } + } + } + memset(&fw, 0, sizeof(fw)); opts = original_opts; global_option_offset = 0; diff --git a/include/arptables.h b/include/arptables.h index 820b664..ed4a549 100644 --- a/include/arptables.h +++ b/include/arptables.h @@ -115,6 +115,8 @@ struct arptables_target unsigned int loaded; /* simulate loading so options are merged properly */ }; +extern int NF_ARP_NUMHOOKS; /* boy, this is dirty */ + /* Your shared library should call one of these. */ extern void register_match(struct arptables_match *me); extern void register_target(struct arptables_target *me); diff --git a/include/netfilter_arp.h b/include/netfilter_arp.h index 2c98a81..aaf0866 100644 --- a/include/netfilter_arp.h +++ b/include/netfilter_arp.h @@ -16,11 +16,7 @@ /* ARP Hooks */ #define NF_ARP_IN 0 #define NF_ARP_OUT 1 -#ifndef KERNEL_2_4 #define NF_ARP_FORWARD 2 -#define NF_ARP_NUMHOOKS 3 -#else -#define NF_ARP_NUMHOOKS 2 -#endif +extern int NF_ARP_NUMHOOKS; /* boy, this is dirty */ #endif /* __LINUX_ARP_NETFILTER_H */ diff --git a/libarptc/libarptc.c b/libarptc/libarptc.c index 5af7e76..7be48d7 100644 --- a/libarptc/libarptc.c +++ b/libarptc/libarptc.c @@ -51,7 +51,6 @@ typedef unsigned int socklen_t; #define GET_TARGET arpt_get_target #define ERROR_TARGET ARPT_ERROR_TARGET -#define NUMHOOKS NF_ARP_NUMHOOKS #define ARPT_CHAINLABEL arpt_chainlabel @@ -471,7 +470,7 @@ do_check(TC_HANDLE_T h, unsigned int line) /* Overflows should be end of entry chains, and unconditional policy nodes. */ - for (i = 0; i < NUMHOOKS; i++) { + for (i = 0; i < NF_ARP_NUMHOOKS; i++) { STRUCT_ENTRY *e; STRUCT_STANDARD_TARGET *t; diff --git a/libarptc/libarptc_incl.c b/libarptc/libarptc_incl.c index ae670da..409602f 100644 --- a/libarptc/libarptc_incl.c +++ b/libarptc/libarptc_incl.c @@ -1,4 +1,4 @@ -/* Library which manipulates firewall rules. Version $Revision: 1.3 $ */ +/* Library which manipulates firewall rules. Version $Revision: 1.4 $ */ /* Architecture of firewall rules is as follows: * @@ -26,9 +26,7 @@ static const char *hooknames[] = { [NF_ARP_IN] "INPUT", [NF_ARP_OUT] "OUTPUT", -#ifndef KERNEL_2_4 [NF_ARP_FORWARD] "FORWARD", -#endif }; struct counter_map @@ -236,6 +234,9 @@ TC_INIT(const char *tablename) return NULL; s = sizeof(info); + if (NF_ARP_NUMHOOKS == 2) + s -= 2 * sizeof(unsigned int); + if (strlen(tablename) >= TABLE_MAXNAMELEN) { errno = EINVAL; return NULL; @@ -244,6 +245,13 @@ TC_INIT(const char *tablename) if (getsockopt(sockfd, TC_IPPROTO, SO_GET_INFO, &info, &s) < 0) return NULL; + if (NF_ARP_NUMHOOKS == 2) { + memmove(&(info.hook_entry[3]), &(info.hook_entry[2]), + 5 * sizeof(unsigned int)); + memmove(&(info.underflow[3]), &(info.underflow[2]), + 2 * sizeof(unsigned int)); + } + if ((h = alloc_handle(info.name, info.size, info.num_entries)) == NULL) return NULL; @@ -323,7 +331,7 @@ is_hook_entry(STRUCT_ENTRY *e, TC_HANDLE_T h) { unsigned int i; - for (i = 0; i < NUMHOOKS; i++) { + for (i = 0; i < NF_ARP_NUMHOOKS; i++) { if ((h->info.valid_hooks & (1 << i)) && get_entry(h, h->info.hook_entry[i]) == e) return i+1; @@ -395,7 +403,7 @@ static int populate_cache(TC_HANDLE_T h) h->cache_num_builtins = 0; /* Count builtins */ - for (i = 0; i < NUMHOOKS; i++) { + for (i = 0; i < NF_ARP_NUMHOOKS; i++) { if (h->info.valid_hooks & (1 << i)) h->cache_num_builtins++; } @@ -456,7 +464,7 @@ get_chain_end(const TC_HANDLE_T handle, unsigned int start) e = get_entry(handle, off); /* We hit an entry point. */ - for (i = 0; i < NUMHOOKS; i++) { + for (i = 0; i < NF_ARP_NUMHOOKS; i++) { if ((handle->info.valid_hooks & (1 << i)) && off == handle->info.hook_entry[i]) return last_off; @@ -625,7 +633,7 @@ TC_BUILTIN(const char *chain, const TC_HANDLE_T handle) { unsigned int i; - for (i = 0; i < NUMHOOKS; i++) { + for (i = 0; i < NF_ARP_NUMHOOKS; i++) { if ((handle->info.valid_hooks & (1 << i)) && handle->hooknames[i] && strcmp(handle->hooknames[i], chain) == 0) @@ -710,7 +718,7 @@ insert_rules(unsigned int num_rules, unsigned int rules_size, newinfo = (*handle)->info; /* Fix up entry points. */ - for (i = 0; i < NUMHOOKS; i++) { + for (i = 0; i < NF_ARP_NUMHOOKS; i++) { /* Entry points to START of chain, so keep same if inserting on at that point. */ if ((*handle)->info.hook_entry[i] > offset) @@ -778,7 +786,7 @@ delete_rules(unsigned int num_rules, unsigned int rules_size, } /* Fix up entry points. */ - for (i = 0; i < NUMHOOKS; i++) { + for (i = 0; i < NF_ARP_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 */ @@ -1578,6 +1586,7 @@ TC_COMMIT(TC_HANDLE_T *handle) size_t counterlen = sizeof(STRUCT_COUNTERS_INFO) + sizeof(STRUCT_COUNTERS) * (*handle)->new_number; + int sizeof_repl = sizeof(*repl); CHECK(*handle); #if 0 @@ -1588,7 +1597,8 @@ TC_COMMIT(TC_HANDLE_T *handle) if (!(*handle)->changed) goto finished; - repl = malloc(sizeof(*repl) + (*handle)->entries.size); + /* allocate a bit more than needed for ease */ + repl = malloc(2 * sizeof(*repl) + (*handle)->entries.size); if (!repl) { errno = ENOMEM; return 0; @@ -1624,14 +1634,29 @@ TC_COMMIT(TC_HANDLE_T *handle) memcpy(repl->entries, (*handle)->entries.entrytable, (*handle)->entries.size); + if (NF_ARP_NUMHOOKS == 2) { + memmove(&(repl->underflow[2]), &(repl->underflow[3]), + ((*handle)->entries.size) + sizeof(struct arpt_replace)); + memmove(&(repl->hook_entry[2]), &(repl->hook_entry[3]), + ((*handle)->entries.size) + sizeof(struct arpt_replace)); + sizeof_repl -= 2 * sizeof(unsigned int); + } + if (setsockopt(sockfd, TC_IPPROTO, SO_SET_REPLACE, repl, - sizeof(*repl) + (*handle)->entries.size) < 0) { + sizeof_repl + (*handle)->entries.size) < 0) { free(repl->counters); free(repl); free(newcounters); return 0; } + if (NF_ARP_NUMHOOKS == 2) { + memmove(&(repl->hook_entry[3]), &(repl->hook_entry[2]), + ((*handle)->entries.size) + sizeof(struct arpt_replace)); + memmove(&(repl->underflow[3]), &(repl->underflow[2]), + ((*handle)->entries.size) + sizeof(struct arpt_replace)); + } + /* Put counters back. */ strcpy(newcounters->name, (*handle)->info.name); newcounters->num_counters = (*handle)->new_number; -- cgit v1.2.3