'iptables-1_3_5'.
+++ /dev/null
-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...
-
+++ /dev/null
-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)
+++ /dev/null
-#!/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 $< $@
+++ /dev/null
-- rewrite kernel-userspace communication from sockopt to netlink
-- IPv6 support
+++ /dev/null
-.TH IPSET 8 "Feb 05, 2004" "" ""
-.\"
-.\" Man page written by 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., 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 ..
+++ /dev/null
-/* 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 <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <time.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <arpa/inet.h>
-#include <stdarg.h>
-#include <netdb.h>
-#include <dlfcn.h>
-#include <asm/bitops.h>
-
-#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 <options>\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);
-
-}
+++ /dev/null
-#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 <getopt.h>
-#include <sys/types.h>
-#include <netdb.h>
-
-#include <linux/netfilter_ipv4/ip_set.h>
-
-#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 */
+++ /dev/null
-/* 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 <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <time.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <asm/bitops.h>
-#include <asm/types.h>
-
-#include <linux/netfilter_ipv4/ip_set_iphash.h>
-#include <linux/netfilter_ipv4/ip_set_jhash.h>
-
-#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);
-
-}
+++ /dev/null
-/* 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 <stdio.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <asm/bitops.h>
-
-#include <linux/netfilter_ipv4/ip_set_ipmap.h>
-#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);
-
-}
+++ /dev/null
-/* 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 <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <time.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <asm/bitops.h>
-#include <asm/types.h>
-
-#include <linux/netfilter_ipv4/ip_set_ipporthash.h>
-#include <linux/netfilter_ipv4/ip_set_jhash.h>
-
-#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);
-
-}
+++ /dev/null
-/* 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <linux/netfilter_ipv4/ip_set_iptree.h>
-#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);
-
-}
+++ /dev/null
-/* 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <asm/bitops.h>
-#include <linux/if_ether.h>
-
-#include <linux/netfilter_ipv4/ip_set_macipmap.h>
-#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);
-
-}
+++ /dev/null
-/* 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 <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <time.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <asm/bitops.h>
-#include <asm/types.h>
-
-#include <linux/netfilter_ipv4/ip_set_nethash.h>
-#include <linux/netfilter_ipv4/ip_set_jhash.h>
-
-#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);
-
-}
+++ /dev/null
-/* 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 <stdio.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <asm/bitops.h>
-
-#include <linux/netfilter_ipv4/ip_set_portmap.h>
-#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);
-
-}
+++ /dev/null
-#ifndef _LIBIPT_SET_H
-#define _LIBIPT_SET_H
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <errno.h>
-
-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*/