From a96e4fca10506462df4ee4035f0f86f09bd9dc34 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Jozsef Kadlecsik/emailAddress=kadlec@blackhole.kfki.hu" Date: Mon, 20 Oct 2008 10:00:26 +0000 Subject: ipset 2.4 release userspace changes: - Added KBUILD_OUTPUT support (Sven Wegener) - Fix memory leak in ipset_iptreemap (Sven Wegener) - Fix multiple compiler warnings (Sven Wegener) - ipportiphash, ipportnethash and setlist types added - binding marked as deprecated functionality - element separator token changed to ',' in anticipating IPv6 addresses, old separator tokens are still supported - unnecessary includes removed - ipset does not try to resolve IP addresses when listing the content of sets (default changed) - manpage updated - ChangeLog forked for kernel part kernel part changes: - ipportiphash, ipportnethash and setlist types added - set type modules reworked to avoid code duplication as much as possible, code unification macros - expand_macros Makefile target added to help debugging code unification macros - ip_set_addip_kernel and ip_set_delip_kernel changed from void to int, __ip_set_get_byname and __ip_set_put_byid added for the sake of setlist type - unnecessary includes removed - compatibility fix for kernels >= 2.6.27: semaphore.h was moved from asm/ to linux/ (James King) - ChangeLog forked for kernel part --- ipset.c | 98 ++++++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 66 insertions(+), 32 deletions(-) (limited to 'ipset.c') diff --git a/ipset.c b/ipset.c index bd23758..d57318a 100644 --- a/ipset.c +++ b/ipset.c @@ -11,11 +11,8 @@ #include #include #include -#include #include #include -#include -#include #include #include #include @@ -23,7 +20,6 @@ #include #include #include -/* #include */ #include "ipset.h" @@ -75,9 +71,10 @@ static const char cmdflags[] = { ' ', /* CMD_NONE */ #define OPT_QUIET 0x0004U /* -q */ #define OPT_DEBUG 0x0008U /* -z */ #define OPT_BINDING 0x0010U /* -b */ -#define NUMBER_OF_OPT 5 +#define OPT_RESOLVE 0x0020U /* -r */ +#define NUMBER_OF_OPT 6 static const char optflags[] = - { 'n', 's', 'q', 'z', 'b' }; + { 'n', 's', 'q', 'z', 'b', 'r' }; static struct option opts_long[] = { /* set operations */ @@ -105,6 +102,7 @@ static struct option opts_long[] = { {"sorted", 0, 0, 's'}, {"quiet", 0, 0, 'q'}, {"binding", 1, 0, 'b'}, + {"resolve", 0, 0, 'r'}, #ifdef IPSET_DEBUG /* debug (if compiled with it) */ @@ -120,7 +118,7 @@ static struct option opts_long[] = { }; static char opts_short[] = - "-N:X::F::E:W:L::S::RA:D:T:B:U:nsqzb:Vh::H::"; + "-N:X::F::E:W:L::S::RA:D:T:B:U:nrsqzb:Vh::H::"; /* Table of legal combinations of commands and options. If any of the * given commands make an option legal, that option is legal. @@ -132,21 +130,21 @@ static char opts_short[] = static char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] = { /* -n -s -q -z -b */ - /*CREATE*/ {'x', 'x', ' ', ' ', 'x'}, - /*DESTROY*/ {'x', 'x', ' ', ' ', 'x'}, - /*FLUSH*/ {'x', 'x', ' ', ' ', 'x'}, - /*RENAME*/ {'x', 'x', ' ', ' ', 'x'}, - /*SWAP*/ {'x', 'x', ' ', ' ', 'x'}, - /*LIST*/ {' ', ' ', 'x', ' ', 'x'}, - /*SAVE*/ {'x', 'x', ' ', ' ', 'x'}, - /*RESTORE*/ {'x', 'x', ' ', ' ', 'x'}, - /*ADD*/ {'x', 'x', ' ', ' ', 'x'}, - /*DEL*/ {'x', 'x', ' ', ' ', 'x'}, - /*TEST*/ {'x', 'x', ' ', ' ', ' '}, - /*BIND*/ {'x', 'x', ' ', ' ', '+'}, - /*UNBIND*/ {'x', 'x', ' ', ' ', 'x'}, - /*HELP*/ {'x', 'x', 'x', ' ', 'x'}, - /*VERSION*/ {'x', 'x', 'x', ' ', 'x'}, + /*CREATE*/ {'x', 'x', ' ', ' ', 'x', 'x'}, + /*DESTROY*/ {'x', 'x', ' ', ' ', 'x', 'x'}, + /*FLUSH*/ {'x', 'x', ' ', ' ', 'x', 'x'}, + /*RENAME*/ {'x', 'x', ' ', ' ', 'x', 'x'}, + /*SWAP*/ {'x', 'x', ' ', ' ', 'x', 'x'}, + /*LIST*/ {' ', ' ', 'x', ' ', 'x', ' '}, + /*SAVE*/ {'x', 'x', ' ', ' ', 'x', 'x'}, + /*RESTORE*/ {'x', 'x', ' ', ' ', 'x', 'x'}, + /*ADD*/ {'x', 'x', ' ', ' ', 'x', 'x'}, + /*DEL*/ {'x', 'x', ' ', ' ', 'x', 'x'}, + /*TEST*/ {'x', 'x', ' ', ' ', ' ', 'x'}, + /*BIND*/ {'x', 'x', ' ', ' ', '+', 'x'}, + /*UNBIND*/ {'x', 'x', ' ', ' ', 'x', 'x'}, + /*HELP*/ {'x', 'x', 'x', ' ', 'x', 'x'}, + /*VERSION*/ {'x', 'x', 'x', ' ', 'x', 'x'}, }; /* Main parser function */ @@ -349,11 +347,12 @@ static void kernel_error(unsigned cmd, int err) { ENOENT, 0, "Unknown set" }, { EAGAIN, 0, "Sets are busy, try again later" }, { ERANGE, CMD_CREATE, "No free slot remained to add a new set" }, - { ERANGE, 0, "IP/port is outside of the set" }, + { ERANGE, 0, "IP/port/element is outside of the set or set is full" }, { ENOEXEC, CMD_CREATE, "Invalid parameters to create a set" }, { ENOEXEC, CMD_SWAP, "Sets with different types cannot be swapped" }, { EEXIST, CMD_CREATE, "Set already exists" }, { EEXIST, CMD_RENAME, "Set with new name already exists" }, + { EEXIST, 0, "Set specified as element does not exist" }, { EBUSY, 0, "Set is in use, operation not permitted" }, }; for (i = 0; i < sizeof(table)/sizeof(struct translate_error); i++) { @@ -429,7 +428,7 @@ static void kernel_sendto(unsigned cmd, void *data, size_t size) kernel_error(cmd, errno); } -static int kernel_getfrom_handleerrno(unsigned cmd, void *data, size_t * size) +static int kernel_getfrom_handleerrno(unsigned cmd, void *data, socklen_t *size) { int res = wrapped_getsockopt(data, size); @@ -856,7 +855,7 @@ void settype_register(struct settype *settype) } /* Find set functions */ -static struct set *set_find_byid(ip_set_id_t id) +struct set *set_find_byid(ip_set_id_t id) { struct set *set = NULL; ip_set_id_t i; @@ -873,7 +872,7 @@ static struct set *set_find_byid(ip_set_id_t id) return set; } -static struct set *set_find_byname(const char *name) +struct set *set_find_byname(const char *name) { struct set *set = NULL; ip_set_id_t i; @@ -1134,6 +1133,11 @@ static size_t save_bindings(void *data, size_t offset, size_t len) if (!(set && set_list[hash->binding])) exit_error(OTHER_PROBLEM, "Save binding failed, try again later."); + if (!set->settype->bindip_tostring) + exit_error(OTHER_PROBLEM, + "Internal error, binding is not supported with set %s" + " of settype %s\n", + set->name, set->settype->typename); printf("-B %s %s -b %s\n", set->name, set->settype->bindip_tostring(set, hash->ip, OPT_NUMERIC), @@ -1638,9 +1642,14 @@ static int set_bind(struct set *set, const char *adt, DP("(%s, %s) -> %s", set ? set->name : IPSET_TOKEN_ALL, adt, binding); /* Ugly */ - if (set && strcmp(set->settype->typename, "iptreemap") == 0) + if (set != NULL + && ((strcmp(set->settype->typename, "iptreemap") == 0) + || (strcmp(set->settype->typename, "ipportiphash") == 0) + || (strcmp(set->settype->typename, "ipportnethash") == 0) + || (strcmp(set->settype->typename, "setlist") == 0))) exit_error(PARAMETER_PROBLEM, - "iptreemap type of sets cannot be used at binding operations\n"); + "%s type of sets cannot be used at binding operations\n", + set->settype->typename); /* Alloc memory for the data to send */ size = sizeof(struct ip_set_req_bind); if (op != IP_SET_OP_UNBIND_SET && adt[0] == ':') @@ -1714,8 +1723,14 @@ static void set_restore_bind(struct set *set, DP("%s -> %s", adt, binding); if (strcmp(adt, IPSET_TOKEN_DEFAULT) == 0) hash_restore->ip = 0; - else + else { + if (!set->settype->bindip_parse) + exit_error(OTHER_PROBLEM, + "Internal error, binding is not supported with set %s" + " of settype %s\n", + set->name, set->settype->typename); set->settype->bindip_parse(adt, &hash_restore->ip); + } hash_restore->id = set->index; hash_restore->binding = (set_find_byname(binding))->index; DP("id %u, ip %u, binding %u", @@ -1735,6 +1750,12 @@ static void print_bindings(struct set *set, size_t offset = 0; struct ip_set_hash_list *hash; + if (offset < size && !printip) + exit_error(OTHER_PROBLEM, + "Internal error, binding is not supported with set %s" + " of settype %s\n", + set->name, set->settype->typename); + while (offset < size) { hash = (struct ip_set_hash_list *) (data + offset); printf("%s -> %s\n", @@ -1747,7 +1768,7 @@ static void print_bindings(struct set *set, /* Help function to set_list() */ static size_t print_set(void *data, unsigned options) { - struct ip_set_list *setlist = (struct ip_set_list *) data; + struct ip_set_list *setlist = data; struct set *set = set_list[setlist->index]; struct settype *settype = set->settype; size_t offset; @@ -1781,7 +1802,8 @@ static size_t print_set(void *data, unsigned options) /* Print bindings */ printf("Bindings:\n"); offset += setlist->members_size; - print_bindings(set, + if (set->settype->bindip_tostring) + print_bindings(set, data + offset, setlist->bindings_size, options, settype->bindip_tostring); @@ -1798,6 +1820,10 @@ static int try_list_sets(const char name[IP_SET_MAXNAMELEN], socklen_t size, req_size; int res = 0; + /* Default is numeric listing */ + if (!(options & (OPT_RESOLVE|OPT_NUMERIC))) + options |= OPT_NUMERIC; + DP("%s", name); /* Load set_list from kernel */ size = req_size = load_set_list(name, &idx, @@ -1907,7 +1933,8 @@ static void set_help(const struct settype *settype) " Prints version information\n\n" "Options:\n" " --sorted -s Numeric sort of the IPs in -L\n" - " --numeric -n Numeric output of addresses in a -L\n" + " --numeric -n Numeric output of addresses in a -L (default)\n" + " --resolve -r Try to resolve addresses in a -L\n" " --quiet -q Suppress any output to stdout and stderr.\n" " --binding -b Specifies the binding for -B\n"); printf(debughelp); @@ -2143,6 +2170,11 @@ int parse_commandline(int argc, char *argv[]) add_option(&options, OPT_NUMERIC); break; + case 'r': + if (!(options & OPT_NUMERIC)) + add_option(&options, OPT_RESOLVE); + break; + case 's': add_option(&options, OPT_SORTED); break; @@ -2269,6 +2301,8 @@ int parse_commandline(int argc, char *argv[]) break; case CMD_BIND: + fprintf(stderr, "Warning: binding will be removed from the next release.\n" + "Please replace bindigs with sets of ipportmap and ipportiphash types\n"); if (restore) set_restore_bind(set, adt, binding); else -- cgit v1.2.3