From edd0ad6de4fcfd0091312add44b783b605984406 Mon Sep 17 00:00:00 2001 From: "/C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=kadlec/emailAddress=kadlec@netfilter.org" Date: Fri, 30 Sep 2005 16:45:42 +0000 Subject: 2.2.4 released, see fixes in pom-ng/set --- ChangeLog | 7 ++++++ Makefile | 4 ++-- ipset.8 | 10 ++++----- ipset.c | 24 ++++++--------------- ipset_iphash.c | 3 +++ ipset_ipmap.c | 65 +++++++++++++++++++++++++++++++++++++------------------- ipset_iptree.c | 2 +- ipset_macipmap.c | 16 +++++++------- ipset_nethash.c | 5 ++++- ipset_portmap.c | 8 +++---- 10 files changed, 83 insertions(+), 61 deletions(-) diff --git a/ChangeLog b/ChangeLog index f26f9e4..e436c8a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2.2.4 + - half-fixed memory allocation bug in iphash and nethash finally + completely fixed (bug reported by Nikolai Malykh) + - restrictions to enter zero-valued entries into all non-hash type sets + were removed + - Too strict check on the set size of ipmap type was corrected + 2.2.3 - memory allocation bug in iphash and nethash in connection with the SET target was fixed (bug reported by Nikolai Malykh) diff --git a/Makefile b/Makefile index 59b2443..d28ef6c 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ ifndef KERNEL_DIR KERNEL_DIR=/usr/src/linux endif -IPSET_VERSION:=2.2.3 +IPSET_VERSION:=2.2.4 PREFIX:=/usr/local LIBDIR:=$(PREFIX)/lib @@ -21,7 +21,7 @@ IPSET_LIB_DIR:=$(LIBDIR)/ipset RELEASE_DIR:=/tmp COPT_FLAGS:=-O2 -CFLAGS:=$(COPT_FLAGS) -Wall -Wunused -I$(KERNEL_DIR)/include -I. #-g -DIPSET_DEBUG #-pg # -DIPTC_DEBUG +CFLAGS:=$(COPT_FLAGS) -Wall -Wunused -I$(KERNEL_DIR)/include -I. # -g -DIPSET_DEBUG #-pg # -DIPTC_DEBUG SH_CFLAGS:=$(CFLAGS) -fPIC SETTYPES:=ipmap portmap macipmap iphash nethash iptree diff --git a/ipset.8 b/ipset.8 index 32b5ae3..8d32b39 100644 --- a/ipset.8 +++ b/ipset.8 @@ -200,7 +200,7 @@ possible errors. ipset supports the following set types: .SS ipmap The ipmap set type uses a memory range, where each bit represents -one IP address. An ipmap set can store up to 65535 (B-class network) +one IP address. An ipmap set can store up to 65536 (B-class network) IP addresses. The ipmap set type is very fast and memory cheap, great for use when one want to match certain IPs in a range. Using the .B "--netmask" @@ -228,7 +228,7 @@ must be a network address. .SS macipmap The macipmap set type uses a memory range, where each 8 bytes represents one IP and a MAC addresses. A macipmap set type can store -up to 65535 (B-class network) IP addresses with MAC. +up to 65536 (B-class network) IP addresses with MAC. When adding an entry to a macipmap set, you must specify the entry as .I IP%MAC. When deleting or testing macipmap entries, the @@ -264,7 +264,7 @@ use the source MAC address from the packet to match, add or delete entries from a macipmap type of set. .SS portmap The portmap set type uses a memory range, where each bit represents -one port. A portmap set type can store up to 65535 ports. +one port. A portmap set type can store up to 65536 ports. The portmap set type is very fast and memory cheap. .P Options to use when creating an portmap set: @@ -325,7 +325,7 @@ The initial hash size (default 1024) .TP .BR "--probes " probes How many times try to resolve clashing at adding an IP to the hash -by double-hashing (default 2). +by double-hashing (default 4). .TP .BR "--resize " percent Increase the hash size by this many percent (default 50) when adding @@ -354,7 +354,7 @@ value using the syntax .I IP%timeout-value. .SH GENERAL RESTRICTIONS Setnames starting with colon (:) cannot be defined. Zero valued set -entries cannot be used. +entries cannot be used with hash type of sets. .SH COMMENTS If you want to store same size subnets from a given network (say /24 blocks from a /8 network), use the ipmap set type. diff --git a/ipset.c b/ipset.c index a1697f3..1c77358 100644 --- a/ipset.c +++ b/ipset.c @@ -483,16 +483,15 @@ static char *ip_tonetwork(const struct in_addr *addr) char *ip_tostring(ip_set_ip_t ip, unsigned options) { struct in_addr addr; - char *name; - addr.s_addr = htonl(ip); if (!(options & OPT_NUMERIC)) { + char *name; if ((name = ip_tohost(&addr)) != NULL || (name = ip_tonetwork(&addr)) != NULL) return name; } - + return inet_ntoa(addr); } @@ -511,9 +510,6 @@ void parse_ip(const char *str, ip_set_ip_t * ip) if (inet_aton(str, &addr) != 0) { *ip = ntohl(addr.s_addr); /* We want host byte order */ - if (!*ip) - exit_error(PARAMETER_PROBLEM, - "Zero valued IP address `%s' specified", str); return; } @@ -530,10 +526,6 @@ void parse_ip(const char *str, ip_set_ip_t * ip) "Please specify one.", str); *ip = ntohl(((struct in_addr *) host->h_addr_list[0])->s_addr); - if (!*ip) - exit_error(PARAMETER_PROBLEM, - "Zero valued IP address `%s' specified", - str); return; } @@ -563,7 +555,7 @@ void parse_mask(const char *str, ip_set_ip_t * mask) DP("bits: %d", bits); - *mask = 0xFFFFFFFF << (32 - bits); + *mask = bits != 0 ? 0xFFFFFFFF << (32 - bits) : 0L; } /* Combines parse_ip and parse_mask */ @@ -589,13 +581,13 @@ parse_ipandmask(const char *str, ip_set_ip_t * ip, ip_set_ip_t * mask) parse_ip(buf, ip); DP("%s ip: %08X (%s) mask: %08X", - str, *ip, ip_tostring(*ip, 0), *mask); + str, *ip, ip_tostring_numeric(*ip), *mask); /* Apply the netmask */ *ip &= *mask; DP("%s ip: %08X (%s) mask: %08X", - str, *ip, ip_tostring(*ip, 0), *mask); + str, *ip, ip_tostring_numeric(*ip), *mask); } /* Return a string representation of a port @@ -654,11 +646,7 @@ void parse_port(const char *str, ip_set_ip_t *port) if ((string_to_number(str, 0, 65535, port) != 0) && (string_to_port(str, port) != 0)) exit_error(PARAMETER_PROBLEM, - "Invalid TCP port `%s' specified", str); - - if (!*port) - exit_error(PARAMETER_PROBLEM, - "Zero valued port `%s' specified", str); + "Invalid TCP port `%s' specified", str); } /* diff --git a/ipset_iphash.c b/ipset_iphash.c index a17efac..ac0340e 100644 --- a/ipset_iphash.c +++ b/ipset_iphash.c @@ -152,6 +152,9 @@ ip_set_ip_t adt_parser(unsigned cmd, const char *optarg, void *data) (struct ip_set_req_iphash *) data; parse_ip(optarg, &mydata->ip); + if (!mydata->ip) + exit_error(PARAMETER_PROBLEM, + "Zero valued IP address `%s' specified", optarg); return mydata->ip; }; diff --git a/ipset_ipmap.c b/ipset_ipmap.c index 1d8377b..50a76c3 100644 --- a/ipset_ipmap.c +++ b/ipset_ipmap.c @@ -80,14 +80,18 @@ int create_parse(int c, char *argv[], void *data, unsigned *flags) parse_ipandmask(optarg, &mydata->from, &mydata->to); /* Make to the last of from + mask */ - mydata->to = mydata->from | ~(mydata->to); - + if (mydata->to) + mydata->to = mydata->from | ~(mydata->to); + else { + mydata->from = 0x00000000; + mydata->to = 0xFFFFFFFF; + } *flags |= OPT_CREATE_NETWORK; - DP("--network from %x (%s)", mydata->from, - ip_tostring_numeric(mydata->from)); - DP("--network to %x (%s)", mydata->to, - ip_tostring_numeric(mydata->to)); + DP("--network from %x (%s)", + mydata->from, ip_tostring_numeric(mydata->from)); + DP("--network to %x (%s)", + mydata->to, ip_tostring_numeric(mydata->to)); break; @@ -112,11 +116,15 @@ int create_parse(int c, char *argv[], void *data, unsigned *flags) return 1; } +#define ERRSTRLEN 256 + /* Final check; exit if not ok. */ void create_final(void *data, unsigned int flags) { struct ip_set_req_ipmap_create *mydata = (struct ip_set_req_ipmap_create *) data; + ip_set_ip_t range; + char errstr[ERRSTRLEN]; if (flags == 0) exit_error(PARAMETER_PROBLEM, @@ -135,17 +143,14 @@ void create_final(void *data, unsigned int flags) "Need to specify both --from and --to\n"); } - DP("from : %x to: %x diff: %d", mydata->from, mydata->to, + DP("from : %x to: %x diff: %x", + mydata->from, mydata->to, mydata->to - mydata->from); if (mydata->from > mydata->to) exit_error(PARAMETER_PROBLEM, - "From can't be lower than to.\n", MAX_RANGE); + "From can't be lower than to.\n"); - if (mydata->to - mydata->from > MAX_RANGE) - exit_error(PARAMETER_PROBLEM, - "Range to large. Max is %d IPs in range\n", - MAX_RANGE); if (flags & OPT_CREATE_NETMASK) { unsigned int mask_bits, netmask_bits; ip_set_ip_t mask; @@ -157,21 +162,37 @@ void create_final(void *data, unsigned int flags) mask_to_bits(mydata->netmask)); mask = range_to_mask(mydata->from, mydata->to, &mask_bits); - if (!mask) + if (!mask + && (mydata->from || mydata->to != 0xFFFFFFFF)) { + strncpy(errstr, ip_tostring_numeric(mydata->from), + ERRSTRLEN-2); + errstr[ERRSTRLEN-1] = '\0'; exit_error(PARAMETER_PROBLEM, - "%s-%s is not a full network\n", - ip_tostring_numeric(mydata->from), - ip_tostring_numeric(mydata->to)); - + "%s-%s is not a full network (%x)\n", + errstr, + ip_tostring_numeric(mydata->to), mask); + } netmask_bits = mask_to_bits(mydata->netmask); - if (netmask_bits <= mask_bits) + if (netmask_bits <= mask_bits) { + strncpy(errstr, ip_tostring_numeric(mydata->from), + ERRSTRLEN-2); + errstr[ERRSTRLEN-1] = '\0'; exit_error(PARAMETER_PROBLEM, - "%d netmask specifies larger or equal netblock than %s-%s\n", + "%d netmask specifies larger or equal netblock than %s-%s (%d)\n", netmask_bits, - ip_tostring_numeric(mydata->from), - ip_tostring_numeric(mydata->to)); + errstr, + ip_tostring_numeric(mydata->to), + mask_bits); + } + range = (1<<(netmask_bits - mask_bits)) - 1; + } else { + range = mydata->to - mydata->from; } + if (range > MAX_RANGE) + exit_error(PARAMETER_PROBLEM, + "Range to large. Max is %d IPs in range\n", + MAX_RANGE+1); } /* Create commandline options */ @@ -194,7 +215,7 @@ ip_set_ip_t adt_parser(unsigned cmd, const char *optarg, void *data) parse_ip(optarg, &mydata->ip); DP("%s", ip_tostring_numeric(mydata->ip)); - return mydata->ip; + return 1; } /* diff --git a/ipset_iptree.c b/ipset_iptree.c index 82e964e..dcdc7e3 100644 --- a/ipset_iptree.c +++ b/ipset_iptree.c @@ -93,7 +93,7 @@ ip_set_ip_t adt_parser(unsigned cmd, const char *optarg, void *data) mydata->timeout = 0; free(saved); - return mydata->ip; + return 1; } /* diff --git a/ipset_macipmap.c b/ipset_macipmap.c index 1a1029e..12dbcb9 100644 --- a/ipset_macipmap.c +++ b/ipset_macipmap.c @@ -84,10 +84,10 @@ int create_parse(int c, char *argv[], void *data, unsigned *flags) *flags |= OPT_CREATE_NETWORK; - DP("--network from %x (%s)", mydata->from, - ip_tostring_numeric(mydata->from)); - DP("--network to %x (%s)", mydata->to, - ip_tostring_numeric(mydata->to)); + DP("--network from %x (%s)", + mydata->from, ip_tostring_numeric(mydata->from)); + DP("--network to %x (%s)", + mydata->to, ip_tostring_numeric(mydata->to)); break; @@ -137,12 +137,12 @@ void create_final(void *data, unsigned int flags) if (mydata->from > mydata->to) exit_error(PARAMETER_PROBLEM, - "From can't be lower than to.\n", MAX_RANGE); + "From can't be lower than to.\n"); if (mydata->to - mydata->from > MAX_RANGE) exit_error(PARAMETER_PROBLEM, - "Range to large. Max is %d IPs in range\n", - MAX_RANGE); + "Range too large. Max is %d IPs in range\n", + MAX_RANGE+1); } /* Create commandline options */ @@ -194,7 +194,7 @@ ip_set_ip_t adt_parser(unsigned cmd, const char *optarg, void *data) memset(mydata->ethernet, 0, ETH_ALEN); free(saved); - return mydata->ip; + return 1; } /* diff --git a/ipset_nethash.c b/ipset_nethash.c index 57f0888..3c6bc9f 100644 --- a/ipset_nethash.c +++ b/ipset_nethash.c @@ -49,7 +49,7 @@ void create_init(void *data) /* Default create parameters */ mydata->hashsize = 1024; - mydata->probes = 2; + mydata->probes = 4; mydata->resize = 50; } @@ -149,6 +149,9 @@ ip_set_ip_t adt_parser(unsigned cmd, const char *optarg, void *data) mydata->cidr = cidr; parse_ip(ptr, &mydata->ip); + if (!mydata->ip) + exit_error(PARAMETER_PROBLEM, + "Zero valued IP address `%s' specified", ptr); free(saved); return mydata->ip; diff --git a/ipset_portmap.c b/ipset_portmap.c index df08574..631e29e 100644 --- a/ipset_portmap.c +++ b/ipset_portmap.c @@ -99,12 +99,12 @@ void create_final(void *data, unsigned int flags) if (mydata->from > mydata->to) exit_error(PARAMETER_PROBLEM, - "From can't be lower than to.\n", MAX_RANGE); + "From can't be lower than to.\n"); if (mydata->to - mydata->from > MAX_RANGE) exit_error(PARAMETER_PROBLEM, - "Range to large. Max is %d ports in range\n", - MAX_RANGE); + "Range too large. Max is %d ports in range\n", + MAX_RANGE+1); } /* Create commandline options */ @@ -123,7 +123,7 @@ ip_set_ip_t adt_parser(unsigned cmd, const char *optarg, void *data) parse_port(optarg, &mydata->port); DP("%s", port_tostring(mydata->port, 0)); - return mydata->port; + return 1; } /* -- cgit v1.2.3