summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--Makefile4
-rw-r--r--ipset.810
-rw-r--r--ipset.c24
-rw-r--r--ipset_iphash.c3
-rw-r--r--ipset_ipmap.c65
-rw-r--r--ipset_iptree.c2
-rw-r--r--ipset_macipmap.c16
-rw-r--r--ipset_nethash.c5
-rw-r--r--ipset_portmap.c8
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;
}
/*