From 9c1d3cce3a43774e69724041cb0c3db5f389f8c8 Mon Sep 17 00:00:00 2001 From: Planet-Lab Support Date: Fri, 28 Jul 2006 14:34:28 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create tag 'iptables-1_3_5'. --- ipset/ChangeLog | 90 -- ipset/ChangeLog.ippool | 59 - ipset/Makefile | 64 -- ipset/TODO | 2 - ipset/ipset.8 | 445 -------- ipset/ipset.c | 2209 -------------------------------------- ipset/ipset.h | 187 ---- ipset/ipset_iphash.c | 297 ----- ipset/ipset_ipmap.c | 360 ------- ipset/ipset_ipporthash.c | 373 ------- ipset/ipset_iptree.c | 223 ---- ipset/ipset_macipmap.c | 340 ------ ipset/ipset_nethash.c | 366 ------- ipset/ipset_portmap.c | 245 ----- ipset/libipt_set.h | 45 - 15 files changed, 5305 deletions(-) delete mode 100644 ipset/ChangeLog delete mode 100644 ipset/ChangeLog.ippool delete mode 100644 ipset/Makefile delete mode 100644 ipset/TODO delete mode 100644 ipset/ipset.8 delete mode 100644 ipset/ipset.c delete mode 100644 ipset/ipset.h delete mode 100644 ipset/ipset_iphash.c delete mode 100644 ipset/ipset_ipmap.c delete mode 100644 ipset/ipset_ipporthash.c delete mode 100644 ipset/ipset_iptree.c delete mode 100644 ipset/ipset_macipmap.c delete mode 100644 ipset/ipset_nethash.c delete mode 100644 ipset/ipset_portmap.c delete mode 100644 ipset/libipt_set.h diff --git a/ipset/ChangeLog b/ipset/ChangeLog deleted file mode 100644 index 5cce591..0000000 --- a/ipset/ChangeLog +++ /dev/null @@ -1,90 +0,0 @@ -2.2.8 - - Nasty off-by-one bug fixed in iptree type of sets - (bug reported by Pablo Sole) - -2.2.7 - All patches were submitted by Jones Desougi - - missing or confusing error message fixes for ipporthash - - minor correction in debugging in nethash - - copy-paste bug in kernel set types at memory allocation - checking fixed - - unified memory allocations in ipset - -2.2.6 - - memory allocation in iptree is changed to GFP_ATOMIC because - we hold a lock (bug reported by Radek Hladik) - - compatibility fix: __nocast is not defined in all 2.6 branches - (problem reported by Ming-Ching Tiew) - - manpage corrections - -2.2.5 - - garbage collector of iptree type of sets is fixed: flushing - sets/removing kernel module could corrupt the timer - - new ipporthash type added - - manpage fixes and corrections - -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) - - lockhelp.h was removed from the 2.6.13 kernel tree, ip_set.c is - updated accordingly (Cardoso Didier, Samir Bellabes) - - manpage is updated to clearly state the command order in restore mode - -2.2.2 - - Jiffies rollover bug in ip_set_iptree reported and fixed by Rob Nielsen - - Compiler warning in the non-SMP case fixed (Marcus Sundberg) - - slab cache names shrunk in order to be compatible with 2.4.* (Marcus - Sundberg) - -2.2.1 - - Magic number in ip_set_nethash.h was mistyped (bug reported by Rob - Carlson) - - ipset can now test IP addresses in nethash type of sets (i.e. addresses - in netblocks added to the set) - -2.2.0 - - Locking bug in ip_set_nethash.c (Clifford Wolf and Rob Carlson) - - Makefile contained an unnecessary variable in IPSET_LIB_DIR (Clifford - Wolf) - - Safety checkings of restore in ipset was incomplete (Robin H. Johnson) - - More careful resizing by avoiding locking completely - - stdin stored internally in a temporary file, so we can feed 'ipset -R' - from a pipe - - iptree maptype added - -2.1 - - Lock debugging used with debugless lock definiton (Piotr Chytla and - others). - - Bindings were not properly filled out at listing (kernel) - - When listing sets from kernel, id was not added to the set structure - (ipset) - - nethash maptype added - - ipset manpage corrections (macipmap) - -2.0.1 - - Missing -fPIC in Makefile (Robert Iakobashvili) - - Cut'n'paste bug at saving macipmap types (Vincent Bernat). - - Bug in printing/saving SET targets reported and fixed by Michal - Pokrywka - -2.0 - - Chaining of sets are changed: child sets replaced by bindings - - Kernel-userspace communication reorganized to minimize the number - of syscalls - - Save and restore functionality implemented - - iphash type reworked: clashing resolved by double-hashing and by - dynamically growing the set - -1.0 - - Renamed to ipset - - Rewritten to support child pools - - portmap, iphash pool support added - - too much other mods here and there to list... - diff --git a/ipset/ChangeLog.ippool b/ipset/ChangeLog.ippool deleted file mode 100644 index 669c304..0000000 --- a/ipset/ChangeLog.ippool +++ /dev/null @@ -1,59 +0,0 @@ -Original changelog as ippool: - -0.3.2b -- Fixed missing kfree(pool) (Martin Josefsson) - -0.3.2a -- Added libipt_pool.c and libipt_POOL.c (Martin Josefsson) - - -0.3.2 -- Passes pointers to skb's around instead of ip's in the (Martin Josefsson) - kernel modules. -- Added a new pooltype, macipmap, which matches ip's (Martin Josefsson) - against macaddresses. -- Cleaned up a lot of typedefs. (Martin Josefsson) -- Fixed an unlocking of the wrong lock. (Martin Josefsson) -- Fixed a refcount bug when allocated memory was too (Martin Josefsson) - small. -- Fixed a free() of unallocated memory. (Martin Josefsson) -- Switched from kmalloc/kfree to vmalloc/vfree for (Martin Josefsson) - pool-listings/additions. - - -0.3.1 -- Changed the API between userspace modules and base. (Joakim Axelsson) - Moved the memberdata pointer to module self. - As a result of this Protocolversion is increased to 4. -- Fixed problems with crashing null-pooltype (Joakim Axelsson) -- Fixed problems with compiling warnings (Joakim Axelsson) - in null pooltype. - - -0.3.0: -- Changed the listing to use getsockopt. (Joakim Axelsson) - /proc is left for debuging purpose. - This is a mayor change. - Protocolversion is increased to 3 -- Added support for --quiet (Joakim Axelsson) -- Added support for --sorted (Joakim Axelsson) -- Added support for --numeric (Joakim Axelsson) -- Added support for --exact (Joakim Axelsson) -- Added -Z (Zero) which zero's the counter (Joakim Axelsson) - on one or all pools. -- Added support for --debug that prints all debug-messages (Joakim Axelsosn) - in userspace. Need to be compiled with - IP_POOL_DEBUG tho. -- Added null pooltype. For demostration and (Joakim Axelsson) - pooltype skeleton mostly -- Fixed bug with possibly renaming to an already (Joakim Axelsson) - existing pool. -- Change error to OTHER_PROBLEM on add and del IP. (Joakim Axelsson) - -0.2.1-0.2.3 -- Better handling of references (Patrick Schaaf) -- Various bugfixes (Patrick Schaaf) -- Cleaning up the code in kernelspace (Patrick Schaaf) - -0.2.0: -- Rewrote the entrie system. Modulized it. (Joakim Axelsson) diff --git a/ipset/Makefile b/ipset/Makefile deleted file mode 100644 index 087a9dd..0000000 --- a/ipset/Makefile +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/make - -###################################################################### -# YOU SHOULD NOT NEED TO TOUCH ANYTHING BELOW THIS LINE -###################################################################### - -ifndef KERNEL_DIR -KERNEL_DIR=/usr/src/linux -endif - -IPSET_VERSION:=2.2.8 - -PREFIX:=/usr/local -LIBDIR:=$(PREFIX)/lib -BINDIR:=$(PREFIX)/sbin -MANDIR:=$(PREFIX)/man -INCDIR:=$(PREFIX)/include -IPSET_LIB_DIR:=$(LIBDIR)/ipset - -# directory for new iptables releases -RELEASE_DIR:=/tmp - -COPT_FLAGS:=-O2 -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 - -PROGRAMS=ipset -SHARED_LIBS=$(foreach T, $(SETTYPES),libipset_$(T).so) -INSTALL=$(DESTDIR)$(BINDIR)/ipset $(DESTDIR)$(MANDIR)/man8/ipset.8 -INSTALL+=$(foreach T, $(SETTYPES), $(DESTDIR)$(LIBDIR)/ipset/libipset_$(T).so) - -all: $(PROGRAMS) $(SHARED_LIBS) - -install: all $(INSTALL) - -clean: $(EXTRA_CLEANS) - rm -rf $(PROGRAMS) $(SHARED_LIBS) *.o *~ - -#The ipset(8) self -ipset.o: ipset.c - $(CC) $(CFLAGS) -DIPSET_VERSION=\"$(IPSET_VERSION)\" -DIPSET_LIB_DIR=\"$(IPSET_LIB_DIR)\" -c -o $@ $< - -ipset: ipset.o - $(CC) $(CFLAGS) -ldl -rdynamic -o $@ $^ - -#Pooltypes -ipset_%.o: ipset_%.c - $(CC) $(SH_CFLAGS) -o $@ -c $< - -libipset_%.so: ipset_%.o - $(LD) -shared -o $@ $< - -$(DESTDIR)$(LIBDIR)/ipset/libipset_%.so: libipset_%.so - @[ -d $(DESTDIR)$(LIBDIR)/ipset ] || mkdir -p $(DESTDIR)$(LIBDIR)/ipset - cp $< $@ - -$(DESTDIR)$(BINDIR)/ipset: ipset - @[ -d $(DESTDIR)$(BINDIR) ] || mkdir -p $(DESTDIR)$(BINDIR) - cp $< $@ - -$(DESTDIR)$(MANDIR)/man8/ipset.8: ipset.8 - @[ -d $(DESTDIR)$(MANDIR)/man8 ] || mkdir -p $(DESTDIR)$(MANDIR)/man8 - cp $< $@ diff --git a/ipset/TODO b/ipset/TODO deleted file mode 100644 index 9d46233..0000000 --- a/ipset/TODO +++ /dev/null @@ -1,2 +0,0 @@ -- rewrite kernel-userspace communication from sockopt to netlink -- IPv6 support diff --git a/ipset/ipset.8 b/ipset/ipset.8 deleted file mode 100644 index 89a86ce..0000000 --- a/ipset/ipset.8 +++ /dev/null @@ -1,445 +0,0 @@ -.TH IPSET 8 "Feb 05, 2004" "" "" -.\" -.\" Man page written by Jozsef Kadlecsik -.\" -.\" 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., 675 Mass Ave, Cambridge, MA 02139, USA. -.\" -.\" -.SH NAME -ipset \- administration tool for IP sets -.SH SYNOPSIS -.BR "ipset -N " "set type-specification [options]" -.br -.BR "ipset -[XFLSHh] " "[set] [options]" -.br -.BR "ipset -[EW] " "from-set to-set" -.br -.BR "ipset -[ADU] " "set entry" -.br -.BR "ipset -B " "set entry -b binding" -.br -.BR "ipset -T " "set entry [-b binding]" -.br -.BR "ipset -R " -.SH DESCRIPTION -.B ipset -is used to set up, maintain and inspect so called IP sets in the Linux -kernel. Depending on the type, an IP set may store IP addresses, (TCP/UDP) -port numbers or additional informations besides IP addresses: the word IP -means a general term here. See the set type definitions below. -.P -Any entry in a set can be bound to another set, which forms a relationship -between a set element and the set it is bound to. In order to define a -binding it is not required that the entry be already added to the set. -The sets may have a default binding, which is valid for every set element -for which there is no binding defined at all. -.P -IP set bindings pointing to sets and iptables matches and targets -referring to sets creates references, which protects the given sets in -the kernel. A set cannot be removed (destroyed) while there is a single -reference pointing to it. -.SH OPTIONS -The options that are recognized by -.B ipset -can be divided into several different groups. -.SS COMMANDS -These options specify the specific action to perform. Only one of them -can be specified on the command line unless otherwise specified -below. For all the long versions of the command and option names, you -need to use only enough letters to ensure that -.B ipset -can differentiate it from all other options. -.TP -.BI "-N, --create " "\fIsetname\fP type type-specific-options" -Create a set identified with setname and specified type. -Type-specific options must be supplied. -.TP -.BI "-X, --destroy " "[\fIsetname\fP]" -Destroy the specified set, or all sets if none or the keyword -.B -:all: -is specified. -Before destroying the set, all bindings belonging to the -set elements and the default binding of the set are removed. - -If the set has got references, nothing is done. -.TP -.BI "-F, --flush " "[\fIsetname\fP]" -Delete all entries from the specified set, or flush -all sets if none or the keyword -.B -:all: -is given. Bindings are not affected by the flush operation. -.TP -.BI "-E, --rename " "\fIfrom-setname\fP \fIto-setname\fP" -Rename a set. Set identified by to-setname must not exist. -.TP -.BI "-W, --swap " "\fIfrom-setname\fP \fIto-setname\fP" -Swap two sets as they referenced in the Linux kernel. -.B -iptables -rules or -.B -ipset -bindings pointing to the content of from-setname will point to -the content of to-setname and vice versa. Both sets must exist. -.TP -.BI "-L, --list " "[\fIsetname\fP]" -List the entries and bindings for the specified set, or for -all sets if none or the keyword -.B -:all: -is given. The -.B "-n, --numeric" -option can be used to suppress name lookups and generate numeric -output. When the -.B "-s, --sorted" -option is given, the entries are listed sorted (if the given set -type supports the operation). -.TP -.BI "-S, --save " "[\fIsetname\fP]" -Save the given set, or all sets if none or the keyword -.B -:all: -is specified to stdout in a format that --restore can read. -.TP -.BI "-R, --restore " -Restore a saved session generated by --save. The saved session -can be fed from stdin. - -When generating a session file please note that the supported commands -(create set, add element, bind) must appear in a strict order: first create -the set, then add all elements. Then create the next set, add all its elements -and so on. Finally you can list all binding commands. Also, it is a restore -operation, so the sets being restored must not exist. -.TP -.BI "-A, --add " "\fIsetname\fP \fIIP\fP" -Add an IP to a set. -.TP -.BI "-D, --del " "\fIsetname\fP \fIIP\fP" -Delete an IP from a set. -.TP -.BI "-T, --test " "\fIsetname\fP \fIIP -Test wether an IP is in a set or not. Exit status number is zero -if the tested IP is in the set and nonzero if it is missing from -the set. -.TP -.BI "-T, --test " "\fIsetname\fP \fIIP\fP \fI--binding\fP \fIto-setname\fP" -Test wether the IP belonging to the set points to the specified binding. -Exit status number is zero if the binding points to the specified set, -otherwise it is nonzero. The keyword -.B -:default: -can be used to test the default binding of the set. -.TP -.BI "-B, --bind " "\fIsetname\fP \fIIP\fP \fI--binding\fP \fIto-setname\fP" -Bind the IP in setname to to-setname. -.TP -.BI "-U, --unbind " "\fIsetname\fP \fIIP\fP" -Delete the binding belonging to IP in set setname. -.TP -.BI "-H, --help " "[settype]" -Print help and settype specific help if settype specified. -.P -At the -.B --B, -U -and -.B --T -commands you can use the token -.B -:default: -to bind, unbind or test the default binding of a set instead -of an IP. At the -.B --U -command you can use the token -.B -:all: -to destroy the bindings of all elements of a set. -.SS "OTHER OPTIONS" -The following additional options can be specified: -.TP -.B "-b, --binding setname" -The option specifies the value of the binding for the -.B "-B" -binding command, for which it is a mandatory option. -You can use it in the -.B "-T" -test command as well to test bindings. -.TP -.B "-s, --sorted" -Sorted output. When listing sets, entries are listed sorted. -.TP -.B "-n, --numeric" -Numeric output. When listing sets, bindings, IP addresses and -port numbers will be printed in numeric format. By default the -program will try to display them as host names, network names -or services (whenever applicable), which can trigger -.B -slow -DNS -lookups. -.TP -.B "-q, --quiet" -Suppress any output to stdout and stderr. ipset will still return -possible errors. -.SH SET TYPES -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 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" -option with a CIDR netmask value between 0-32 when creating an ipmap -set, you will be able to store and match network addresses: i.e an -IP address will be in the set if the value resulted by masking the address -with the specified netmask can be found in the set. -.P -Options to use when creating an ipmap set: -.TP -.BR "--from " from-IP -.TP -.BR "--to " to-IP -Create an ipmap set from the specified range. -.TP -.BR "--network " IP/mask -Create an ipmap set from the specified network. -.TP -.BR "--netmask " CIDR-netmask -When the optional -.B "--netmask" -parameter specified, network addresses will be -stored in the set instead of IP addresses, and the from-IP parameter -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 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 -.I %MAC -part is not mandatory. -.P -Options to use when creating an macipmap set: -.TP -.BR "--from " from-IP -.TP -.BR "--to " to-IP -Create a macipmap set from the specified range. -.TP -.BR "--network " IP/mask -Create a macipmap set from the specified network. -.TP -.BR "--matchunset" -When the optional -.B "--matchunset" -parameter specified, IP addresses which could be stored -in the set but not set yet, will always match. -.P -Please note, the -.I -set -and -.I -SET -netfilter kernel modules -.B -always -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 65536 ports. -The portmap set type is very fast and memory cheap. -.P -Options to use when creating an portmap set: -.TP -.BR "--from " from-port -.TP -.BR "--to " to-port -Create a portmap set from the specified range. -.SS iphash -The iphash set type uses a hash to store IP addresses. -In order to avoid clashes in the hash double-hashing, and as a last -resort, dynamic growing of the hash performed. The iphash set type is -great to store random addresses. By supplyig the -.B "--netmask" -option with a CIDR netmask value between 0-32 at creating the set, -you will be able to store and match network addresses instead: i.e -an IP address will be in the set if the value of the address -masked with the specified netmask can be found in the set. -.P -Options to use when creating an iphash set: -.TP -.BR "--hashsize " hashsize -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 8). -.TP -.BR "--resize " percent -Increase the hash size by this many percent (default 50) when adding -an IP to the hash could not be performed after -.B -probes -number of double-hashing. -.TP -.BR "--netmask " CIDR-netmask -When the optional -.B "--netmask" -parameter specified, network addresses will be -stored in the set instead of IP addresses. -.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 -.B -probes -parameter. At the same time higher -.B -probes -values result a better utilized hash while smaller values -produce a larger, sparse hash. -.SS nethash -The nethash set type uses a hash to store different size of -network addresses. The -.I -IP -"address" used in the ipset commands must be in the form -.I -IP-address/cidr-size -where the CIDR block size must be in the inclusive range of 1-31. -In order to avoid clashes in the hash -double-hashing, and as a last resort, dynamic growing of the hash performed. -.P -Options to use when creating an nethash set: -.TP -.BR "--hashsize " hashsize -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 4). -.TP -.BR "--resize " percent -Increase the hash size by this many percent (default 50) when adding -an IP to the hash could not be performed after -.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 -specific netmasks). When adding/deleting IP addresses -to a nethash set by the -.I -SET -netfilter kernel module, it will be added/deleted by the smallest -netblock size which can be found in the set. -.P -The lookup time in a nethash type of set is approximately linearly -grows with the times of the -.B -probes -parameter and the number of different mask parameters in the hash. -Otherwise the same speed and memory efficiency comments applies here -as at the iphash type. -.SS ipporthash -The ipporthash set type uses a hash to store IP address and port pairs. -In order to avoid clashes in the hash double-hashing, and as a last -resort, dynamic growing of the hash performed. An ipporthash set can -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". -.P -The ipporthash types of sets evaluates two src/dst parameters of the -.I -set -match and -.I -SET -target. -.P -Options to use when creating an ipporthash set: -.TP -.BR "--from " from-IP -.TP -.BR "--to " to-IP -Create an ipporthash set from the specified range. -.TP -.BR "--network " IP/mask -Create an ipporthash set from the specified network. -.TP -.BR "--hashsize " hashsize -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 8). -.TP -.BR "--resize " percent -Increase the hash size by this many percent (default 50) when adding -an IP to the hash could not be performed after -.B -probes -number of double-hashing. -.P -The same resizing, speed and memory efficiency comments applies here -as at the iphash type. -.SS iptree -The iptree set type uses a tree to store IP addresses, optionally -with timeout values. -.P -Options to use when creating an iptree set: -.TP -.BR "--timeout " value -The timeout value for the entries in seconds (default 0) -.P -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. -.SH GENERAL RESTRICTIONS -Setnames starting with colon (:) cannot be defined. Zero valued set -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. -If you want to store random same size networks (say random /24 blocks), -use the iphash set type. If you have got random size of netblocks, -use nethash. -.SH DIAGNOSTICS -Various error messages are printed to standard error. The exit code -is 0 for correct functioning. Errors which appear to be caused by -invalid or abused command line parameters cause an exit code of 2, and -other errors cause an exit code of 1. -.SH BUGS -Bugs? No, just funny features. :-) -OK, just kidding... -.SH SEE ALSO -.BR iptables (8), -.SH AUTHORS -Jozsef Kadlecsik wrote ipset, which is based on ippool by -Joakim Axelsson, Patrick Schaaf and Martin Josefsson. -.\" .. and did I mention that we are incredibly cool people? -.\" .. sexy, too .. -.\" .. witty, charming, powerful .. -.\" .. and most of all, modest .. diff --git a/ipset/ipset.c b/ipset/ipset.c deleted file mode 100644 index adf37b1..0000000 --- a/ipset/ipset.c +++ /dev/null @@ -1,2209 +0,0 @@ -/* Copyright 2000-2002 Joakim Axelsson (gozem@linux.nu) - * Patrick Schaaf (bof@bof.de) - * Copyright 2003-2004 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ipset.h" - -char program_name[] = "ipset"; -char program_version[] = IPSET_VERSION; - -/* The list of loaded set types */ -static struct settype *all_settypes = NULL; - -/* Array of sets */ -struct set **set_list = NULL; -ip_set_id_t max_sets = 0; - -/* Suppress output to stdout and stderr? */ -static int option_quiet = 0; - -/* Data for restore mode */ -static int restore = 0; -void *restore_data = NULL; -struct ip_set_restore *restore_set = NULL; -size_t restore_offset = 0, restore_size; -unsigned line = 0; - -#define TEMPFILE_PATTERN "/ipsetXXXXXX" - -#ifdef IPSET_DEBUG -int option_debug = 0; -#endif - -#define OPTION_OFFSET 256 -static unsigned int global_option_offset = 0; - -/* Most of these command parsing functions are borrowed from iptables.c */ - -static const char cmdflags[] = { ' ', /* CMD_NONE */ - 'N', 'X', 'F', 'E', 'W', 'L', 'S', 'R', - 'A', 'D', 'T', 'B', 'U', 'H', 'V', -}; - -/* Options */ -#define OPT_NONE 0x0000U -#define OPT_NUMERIC 0x0001U /* -n */ -#define OPT_SORTED 0x0002U /* -s */ -#define OPT_QUIET 0x0004U /* -q */ -#define OPT_DEBUG 0x0008U /* -z */ -#define OPT_BINDING 0x0010U /* -b */ -#define NUMBER_OF_OPT 5 -static const char optflags[] = - { 'n', 's', 'q', 'z', 'b' }; - -static struct option opts_long[] = { - /* set operations */ - {"create", 1, 0, 'N'}, - {"destroy", 2, 0, 'X'}, - {"flush", 2, 0, 'F'}, - {"rename", 1, 0, 'E'}, - {"swap", 1, 0, 'W'}, - {"list", 2, 0, 'L'}, - - {"save", 2, 0, 'S'}, - {"restore", 0, 0, 'R'}, - - /* ip in set operations */ - {"add", 1, 0, 'A'}, - {"del", 1, 0, 'D'}, - {"test", 1, 0, 'T'}, - - /* binding operations */ - {"bind", 1, 0, 'B'}, - {"unbind", 1, 0, 'U'}, - - /* free options */ - {"numeric", 0, 0, 'n'}, - {"sorted", 0, 0, 's'}, - {"quiet", 0, 0, 'q'}, - {"binding", 1, 0, 'b'}, - -#ifdef IPSET_DEBUG - /* debug (if compiled with it) */ - {"debug", 0, 0, 'z'}, -#endif - - /* version and help */ - {"version", 0, 0, 'V'}, - {"help", 2, 0, 'H'}, - - /* end */ - {0} -}; - -static char opts_short[] = - "-N:X::F::E:W:L::S::RA:D:T:B:U:nsqzb:Vh::H::"; - -/* Table of legal combinations of commands and options. If any of the - * given commands make an option legal, that option is legal. - * Key: - * + compulsory - * x illegal - * optional - */ - -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'}, -}; - -/* Main parser function */ -int parse_commandline(int argc, char *argv[]); - -void exit_tryhelp(int status) -{ - fprintf(stderr, - "Try `%s -H' or '%s --help' for more information.\n", - program_name, program_name); - exit(status); -} - -void exit_error(enum exittype status, char *msg, ...) -{ - va_list args; - - if (!option_quiet) { - va_start(args, msg); - fprintf(stderr, "%s v%s: ", program_name, program_version); - vfprintf(stderr, msg, args); - va_end(args); - fprintf(stderr, "\n"); - if (line) - fprintf(stderr, "Restore failed at line %u:\n", line); - if (status == PARAMETER_PROBLEM) - exit_tryhelp(status); - if (status == VERSION_PROBLEM) - fprintf(stderr, - "Perhaps %s or your kernel needs to be upgraded.\n", - program_name); - } - - exit(status); -} - -void ipset_printf(char *msg, ...) -{ - va_list args; - - if (!option_quiet) { - va_start(args, msg); - vfprintf(stdout, msg, args); - va_end(args); - fprintf(stdout, "\n"); - } -} - -static void generic_opt_check(int command, int options) -{ - int i, j, legal = 0; - - /* Check that commands are valid with options. Complicated by the - * fact that if an option is legal with *any* command given, it is - * legal overall (ie. -z and -l). - */ - for (i = 0; i < NUMBER_OF_OPT; i++) { - legal = 0; /* -1 => illegal, 1 => legal, 0 => undecided. */ - - for (j = 1; j <= NUMBER_OF_CMD; j++) { - if (command != j) - continue; - - if (!(options & (1 << i))) { - if (commands_v_options[j-1][i] == '+') - exit_error(PARAMETER_PROBLEM, - "You need to supply the `-%c' " - "option for this command\n", - optflags[i]); - } else { - if (commands_v_options[j-1][i] != 'x') - legal = 1; - else if (legal == 0) - legal = -1; - } - } - if (legal == -1) - exit_error(PARAMETER_PROBLEM, - "Illegal option `-%c' with this command\n", - optflags[i]); - } -} - -static char opt2char(int option) -{ - const char *ptr; - for (ptr = optflags; option > 1; option >>= 1, ptr++); - - return *ptr; -} - -static char cmd2char(int option) -{ - if (option <= CMD_NONE || option > NUMBER_OF_CMD) - return ' '; - - return cmdflags[option]; -} - -static int kernel_getsocket(void) -{ - int sockfd = -1; - - sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); - if (sockfd < 0) - exit_error(OTHER_PROBLEM, - "You need to be root to perform this command."); - - return sockfd; -} - -static void kernel_error(unsigned cmd, int err) -{ - unsigned int i; - struct translate_error { - int err; - unsigned cmd; - char *message; - } table[] = - { /* Generic error codes */ - { EPERM, 0, "Missing capability" }, - { EBADF, 0, "Invalid socket option" }, - { EINVAL, 0, "Size mismatch for expected socket data" }, - { ENOMEM, 0, "Not enough memory" }, - { EFAULT, 0, "Failed to copy data" }, - { EPROTO, 0, "ipset kernel/userspace version mismatch" }, - { EBADMSG, 0, "Unknown command" }, - /* Per command error codes */ - /* Reserved ones for add/del/test to handle internally: - * EEXIST - */ - { ENOENT, CMD_CREATE, "Unknown set type" }, - { 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" }, - { 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" }, - { EBUSY, 0, "Set is in use, operation not permitted" }, - }; - for (i = 0; i < sizeof(table)/sizeof(struct translate_error); i++) { - if ((table[i].cmd == cmd || table[i].cmd == 0) - && table[i].err == err) - exit_error(err == EPROTO ? VERSION_PROBLEM - : OTHER_PROBLEM, - table[i].message); - } - exit_error(OTHER_PROBLEM, "Error from kernel: %s", strerror(err)); -} - -static void kernel_getfrom(unsigned cmd, void *data, size_t * size) -{ - int res; - int sockfd = kernel_getsocket(); - - /* Send! */ - res = getsockopt(sockfd, SOL_IP, SO_IP_SET, data, size); - - DP("res=%d errno=%d", res, errno); - - if (res != 0) - kernel_error(cmd, errno); -} - -static int kernel_sendto_handleerrno(unsigned cmd, unsigned op, - void *data, size_t size) -{ - int res; - int sockfd = kernel_getsocket(); - - /* Send! */ - res = setsockopt(sockfd, SOL_IP, SO_IP_SET, data, size); - - DP("res=%d errno=%d", res, errno); - - if (res != 0) { - if (errno == EEXIST) - return -1; - else - kernel_error(cmd, errno); - } - - return 0; /* all ok */ -} - -static void kernel_sendto(unsigned cmd, void *data, size_t size) -{ - int res; - int sockfd = kernel_getsocket(); - - /* Send! */ - res = setsockopt(sockfd, SOL_IP, SO_IP_SET, data, size); - - DP("res=%d errno=%d", res, errno); - - if (res != 0) - kernel_error(cmd, errno); -} - -static int kernel_getfrom_handleerrno(unsigned cmd, void *data, size_t * size) -{ - int res; - int sockfd = kernel_getsocket(); - - /* Send! */ - res = getsockopt(sockfd, SOL_IP, SO_IP_SET, data, size); - - DP("res=%d errno=%d", res, errno); - - if (res != 0) { - if (errno == EAGAIN) - return -1; - else - kernel_error(cmd, errno); - } - - return 0; /* all ok */ -} - -static void check_protocolversion(void) -{ - struct ip_set_req_version req_version; - size_t size = sizeof(struct ip_set_req_version); - int sockfd = kernel_getsocket(); - int res; - - req_version.op = IP_SET_OP_VERSION; - res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req_version, &size); - - if (res != 0) { - ipset_printf("I'm of protocol version %u.\n" - "Kernel module is not loaded in, " - "cannot verify kernel version.", - IP_SET_PROTOCOL_VERSION); - return; - } - if (req_version.version != IP_SET_PROTOCOL_VERSION) - exit_error(OTHER_PROBLEM, - "Kernel ipset code is of protocol version %u." - "I'm of protocol version %u.\n" - "Please upgrade your kernel and/or ipset(8) utillity.", - req_version.version, IP_SET_PROTOCOL_VERSION); -} - -static void set_command(int *cmd, const int newcmd) -{ - if (*cmd != CMD_NONE) - exit_error(PARAMETER_PROBLEM, "Can't use -%c with -%c\n", - cmd2char(*cmd), cmd2char(newcmd)); - *cmd = newcmd; -} - -static void add_option(unsigned int *options, unsigned int option) -{ - if (*options & option) - exit_error(PARAMETER_PROBLEM, - "multiple -%c flags not allowed", - opt2char(option)); - *options |= option; -} - -void *ipset_malloc(size_t size) -{ - void *p; - - if (size == 0) - return NULL; - - if ((p = malloc(size)) == NULL) { - perror("ipset: not enough memory"); - exit(1); - } - return p; -} - -char *ipset_strdup(const char *s) -{ - char *p; - - if ((p = strdup(s)) == NULL) { - perror("ipset: not enough memory"); - exit(1); - } - return p; -} - -void ipset_free(void **data) -{ - if (*data == NULL) - return; - - free(*data); - *data = NULL; -} - -static struct option *merge_options(struct option *oldopts, - const struct option *newopts, - unsigned int *option_offset) -{ - unsigned int num_old, num_new, i; - struct option *merge; - - for (num_old = 0; oldopts[num_old].name; num_old++); - for (num_new = 0; newopts[num_new].name; num_new++); - - global_option_offset += OPTION_OFFSET; - *option_offset = global_option_offset; - - merge = ipset_malloc(sizeof(struct option) * (num_new + num_old + 1)); - memcpy(merge, oldopts, num_old * sizeof(struct option)); - for (i = 0; i < num_new; i++) { - merge[num_old + i] = newopts[i]; - merge[num_old + i].val += *option_offset; - } - memset(merge + num_old + num_new, 0, sizeof(struct option)); - - return merge; -} - -static char *ip_tohost(const struct in_addr *addr) -{ - struct hostent *host; - - if ((host = gethostbyaddr((char *) addr, - sizeof(struct in_addr), - AF_INET)) != NULL) { - DP("%s", host->h_name); - return (char *) host->h_name; - } - - return (char *) NULL; -} - -static char *ip_tonetwork(const struct in_addr *addr) -{ - struct netent *net; - - if ((net = getnetbyaddr((long) ntohl(addr->s_addr), - AF_INET)) != NULL) { - DP("%s", net->n_name); - return (char *) net->n_name; - } - - return (char *) NULL; -} - -/* Return a string representation of an IP address. - * Please notice that a pointer to static char* area is returned. - */ -char *ip_tostring(ip_set_ip_t ip, unsigned options) -{ - struct in_addr addr; - 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); -} - -char *binding_ip_tostring(struct set *set, ip_set_ip_t ip, unsigned options) -{ - return ip_tostring(ip, options); -} -char *ip_tostring_numeric(ip_set_ip_t ip) -{ - return ip_tostring(ip, OPT_NUMERIC); -} - -/* Fills the 'ip' with the parsed ip or host in host byte order */ -void parse_ip(const char *str, ip_set_ip_t * ip) -{ - struct hostent *host; - struct in_addr addr; - - DP("%s", str); - - if (inet_aton(str, &addr) != 0) { - *ip = ntohl(addr.s_addr); /* We want host byte order */ - return; - } - - host = gethostbyname(str); - if (host != NULL) { - if (host->h_addrtype != AF_INET || - host->h_length != sizeof(struct in_addr)) - exit_error(PARAMETER_PROBLEM, - "host/network `%s' not an internet name", - str); - if (host->h_addr_list[1] != 0) - exit_error(PARAMETER_PROBLEM, - "host/network `%s' resolves to serveral ip-addresses. " - "Please specify one.", str); - - *ip = ntohl(((struct in_addr *) host->h_addr_list[0])->s_addr); - return; - } - - exit_error(PARAMETER_PROBLEM, "host/network `%s' not found", str); -} - -/* Fills 'mask' with the parsed mask in host byte order */ -void parse_mask(const char *str, ip_set_ip_t * mask) -{ - struct in_addr addr; - unsigned int bits; - - DP("%s", str); - - if (str == NULL) { - /* no mask at all defaults to 32 bits */ - *mask = 0xFFFFFFFF; - return; - } - if (strchr(str, '.') && inet_aton(str, &addr) != 0) { - *mask = ntohl(addr.s_addr); /* We want host byte order */ - return; - } - if (sscanf(str, "%d", &bits) != 1 || bits < 0 || bits > 32) - exit_error(PARAMETER_PROBLEM, - "invalid mask `%s' specified", str); - - DP("bits: %d", bits); - - *mask = bits != 0 ? 0xFFFFFFFF << (32 - bits) : 0L; -} - -/* Combines parse_ip and parse_mask */ -void -parse_ipandmask(const char *str, ip_set_ip_t * ip, ip_set_ip_t * mask) -{ - char buf[256]; - char *p; - - strncpy(buf, str, sizeof(buf) - 1); - buf[255] = '\0'; - - if ((p = strrchr(buf, '/')) != NULL) { - *p = '\0'; - parse_mask(p + 1, mask); - } else - parse_mask(NULL, mask); - - /* if a null mask is given, the name is ignored, like in "any/0" */ - if (*mask == 0U) - *ip = 0U; - else - parse_ip(buf, ip); - - DP("%s ip: %08X (%s) mask: %08X", - str, *ip, ip_tostring_numeric(*ip), *mask); - - /* Apply the netmask */ - *ip &= *mask; - - DP("%s ip: %08X (%s) mask: %08X", - str, *ip, ip_tostring_numeric(*ip), *mask); -} - -/* Return a string representation of a port - * Please notice that a pointer to static char* area is returned - * and we assume TCP protocol. - */ -char *port_tostring(ip_set_ip_t port, unsigned options) -{ - struct servent *service; - static char name[] = "65535"; - - if (!(options & OPT_NUMERIC)) { - if ((service = getservbyport(htons(port), "tcp"))) - return service->s_name; - } - sprintf(name, "%u", port); - return name; -} - -int -string_to_number(const char *str, unsigned int min, unsigned int max, - ip_set_ip_t *port) -{ - long number; - char *end; - - /* Handle hex, octal, etc. */ - errno = 0; - number = strtol(str, &end, 0); - if (*end == '\0' && end != str) { - /* we parsed a number, let's see if we want this */ - if (errno != ERANGE && min <= number && number <= max) { - *port = number; - return 0; - } - } - return -1; -} - -static int -string_to_port(const char *str, ip_set_ip_t *port) -{ - struct servent *service; - - if ((service = getservbyname(str, "tcp")) != NULL) { - *port = ntohs((unsigned short) service->s_port); - return 0; - } - - return -1; -} - -/* Fills the 'ip' with the parsed port in host byte order */ -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); -} - -/* - * Settype functions - */ -static struct settype *settype_find(const char *typename) -{ - struct settype *runner = all_settypes; - - DP("%s", typename); - - while (runner != NULL) { - if (strncmp(runner->typename, typename, - IP_SET_MAXNAMELEN) == 0) - return runner; - - runner = runner->next; - } - - return NULL; /* not found */ -} - -static struct settype *settype_load(const char *typename) -{ - char path[sizeof(IPSET_LIB_DIR) + sizeof(IPSET_LIB_NAME) + - strlen(typename)]; - struct settype *settype; - - /* do some search in list */ - settype = settype_find(typename); - if (settype != NULL) - return settype; /* found */ - - /* Else we have to load it */ - sprintf(path, IPSET_LIB_DIR IPSET_LIB_NAME, typename); - - if (dlopen(path, RTLD_NOW)) { - /* Found library. */ - - settype = settype_find(typename); - - if (settype != NULL) - return settype; - } - - /* Can't load the settype */ - exit_error(PARAMETER_PROBLEM, - "Couldn't load settype `%s':%s\n", - typename, dlerror()); - - return NULL; /* Never executed, but keep compilers happy */ -} - -static char *check_set_name(char *setname) -{ - if (strlen(setname) > IP_SET_MAXNAMELEN - 1) - exit_error(PARAMETER_PROBLEM, - "Setname '%s' too long, max %d characters.", - setname, IP_SET_MAXNAMELEN - 1); - - return setname; -} - -static struct settype *check_set_typename(const char *typename) -{ - if (strlen(typename) > IP_SET_MAXNAMELEN - 1) - exit_error(PARAMETER_PROBLEM, - "Typename '%s' too long, max %d characters.", - typename, IP_SET_MAXNAMELEN - 1); - - return settype_load(typename); -} - -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - -/* Register a new set type */ -void settype_register(struct settype *settype) -{ - struct settype *chk; - size_t size; - - DP("%s", settype->typename); - - /* Check if this typename already exists */ - chk = settype_find(settype->typename); - - if (chk != NULL) - exit_error(OTHER_PROBLEM, - "Set type '%s' already registered!\n", - settype->typename); - - /* Check version */ - if (settype->protocol_version != IP_SET_PROTOCOL_VERSION) - exit_error(OTHER_PROBLEM, - "Set type %s is of wrong protocol version %u!" - " I'm of version %u.\n", settype->typename, - settype->protocol_version, - IP_SET_PROTOCOL_VERSION); - - /* Initialize internal data */ - settype->header = ipset_malloc(settype->header_size); - size = MAX(settype->create_size, settype->adt_size); - settype->data = ipset_malloc(size); - - /* Insert first */ - settype->next = all_settypes; - all_settypes = settype; - - DP("%s registered", settype->typename); -} - -/* Find set functions */ -static struct set *set_find_byid(ip_set_id_t id) -{ - struct set *set = NULL; - ip_set_id_t i; - - for (i = 0; i < max_sets; i++) - if (set_list[i] && set_list[i]->id == id) { - set = set_list[i]; - break; - } - - if (set == NULL) - exit_error(PARAMETER_PROBLEM, - "Set identified by id %u is not found", id); - return set; -} - -static struct set *set_find_byname(const char *name) -{ - struct set *set = NULL; - ip_set_id_t i; - - for (i = 0; i < max_sets; i++) - if (set_list[i] - && strncmp(set_list[i]->name, name, - IP_SET_MAXNAMELEN) == 0) { - set = set_list[i]; - break; - } - if (set == NULL) - exit_error(PARAMETER_PROBLEM, - "Set %s is not found", name); - return set; -} - -static ip_set_id_t set_find_free_index(const char *name) -{ - ip_set_id_t i, index = IP_SET_INVALID_ID; - - for (i = 0; i < max_sets; i++) { - if (index == IP_SET_INVALID_ID - && set_list[i] == NULL) - index = i; - if (set_list[i] != NULL - && strncmp(set_list[i]->name, name, - IP_SET_MAXNAMELEN) == 0) - exit_error(PARAMETER_PROBLEM, - "Set %s is already defined, cannot be restored", - name); - } - - if (index == IP_SET_INVALID_ID) - exit_error(PARAMETER_PROBLEM, - "Set %s cannot be restored, " - "max number of set %u reached", - name, max_sets); - - return index; -} - -/* - * Send create set order to kernel - */ -static void set_create(const char *name, struct settype *settype) -{ - struct ip_set_req_create req_create; - size_t size; - void *data; - - DP("%s %s", name, settype->typename); - - req_create.op = IP_SET_OP_CREATE; - req_create.version = IP_SET_PROTOCOL_VERSION; - strcpy(req_create.name, name); - strcpy(req_create.typename, settype->typename); - - /* Final checks */ - settype->create_final(settype->data, settype->flags); - - /* Alloc memory for the data to send */ - size = sizeof(struct ip_set_req_create) + settype->create_size; - data = ipset_malloc(size); - - /* Add up ip_set_req_create and the settype data */ - memcpy(data, &req_create, sizeof(struct ip_set_req_create)); - memcpy(data + sizeof(struct ip_set_req_create), - settype->data, settype->create_size); - - kernel_sendto(CMD_CREATE, data, size); - free(data); -} - -static void set_restore_create(const char *name, struct settype *settype) -{ - struct set *set; - - DP("%s %s %u %u %u %u", name, settype->typename, - restore_offset, sizeof(struct ip_set_restore), - settype->create_size, restore_size); - - /* Sanity checking */ - if (restore_offset - + sizeof(struct ip_set_restore) - + settype->create_size > restore_size) - exit_error(PARAMETER_PROBLEM, - "Giving up, restore file is screwed up!"); - - /* Final checks */ - settype->create_final(settype->data, settype->flags); - - /* Fill out restore_data */ - restore_set = (struct ip_set_restore *) - (restore_data + restore_offset); - strcpy(restore_set->name, name); - strcpy(restore_set->typename, settype->typename); - restore_set->index = set_find_free_index(name); - restore_set->header_size = settype->create_size; - restore_set->members_size = 0; - - DP("name %s, restore index %u", restore_set->name, restore_set->index); - /* Add settype data */ - - memcpy(restore_data + restore_offset + sizeof(struct ip_set_restore), - settype->data, settype->create_size); - - restore_offset += sizeof(struct ip_set_restore) - + settype->create_size; - - /* Add set to set_list */ - set = ipset_malloc(sizeof(struct set)); - strcpy(set->name, name); - set->settype = settype; - set->index = restore_set->index; - set_list[restore_set->index] = set; -} - -/* - * Send destroy/flush order to kernel for one or all sets - */ -static void set_destroy(const char *name, unsigned op, unsigned cmd) -{ - struct ip_set_req_std req; - - DP("%s %s", cmd == CMD_DESTROY ? "destroy" : "flush", name); - - req.op = op; - req.version = IP_SET_PROTOCOL_VERSION; - strcpy(req.name, name); - - kernel_sendto(cmd, &req, sizeof(struct ip_set_req_std)); -} - -/* - * Send rename/swap order to kernel - */ -static void set_rename(const char *name, const char *newname, - unsigned op, unsigned cmd) -{ - struct ip_set_req_create req; - - DP("%s %s %s", cmd == CMD_RENAME ? "rename" : "swap", - name, newname); - - req.op = op; - req.version = IP_SET_PROTOCOL_VERSION; - strcpy(req.name, name); - strcpy(req.typename, newname); - - kernel_sendto(cmd, &req, - sizeof(struct ip_set_req_create)); -} - -/* - * Send MAX_SETS, LIST_SIZE and/or SAVE_SIZE orders to kernel - */ -static size_t load_set_list(const char name[IP_SET_MAXNAMELEN], - ip_set_id_t *index, - unsigned op, unsigned cmd) -{ - void *data = NULL; - struct ip_set_req_max_sets req_max_sets; - struct ip_set_name_list *name_list; - struct set *set; - ip_set_id_t i; - size_t size, req_size; - int repeated = 0, res = 0; - - DP("%s %s", cmd == CMD_MAX_SETS ? "MAX_SETS" - : cmd == CMD_LIST_SIZE ? "LIST_SIZE" - : "SAVE_SIZE", - name); - -tryagain: - if (set_list) { - for (i = 0; i < max_sets; i++) - if (set_list[i]) - free(set_list[i]); - free(set_list); - set_list = NULL; - } - /* Get max_sets */ - req_max_sets.op = IP_SET_OP_MAX_SETS; - req_max_sets.version = IP_SET_PROTOCOL_VERSION; - strcpy(req_max_sets.set.name, name); - size = sizeof(req_max_sets); - kernel_getfrom(CMD_MAX_SETS, &req_max_sets, &size); - - DP("got MAX_SETS: sets %d, max_sets %d", - req_max_sets.sets, req_max_sets.max_sets); - - max_sets = req_max_sets.max_sets; - set_list = ipset_malloc(max_sets * sizeof(struct set *)); - memset(set_list, 0, max_sets * sizeof(struct set *)); - *index = req_max_sets.set.index; - - if (req_max_sets.sets == 0) - /* No sets in kernel */ - return 0; - - /* Get setnames */ - size = req_size = sizeof(struct ip_set_req_setnames) - + req_max_sets.sets * sizeof(struct ip_set_name_list); - data = ipset_malloc(size); - ((struct ip_set_req_setnames *) data)->op = op; - ((struct ip_set_req_setnames *) data)->index = *index; - - res = kernel_getfrom_handleerrno(cmd, data, &size); - - if (res != 0 || size != req_size) { - free(data); - if (repeated++ < LIST_TRIES) - goto tryagain; - exit_error(OTHER_PROBLEM, - "Tried to get sets from kernel %d times" - " and failed. Please try again when the load on" - " the sets has gone down.", LIST_TRIES); - } - - /* Load in setnames */ - size = sizeof(struct ip_set_req_setnames); - while (size + sizeof(struct ip_set_name_list) <= req_size) { - name_list = (struct ip_set_name_list *) - (data + size); - set = ipset_malloc(sizeof(struct set)); - strcpy(set->name, name_list->name); - set->index = name_list->index; - set->id = name_list->id; - set->settype = settype_load(name_list->typename); - set_list[name_list->index] = set; - DP("loaded %s, type %s, index %u", - set->name, set->settype->typename, set->index); - size += sizeof(struct ip_set_name_list); - } - /* Size to get set members, bindings */ - size = ((struct ip_set_req_setnames *)data)->size; - free(data); - - return size; -} - -/* - * Save operation - */ -static size_t save_bindings(void *data, size_t offset, size_t len) -{ - struct ip_set_hash_save *hash = - (struct ip_set_hash_save *) (data + offset); - struct set *set; - - DP("offset %u, len %u", offset, len); - if (offset + sizeof(struct ip_set_hash_save) > len) - exit_error(OTHER_PROBLEM, - "Save operation failed, try again later."); - - set = set_find_byid(hash->id); - if (!(set && set_list[hash->binding])) - exit_error(OTHER_PROBLEM, - "Save binding failed, try again later."); - printf("-B %s %s -b %s\n", - set->name, - set->settype->bindip_tostring(set, hash->ip, OPT_NUMERIC), - set_list[hash->binding]->name); - - return sizeof(struct ip_set_hash_save); -} - -static size_t save_set(void *data, int *bindings, - size_t offset, size_t len) -{ - struct ip_set_save *set_save = - (struct ip_set_save *) (data + offset); - struct set *set; - struct settype *settype; - size_t used; - - DP("offset %u, len %u", offset, 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."); - - if (set_save->index == IP_SET_INVALID_ID) { - /* Marker */ - *bindings = 1; - return sizeof(struct ip_set_save); - } - set = set_list[set_save->index]; - if (!set) - exit_error(OTHER_PROBLEM, - "Save set failed, try again later."); - settype = set->settype; - - /* Init set header */ - used = sizeof(struct ip_set_save); - settype->initheader(set, data + offset + used); - - /* Print create set */ - settype->saveheader(set, OPT_NUMERIC); - - /* Print add IPs */ - used += set_save->header_size; - settype->saveips(set, data + offset + used, - set_save->members_size, OPT_NUMERIC); - - return (used + set_save->members_size); -} - -static size_t save_default_bindings(void *data, int *bindings) -{ - struct ip_set_save *set_save = (struct ip_set_save *) data; - struct set *set; - - if (set_save->index == IP_SET_INVALID_ID) { - /* Marker */ - *bindings = 1; - return sizeof(struct ip_set_save); - } - - set = set_list[set_save->index]; - DP("%s, binding %u", set->name, set_save->binding); - if (set_save->binding != IP_SET_INVALID_ID) { - if (!set_list[set_save->binding]) - exit_error(OTHER_PROBLEM, - "Save set failed, try again later."); - - printf("-B %s %s -b %s\n", - set->name, IPSET_TOKEN_DEFAULT, - set_list[set_save->binding]->name); - } - return (sizeof(struct ip_set_save) - + set_save->header_size - + set_save->members_size); -} - -static int try_save_sets(const char name[IP_SET_MAXNAMELEN]) -{ - void *data = NULL; - size_t size, req_size = 0; - ip_set_id_t index; - int res = 0, bindings = 0; - time_t now = time(NULL); - - /* Load set_list from kernel */ - size = load_set_list(name, &index, - IP_SET_OP_SAVE_SIZE, CMD_SAVE); - - if (size) { - /* Get sets, bindings and print them */ - /* Take into account marker */ - req_size = (size += sizeof(struct ip_set_save)); - data = ipset_malloc(size); - ((struct ip_set_req_list *) data)->op = IP_SET_OP_SAVE; - ((struct ip_set_req_list *) data)->index = index; - res = kernel_getfrom_handleerrno(CMD_SAVE, data, &size); - - if (res != 0 || size != req_size) { - free(data); - return -EAGAIN; - } - } - - printf("# Generated by ipset %s on %s", IPSET_VERSION, ctime(&now)); - size = 0; - while (size < req_size) { - DP("size: %u, req_size: %u", size, req_size); - if (bindings) - size += save_bindings(data, size, req_size); - else - size += save_set(data, &bindings, size, req_size); - } - /* Re-read data to save default bindings */ - bindings = 0; - size = 0; - while (size < req_size && bindings == 0) - size += save_default_bindings(data + size, &bindings); - - printf("COMMIT\n"); - now = time(NULL); - printf("# Completed on %s", ctime(&now)); - ipset_free(&data); - return res; -} - -/* - * Performs a save to stdout - */ -static void set_save(const char name[IP_SET_MAXNAMELEN]) -{ - int i; - - DP("%s", name); - for (i = 0; i < LIST_TRIES; i++) - if (try_save_sets(name) == 0) - return; - - if (errno == EAGAIN) - exit_error(OTHER_PROBLEM, - "Tried to save sets from kernel %d times" - " and failed. Please try again when the load on" - " the sets has gone down.", LIST_TRIES); - else - kernel_error(CMD_SAVE, errno); -} - -/* - * Restore operation - */ - -/* global new argv and argc */ -static char *newargv[255]; -static int newargc = 0; - -/* Build faked argv from parsed line */ -static void build_argv(int line, char *buffer) { - char *ptr; - int i; - - /* Reset */ - for (i = 1; i < newargc; i++) - free(newargv[i]); - newargc = 1; - - ptr = strtok(buffer, " \t\n"); - newargv[newargc++] = ipset_strdup(ptr); - while ((ptr = strtok(NULL, " \t\n")) != NULL) { - if ((newargc + 1) < sizeof(newargv)/sizeof(char *)) - newargv[newargc++] = ipset_strdup(ptr); - else - exit_error(PARAMETER_PROBLEM, - "Line %d is too long to restore\n", line); - } -} - -static FILE *create_tempfile(void) -{ - char buffer[1024]; - char *tmpdir = NULL; - char *filename; - int fd; - FILE *file; - - if (!(tmpdir = getenv("TMPDIR")) && !(tmpdir = getenv("TMP"))) - tmpdir = "/tmp"; - filename = ipset_malloc(strlen(tmpdir) + strlen(TEMPFILE_PATTERN) + 1); - strcpy(filename, tmpdir); - strcat(filename, TEMPFILE_PATTERN); - - (void) umask(077); /* Create with restrictive permissions */ - fd = mkstemp(filename); - if (fd == -1) - exit_error(OTHER_PROBLEM, "Could not create temporary file."); - if (!(file = fdopen(fd, "r+"))) - exit_error(OTHER_PROBLEM, "Could not open temporary file."); - if (unlink(filename) == -1) - exit_error(OTHER_PROBLEM, "Could not unlink temporary file."); - free(filename); - - while (fgets(buffer, sizeof(buffer), stdin)) { - fputs(buffer, file); - } - fseek(file, 0L, SEEK_SET); - - return file; -} - -/* - * Performs a restore from a file - */ -static void set_restore(char *argv0) -{ - char buffer[1024]; - char *ptr, *name = NULL; - char cmd = ' '; - int line = 0, first_pass, i, bindings = 0; - struct settype *settype = NULL; - struct ip_set_req_setnames *header; - ip_set_id_t index; - FILE *in; - int res; - - /* Create and store stdin in temporary file */ - in = create_tempfile(); - - /* Load existing sets from kernel */ - load_set_list(IPSET_TOKEN_ALL, &index, - IP_SET_OP_LIST_SIZE, CMD_RESTORE); - - restore_size = sizeof(struct ip_set_req_setnames)/* header */ - + sizeof(struct ip_set_restore); /* marker */ - DP("restore_size: %u", restore_size); - /* First pass: calculate required amount of data */ - while (fgets(buffer, sizeof(buffer), in)) { - line++; - - if (buffer[0] == '\n') - continue; - else if (buffer[0] == '#') - continue; - else if (strcmp(buffer, "COMMIT\n") == 0) { - /* Enable restore mode */ - restore = 1; - break; - } - - /* -N, -A or -B */ - ptr = strtok(buffer, " \t\n"); - DP("ptr: %s", ptr); - if (ptr == NULL - || ptr[0] != '-' - || !(ptr[1] == 'N' - || ptr[1] == 'A' - || ptr[1] == 'B') - || ptr[2] != '\0') { - exit_error(PARAMETER_PROBLEM, - "Line %u does not start as a valid restore command\n", - line); - } - cmd = ptr[1]; - /* setname */ - ptr = strtok(NULL, " \t\n"); - DP("setname: %s", ptr); - if (ptr == NULL) - exit_error(PARAMETER_PROBLEM, - "Missing set name in line %u\n", - line); - DP("cmd %c", cmd); - switch (cmd) { - case 'N': { - name = check_set_name(ptr); - /* settype */ - ptr = strtok(NULL, " \t\n"); - if (ptr == NULL) - exit_error(PARAMETER_PROBLEM, - "Missing settype in line %u\n", - line); - if (bindings) - exit_error(PARAMETER_PROBLEM, - "Invalid line %u: create must precede bindings\n", - line); - settype = check_set_typename(ptr); - restore_size += sizeof(struct ip_set_restore) - + settype->create_size; - DP("restore_size (N): %u", restore_size); - break; - } - case 'A': { - if (name == NULL - || strncmp(name, ptr, sizeof(name)) != 0) - exit_error(PARAMETER_PROBLEM, - "Add IP to set %s in line %u without " - "preceding corresponding create set line\n", - ptr, line); - if (bindings) - exit_error(PARAMETER_PROBLEM, - "Invalid line %u: adding entries must precede bindings\n", - line); - restore_size += settype->adt_size; - DP("restore_size (A): %u", restore_size); - break; - } - case 'B': { - bindings = 1; - restore_size += sizeof(struct ip_set_hash_save); - DP("restore_size (B): %u", restore_size); - break; - } - default: { - exit_error(PARAMETER_PROBLEM, - "Unrecognized restore command in line %u\n", - line); - } - } /* end of switch */ - } - /* Sanity checking */ - if (!restore) - exit_error(PARAMETER_PROBLEM, - "Missing COMMIT line\n"); - DP("restore_size: %u", restore_size); - restore_data = ipset_malloc(restore_size); - header = (struct ip_set_req_setnames *) restore_data; - header->op = IP_SET_OP_RESTORE; - header->size = restore_size; - restore_offset = sizeof(struct ip_set_req_setnames); - - /* Rewind to scan the file again */ - fseek(in, 0L, SEEK_SET); - first_pass = line; - line = 0; - - /* Initialize newargv/newargc */ - newargv[newargc++] = ipset_strdup(argv0); - - /* Second pass: build up restore request */ - while (fgets(buffer, sizeof(buffer), in)) { - line++; - - if (buffer[0] == '\n') - continue; - else if (buffer[0] == '#') - continue; - else if (strcmp(buffer, "COMMIT\n") == 0) - goto do_restore; - DP("restoring: %s", buffer); - /* Build faked argv, argc */ - build_argv(line, buffer); - for (i = 0; i < newargc; i++) - DP("argv[%u]: %s", i, newargv[i]); - - /* Parse line */ - parse_commandline(newargc, newargv); - } - exit_error(PARAMETER_PROBLEM, - "Broken restore file\n"); - do_restore: - if (bindings == 0 - && restore_size == - (restore_offset + sizeof(struct ip_set_restore))) { - /* No bindings */ - struct ip_set_restore *marker = - (struct ip_set_restore *) (restore_data + restore_offset); - - DP("restore marker"); - marker->index = IP_SET_INVALID_ID; - marker->header_size = marker->members_size = 0; - restore_offset += sizeof(struct ip_set_restore); - } - if (restore_size != restore_offset) - exit_error(PARAMETER_PROBLEM, - "Giving up, restore file is screwed up!"); - res = kernel_getfrom_handleerrno(CMD_RESTORE, restore_data, &restore_size); - - if (res != 0) { - if (restore_size != sizeof(struct ip_set_req_setnames)) - exit_error(PARAMETER_PROBLEM, - "Communication with kernel failed (%u %u)!", - restore_size, sizeof(struct ip_set_req_setnames)); - /* Check errors */ - header = (struct ip_set_req_setnames *) restore_data; - if (header->size != 0) - exit_error(PARAMETER_PROBLEM, - "Committing restoring failed at line %u!", - header->size); - } -} - -/* - * Send ADT_GET order to kernel for a set - */ -static struct set *set_adt_get(const char *name) -{ - struct ip_set_req_adt_get req_adt_get; - struct set *set; - size_t size; - - DP("%s", name); - - req_adt_get.op = IP_SET_OP_ADT_GET; - req_adt_get.version = IP_SET_PROTOCOL_VERSION; - strcpy(req_adt_get.set.name, name); - size = sizeof(struct ip_set_req_adt_get); - - kernel_getfrom(CMD_ADT_GET, &req_adt_get, &size); - - set = ipset_malloc(sizeof(struct set)); - strcpy(set->name, name); - set->index = req_adt_get.set.index; - set->settype = settype_load(req_adt_get.typename); - - return set; -} - -/* - * Send add/del/test order to kernel for a set - */ -static int set_adtip(struct set *set, const char *adt, - unsigned op, unsigned cmd) -{ - struct ip_set_req_adt *req_adt; - size_t size; - void *data; - int res = 0; - - DP("%s -> %s", set->name, adt); - - /* Alloc memory for the data to send */ - size = sizeof(struct ip_set_req_adt) + set->settype->adt_size ; - DP("alloc size %i", size); - data = ipset_malloc(size); - - /* Fill out the request */ - req_adt = (struct ip_set_req_adt *) data; - req_adt->op = op; - req_adt->index = set->index; - memcpy(data + sizeof(struct ip_set_req_adt), - set->settype->data, set->settype->adt_size); - - if (kernel_sendto_handleerrno(cmd, op, data, size) == -1) - switch (op) { - case IP_SET_OP_ADD_IP: - exit_error(OTHER_PROBLEM, "%s is already in set %s.", - adt, set->name); - break; - case IP_SET_OP_DEL_IP: - exit_error(OTHER_PROBLEM, "%s is not in set %s.", - adt, set->name); - break; - case IP_SET_OP_TEST_IP: - ipset_printf("%s is in set %s.", adt, set->name); - res = 0; - break; - default: - break; - } - else - switch (op) { - case IP_SET_OP_TEST_IP: - ipset_printf("%s is NOT in set %s.", adt, set->name); - res = 1; - break; - default: - break; - } - free(data); - - return res; -} - -static void set_restore_add(struct set *set, const char *adt) -{ - DP("%s %s", set->name, adt); - /* Sanity checking */ - if (restore_offset + set->settype->adt_size > restore_size) - exit_error(PARAMETER_PROBLEM, - "Giving up, restore file is screwed up!"); - - memcpy(restore_data + restore_offset, - set->settype->data, set->settype->adt_size); - restore_set->members_size += set->settype->adt_size; - restore_offset += set->settype->adt_size; -} - -/* - * Send bind/unbind/test binding order to kernel for a set - */ -static int set_bind(struct set *set, const char *adt, - const char *binding, - unsigned op, unsigned cmd) -{ - struct ip_set_req_bind *req_bind; - size_t size; - void *data; - int res = 0; - - /* set may be null: '-U :all: :all:|:default:' */ - DP("(%s, %s) -> %s", set ? set->name : IPSET_TOKEN_ALL, adt, binding); - - /* Alloc memory for the data to send */ - size = sizeof(struct ip_set_req_bind); - if (op != IP_SET_OP_UNBIND_SET && adt[0] == ':') - /* Set default binding */ - size += IP_SET_MAXNAMELEN; - else if (!(op == IP_SET_OP_UNBIND_SET && set == NULL)) - size += set->settype->adt_size; - DP("alloc size %i", size); - data = ipset_malloc(size); - - /* Fill out the request */ - req_bind = (struct ip_set_req_bind *) data; - req_bind->op = op; - req_bind->index = set ? set->index : IP_SET_INVALID_ID; - if (adt[0] == ':') { - /* ':default:' and ':all:' */ - strncpy(req_bind->binding, adt, IP_SET_MAXNAMELEN); - if (op != IP_SET_OP_UNBIND_SET && adt[0] == ':') - strncpy(data + sizeof(struct ip_set_req_bind), - binding, IP_SET_MAXNAMELEN); - } else { - strncpy(req_bind->binding, binding, IP_SET_MAXNAMELEN); - memcpy(data + sizeof(struct ip_set_req_bind), - set->settype->data, set->settype->adt_size); - } - - if (op == IP_SET_OP_TEST_BIND_SET) { - if (kernel_sendto_handleerrno(cmd, op, data, size) == -1) { - ipset_printf("%s in set %s is bound to %s.", - adt, set->name, binding); - res = 0; - } else { - ipset_printf("%s in set %s is NOT bound to %s.", - adt, set->name, binding); - res = 1; - } - } else - kernel_sendto(cmd, data, size); - free(data); - - return res; -} - -static void set_restore_bind(struct set *set, - const char *adt, - const char *binding) -{ - struct ip_set_hash_save *hash_restore; - - if (restore == 1) { - /* Marker */ - struct ip_set_restore *marker = - (struct ip_set_restore *) (restore_data + restore_offset); - - DP("restore marker"); - if (restore_offset + sizeof(struct ip_set_restore) - > restore_size) - exit_error(PARAMETER_PROBLEM, - "Giving up, restore file is screwed up!"); - marker->index = IP_SET_INVALID_ID; - marker->header_size = marker->members_size = 0; - restore_offset += sizeof(struct ip_set_restore); - restore = 2; - } - /* Sanity checking */ - if (restore_offset + sizeof(struct ip_set_hash_save) > restore_size) - exit_error(PARAMETER_PROBLEM, - "Giving up, restore file is screwed up!"); - - hash_restore = (struct ip_set_hash_save *) (restore_data + restore_offset); - DP("%s -> %s", adt, binding); - if (strcmp(adt, IPSET_TOKEN_DEFAULT) == 0) - hash_restore->ip = 0; - else - 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", - hash_restore->id, hash_restore->ip, hash_restore->binding); - restore_offset += sizeof(struct ip_set_hash_save); -} - -/* - * Print operation - */ - -static void print_bindings(struct set *set, - void *data, size_t size, unsigned options, - char * (*printip)(struct set *set, - ip_set_ip_t ip, unsigned options)) -{ - size_t offset = 0; - struct ip_set_hash_list *hash; - - while (offset < size) { - hash = (struct ip_set_hash_list *) (data + offset); - printf("%s -> %s\n", - printip(set, hash->ip, options), - set_list[hash->binding]->name); - offset += sizeof(struct ip_set_hash_list); - } -} - -/* 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 set *set = set_list[setlist->index]; - struct settype *settype = set->settype; - size_t offset; - - /* Pretty print the set */ - printf("Name: %s\n", set->name); - printf("Type: %s\n", settype->typename); - printf("References: %d\n", setlist->ref); - printf("Default binding: %s\n", - setlist->binding == IP_SET_INVALID_ID ? "" - : set_list[setlist->binding]->name); - - /* Init header */ - offset = sizeof(struct ip_set_list); - settype->initheader(set, data + offset); - - /* Pretty print the type header */ - printf("Header:"); - settype->printheader(set, options); - - /* Pretty print all IPs */ - printf("Members:\n"); - offset += setlist->header_size; - if (options & OPT_SORTED) - settype->printips_sorted(set, data + offset, - setlist->members_size, options); - else - settype->printips(set, data + offset, - setlist->members_size, options); - - /* Print bindings */ - printf("Bindings:\n"); - offset += setlist->members_size; - print_bindings(set, - data + offset, setlist->bindings_size, options, - settype->bindip_tostring); - - printf("\n"); /* One newline between sets */ - - return (offset + setlist->bindings_size); -} - -static int try_list_sets(const char name[IP_SET_MAXNAMELEN], - unsigned options) -{ - void *data = NULL; - ip_set_id_t index; - size_t size, req_size; - int res = 0; - - DP("%s", name); - /* Load set_list from kernel */ - size = req_size = load_set_list(name, &index, - IP_SET_OP_LIST_SIZE, CMD_LIST); - - if (size) { - /* Get sets and print them */ - data = ipset_malloc(size); - ((struct ip_set_req_list *) data)->op = IP_SET_OP_LIST; - ((struct ip_set_req_list *) data)->index = index; - res = kernel_getfrom_handleerrno(CMD_LIST, data, &size); - DP("get_lists getsockopt() res=%d errno=%d", res, errno); - - if (res != 0 || size != req_size) { - free(data); - return -EAGAIN; - } - size = 0; - } - while (size != req_size) - size += print_set(data + size, options); - - ipset_free(&data); - return res; -} - -/* Print a set or all sets - * All sets: name = NULL - */ -static void list_sets(const char name[IP_SET_MAXNAMELEN], unsigned options) -{ - int i; - - DP("%s", name); - for (i = 0; i < LIST_TRIES; i++) - if (try_list_sets(name, options) == 0) - return; - - if (errno == EAGAIN) - exit_error(OTHER_PROBLEM, - "Tried to list sets from kernel %d times" - " and failed. Please try again when the load on" - " the sets has gone down.", LIST_TRIES); - else - kernel_error(CMD_LIST, errno); -} - -/* Prints help - * If settype is non null help for that type is printed as well - */ -static void set_help(const struct settype *settype) -{ -#ifdef IPSET_DEBUG - char debughelp[] = - " --debug -z Enable debugging\n\n"; -#else - char debughelp[] = "\n"; -#endif - - printf("%s v%s\n\n" - "Usage: %s -N new-set settype [options]\n" - " %s -[XFLSH] [set] [options]\n" - " %s -[EW] from-set to-set\n" - " %s -[ADTU] set IP\n" - " %s -B set IP option\n" - " %s -R\n" - " %s -h (print this help information)\n\n", - program_name, program_version, - program_name, program_name, program_name, - program_name, program_name, program_name, - program_name); - - printf("Commands:\n" - "Either long or short options are allowed.\n" - " --create -N setname settype \n" - " Create a new set\n" - " --destroy -X [setname]\n" - " Destroy a set or all sets\n" - " --flush -F [setname]\n" - " Flush a set or all sets\n" - " --rename -E from-set to-set\n" - " Rename from-set to to-set\n" - " --swap -W from-set to-set\n" - " Swap the content of two existing sets\n" - " --list -L [setname] [options]\n" - " List the IPs in a set or all sets\n" - " --save -S [setname]\n" - " Save the set or all sets to stdout\n" - " --restore -R [option]\n" - " Restores a saved state\n" - " --add -A setname IP\n" - " Add an IP to a set\n" - " --del -D setname IP\n" - " Deletes an IP from a set\n" - " --test -T setname IP \n" - " Tests if an IP exists in a set.\n" - " --bind -B setname IP|:default: -b bind-setname\n" - " Bind the IP in setname to bind-setname.\n" - " --unbind -U setname IP|:all:|:default:\n" - " Delete binding belonging to IP,\n" - " all bindings or default binding of setname.\n" - " --unbind -U :all: :all:|:default:\n" - " Delete all bindings or all default bindings.\n" - " --help -H [settype]\n" - " Prints this help, and settype specific help\n" - " --version -V\n" - " 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" - " --quiet -q Suppress any output to stdout and stderr.\n" - " --binding -b Specifies the binding for -B\n"); - printf(debughelp); - - if (settype != NULL) { - printf("Type '%s' specific:\n", settype->typename); - settype->usage(); - } -} - -static int find_cmd(const char option) -{ - int i; - - for (i = 1; i <= NUMBER_OF_CMD; i++) - if (cmdflags[i] == option) - return i; - - return CMD_NONE; -} - -static int parse_adt_cmdline(unsigned command, - const char *name, - char *adt, - struct set **set, - struct settype **settype) -{ - int res = 0; - - /* -U :all: :all:|:default: */ - if (command == CMD_UNBIND) { - if (strcmp(name, IPSET_TOKEN_ALL) == 0) { - if (strcmp(adt, IPSET_TOKEN_DEFAULT) == 0 - || strcmp(adt, IPSET_TOKEN_ALL) == 0) { - *set = NULL; - *settype = NULL; - return 1; - } else - exit_error(PARAMETER_PROBLEM, - "-U %s requires %s or %s as binding name", - IPSET_TOKEN_ALL, - IPSET_TOKEN_DEFAULT, - IPSET_TOKEN_ALL); - } - } - *set = restore ? set_find_byname(name) - : set_adt_get(name); - - /* Reset space for adt data */ - *settype = (*set)->settype; - memset((*settype)->data, 0, (*settype)->adt_size); - - if ((command == CMD_TEST - || command == CMD_BIND - || command == CMD_UNBIND) - && (strcmp(adt, IPSET_TOKEN_DEFAULT) == 0 - || strcmp(adt, IPSET_TOKEN_ALL) == 0)) - res = 1; - else - res = (*settype)->adt_parser( - command, - adt, - (*settype)->data); - - return res; -} - -/* Main worker function */ -int parse_commandline(int argc, char *argv[]) -{ - int res = 0; - unsigned command = CMD_NONE; - unsigned options = 0; - int c; - - char *name = NULL; /* All except -H, -R */ - char *newname = NULL; /* -E, -W */ - char *adt = NULL; /* -A, -D, -T, -B, -U */ - char *binding = NULL; /* -B */ - struct set *set = NULL; /* -A, -D, -T, -B, -U */ - struct settype *settype = NULL; /* -N, -H */ - char all_sets[] = IPSET_TOKEN_ALL; - - struct option *opts = opts_long; - - /* Suppress error messages: we may add new options if we - demand-load a protocol. */ - opterr = 0; - /* Reset optind to 0 for restore */ - optind = 0; - - while ((c = getopt_long(argc, argv, opts_short, opts, NULL)) != -1) { - - DP("commandline parsed: opt %c (%s)", c, argv[optind]); - - switch (c) { - /* - * Command selection - */ - case 'h': - case 'H':{ /* Help: -H [typename [options]] */ - check_protocolversion(); - set_command(&command, CMD_HELP); - - if (optarg) - settype = check_set_typename(optarg); - else if (optind < argc - && argv[optind][0] != '-') - settype = check_set_typename(argv[optind++]); - - break; - } - - case 'V':{ /* Version */ - printf("%s v%s Protocol version %u.\n", - program_name, program_version, - IP_SET_PROTOCOL_VERSION); - check_protocolversion(); - exit(0); - } - - case 'N':{ /* Create: -N name typename options */ - set_command(&command, CMD_CREATE); - - name = check_set_name(optarg); - - /* Protect reserved names (binding) */ - if (name[0] == ':') - exit_error(PARAMETER_PROBLEM, - "setname might not start with colon", - cmd2char(CMD_CREATE)); - - if (optind < argc - && argv[optind][0] != '-') - settype = check_set_typename(argv[optind++]); - else - exit_error(PARAMETER_PROBLEM, - "-%c requires setname and settype", - cmd2char(CMD_CREATE)); - - DP("merge options"); - /* Merge the create options */ - opts = merge_options(opts, - settype->create_opts, - &settype->option_offset); - - /* Reset space for create data */ - memset(settype->data, 0, settype->create_size); - - /* Zero the flags */ - settype->flags = 0; - - DP("call create_init"); - /* Call the settype create_init */ - settype->create_init(settype->data); - - break; - } - - case 'X': /* Destroy */ - case 'F': /* Flush */ - case 'L': /* List */ - case 'S':{ /* Save */ - set_command(&command, find_cmd(c)); - - if (optarg) - name = check_set_name(optarg); - else if (optind < argc - && argv[optind][0] != '-') - name = check_set_name(argv[optind++]); - else - name = all_sets; - - break; - } - - case 'R':{ /* Restore */ - set_command(&command, find_cmd(c)); - - break; - } - - case 'E': /* Rename */ - case 'W':{ /* Swap */ - set_command(&command, find_cmd(c)); - name = check_set_name(optarg); - - if (optind < argc - && argv[optind][0] != '-') - newname = check_set_name(argv[optind++]); - else - exit_error(PARAMETER_PROBLEM, - "-%c requires a setname " - "and the new name for that set", - cmd2char(CMD_RENAME)); - - break; - } - - case 'A': /* Add IP */ - case 'D': /* Del IP */ - case 'T': /* Test IP */ - case 'B': /* Bind IP */ - case 'U':{ /* Unbind IP */ - set_command(&command, find_cmd(c)); - - name = check_set_name(optarg); - - /* IP */ - if (optind < argc - && argv[optind][0] != '-') - adt = argv[optind++]; - else - exit_error(PARAMETER_PROBLEM, - "-%c requires setname and IP", - c); - - res = parse_adt_cmdline(command, name, adt, - &set, &settype); - - if (!res) - exit_error(PARAMETER_PROBLEM, - "Unknown arg `%s'", - argv[optind - 1]); - - break; - } - - /* options */ - - case 'n': - add_option(&options, OPT_NUMERIC); - break; - - case 's': - add_option(&options, OPT_SORTED); - break; - - case 'q': - add_option(&options, OPT_QUIET); - option_quiet = 1; - break; - -#ifdef IPSET_DEBUG - case 'z': /* debug */ - add_option(&options, OPT_DEBUG); - option_debug = 1; - break; -#endif - - case 'b': - add_option(&options, OPT_BINDING); - binding = check_set_name(optarg); - break; - - case 1: /* non option */ - printf("Bad argument `%s'\n", optarg); - exit_tryhelp(2); - break; /*always good */ - - default:{ - DP("default"); - - switch (command) { - case CMD_CREATE: - res = settype->create_parse( - c - settype->option_offset, - argv, - settype->data, - &settype->flags); - break; - - default: - res = 0; /* failed */ - } /* switch (command) */ - - - if (!res) - exit_error(PARAMETER_PROBLEM, - "Unknown arg `%s'", - argv[optind - 1]); - - } - - DP("next arg"); - } /* switch */ - - } /* while( getopt_long() ) */ - - - if (optind < argc) - exit_error(PARAMETER_PROBLEM, - "unknown arguments found on commandline"); - if (command == CMD_NONE) - exit_error(PARAMETER_PROBLEM, "no command specified"); - - /* Check options */ - generic_opt_check(command, options); - - DP("cmd: %c", cmd2char(command)); - - switch (command) { - case CMD_CREATE: - DP("CMD_CREATE"); - if (restore) - set_restore_create(name, settype); - else - set_create(name, settype); - break; - - case CMD_DESTROY: - set_destroy(name, IP_SET_OP_DESTROY, CMD_DESTROY); - break; - - case CMD_FLUSH: - set_destroy(name, IP_SET_OP_FLUSH, CMD_FLUSH); - break; - - case CMD_RENAME: - set_rename(name, newname, IP_SET_OP_RENAME, CMD_RENAME); - break; - - case CMD_SWAP: - set_rename(name, newname, IP_SET_OP_SWAP, CMD_SWAP); - break; - - case CMD_LIST: - list_sets(name, options); - break; - - case CMD_SAVE: - set_save(name); - break; - - case CMD_RESTORE: - set_restore(argv[0]); - break; - - case CMD_ADD: - if (restore) - set_restore_add(set, adt); - else - set_adtip(set, adt, IP_SET_OP_ADD_IP, CMD_ADD); - break; - - case CMD_DEL: - set_adtip(set, adt, IP_SET_OP_DEL_IP, CMD_DEL); - break; - - case CMD_TEST: - if (binding) - res = set_bind(set, adt, binding, - IP_SET_OP_TEST_BIND_SET, CMD_TEST); - else - res = set_adtip(set, adt, - IP_SET_OP_TEST_IP, CMD_TEST); - break; - - case CMD_BIND: - if (restore) - set_restore_bind(set, adt, binding); - else - set_bind(set, adt, binding, - IP_SET_OP_BIND_SET, CMD_BIND); - break; - - case CMD_UNBIND: - set_bind(set, adt, "", IP_SET_OP_UNBIND_SET, CMD_UNBIND); - break; - - case CMD_HELP: - set_help(settype); - break; - - default: - /* Will never happen */ - break; /* Keep the compiler happy */ - - } /* switch( command ) */ - - return res; -} - - -int main(int argc, char *argv[]) -{ - return parse_commandline(argc, argv); - -} diff --git a/ipset/ipset.h b/ipset/ipset.h deleted file mode 100644 index 50a3476..0000000 --- a/ipset/ipset.h +++ /dev/null @@ -1,187 +0,0 @@ -#ifndef __IPSET_H -#define __IPSET_H - -/* Copyright 2000-2004 Joakim Axelsson (gozem@linux.nu) - * Patrick Schaaf (bof@bof.de) - * Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * 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 -#include -#include - -#include - -#define IPSET_LIB_NAME "/libipset_%s.so" -#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe" - -#define LIST_TRIES 5 - -#ifdef IPSET_DEBUG -extern int option_debug; -#define DP(format, args...) if (option_debug) \ - do { \ - fprintf(stderr, "%s: %s (DBG): ", __FILE__, __FUNCTION__);\ - fprintf(stderr, format "\n" , ## args); \ - } while (0) -#else -#define DP(format, args...) -#endif - -/* Commands */ -enum set_commands { - CMD_NONE, - CMD_CREATE, /* -N */ - CMD_DESTROY, /* -X */ - CMD_FLUSH, /* -F */ - CMD_RENAME, /* -E */ - CMD_SWAP, /* -W */ - CMD_LIST, /* -L */ - CMD_SAVE, /* -S */ - CMD_RESTORE, /* -R */ - CMD_ADD, /* -A */ - CMD_DEL, /* -D */ - CMD_TEST, /* -T */ - CMD_BIND, /* -B */ - CMD_UNBIND, /* -U */ - CMD_HELP, /* -H */ - CMD_VERSION, /* -V */ - NUMBER_OF_CMD = CMD_VERSION, - /* Internal commands */ - CMD_MAX_SETS, - CMD_LIST_SIZE, - CMD_SAVE_SIZE, - CMD_ADT_GET, -}; - -enum exittype { - OTHER_PROBLEM = 1, - PARAMETER_PROBLEM, - VERSION_PROBLEM -}; - -/* The view of an ipset in userspace */ -struct set { - char name[IP_SET_MAXNAMELEN]; /* Name of the set */ - ip_set_id_t id; /* Unique set id */ - ip_set_id_t index; /* Array index */ - unsigned ref; /* References in kernel */ - struct settype *settype; /* Pointer to set type functions */ -}; - -struct settype { - struct settype *next; - - char typename[IP_SET_MAXNAMELEN]; - - int protocol_version; - - /* - * Create set - */ - - /* Size of create data. Will be sent to kernel */ - size_t create_size; - - /* Initialize the create. */ - void (*create_init) (void *data); - - /* Function which parses command options; returns true if it ate an option */ - int (*create_parse) (int c, char *argv[], void *data, - unsigned *flags); - - /* Final check; exit if not ok. */ - void (*create_final) (void *data, unsigned int flags); - - /* Pointer to list of extra command-line options for create */ - struct option *create_opts; - - /* - * Add/del/test IP - */ - - /* Size of data. Will be sent to kernel */ - size_t adt_size; - - /* Function which parses command options */ - ip_set_ip_t (*adt_parser) (unsigned cmd, const char *optarg, void *data); - - /* - * Printing - */ - - /* Size of header. */ - size_t header_size; - - /* Initialize the type-header */ - void (*initheader) (struct set *set, const void *data); - - /* Pretty print the type-header */ - void (*printheader) (struct set *set, unsigned options); - - /* Pretty print all IPs */ - void (*printips) (struct set *set, void *data, size_t len, unsigned options); - - /* Pretty print all IPs sorted */ - void (*printips_sorted) (struct set *set, void *data, size_t len, unsigned options); - - /* Print save arguments for creating the set */ - void (*saveheader) (struct set *set, unsigned options); - - /* Print save for all IPs */ - void (*saveips) (struct set *set, void *data, size_t len, unsigned options); - - /* Conver a single IP (binding) to string */ - char * (*bindip_tostring)(struct set *set, ip_set_ip_t ip, unsigned options); - - /* Parse an IP at restoring bindings. FIXME */ - void (*bindip_parse) (const char *str, ip_set_ip_t * ip); - - /* Print usage */ - void (*usage) (void); - - /* Internal data */ - void *header; - void *data; - unsigned int option_offset; - unsigned int flags; -}; - -extern void settype_register(struct settype *settype); - -/* extern void unregister_settype(set_type_t *set_type); */ - -extern void exit_error(enum exittype status, char *msg, ...); - -extern char *binding_ip_tostring(struct set *set, - ip_set_ip_t ip, unsigned options); -extern char *ip_tostring(ip_set_ip_t ip, unsigned options); -extern char *ip_tostring_numeric(ip_set_ip_t ip); -extern void parse_ip(const char *str, ip_set_ip_t * ip); -extern void parse_mask(const char *str, ip_set_ip_t * mask); -extern void parse_ipandmask(const char *str, ip_set_ip_t * ip, - ip_set_ip_t * mask); -extern char *port_tostring(ip_set_ip_t port, unsigned options); -extern void parse_port(const char *str, ip_set_ip_t * port); -extern int string_to_number(const char *str, unsigned int min, unsigned int max, - ip_set_ip_t *port); - -extern void *ipset_malloc(size_t size); -extern char *ipset_strdup(const char *); -extern void ipset_free(void **data); - -#endif /* __IPSET_H */ diff --git a/ipset/ipset_iphash.c b/ipset/ipset_iphash.c deleted file mode 100644 index 3272e6e..0000000 --- a/ipset/ipset_iphash.c +++ /dev/null @@ -1,297 +0,0 @@ -/* Copyright 2004 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "ipset.h" - -#define BUFLEN 30; - -#define OPT_CREATE_HASHSIZE 0x01U -#define OPT_CREATE_PROBES 0x02U -#define OPT_CREATE_RESIZE 0x04U -#define OPT_CREATE_NETMASK 0x08U - -/* Initialize the create. */ -void create_init(void *data) -{ - struct ip_set_req_iphash_create *mydata = - (struct ip_set_req_iphash_create *) data; - - DP("create INIT"); - - /* Default create parameters */ - mydata->hashsize = 1024; - mydata->probes = 8; - mydata->resize = 50; - - mydata->netmask = 0xFFFFFFFF; -} - -/* Function which parses command options; returns true if it ate an option */ -int create_parse(int c, char *argv[], void *data, unsigned *flags) -{ - struct ip_set_req_iphash_create *mydata = - (struct ip_set_req_iphash_create *) data; - unsigned int bits; - ip_set_ip_t value; - - DP("create_parse"); - - switch (c) { - case '1': - - if (string_to_number(optarg, 1, UINT_MAX - 1, &mydata->hashsize)) - exit_error(PARAMETER_PROBLEM, "Invalid hashsize `%s' specified", optarg); - - *flags |= OPT_CREATE_HASHSIZE; - - DP("--hashsize %u", mydata->hashsize); - - break; - - case '2': - - if (string_to_number(optarg, 1, 65535, &value)) - exit_error(PARAMETER_PROBLEM, "Invalid probes `%s' specified", optarg); - - mydata->probes = value; - *flags |= OPT_CREATE_PROBES; - - DP("--probes %u", mydata->probes); - - break; - - case '3': - - if (string_to_number(optarg, 0, 65535, &value)) - exit_error(PARAMETER_PROBLEM, "Invalid resize `%s' specified", optarg); - - mydata->resize = value; - *flags |= OPT_CREATE_RESIZE; - - DP("--resize %u", mydata->resize); - - break; - - case '4': - - if (string_to_number(optarg, 0, 32, &bits)) - exit_error(PARAMETER_PROBLEM, - "Invalid netmask `%s' specified", optarg); - - if (bits != 0) - mydata->netmask = 0xFFFFFFFF << (32 - bits); - - *flags |= OPT_CREATE_NETMASK; - - DP("--netmask %x", mydata->netmask); - - break; - - default: - return 0; - } - - return 1; -} - -/* Final check; exit if not ok. */ -void create_final(void *data, unsigned int flags) -{ -#ifdef IPSET_DEBUG - struct ip_set_req_iphash_create *mydata = - (struct ip_set_req_iphash_create *) data; - - DP("hashsize %u probes %u resize %u", - mydata->hashsize, mydata->probes, mydata->resize); -#endif -} - -/* Create commandline options */ -static struct option create_opts[] = { - {"hashsize", 1, 0, '1'}, - {"probes", 1, 0, '2'}, - {"resize", 1, 0, '3'}, - {"netmask", 1, 0, '4'}, - {0} -}; - -/* Add, del, test parser */ -ip_set_ip_t adt_parser(unsigned cmd, const char *optarg, void *data) -{ - struct ip_set_req_iphash *mydata = - (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; -}; - -/* - * Print and save - */ - -void initheader(struct set *set, const void *data) -{ - struct ip_set_req_iphash_create *header = - (struct ip_set_req_iphash_create *) data; - struct ip_set_iphash *map = - (struct ip_set_iphash *) set->settype->header; - - memset(map, 0, sizeof(struct ip_set_iphash)); - map->hashsize = header->hashsize; - map->probes = header->probes; - map->resize = header->resize; - map->netmask = header->netmask; -} - -unsigned int -mask_to_bits(ip_set_ip_t mask) -{ - unsigned int bits = 32; - ip_set_ip_t maskaddr; - - if (mask == 0xFFFFFFFF) - return bits; - - maskaddr = 0xFFFFFFFE; - while (--bits >= 0 && maskaddr != mask) - maskaddr <<= 1; - - return bits; -} - -void printheader(struct set *set, unsigned options) -{ - struct ip_set_iphash *mysetdata = - (struct ip_set_iphash *) set->settype->header; - - printf(" hashsize: %u", mysetdata->hashsize); - printf(" probes: %u", mysetdata->probes); - printf(" resize: %u", mysetdata->resize); - if (mysetdata->netmask == 0xFFFFFFFF) - printf("\n"); - else - printf(" netmask: %d\n", mask_to_bits(mysetdata->netmask)); -} - -void printips(struct set *set, void *data, size_t len, unsigned options) -{ - size_t offset = 0; - ip_set_ip_t *ip; - - while (offset < len) { - ip = data + offset; - if (*ip) - printf("%s\n", ip_tostring(*ip, options)); - offset += sizeof(ip_set_ip_t); - } -} - -void saveheader(struct set *set, unsigned options) -{ - struct ip_set_iphash *mysetdata = - (struct ip_set_iphash *) set->settype->header; - - printf("-N %s %s --hashsize %u --probes %u --resize %u", - set->name, set->settype->typename, - mysetdata->hashsize, mysetdata->probes, mysetdata->resize); - if (mysetdata->netmask == 0xFFFFFFFF) - printf("\n"); - else - printf(" --netmask %d\n", mask_to_bits(mysetdata->netmask)); -} - -/* Print save for an IP */ -void saveips(struct set *set, void *data, size_t len, unsigned options) -{ - size_t offset = 0; - ip_set_ip_t *ip; - - while (offset < len) { - ip = data + offset; - if (*ip) - printf("-A %s %s\n", set->name, - ip_tostring(*ip, options)); - offset += sizeof(ip_set_ip_t); - } -} - -void usage(void) -{ - printf - ("-N set iphash [--hashsize hashsize] [--probes probes ]\n" - " [--resize resize] [--netmask CIDR-netmask]\n" - "-A set IP\n" - "-D set IP\n" - "-T set IP\n"); -} - -static struct settype settype_iphash = { - .typename = SETTYPE_NAME, - .protocol_version = IP_SET_PROTOCOL_VERSION, - - /* Create */ - .create_size = sizeof(struct ip_set_req_iphash_create), - .create_init = &create_init, - .create_parse = &create_parse, - .create_final = &create_final, - .create_opts = create_opts, - - /* Add/del/test */ - .adt_size = sizeof(struct ip_set_req_iphash), - .adt_parser = &adt_parser, - - /* Printing */ - .header_size = sizeof(struct ip_set_iphash), - .initheader = &initheader, - .printheader = &printheader, - .printips = &printips, /* We only have the unsorted version */ - .printips_sorted = &printips, - .saveheader = &saveheader, - .saveips = &saveips, - - /* Bindings */ - .bindip_tostring = &binding_ip_tostring, - .bindip_parse = &parse_ip, - - .usage = &usage, -}; - -void _init(void) -{ - settype_register(&settype_iphash); - -} diff --git a/ipset/ipset_ipmap.c b/ipset/ipset_ipmap.c deleted file mode 100644 index 2d1c81c..0000000 --- a/ipset/ipset_ipmap.c +++ /dev/null @@ -1,360 +0,0 @@ -/* Copyright 2000-2004 Joakim Axelsson (gozem@linux.nu) - * Patrick Schaaf (bof@bof.de) - * Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * 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 -#include -#include -#include -#include -#include - -#include -#include "ipset.h" - -#define BUFLEN 30; - -#define OPT_CREATE_FROM 0x01U -#define OPT_CREATE_TO 0x02U -#define OPT_CREATE_NETWORK 0x04U -#define OPT_CREATE_NETMASK 0x08U - -#define OPT_ADDDEL_IP 0x01U - -/* Initialize the create. */ -void create_init(void *data) -{ - struct ip_set_req_ipmap_create *mydata = - (struct ip_set_req_ipmap_create *) data; - - DP("create INIT"); - mydata->netmask = 0xFFFFFFFF; -} - -/* Function which parses command options; returns true if it ate an option */ -int create_parse(int c, char *argv[], void *data, unsigned *flags) -{ - struct ip_set_req_ipmap_create *mydata = - (struct ip_set_req_ipmap_create *) data; - unsigned int bits; - - DP("create_parse"); - - switch (c) { - case '1': - parse_ip(optarg, &mydata->from); - - *flags |= OPT_CREATE_FROM; - - DP("--from %x (%s)", mydata->from, - ip_tostring_numeric(mydata->from)); - - break; - - case '2': - parse_ip(optarg, &mydata->to); - - *flags |= OPT_CREATE_TO; - - DP("--to %x (%s)", mydata->to, - ip_tostring_numeric(mydata->to)); - - break; - - case '3': - parse_ipandmask(optarg, &mydata->from, &mydata->to); - - /* Make to the last of from + mask */ - 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)); - - break; - - case '4': - if (string_to_number(optarg, 0, 32, &bits)) - exit_error(PARAMETER_PROBLEM, - "Invalid netmask `%s' specified", optarg); - - if (bits != 0) - mydata->netmask = 0xFFFFFFFF << (32 - bits); - - *flags |= OPT_CREATE_NETMASK; - - DP("--netmask %x", mydata->netmask); - - break; - - default: - return 0; - } - - 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, - "Need to specify --from and --to, or --network\n"); - - if (flags & OPT_CREATE_NETWORK) { - /* --network */ - if ((flags & OPT_CREATE_FROM) || (flags & OPT_CREATE_TO)) - exit_error(PARAMETER_PROBLEM, - "Can't specify --from or --to with --network\n"); - } else { - /* --from --to */ - if ((flags & OPT_CREATE_FROM) == 0 - || (flags & OPT_CREATE_TO) == 0) - exit_error(PARAMETER_PROBLEM, - "Need to specify both --from and --to\n"); - } - - 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"); - - if (flags & OPT_CREATE_NETMASK) { - unsigned int mask_bits, netmask_bits; - ip_set_ip_t mask; - - if ((mydata->from & mydata->netmask) != mydata->from) - exit_error(PARAMETER_PROBLEM, - "%s is not a network address according to netmask %d\n", - ip_tostring_numeric(mydata->from), - mask_to_bits(mydata->netmask)); - - mask = range_to_mask(mydata->from, mydata->to, &mask_bits); - 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 (%x)\n", - errstr, - ip_tostring_numeric(mydata->to), mask); - } - netmask_bits = mask_to_bits(mydata->netmask); - - 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 (%d)\n", - netmask_bits, - 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 */ -static struct option create_opts[] = { - {"from", 1, 0, '1'}, - {"to", 1, 0, '2'}, - {"network", 1, 0, '3'}, - {"netmask", 1, 0, '4'}, - {0} -}; - -/* Add, del, test parser */ -ip_set_ip_t adt_parser(unsigned cmd, const char *optarg, void *data) -{ - struct ip_set_req_ipmap *mydata = - (struct ip_set_req_ipmap *) data; - - DP("ipmap: %p %p", optarg, data); - - parse_ip(optarg, &mydata->ip); - DP("%s", ip_tostring_numeric(mydata->ip)); - - return 1; -} - -/* - * Print and save - */ - -void initheader(struct set *set, const void *data) -{ - struct ip_set_req_ipmap_create *header = - (struct ip_set_req_ipmap_create *) data; - struct ip_set_ipmap *map = - (struct ip_set_ipmap *) set->settype->header; - - memset(map, 0, sizeof(struct ip_set_ipmap)); - map->first_ip = header->from; - map->last_ip = header->to; - map->netmask = header->netmask; - - if (map->netmask == 0xFFFFFFFF) { - map->hosts = 1; - map->sizeid = map->last_ip - map->first_ip + 1; - } else { - unsigned int mask_bits, netmask_bits; - ip_set_ip_t mask; - - mask = range_to_mask(header->from, header->to, &mask_bits); - netmask_bits = mask_to_bits(header->netmask); - - DP("bits: %i %i", mask_bits, netmask_bits); - map->hosts = 2 << (32 - netmask_bits - 1); - map->sizeid = 2 << (netmask_bits - mask_bits - 1); - } - - DP("%i %i", map->hosts, map->sizeid ); -} - -void printheader(struct set *set, unsigned options) -{ - struct ip_set_ipmap *mysetdata = - (struct ip_set_ipmap *) set->settype->header; - - printf(" from: %s", ip_tostring(mysetdata->first_ip, options)); - printf(" to: %s", ip_tostring(mysetdata->last_ip, options)); - if (mysetdata->netmask == 0xFFFFFFFF) - printf("\n"); - else - printf(" netmask: %d\n", mask_to_bits(mysetdata->netmask)); -} - -void printips_sorted(struct set *set, void *data, size_t len, unsigned options) -{ - struct ip_set_ipmap *mysetdata = - (struct ip_set_ipmap *) set->settype->header; - ip_set_ip_t id; - - for (id = 0; id < mysetdata->sizeid; id++) - if (test_bit(id, data)) - printf("%s\n", - ip_tostring(mysetdata->first_ip - + id * mysetdata->hosts, - options)); -} - -void saveheader(struct set *set, unsigned options) -{ - struct ip_set_ipmap *mysetdata = - (struct ip_set_ipmap *) set->settype->header; - - printf("-N %s %s --from %s", - set->name, set->settype->typename, - ip_tostring(mysetdata->first_ip, options)); - printf(" --to %s", - ip_tostring(mysetdata->last_ip, options)); - if (mysetdata->netmask == 0xFFFFFFFF) - printf("\n"); - else - printf(" --netmask %d\n", - mask_to_bits(mysetdata->netmask)); -} - -void saveips(struct set *set, void *data, size_t len, unsigned options) -{ - struct ip_set_ipmap *mysetdata = - (struct ip_set_ipmap *) set->settype->header; - ip_set_ip_t id; - - DP("%s", set->name); - for (id = 0; id < mysetdata->sizeid; id++) - if (test_bit(id, data)) - printf("-A %s %s\n", - set->name, - ip_tostring(mysetdata->first_ip - + id * mysetdata->hosts, - options)); -} - -void usage(void) -{ - printf - ("-N set ipmap --from IP --to IP [--netmask CIDR-netmask]\n" - "-N set ipmap --network IP/mask [--netmask CIDR-netmask]\n" - "-A set IP\n" - "-D set IP\n" - "-T set IP\n"); -} - -static struct settype settype_ipmap = { - .typename = SETTYPE_NAME, - .protocol_version = IP_SET_PROTOCOL_VERSION, - - /* Create */ - .create_size = sizeof(struct ip_set_req_ipmap_create), - .create_init = &create_init, - .create_parse = &create_parse, - .create_final = &create_final, - .create_opts = create_opts, - - /* Add/del/test */ - .adt_size = sizeof(struct ip_set_req_ipmap), - .adt_parser = &adt_parser, - - /* Printing */ - .header_size = sizeof(struct ip_set_ipmap), - .initheader = &initheader, - .printheader = &printheader, - .printips = &printips_sorted, /* We only have sorted version */ - .printips_sorted = &printips_sorted, - .saveheader = &saveheader, - .saveips = &saveips, - - /* Bindings */ - .bindip_tostring = &binding_ip_tostring, - .bindip_parse = &parse_ip, - - .usage = &usage, -}; - -void _init(void) -{ - settype_register(&settype_ipmap); - -} diff --git a/ipset/ipset_ipporthash.c b/ipset/ipset_ipporthash.c deleted file mode 100644 index 1ebbc50..0000000 --- a/ipset/ipset_ipporthash.c +++ /dev/null @@ -1,373 +0,0 @@ -/* Copyright 2004 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "ipset.h" - -#define OPT_CREATE_HASHSIZE 0x01U -#define OPT_CREATE_PROBES 0x02U -#define OPT_CREATE_RESIZE 0x04U -#define OPT_CREATE_NETWORK 0x08U -#define OPT_CREATE_FROM 0x10U -#define OPT_CREATE_TO 0x20U - -/* Initialize the create. */ -void create_init(void *data) -{ - struct ip_set_req_ipporthash_create *mydata = - (struct ip_set_req_ipporthash_create *) data; - - DP("create INIT"); - - /* Default create parameters */ - mydata->hashsize = 1024; - mydata->probes = 8; - mydata->resize = 50; -} - -/* Function which parses command options; returns true if it ate an option */ -int create_parse(int c, char *argv[], void *data, unsigned *flags) -{ - struct ip_set_req_ipporthash_create *mydata = - (struct ip_set_req_ipporthash_create *) data; - ip_set_ip_t value; - - DP("create_parse"); - - switch (c) { - case '1': - - if (string_to_number(optarg, 1, UINT_MAX - 1, &mydata->hashsize)) - exit_error(PARAMETER_PROBLEM, "Invalid hashsize `%s' specified", optarg); - - *flags |= OPT_CREATE_HASHSIZE; - - DP("--hashsize %u", mydata->hashsize); - - break; - - case '2': - - if (string_to_number(optarg, 1, 65535, &value)) - exit_error(PARAMETER_PROBLEM, "Invalid probes `%s' specified", optarg); - - mydata->probes = value; - *flags |= OPT_CREATE_PROBES; - - DP("--probes %u", mydata->probes); - - break; - - case '3': - - if (string_to_number(optarg, 0, 65535, &value)) - exit_error(PARAMETER_PROBLEM, "Invalid resize `%s' specified", optarg); - - mydata->resize = value; - *flags |= OPT_CREATE_RESIZE; - - DP("--resize %u", mydata->resize); - - break; - - case '4': - parse_ip(optarg, &mydata->from); - - *flags |= OPT_CREATE_FROM; - - DP("--from %x (%s)", mydata->from, - ip_tostring_numeric(mydata->from)); - - break; - - case '5': - parse_ip(optarg, &mydata->to); - - *flags |= OPT_CREATE_TO; - - DP("--to %x (%s)", mydata->to, - ip_tostring_numeric(mydata->to)); - - break; - - case '6': - parse_ipandmask(optarg, &mydata->from, &mydata->to); - - /* Make to the last of from + mask */ - 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)); - - break; - - default: - return 0; - } - - return 1; -} - -/* Final check; exit if not ok. */ -void create_final(void *data, unsigned int flags) -{ - struct ip_set_req_ipporthash_create *mydata = - (struct ip_set_req_ipporthash_create *) data; - -#ifdef IPSET_DEBUG - DP("hashsize %u probes %u resize %u", - mydata->hashsize, mydata->probes, mydata->resize); -#endif - - if (flags & OPT_CREATE_NETWORK) { - /* --network */ - if ((flags & OPT_CREATE_FROM) || (flags & OPT_CREATE_TO)) - exit_error(PARAMETER_PROBLEM, - "Can't specify --from or --to with --network\n"); - } else if (flags & (OPT_CREATE_FROM | OPT_CREATE_TO)) { - /* --from --to */ - if (!(flags & OPT_CREATE_FROM) || !(flags & OPT_CREATE_TO)) - exit_error(PARAMETER_PROBLEM, - "Need to specify both --from and --to\n"); - } else { - exit_error(PARAMETER_PROBLEM, - "Need to specify --from and --to, or --network\n"); - - } - - 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 higher 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+1); -} - -/* Create commandline options */ -static struct option create_opts[] = { - {"hashsize", 1, 0, '1'}, - {"probes", 1, 0, '2'}, - {"resize", 1, 0, '3'}, - {"from", 1, 0, '4'}, - {"to", 1, 0, '5'}, - {"network", 1, 0, '6'}, - {0} -}; - -/* Add, del, test parser */ -ip_set_ip_t adt_parser(unsigned cmd, const char *optarg, void *data) -{ - struct ip_set_req_ipporthash *mydata = - (struct ip_set_req_ipporthash *) data; - char *saved = ipset_strdup(optarg); - char *ptr, *tmp = saved; - - DP("ipporthash: %p %p", optarg, data); - - ptr = strsep(&tmp, "%"); - parse_ip(ptr, &mydata->ip); - - if (tmp) - parse_port(tmp, &mydata->port); - else - exit_error(PARAMETER_PROBLEM, - "IP address and port must be specified: ip%%port"); - free(saved); - return 1; -}; - -/* - * Print and save - */ - -void initheader(struct set *set, const void *data) -{ - struct ip_set_req_ipporthash_create *header = - (struct ip_set_req_ipporthash_create *) data; - struct ip_set_ipporthash *map = - (struct ip_set_ipporthash *) set->settype->header; - - memset(map, 0, sizeof(struct ip_set_ipporthash)); - map->hashsize = header->hashsize; - map->probes = header->probes; - map->resize = header->resize; - map->first_ip = header->from; - map->last_ip = header->to; -} - -void printheader(struct set *set, unsigned options) -{ - struct ip_set_ipporthash *mysetdata = - (struct ip_set_ipporthash *) set->settype->header; - - printf(" from: %s", ip_tostring(mysetdata->first_ip, options)); - printf(" to: %s", ip_tostring(mysetdata->last_ip, options)); - printf(" hashsize: %u", mysetdata->hashsize); - printf(" probes: %u", mysetdata->probes); - printf(" resize: %u\n", mysetdata->resize); -} - -void printips(struct set *set, void *data, size_t len, unsigned options) -{ - struct ip_set_ipporthash *mysetdata = - (struct ip_set_ipporthash *) set->settype->header; - size_t offset = 0; - ip_set_ip_t *ipptr, ip; - uint16_t port; - - while (offset < len) { - ipptr = data + offset; - if (*ipptr) { - ip = (*ipptr>>16) + mysetdata->first_ip; - port = (uint16_t) *ipptr; - printf("%s%%%s\n", - ip_tostring(ip, options), - port_tostring(port, options)); - } - offset += sizeof(ip_set_ip_t); - } -} - -void saveheader(struct set *set, unsigned options) -{ - struct ip_set_ipporthash *mysetdata = - (struct ip_set_ipporthash *) set->settype->header; - - printf("-N %s %s --from %s", - set->name, set->settype->typename, - ip_tostring(mysetdata->first_ip, options)); - printf(" --to %s", - ip_tostring(mysetdata->last_ip, options)); - printf(" --hashsize %u --probes %u --resize %u\n", - mysetdata->hashsize, mysetdata->probes, mysetdata->resize); -} - -/* Print save for an IP */ -void saveips(struct set *set, void *data, size_t len, unsigned options) -{ - struct ip_set_ipporthash *mysetdata = - (struct ip_set_ipporthash *) set->settype->header; - size_t offset = 0; - ip_set_ip_t *ipptr, ip; - uint16_t port; - - while (offset < len) { - ipptr = data + offset; - if (*ipptr) { - ip = (*ipptr>>16) + mysetdata->first_ip; - port = (uint16_t) *ipptr; - printf("-A %s %s%%%s\n", set->name, - ip_tostring(ip, options), - port_tostring(port, options)); - } - offset += sizeof(ip_set_ip_t); - } -} - -static char buffer[22]; - -static char * unpack_ipport_tostring(struct set *set, ip_set_ip_t bip, unsigned options) -{ - struct ip_set_ipporthash *mysetdata = - (struct ip_set_ipporthash *) set->settype->header; - ip_set_ip_t ip, port; - - ip = (bip>>16) + mysetdata->first_ip; - port = (uint16_t) bip; - sprintf(buffer, "%s%%%s", - ip_tostring(ip, options), port_tostring(port, options)); - - return buffer; -} - -void usage(void) -{ - printf - ("-N set ipporthash --from IP --to IP\n" - " [--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"); -} - -static struct settype settype_ipporthash = { - .typename = SETTYPE_NAME, - .protocol_version = IP_SET_PROTOCOL_VERSION, - - /* Create */ - .create_size = sizeof(struct ip_set_req_ipporthash_create), - .create_init = &create_init, - .create_parse = &create_parse, - .create_final = &create_final, - .create_opts = create_opts, - - /* Add/del/test */ - .adt_size = sizeof(struct ip_set_req_ipporthash), - .adt_parser = &adt_parser, - - /* Printing */ - .header_size = sizeof(struct ip_set_ipporthash), - .initheader = &initheader, - .printheader = &printheader, - .printips = &printips, /* We only have the unsorted version */ - .printips_sorted = &printips, - .saveheader = &saveheader, - .saveips = &saveips, - - /* Bindings */ - .bindip_tostring = &unpack_ipport_tostring, - .bindip_parse = &parse_ip, - - .usage = &usage, -}; - -void _init(void) -{ - settype_register(&settype_ipporthash); - -} diff --git a/ipset/ipset_iptree.c b/ipset/ipset_iptree.c deleted file mode 100644 index cce9884..0000000 --- a/ipset/ipset_iptree.c +++ /dev/null @@ -1,223 +0,0 @@ -/* Copyright 2005 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * 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 -#include -#include -#include -#include -#include - -#include -#include "ipset.h" - -#define BUFLEN 30; - -#define OPT_CREATE_TIMEOUT 0x01U - -/* Initialize the create. */ -void create_init(void *data) -{ - struct ip_set_req_iptree_create *mydata = - (struct ip_set_req_iptree_create *) data; - - DP("create INIT"); - mydata->timeout = 0; -} - -/* Function which parses command options; returns true if it ate an option */ -int create_parse(int c, char *argv[], void *data, unsigned *flags) -{ - struct ip_set_req_iptree_create *mydata = - (struct ip_set_req_iptree_create *) data; - - DP("create_parse"); - - switch (c) { - case '1': - string_to_number(optarg, 0, UINT_MAX, &mydata->timeout); - - *flags |= OPT_CREATE_TIMEOUT; - - DP("--timeout %u", mydata->timeout); - - break; - default: - return 0; - } - - return 1; -} - -/* Final check; exit if not ok. */ -void create_final(void *data, unsigned int flags) -{ -} - -/* Create commandline options */ -static struct option create_opts[] = { - {"timeout", 1, 0, '1'}, - {0} -}; - -/* Add, del, test parser */ -ip_set_ip_t adt_parser(unsigned cmd, const char *optarg, void *data) -{ - struct ip_set_req_iptree *mydata = - (struct ip_set_req_iptree *) data; - char *saved = ipset_strdup(optarg); - char *ptr, *tmp = saved; - - DP("iptree: %p %p", optarg, data); - - ptr = strsep(&tmp, "%"); - parse_ip(ptr, &mydata->ip); - - if (tmp) - string_to_number(tmp, 0, UINT_MAX, &mydata->timeout); - else - mydata->timeout = 0; - - free(saved); - return 1; -} - -/* - * Print and save - */ - -void initheader(struct set *set, const void *data) -{ - struct ip_set_req_iptree_create *header = - (struct ip_set_req_iptree_create *) data; - struct ip_set_iptree *map = - (struct ip_set_iptree *) set->settype->header; - - map->timeout = header->timeout; -} - -void printheader(struct set *set, unsigned options) -{ - struct ip_set_iptree *mysetdata = - (struct ip_set_iptree *) set->settype->header; - - if (mysetdata->timeout) - printf(" timeout: %u", mysetdata->timeout); - printf("\n"); -} - -void printips_sorted(struct set *set, void *data, size_t len, unsigned options) -{ - struct ip_set_iptree *mysetdata = - (struct ip_set_iptree *) set->settype->header; - struct ip_set_req_iptree *req; - size_t offset = 0; - - 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); - else - printf("%s\n", ip_tostring(req->ip, options)); - offset += sizeof(struct ip_set_req_iptree); - } -} - -void saveheader(struct set *set, unsigned options) -{ - struct ip_set_iptree *mysetdata = - (struct ip_set_iptree *) set->settype->header; - - if (mysetdata->timeout) - printf("-N %s %s --timeout %u\n", - set->name, set->settype->typename, - mysetdata->timeout); - else - printf("-N %s %s\n", - set->name, set->settype->typename); -} - -void saveips(struct set *set, void *data, size_t len, unsigned options) -{ - struct ip_set_iptree *mysetdata = - (struct ip_set_iptree *) set->settype->header; - struct ip_set_req_iptree *req; - size_t offset = 0; - - DP("%s", set->name); - - 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", - set->name, - ip_tostring(req->ip, options), - req->timeout); - else - printf("-A %s %s\n", - set->name, - ip_tostring(req->ip, options)); - offset += sizeof(struct ip_set_req_iptree); - } -} - -void usage(void) -{ - printf - ("-N set iptree [--timeout value]\n" - "-A set IP[%%timeout]\n" - "-D set IP\n" - "-T set IP\n"); -} - -static struct settype settype_iptree = { - .typename = SETTYPE_NAME, - .protocol_version = IP_SET_PROTOCOL_VERSION, - - /* Create */ - .create_size = sizeof(struct ip_set_req_iptree_create), - .create_init = &create_init, - .create_parse = &create_parse, - .create_final = &create_final, - .create_opts = create_opts, - - /* Add/del/test */ - .adt_size = sizeof(struct ip_set_req_iptree), - .adt_parser = &adt_parser, - - /* Printing */ - .header_size = sizeof(struct ip_set_iptree), - .initheader = &initheader, - .printheader = &printheader, - .printips = &printips_sorted, /* We only have sorted version */ - .printips_sorted = &printips_sorted, - .saveheader = &saveheader, - .saveips = &saveips, - - /* Bindings */ - .bindip_tostring = &binding_ip_tostring, - .bindip_parse = &parse_ip, - - .usage = &usage, -}; - -void _init(void) -{ - settype_register(&settype_iptree); - -} diff --git a/ipset/ipset_macipmap.c b/ipset/ipset_macipmap.c deleted file mode 100644 index 3ef8fb1..0000000 --- a/ipset/ipset_macipmap.c +++ /dev/null @@ -1,340 +0,0 @@ -/* Copyright 2000, 2001, 2002 Joakim Axelsson (gozem@linux.nu) - * Patrick Schaaf (bof@bof.de) - * Martin Josefsson (gandalf@wlug.westbo.se) - * - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include "ipset.h" - -#define BUFLEN 30; - -#define OPT_CREATE_FROM 0x01U -#define OPT_CREATE_TO 0x02U -#define OPT_CREATE_NETWORK 0x04U -#define OPT_CREATE_MATCHUNSET 0x08U - -#define OPT_ADDDEL_IP 0x01U -#define OPT_ADDDEL_MAC 0x02U - -/* Initialize the create. */ -void create_init(void *data) -{ - DP("create INIT"); - /* Nothing */ -} - -/* Function which parses command options; returns true if it ate an option */ -int create_parse(int c, char *argv[], void *data, unsigned *flags) -{ - struct ip_set_req_macipmap_create *mydata = - (struct ip_set_req_macipmap_create *) data; - - DP("create_parse"); - - switch (c) { - case '1': - parse_ip(optarg, &mydata->from); - - *flags |= OPT_CREATE_FROM; - - DP("--from %x (%s)", mydata->from, - ip_tostring_numeric(mydata->from)); - - break; - - case '2': - parse_ip(optarg, &mydata->to); - - *flags |= OPT_CREATE_TO; - - DP("--to %x (%s)", mydata->to, - ip_tostring_numeric(mydata->to)); - - break; - - case '3': - parse_ipandmask(optarg, &mydata->from, &mydata->to); - - /* Make to the last of from + mask */ - mydata->to = mydata->from | (~mydata->to); - - *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)); - - break; - - case '4': - mydata->flags |= IPSET_MACIP_MATCHUNSET; - - *flags |= OPT_CREATE_MATCHUNSET; - - DP("--matchunset"); - - break; - - default: - return 0; - } - - return 1; -} - -/* Final check; exit if not ok. */ -void create_final(void *data, unsigned int flags) -{ - struct ip_set_req_macipmap_create *mydata = - (struct ip_set_req_macipmap_create *) data; - - if (flags == 0) - exit_error(PARAMETER_PROBLEM, - "Need to specify --from and --to, or --network\n"); - - if (flags & OPT_CREATE_NETWORK) { - /* --network */ - if ((flags & OPT_CREATE_FROM) || (flags & OPT_CREATE_TO)) - exit_error(PARAMETER_PROBLEM, - "Can't specify --from or --to with --network\n"); - } else { - /* --from --to */ - if ((flags & OPT_CREATE_FROM) == 0 - || (flags & OPT_CREATE_TO) == 0) - exit_error(PARAMETER_PROBLEM, - "Need to specify both --from and --to\n"); - } - - - DP("from : %x to: %x diff: %d match unset: %d", mydata->from, - mydata->to, mydata->to - mydata->from, - flags & OPT_CREATE_MATCHUNSET); - - if (mydata->from > mydata->to) - exit_error(PARAMETER_PROBLEM, - "From can't be lower than to.\n"); - - if (mydata->to - mydata->from > MAX_RANGE) - exit_error(PARAMETER_PROBLEM, - "Range too large. Max is %d IPs in range\n", - MAX_RANGE+1); -} - -/* Create commandline options */ -static struct option create_opts[] = { - {"from", 1, 0, '1'}, - {"to", 1, 0, '2'}, - {"network", 1, 0, '3'}, - {"matchunset", 0, 0, '4'}, - {0} -}; - -static void parse_mac(const char *mac, unsigned char *ethernet) -{ - unsigned int i = 0; - - if (strlen(mac) != ETH_ALEN * 3 - 1) - exit_error(PARAMETER_PROBLEM, "Bad mac address `%s'", mac); - - for (i = 0; i < ETH_ALEN; i++) { - long number; - char *end; - - number = strtol(mac + i * 3, &end, 16); - - if (end == mac + i * 3 + 2 && number >= 0 && number <= 255) - ethernet[i] = number; - else - exit_error(PARAMETER_PROBLEM, - "Bad mac address `%s'", mac); - } -} - -/* Add, del, test parser */ -ip_set_ip_t adt_parser(unsigned cmd, const char *optarg, void *data) -{ - struct ip_set_req_macipmap *mydata = - (struct ip_set_req_macipmap *) data; - char *saved = ipset_strdup(optarg); - char *ptr, *tmp = saved; - - DP("macipmap: %p %p", optarg, data); - - ptr = strsep(&tmp, "%"); - parse_ip(ptr, &mydata->ip); - - if (tmp) - parse_mac(tmp, mydata->ethernet); - else - memset(mydata->ethernet, 0, ETH_ALEN); - - free(saved); - return 1; -} - -/* - * Print and save - */ - -void initheader(struct set *set, const void *data) -{ - struct ip_set_req_macipmap_create *header = - (struct ip_set_req_macipmap_create *) data; - struct ip_set_macipmap *map = - (struct ip_set_macipmap *) set->settype->header; - - memset(map, 0, sizeof(struct ip_set_macipmap)); - map->first_ip = header->from; - map->last_ip = header->to; - map->flags = header->flags; -} - -void printheader(struct set *set, unsigned options) -{ - struct ip_set_macipmap *mysetdata = - (struct ip_set_macipmap *) set->settype->header; - - printf(" from: %s", ip_tostring(mysetdata->first_ip, options)); - printf(" to: %s", ip_tostring(mysetdata->last_ip, options)); - - if (mysetdata->flags & IPSET_MACIP_MATCHUNSET) - printf(" matchunset"); - printf("\n"); -} - -static void print_mac(unsigned char macaddress[ETH_ALEN]) -{ - unsigned int i; - - printf("%02X", macaddress[0]); - for (i = 1; i < ETH_ALEN; i++) - printf(":%02X", macaddress[i]); -} - -void printips_sorted(struct set *set, void *data, size_t len, unsigned options) -{ - struct ip_set_macipmap *mysetdata = - (struct ip_set_macipmap *) set->settype->header; - struct ip_set_macip *table = - (struct ip_set_macip *) data; - u_int32_t addr = mysetdata->first_ip; - - while (addr <= mysetdata->last_ip) { - if (test_bit(IPSET_MACIP_ISSET, - (void *)&table[addr - mysetdata->first_ip].flags)) { - printf("%s%%", ip_tostring(addr, options)); - print_mac(table[addr - mysetdata->first_ip]. - ethernet); - printf("\n"); - } - addr++; - } -} - -void saveheader(struct set *set, unsigned options) -{ - struct ip_set_macipmap *mysetdata = - (struct ip_set_macipmap *) set->settype->header; - - printf("-N %s %s --from %s", - set->name, set->settype->typename, - ip_tostring(mysetdata->first_ip, options)); - printf(" --to %s", ip_tostring(mysetdata->last_ip, options)); - - if (mysetdata->flags & IPSET_MACIP_MATCHUNSET) - printf(" --matchunset"); - printf("\n"); -} - -void saveips(struct set *set, void *data, size_t len, unsigned options) -{ - struct ip_set_macipmap *mysetdata = - (struct ip_set_macipmap *) set->settype->header; - struct ip_set_macip *table = - (struct ip_set_macip *) data; - u_int32_t addr = mysetdata->first_ip; - - while (addr <= mysetdata->last_ip) { - if (test_bit(IPSET_MACIP_ISSET, - (void *)&table[addr - mysetdata->first_ip].flags)) { - printf("-A %s %s%%", - set->name, ip_tostring(addr, options)); - print_mac(table[addr - mysetdata->first_ip]. - ethernet); - printf("\n"); - } - addr++; - } -} - -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"); -} - -static struct settype settype_macipmap = { - .typename = SETTYPE_NAME, - .protocol_version = IP_SET_PROTOCOL_VERSION, - - /* Create */ - .create_size = sizeof(struct ip_set_req_macipmap_create), - .create_init = &create_init, - .create_parse = &create_parse, - .create_final = &create_final, - .create_opts = create_opts, - - /* Add/del/test */ - .adt_size = sizeof(struct ip_set_req_macipmap), - .adt_parser = &adt_parser, - - /* Printing */ - .header_size = sizeof(struct ip_set_macipmap), - .initheader = &initheader, - .printheader = &printheader, - .printips = &printips_sorted, /* We only have sorted version */ - .printips_sorted = &printips_sorted, - .saveheader = &saveheader, - .saveips = &saveips, - - /* Bindings */ - .bindip_tostring = &binding_ip_tostring, - .bindip_parse = &parse_ip, - - .usage = &usage, -}; - -void _init(void) -{ - settype_register(&settype_macipmap); - -} diff --git a/ipset/ipset_nethash.c b/ipset/ipset_nethash.c deleted file mode 100644 index 758c4c1..0000000 --- a/ipset/ipset_nethash.c +++ /dev/null @@ -1,366 +0,0 @@ -/* Copyright 2004 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "ipset.h" - -#define BUFLEN 30; - -#define OPT_CREATE_HASHSIZE 0x01U -#define OPT_CREATE_PROBES 0x02U -#define OPT_CREATE_RESIZE 0x04U - -/* Initialize the create. */ -void create_init(void *data) -{ - struct ip_set_req_nethash_create *mydata = - (struct ip_set_req_nethash_create *) data; - - DP("create INIT"); - - /* Default create parameters */ - mydata->hashsize = 1024; - mydata->probes = 4; - mydata->resize = 50; -} - -/* Function which parses command options; returns true if it ate an option */ -int create_parse(int c, char *argv[], void *data, unsigned *flags) -{ - struct ip_set_req_nethash_create *mydata = - (struct ip_set_req_nethash_create *) data; - ip_set_ip_t value; - - DP("create_parse"); - - switch (c) { - case '1': - - if (string_to_number(optarg, 1, UINT_MAX - 1, &mydata->hashsize)) - exit_error(PARAMETER_PROBLEM, "Invalid hashsize `%s' specified", optarg); - - *flags |= OPT_CREATE_HASHSIZE; - - DP("--hashsize %u", mydata->hashsize); - - break; - - case '2': - - if (string_to_number(optarg, 1, 65535, &value)) - exit_error(PARAMETER_PROBLEM, "Invalid probes `%s' specified", optarg); - - mydata->probes = value; - *flags |= OPT_CREATE_PROBES; - - DP("--probes %u", mydata->probes); - - break; - - case '3': - - if (string_to_number(optarg, 0, 65535, &value)) - exit_error(PARAMETER_PROBLEM, "Invalid resize `%s' specified", optarg); - - mydata->resize = value; - *flags |= OPT_CREATE_RESIZE; - - DP("--resize %u", mydata->resize); - - break; - - default: - return 0; - } - - return 1; -} - -/* Final check; exit if not ok. */ -void create_final(void *data, unsigned int flags) -{ -#ifdef IPSET_DEBUG - struct ip_set_req_nethash_create *mydata = - (struct ip_set_req_nethash_create *) data; - - DP("hashsize %u probes %u resize %u", - mydata->hashsize, mydata->probes, mydata->resize); -#endif -} - -/* Create commandline options */ -static struct option create_opts[] = { - {"hashsize", 1, 0, '1'}, - {"probes", 1, 0, '2'}, - {"resize", 1, 0, '3'}, - {0} -}; - -/* Add, del, test parser */ -ip_set_ip_t adt_parser(unsigned cmd, const char *optarg, void *data) -{ - struct ip_set_req_nethash *mydata = - (struct ip_set_req_nethash *) data; - char *saved = ipset_strdup(optarg); - char *ptr, *tmp = saved; - ip_set_ip_t cidr; - - ptr = strsep(&tmp, "/"); - - if (tmp == NULL) { - if (cmd == CMD_TEST) - cidr = 32; - else - exit_error(PARAMETER_PROBLEM, - "Missing cidr from `%s'", optarg); - } else - if (string_to_number(tmp, 1, 31, &cidr)) - exit_error(PARAMETER_PROBLEM, - "Out of range cidr `%s' specified", optarg); - - 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; -}; - -/* - * Print and save - */ - -void initheader(struct set *set, const void *data) -{ - struct ip_set_req_nethash_create *header = - (struct ip_set_req_nethash_create *) data; - struct ip_set_nethash *map = - (struct ip_set_nethash *) set->settype->header; - - memset(map, 0, sizeof(struct ip_set_nethash)); - map->hashsize = header->hashsize; - map->probes = header->probes; - map->resize = header->resize; -} - -unsigned int -mask_to_bits(ip_set_ip_t mask) -{ - unsigned int bits = 32; - ip_set_ip_t maskaddr; - - if (mask == 0xFFFFFFFF) - return bits; - - maskaddr = 0xFFFFFFFE; - while (--bits >= 0 && maskaddr != mask) - maskaddr <<= 1; - - return bits; -} - -void printheader(struct set *set, unsigned options) -{ - struct ip_set_nethash *mysetdata = - (struct ip_set_nethash *) set->settype->header; - - printf(" hashsize: %u", mysetdata->hashsize); - printf(" probes: %u", mysetdata->probes); - printf(" resize: %u\n", mysetdata->resize); -} - -static char buf[20]; - -static char * unpack_ip_tostring(ip_set_ip_t ip, unsigned options) -{ - int i, j = 3; - unsigned char a, b; - - ip = htonl(ip); - for (i = 3; i >= 0; i--) - if (((unsigned char *)&ip)[i] != 0) { - j = i; - break; - } - - a = ((unsigned char *)&ip)[j]; - if (a <= 128) { - a = (a - 1) * 2; - b = 7; - } else if (a <= 192) { - a = (a - 129) * 4; - b = 6; - } else if (a <= 224) { - a = (a - 193) * 8; - b = 5; - } else if (a <= 240) { - a = (a - 225) * 16; - b = 4; - } else if (a <= 248) { - a = (a - 241) * 32; - b = 3; - } else if (a <= 252) { - a = (a - 249) * 64; - b = 2; - } else if (a <= 254) { - a = (a - 253) * 128; - b = 1; - } else { - a = b = 0; - } - ((unsigned char *)&ip)[j] = a; - b += j * 8; - - sprintf(buf, "%u.%u.%u.%u/%u", - ((unsigned char *)&ip)[0], - ((unsigned char *)&ip)[1], - ((unsigned char *)&ip)[2], - ((unsigned char *)&ip)[3], - b); - - DP("%s %s", ip_tostring(ntohl(ip), options), buf); - return buf; -} - -void printips(struct set *set, void *data, size_t len, unsigned options) -{ - size_t offset = 0; - ip_set_ip_t *ip; - - while (offset < len) { - ip = data + offset; - if (*ip) - printf("%s\n", unpack_ip_tostring(*ip, options)); - offset += sizeof(ip_set_ip_t); - } -} - -void saveheader(struct set *set, unsigned options) -{ - struct ip_set_nethash *mysetdata = - (struct ip_set_nethash *) set->settype->header; - - printf("-N %s %s --hashsize %u --probes %u --resize %u\n", - set->name, set->settype->typename, - mysetdata->hashsize, mysetdata->probes, mysetdata->resize); -} - -/* Print save for an IP */ -void saveips(struct set *set, void *data, size_t len, unsigned options) -{ - size_t offset = 0; - ip_set_ip_t *ip; - - while (offset < len) { - ip = data + offset; - if (*ip) - printf("-A %s %s\n", set->name, - unpack_ip_tostring(*ip, options)); - offset += sizeof(ip_set_ip_t); - } -} - -static char * net_tostring(struct set *set, ip_set_ip_t ip, unsigned options) -{ - return unpack_ip_tostring(ip, options); -} - -static void parse_net(const char *str, ip_set_ip_t *ip) -{ - char *saved = strdup(str); - char *ptr, *tmp = saved; - ip_set_ip_t cidr; - - ptr = strsep(&tmp, "/"); - - if (tmp == NULL) - exit_error(PARAMETER_PROBLEM, - "Missing cidr from `%s'", str); - - if (string_to_number(tmp, 1, 31, &cidr)) - exit_error(PARAMETER_PROBLEM, - "Out of range cidr `%s' specified", str); - - parse_ip(ptr, ip); - free(saved); - - *ip = pack(*ip, cidr); -} - -void usage(void) -{ - printf - ("-N set nethash [--hashsize hashsize] [--probes probes ]\n" - " [--resize resize]\n" - "-A set IP/cidr\n" - "-D set IP/cidr\n" - "-T set IP/cidr\n"); -} - -static struct settype settype_nethash = { - .typename = SETTYPE_NAME, - .protocol_version = IP_SET_PROTOCOL_VERSION, - - /* Create */ - .create_size = sizeof(struct ip_set_req_nethash_create), - .create_init = &create_init, - .create_parse = &create_parse, - .create_final = &create_final, - .create_opts = create_opts, - - /* Add/del/test */ - .adt_size = sizeof(struct ip_set_req_nethash), - .adt_parser = &adt_parser, - - /* Printing */ - .header_size = sizeof(struct ip_set_nethash), - .initheader = &initheader, - .printheader = &printheader, - .printips = &printips, /* We only have the unsorted version */ - .printips_sorted = &printips, - .saveheader = &saveheader, - .saveips = &saveips, - - /* Bindings */ - .bindip_tostring = &net_tostring, - .bindip_parse = &parse_net, - - .usage = &usage, -}; - -void _init(void) -{ - settype_register(&settype_nethash); - -} diff --git a/ipset/ipset_portmap.c b/ipset/ipset_portmap.c deleted file mode 100644 index 1c3965b..0000000 --- a/ipset/ipset_portmap.c +++ /dev/null @@ -1,245 +0,0 @@ -/* Copyright 2004 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * 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 -#include -#include -#include -#include -#include - -#include -#include "ipset.h" - - -#define BUFLEN 30; - -#define OPT_CREATE_FROM 0x01U -#define OPT_CREATE_TO 0x02U - -#define OPT_ADDDEL_PORT 0x01U - -/* Initialize the create. */ -void create_init(void *data) -{ - DP("create INIT"); - /* Nothing */ -} - -/* Function which parses command options; returns true if it ate an option */ -int create_parse(int c, char *argv[], void *data, unsigned *flags) -{ - struct ip_set_req_portmap_create *mydata = - (struct ip_set_req_portmap_create *) data; - - DP("create_parse"); - - switch (c) { - case '1': - parse_port(optarg, &mydata->from); - - *flags |= OPT_CREATE_FROM; - - DP("--from %x (%s)", mydata->from, - port_tostring(mydata->from, 0)); - - break; - - case '2': - parse_port(optarg, &mydata->to); - - *flags |= OPT_CREATE_TO; - - DP("--to %x (%s)", mydata->to, - port_tostring(mydata->to, 0)); - - break; - - default: - return 0; - } - - return 1; -} - -/* Final check; exit if not ok. */ -void create_final(void *data, unsigned int flags) -{ - struct ip_set_req_portmap_create *mydata = - (struct ip_set_req_portmap_create *) data; - - if (flags == 0) { - exit_error(PARAMETER_PROBLEM, - "Need to specify --from and --to\n"); - } else { - /* --from --to */ - if ((flags & OPT_CREATE_FROM) == 0 - || (flags & OPT_CREATE_TO) == 0) - exit_error(PARAMETER_PROBLEM, - "Need to specify both --from and --to\n"); - } - - DP("from : %x to: %x diff: %d", 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"); - - if (mydata->to - mydata->from > MAX_RANGE) - exit_error(PARAMETER_PROBLEM, - "Range too large. Max is %d ports in range\n", - MAX_RANGE+1); -} - -/* Create commandline options */ -static struct option create_opts[] = { - {"from", 1, 0, '1'}, - {"to", 1, 0, '2'}, - {0} -}; - -/* Add, del, test parser */ -ip_set_ip_t adt_parser(unsigned cmd, const char *optarg, void *data) -{ - struct ip_set_req_portmap *mydata = - (struct ip_set_req_portmap *) data; - - parse_port(optarg, &mydata->port); - DP("%s", port_tostring(mydata->port, 0)); - - return 1; -} - -/* - * Print and save - */ - -void initheader(struct set *set, const void *data) -{ - struct ip_set_req_portmap_create *header = - (struct ip_set_req_portmap_create *) data; - struct ip_set_portmap *map = - (struct ip_set_portmap *) set->settype->header; - - memset(map, 0, sizeof(struct ip_set_portmap)); - map->first_port = header->from; - map->last_port = header->to; -} - -void printheader(struct set *set, unsigned options) -{ - struct ip_set_portmap *mysetdata = - (struct ip_set_portmap *) set->settype->header; - - printf(" from: %s", port_tostring(mysetdata->first_port, options)); - printf(" to: %s\n", port_tostring(mysetdata->last_port, options)); -} - -void printports_sorted(struct set *set, void *data, size_t len, unsigned options) -{ - struct ip_set_portmap *mysetdata = - (struct ip_set_portmap *) set->settype->header; - u_int32_t addr = mysetdata->first_port; - - DP("%u -- %u", mysetdata->first_port, mysetdata->last_port); - while (addr <= mysetdata->last_port) { - if (test_bit(addr - mysetdata->first_port, data)) - printf("%s\n", port_tostring(addr, options)); - addr++; - } -} - -char * binding_port_tostring(struct set *set, ip_set_ip_t ip, unsigned options) -{ - return port_tostring(ip, options); -} - -void saveheader(struct set *set, unsigned options) -{ - struct ip_set_portmap *mysetdata = - (struct ip_set_portmap *) set->settype->header; - - printf("-N %s %s --from %s", - set->name, - set->settype->typename, - port_tostring(mysetdata->first_port, options)); - printf(" --to %s\n", - port_tostring(mysetdata->last_port, options)); -} - -void saveports(struct set *set, void *data, size_t len, unsigned options) -{ - struct ip_set_portmap *mysetdata = - (struct ip_set_portmap *) set->settype->header; - u_int32_t addr = mysetdata->first_port; - - while (addr <= mysetdata->last_port) { - if (test_bit(addr - mysetdata->first_port, data)) - printf("-A %s %s\n", - set->name, - port_tostring(addr, options)); - addr++; - } -} - -void usage(void) -{ - printf - ("-N set portmap --from PORT --to PORT\n" - "-A set PORT\n" - "-D set PORT\n" - "-T set PORT\n"); -} - -static struct settype settype_portmap = { - .typename = SETTYPE_NAME, - .protocol_version = IP_SET_PROTOCOL_VERSION, - - /* Create */ - .create_size = sizeof(struct ip_set_req_portmap_create), - .create_init = &create_init, - .create_parse = &create_parse, - .create_final = &create_final, - .create_opts = create_opts, - - /* Add/del/test */ - .adt_size = sizeof(struct ip_set_req_portmap), - .adt_parser = &adt_parser, - - /* Printing */ - .header_size = sizeof(struct ip_set_portmap), - .initheader = &initheader, - .printheader = &printheader, - .printips = &printports_sorted, /* We only have sorted version */ - .printips_sorted = &printports_sorted, - .saveheader = &saveheader, - .saveips = &saveports, - - /* Bindings */ - .bindip_tostring = &binding_port_tostring, - .bindip_parse = &parse_port, - - .usage = &usage, -}; - -void _init(void) -{ - settype_register(&settype_portmap); - -} diff --git a/ipset/libipt_set.h b/ipset/libipt_set.h deleted file mode 100644 index 0521251..0000000 --- a/ipset/libipt_set.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef _LIBIPT_SET_H -#define _LIBIPT_SET_H - -#include -#include -#include - -static int get_set_getsockopt(void *data, size_t * size) -{ - int sockfd = -1; - sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); - if (sockfd < 0) - exit_error(OTHER_PROBLEM, - "Can't open socket to ipset.\n"); - /* Send! */ - return getsockopt(sockfd, SOL_IP, SO_IP_SET, data, size); -} - -static void -parse_bindings(const char *optarg, struct ipt_set_info *info) -{ - char *saved = strdup(optarg); - char *ptr, *tmp = saved; - int i = 0; - - while (i < IP_SET_MAX_BINDINGS && tmp != NULL) { - ptr = strsep(&tmp, ","); - if (strncmp(ptr, "src", 3) == 0) - info->flags[i++] |= IPSET_SRC; - else if (strncmp(ptr, "dst", 3) == 0) - info->flags[i++] |= IPSET_DST; - else - exit_error(PARAMETER_PROBLEM, - "You must spefify (the comma separated list of) 'src' or 'dst'."); - } - - if (tmp) - exit_error(PARAMETER_PROBLEM, - "Can't follow bindings deeper than %i.", - IP_SET_MAX_BINDINGS); - - free(saved); -} - -#endif /*_LIBIPT_SET_H*/ -- 2.43.0