diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | ipset.8 | 31 | ||||
-rw-r--r-- | ipset.c | 10 | ||||
-rw-r--r-- | ipset_ipmap.c | 2 | ||||
-rw-r--r-- | ipset_ipporthash.c | 16 | ||||
-rw-r--r-- | ipset_iptree.c | 10 | ||||
-rw-r--r-- | ipset_iptreemap.c | 206 | ||||
-rw-r--r-- | ipset_macipmap.c | 12 |
9 files changed, 273 insertions, 29 deletions
@@ -1,3 +1,12 @@ +2.3.0 + - jiffies rollover bug in iptree type fixed (reported by Lukasz Nierycho + and others) + - endiannes bug in iptree type fixed (spotted by Jan Engelhardt) + - iptreemap type added (submitted by Sven Wegener) + - 2.6.22/23 compatibility fixes (Jeremy Jacque) + - typo fixes in ipset (Neville D) + - separator changed to ':' from '%' (old one still supported) in ipset + 2.2.9a - use correct type (socklen_t) for getsockopt (H. Nakano) - incorrect return codes fixed (Tomasz Lemiech, Alexey Bortnikov) @@ -8,7 +8,7 @@ ifndef KERNEL_DIR KERNEL_DIR=/usr/src/linux endif -IPSET_VERSION:=2.2.9a +IPSET_VERSION:=2.3.0 PREFIX:=/usr/local LIBDIR:=$(PREFIX)/lib @@ -21,9 +21,9 @@ 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 ipporthash +SETTYPES:=ipmap portmap macipmap iphash nethash iptree iptreemap ipporthash PROGRAMS=ipset SHARED_LIBS=$(foreach T, $(SETTYPES),libipset_$(T).so) @@ -231,10 +231,11 @@ 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 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. +.I IP:MAC. When deleting or testing macipmap entries, the -.I %MAC -part is not mandatory. +.I :MAC +part is not mandatory. (The old "%" separation token instead of ":", i.e +IP%MAC is accepted as well.) .P Options to use when creating an macipmap set: .TP @@ -307,6 +308,9 @@ When the optional parameter specified, network addresses will be stored in the set instead of IP addresses. .P +The iphash type of sets can store up to 65535 entries. If a set is full, +no new entries can be added to it. +.P Sets created by zero valued resize parameter won't be resized at all. The lookup time in an iphash type of set approximately linearly grows with the value of the @@ -342,6 +346,9 @@ by double-hashing (default 4). Increase the hash size by this many percent (default 50) when adding an IP to the hash could not be performed after .P +The nethash type of sets can store up to 65535 entries. If a set is full, +no new entries can be added to it. +.P An IP address will be in a nethash type of set if it is in any of the netblocks added to the set and the matching always start from the smallest size of netblock (most specific netmask) to the biggest ones (least @@ -367,7 +374,8 @@ store up to 65536 (B-class network) IP addresses with all possible port values. When adding, deleting and testing values in an ipporthash type of set, the entries must be specified as .B -"IP%port". +"IP:port". +(Old "IP%port" format accepted as well.) .P The ipporthash types of sets evaluates two src/dst parameters of the .I @@ -416,7 +424,20 @@ If a set was created with a nonzero valued .B "--timeout" parameter then one may add IP addresses to the set with a specific timeout value using the syntax -.I IP%timeout-value. +.I IP:timeout-value. +Similarly to the hash types, the iptree type of sets can store up to 65535 +entries. +.SS iptreemap +The iptreemap set type uses a tree to store IP addresses or networks, +where the last octet of an IP address are stored in a bitmap. +As input entry, you can add IP addresses, CIDR blocks or network ranges +to the set. Network ranges can be specified in the format +.I IP1:IP2 +.P +Options to use when creating an iptreemap set: +.TP +.BR "--gc " value +How often the garbage collection should be called, in seconds (default 300) .SH GENERAL RESTRICTIONS Setnames starting with colon (:) cannot be defined. Zero valued set entries cannot be used with hash type of sets. @@ -1151,13 +1151,17 @@ static size_t save_set(void *data, int *bindings, struct settype *settype; size_t used; - DP("offset %u, len %u", offset, len); + DP("offset %u (%u/%u/%u), len %u", offset, + sizeof(struct ip_set_save), + set_save->header_size, set_save->members_size, + len); if (offset + sizeof(struct ip_set_save) > len || offset + sizeof(struct ip_set_save) + set_save->header_size + set_save->members_size > len) exit_error(OTHER_PROBLEM, "Save operation failed, try again later."); + DP("index: %u", set_save->index); if (set_save->index == IP_SET_INVALID_ID) { /* Marker */ *bindings = 1; @@ -1633,6 +1637,10 @@ static int set_bind(struct set *set, const char *adt, /* set may be null: '-U :all: :all:|:default:' */ DP("(%s, %s) -> %s", set ? set->name : IPSET_TOKEN_ALL, adt, binding); + /* Ugly */ + if (strcmp(set->settype->typename, "iptreemap") == 0) + exit_error(PARAMETER_PROBLEM, + "iptreemap type of sets cannot be used at binding operations\n"); /* Alloc memory for the data to send */ size = sizeof(struct ip_set_req_bind); if (op != IP_SET_OP_UNBIND_SET && adt[0] == ':') diff --git a/ipset_ipmap.c b/ipset_ipmap.c index ed38ec9..df8efbf 100644 --- a/ipset_ipmap.c +++ b/ipset_ipmap.c @@ -191,7 +191,7 @@ void create_final(void *data, unsigned int flags) } if (range > MAX_RANGE) exit_error(PARAMETER_PROBLEM, - "Range to large. Max is %d IPs in range\n", + "Range too large. Max is %d IPs in range\n", MAX_RANGE+1); } diff --git a/ipset_ipporthash.c b/ipset_ipporthash.c index 0548b86..ef527fa 100644 --- a/ipset_ipporthash.c +++ b/ipset_ipporthash.c @@ -181,7 +181,7 @@ void create_final(void *data, unsigned int flags) if (mydata->to - mydata->from > MAX_RANGE) exit_error(PARAMETER_PROBLEM, - "Range to large. Max is %d IPs in range\n", + "Range too large. Max is %d IPs in range\n", MAX_RANGE+1); } @@ -206,7 +206,7 @@ ip_set_ip_t adt_parser(unsigned cmd, const char *optarg, void *data) DP("ipporthash: %p %p", optarg, data); - ptr = strsep(&tmp, "%"); + ptr = strsep(&tmp, ":%"); parse_ip(ptr, &mydata->ip); if (tmp) @@ -262,7 +262,7 @@ void printips(struct set *set, void *data, size_t len, unsigned options) if (*ipptr) { ip = (*ipptr>>16) + mysetdata->first_ip; port = (uint16_t) *ipptr; - printf("%s%%%s\n", + printf("%s:%s\n", ip_tostring(ip, options), port_tostring(port, options)); } @@ -298,7 +298,7 @@ void saveips(struct set *set, void *data, size_t len, unsigned options) if (*ipptr) { ip = (*ipptr>>16) + mysetdata->first_ip; port = (uint16_t) *ipptr; - printf("-A %s %s%%%s\n", set->name, + printf("-A %s %s:%s\n", set->name, ip_tostring(ip, options), port_tostring(port, options)); } @@ -316,7 +316,7 @@ static char * unpack_ipport_tostring(struct set *set, ip_set_ip_t bip, unsigned ip = (bip>>16) + mysetdata->first_ip; port = (uint16_t) bip; - sprintf(buffer, "%s%%%s", + sprintf(buffer, "%s:%s", ip_tostring(ip, options), port_tostring(port, options)); return buffer; @@ -329,9 +329,9 @@ void usage(void) " [--hashsize hashsize] [--probes probes ] [--resize resize]\n" "-N set ipporthash --network IP/mask\n" " [--hashsize hashsize] [--probes probes ] [--resize resize]\n" - "-A set IP%%port\n" - "-D set IP%%port\n" - "-T set IP%%port\n"); + "-A set IP:port\n" + "-D set IP:port\n" + "-T set IP:port\n"); } static struct settype settype_ipporthash = { diff --git a/ipset_iptree.c b/ipset_iptree.c index cce9884..c3678df 100644 --- a/ipset_iptree.c +++ b/ipset_iptree.c @@ -84,7 +84,7 @@ ip_set_ip_t adt_parser(unsigned cmd, const char *optarg, void *data) DP("iptree: %p %p", optarg, data); - ptr = strsep(&tmp, "%"); + ptr = strsep(&tmp, ":%"); parse_ip(ptr, &mydata->ip); if (tmp) @@ -130,8 +130,8 @@ void printips_sorted(struct set *set, void *data, size_t len, unsigned options) while (len >= offset + sizeof(struct ip_set_req_iptree)) { req = (struct ip_set_req_iptree *)(data + offset); if (mysetdata->timeout) - printf("%s%%%u\n", ip_tostring(req->ip, options), - req->timeout); + printf("%s:%u\n", ip_tostring(req->ip, options), + req->timeout); else printf("%s\n", ip_tostring(req->ip, options)); offset += sizeof(struct ip_set_req_iptree); @@ -164,7 +164,7 @@ void saveips(struct set *set, void *data, size_t len, unsigned options) while (len >= offset + sizeof(struct ip_set_req_iptree)) { req = (struct ip_set_req_iptree *)(data + offset); if (mysetdata->timeout) - printf("-A %s %s%%%u\n", + printf("-A %s %s:%u\n", set->name, ip_tostring(req->ip, options), req->timeout); @@ -180,7 +180,7 @@ void usage(void) { printf ("-N set iptree [--timeout value]\n" - "-A set IP[%%timeout]\n" + "-A set IP[:timeout]\n" "-D set IP\n" "-T set IP\n"); } diff --git a/ipset_iptreemap.c b/ipset_iptreemap.c new file mode 100644 index 0000000..ccc5ec3 --- /dev/null +++ b/ipset_iptreemap.c @@ -0,0 +1,206 @@ +/* Copyright 2007 Sven Wegener <sven.wegener@stealer.net> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <stdio.h> +#include <string.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <linux/netfilter_ipv4/ip_set_iptreemap.h> + +#include "ipset.h" + +#define OPT_CREATE_GC 0x1 + +void +create_init(void *data) +{ + struct ip_set_req_iptreemap_create *mydata = (struct ip_set_req_iptreemap_create *) data; + + mydata->gc_interval = 0; +} + +int +create_parse(int c, char *argv[], void *data, unsigned int *flags) +{ + struct ip_set_req_iptreemap_create *mydata = (struct ip_set_req_iptreemap_create *) data; + + switch (c) { + case 'g': + string_to_number(optarg, 0, UINT_MAX, &mydata->gc_interval); + + *flags |= OPT_CREATE_GC; + break; + default: + return 0; + break; + } + + return 1; +} + +void +create_final(void *data, unsigned int flags) +{ +} + +static struct option create_opts[] = { + {"gc", 1, 0, 'g'}, + {0} +}; + +ip_set_ip_t +adt_parser(unsigned int cmd, const char *optarg, void *data) +{ + struct ip_set_req_iptreemap *mydata = (struct ip_set_req_iptreemap *) data; + ip_set_ip_t mask; + + char *saved = ipset_strdup(optarg); + char *ptr, *tmp = saved; + + if (strchr(tmp, '/')) { + parse_ipandmask(tmp, &mydata->start, &mask); + mydata->end = mydata->start | ~mask; + } else { + ptr = strsep(&tmp, ":"); + parse_ip(ptr, &mydata->start); + + if (tmp) { + parse_ip(tmp, &mydata->end); + } else { + mydata->end = mydata->start; + } + } + + return 1; +} + +void +initheader(struct set *set, const void *data) +{ + struct ip_set_req_iptreemap_create *header = (struct ip_set_req_iptreemap_create *) data; + struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->settype->header; + + map->gc_interval = header->gc_interval; +} + +void +printheader(struct set *set, unsigned int options) +{ + struct ip_set_iptreemap *mysetdata = (struct ip_set_iptreemap *) set->settype->header; + + if (mysetdata->gc_interval) + printf(" gc: %u", mysetdata->gc_interval); + + printf("\n"); +} + +void +printips_sorted(struct set *set, void *data, size_t len, unsigned int options) +{ + struct ip_set_req_iptreemap *req; + size_t offset = 0; + + while (len >= offset + sizeof(struct ip_set_req_iptreemap)) { + req = (struct ip_set_req_iptreemap *) (data + offset); + + printf("%s", ip_tostring(req->start, options)); + if (req->start != req->end) + printf(":%s", ip_tostring(req->end, options)); + printf("\n"); + + offset += sizeof(struct ip_set_req_iptreemap); + } +} + +void +saveheader(struct set *set, unsigned int options) +{ + struct ip_set_iptreemap *mysetdata = (struct ip_set_iptreemap *) set->settype->header; + + printf("-N %s %s", set->name, set->settype->typename); + + if (mysetdata->gc_interval) + printf(" --gc %u", mysetdata->gc_interval); + + printf("\n"); +} + +void +saveips(struct set *set, void *data, size_t len, unsigned int options) +{ + struct ip_set_req_iptreemap *req; + size_t offset = 0; + + while (len >= offset + sizeof(struct ip_set_req_iptreemap)) { + req = (struct ip_set_req_iptreemap *) (data + offset); + + printf("-A %s %s", set->name, ip_tostring(req->start, options)); + + if (req->start != req->end) + printf(":%s", ip_tostring(req->end, options)); + + printf("\n"); + + offset += sizeof(struct ip_set_req_iptreemap); + } +} + +void +usage(void) +{ + printf( + "-N set iptreemap --gc interval\n" + "-A set IP\n" + "-D set IP\n" + "-T set IP\n" + ); +} + +static struct settype settype_iptreemap = { + .typename = SETTYPE_NAME, + .protocol_version = IP_SET_PROTOCOL_VERSION, + + .create_size = sizeof(struct ip_set_req_iptreemap_create), + .create_init = &create_init, + .create_parse = &create_parse, + .create_final = &create_final, + .create_opts = create_opts, + + .adt_size = sizeof(struct ip_set_req_iptreemap), + .adt_parser = &adt_parser, + + .header_size = sizeof(struct ip_set_iptreemap), + .initheader = &initheader, + .printheader = &printheader, + .printips = &printips_sorted, + .printips_sorted = &printips_sorted, + .saveheader = &saveheader, + .saveips = &saveips, + + .bindip_tostring = &binding_ip_tostring, + .bindip_parse = &parse_ip, + + .usage = &usage, +}; + +void +_init(void) +{ + settype_register(&settype_iptreemap); +} diff --git a/ipset_macipmap.c b/ipset_macipmap.c index c14547a..3385f19 100644 --- a/ipset_macipmap.c +++ b/ipset_macipmap.c @@ -184,7 +184,7 @@ ip_set_ip_t adt_parser(unsigned cmd, const char *optarg, void *data) DP("macipmap: %p %p", optarg, data); - ptr = strsep(&tmp, "%"); + ptr = strsep(&tmp, ":%"); parse_ip(ptr, &mydata->ip); if (tmp) @@ -246,7 +246,7 @@ void printips_sorted(struct set *set, void *data, size_t len, unsigned options) while (addr <= mysetdata->last_ip) { if (test_bit(IPSET_MACIP_ISSET, (void *)&table[addr - mysetdata->first_ip].flags)) { - printf("%s%%", ip_tostring(addr, options)); + printf("%s:", ip_tostring(addr, options)); print_mac(table[addr - mysetdata->first_ip]. ethernet); printf("\n"); @@ -281,7 +281,7 @@ void saveips(struct set *set, void *data, size_t len, unsigned options) while (addr <= mysetdata->last_ip) { if (test_bit(IPSET_MACIP_ISSET, (void *)&table[addr - mysetdata->first_ip].flags)) { - printf("-A %s %s%%", + printf("-A %s %s:", set->name, ip_tostring(addr, options)); print_mac(table[addr - mysetdata->first_ip]. ethernet); @@ -296,9 +296,9 @@ void usage(void) printf ("-N set macipmap --from IP --to IP [--matchunset]\n" "-N set macipmap --network IP/mask [--matchunset]\n" - "-A set IP%%MAC\n" - "-D set IP[%%MAC]\n" - "-T set IP[%%MAC]\n"); + "-A set IP:MAC\n" + "-D set IP[:MAC]\n" + "-T set IP[:MAC]\n"); } static struct settype settype_macipmap = { |