mirror of
git://git.code.sf.net/p/xtables-addons/xtables-addons
synced 2025-09-05 20:26:38 +02:00
Import ipset-2.3.2a (userspace components)
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,6 +6,7 @@
|
||||
.libs
|
||||
Makefile
|
||||
Makefile.in
|
||||
GNUmakefile
|
||||
|
||||
/downloads
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign subdir-objects
|
||||
SUBDIRS = extensions
|
||||
SUBDIRS = extensions extensions/ipset
|
||||
|
||||
man_MANS := xtables-addons.8
|
||||
|
||||
|
@@ -65,4 +65,4 @@ AC_SUBST([kinclude_CFLAGS])
|
||||
AC_SUBST([kbuilddir])
|
||||
AC_SUBST([ksourcedir])
|
||||
AC_SUBST([xtlibdir])
|
||||
AC_OUTPUT([Makefile extensions/GNUmakefile])
|
||||
AC_OUTPUT([Makefile extensions/GNUmakefile extensions/ipset/GNUmakefile])
|
||||
|
1
extensions/.gitignore
vendored
1
extensions/.gitignore
vendored
@@ -8,7 +8,6 @@ modules.order
|
||||
|
||||
/*.so
|
||||
/*.oo
|
||||
/GNUmakefile
|
||||
/matches.man
|
||||
/targets.man
|
||||
/.manpages.lst
|
||||
|
3
extensions/ipset/.gitignore
vendored
Normal file
3
extensions/ipset/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
*.oo
|
||||
*.so
|
||||
/ipset
|
84
extensions/ipset/GNUmakefile.in
Normal file
84
extensions/ipset/GNUmakefile.in
Normal file
@@ -0,0 +1,84 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
top_srcdir := @top_srcdir@
|
||||
srcdir := @srcdir@
|
||||
abstop_srcdir := $(shell readlink -e ${top_srcdir})
|
||||
abssrcdir := $(shell readlink -e ${srcdir})
|
||||
|
||||
ifeq (${abstop_srcdir},)
|
||||
$(error Path resolution of ${top_srcdir} failed)
|
||||
endif
|
||||
ifeq (${abssrcdir},)
|
||||
$(error Path resolution of ${srcdir} failed)
|
||||
endif
|
||||
|
||||
prefix := @prefix@
|
||||
exec_prefix := @exec_prefix@
|
||||
sbindir := @sbindir@
|
||||
libdir := @libdir@
|
||||
libexecdir := @libexecdir@
|
||||
xtlibdir := @xtlibdir@
|
||||
kbuilddir := @kbuilddir@
|
||||
man8dir := @mandir@/man8
|
||||
|
||||
CC := @CC@
|
||||
CCLD := ${CC}
|
||||
CFLAGS := @CFLAGS@
|
||||
LDFLAGS := @LDFLAGS@
|
||||
regular_CFLAGS := @regular_CFLAGS@
|
||||
kinclude_CFLAGS := @kinclude_CFLAGS@
|
||||
xtables_CFLAGS := @xtables_CFLAGS@
|
||||
|
||||
AM_CFLAGS := ${regular_CFLAGS} -I${top_srcdir}/include ${xtables_CFLAGS} ${kinclude_CFLAGS} -DXTABLES_LIBDIR=\"${xtlibdir}\"
|
||||
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
|
||||
|
||||
ifeq (${V},)
|
||||
AM_LIBTOOL_SILENT = --silent
|
||||
AM_VERBOSE_CC = @echo " CC " $@;
|
||||
AM_VERBOSE_CCLD = @echo " CCLD " $@;
|
||||
AM_VERBOSE_CXX = @echo " CXX " $@;
|
||||
AM_VERBOSE_CXXLD = @echo " CXXLD " $@;
|
||||
AM_VERBOSE_AR = @echo " AR " $@;
|
||||
AM_VERBOSE_GEN = @echo " GEN " $@;
|
||||
endif
|
||||
|
||||
#
|
||||
# Building blocks
|
||||
#
|
||||
targets := $(addsuffix .so,$(addprefix libipset_,iphash ipmap ipporthash iptree iptreemap macipmap nethash portmap))
|
||||
|
||||
.SECONDARY:
|
||||
|
||||
.PHONY: all install clean distclean FORCE
|
||||
|
||||
all: ipset ${targets}
|
||||
|
||||
install: all
|
||||
@mkdir -p "${DESTDIR}${sbindir}" "${DESTDIR}${xtlibdir}" "${DESTDIR}${man8dir}";
|
||||
install -pm0755 ipset "${DESTDIR}${sbindir}/";
|
||||
install -pm0755 ${targets} "${DESTDIR}${xtlibdir}/";
|
||||
install -pm0644 ipset.8 "${DESTDIR}${man8dir}/";
|
||||
|
||||
clean:
|
||||
rm -f *.oo *.so *.o ipset;
|
||||
|
||||
distclean: clean
|
||||
rm -f .*.d;
|
||||
|
||||
-include .*.d
|
||||
|
||||
|
||||
ipset: ipset.o
|
||||
${AM_VERBOSE_CCLD} ${CCLD} ${AM_LDFLAGS} ${LDFLAGS} -o $@ $< -ldl -rdynamic;
|
||||
|
||||
#
|
||||
# Shared libraries
|
||||
#
|
||||
lib%.so: lib%.oo
|
||||
${AM_VERBOSE_CCLD} ${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $<;
|
||||
|
||||
libipset_%.oo: ${srcdir}/ipset_%.c
|
||||
${AM_VERBOSE_CC} ${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
|
||||
|
||||
%.o: %.c
|
||||
${AM_VERBOSE_CC} ${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} ${CFLAGS} -o $@ -c $<;
|
470
extensions/ipset/ipset.8
Normal file
470
extensions/ipset/ipset.8
Normal file
@@ -0,0 +1,470 @@
|
||||
.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. (The old "%" separation token instead of ":", i.e
|
||||
IP%MAC is accepted as well.)
|
||||
.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
|
||||
The iphash type of sets can store up to 65536 entries. If a set is full,
|
||||
no new entries can be added to it.
|
||||
.P
|
||||
Sets created by zero valued resize parameter won't be resized at all.
|
||||
The lookup time in an iphash type of set approximately linearly grows with
|
||||
the value of the
|
||||
.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
|
||||
The nethash type of sets can store up to 65536 entries. If a set is full,
|
||||
no new entries can be added to it.
|
||||
.P
|
||||
An IP address will be in a nethash type of set if it is in any of the
|
||||
netblocks added to the set and the matching always start from the smallest
|
||||
size of netblock (most specific netmask) to the biggest ones (least
|
||||
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".
|
||||
(Old "IP%port" format accepted as well.)
|
||||
.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.
|
||||
Similarly to the hash types, the iptree type of sets can store up to 65536
|
||||
entries.
|
||||
.SS iptreemap
|
||||
The iptreemap set type uses a tree to store IP addresses or networks,
|
||||
where the last octet of an IP address are stored in a bitmap.
|
||||
As input entry, you can add IP addresses, CIDR blocks or network ranges
|
||||
to the set. Network ranges can be specified in the format
|
||||
.I IP1:IP2
|
||||
.P
|
||||
Options to use when creating an iptreemap set:
|
||||
.TP
|
||||
.BR "--gc " value
|
||||
How often the garbage collection should be called, in seconds (default 300)
|
||||
.SH GENERAL RESTRICTIONS
|
||||
Setnames starting with colon (:) cannot be defined. Zero valued set
|
||||
entries cannot be used with hash type of sets.
|
||||
.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.
|
||||
.P
|
||||
Sven Wegener wrote the iptreemap type.
|
||||
.SH LAST REMARK
|
||||
.BR "I stand on the shoulder of giants."
|
||||
.\" .. and did I mention that we are incredibly cool people?
|
||||
.\" .. sexy, too ..
|
||||
.\" .. witty, charming, powerful ..
|
||||
.\" .. and most of all, modest ..
|
2309
extensions/ipset/ipset.c
Normal file
2309
extensions/ipset/ipset.c
Normal file
File diff suppressed because it is too large
Load Diff
191
extensions/ipset/ipset.h
Normal file
191
extensions/ipset/ipset.h
Normal file
@@ -0,0 +1,191 @@
|
||||
#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 "ip_set.h"
|
||||
|
||||
#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);
|
||||
|
||||
#define BITSPERBYTE (8*sizeof(char))
|
||||
#define ID2BYTE(id) ((id)/BITSPERBYTE)
|
||||
#define ID2MASK(id) (1 << ((id)%BITSPERBYTE))
|
||||
#define test_bit(id, heap) ((((char *)(heap))[ID2BYTE(id)] & ID2MASK(id)) != 0)
|
||||
|
||||
#endif /* __IPSET_H */
|
297
extensions/ipset/ipset_iphash.c
Normal file
297
extensions/ipset/ipset_iphash.c
Normal file
@@ -0,0 +1,297 @@
|
||||
/* 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 <limits.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/types.h>
|
||||
|
||||
#include "ip_set_iphash.h"
|
||||
#include "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,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) iphash_init(void)
|
||||
{
|
||||
settype_register(&settype_iphash);
|
||||
|
||||
}
|
360
extensions/ipset/ipset_ipmap.c
Normal file
360
extensions/ipset/ipset_ipmap.c
Normal file
@@ -0,0 +1,360 @@
|
||||
/* 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 "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 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'},
|
||||
{"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,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void ipmap_init(void)
|
||||
{
|
||||
settype_register(&settype_ipmap);
|
||||
|
||||
}
|
373
extensions/ipset/ipset_ipporthash.c
Normal file
373
extensions/ipset/ipset_ipporthash.c
Normal file
@@ -0,0 +1,373 @@
|
||||
/* 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 <limits.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/types.h>
|
||||
|
||||
#include "ip_set_ipporthash.h"
|
||||
#include "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 too 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,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void ipporthash_init(void)
|
||||
{
|
||||
settype_register(&settype_ipporthash);
|
||||
|
||||
}
|
224
extensions/ipset/ipset_iptree.c
Normal file
224
extensions/ipset/ipset_iptree.c
Normal file
@@ -0,0 +1,224 @@
|
||||
/* 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 <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "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,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void iptree_init(void)
|
||||
{
|
||||
settype_register(&settype_iptree);
|
||||
|
||||
}
|
206
extensions/ipset/ipset_iptreemap.c
Normal file
206
extensions/ipset/ipset_iptreemap.c
Normal file
@@ -0,0 +1,206 @@
|
||||
/* Copyright 2007 Sven Wegener <sven.wegener@stealer.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
* Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "ip_set_iptreemap.h"
|
||||
|
||||
#include "ipset.h"
|
||||
|
||||
#define OPT_CREATE_GC 0x1
|
||||
|
||||
void
|
||||
create_init(void *data)
|
||||
{
|
||||
struct ip_set_req_iptreemap_create *mydata = data;
|
||||
|
||||
mydata->gc_interval = 0;
|
||||
}
|
||||
|
||||
int
|
||||
create_parse(int c, char *argv[], void *data, unsigned int *flags)
|
||||
{
|
||||
struct ip_set_req_iptreemap_create *mydata = data;
|
||||
|
||||
switch (c) {
|
||||
case 'g':
|
||||
string_to_number(optarg, 0, UINT_MAX, &mydata->gc_interval);
|
||||
|
||||
*flags |= OPT_CREATE_GC;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
create_final(void *data, unsigned int flags)
|
||||
{
|
||||
}
|
||||
|
||||
static struct option create_opts[] = {
|
||||
{"gc", 1, 0, 'g'},
|
||||
{0}
|
||||
};
|
||||
|
||||
ip_set_ip_t
|
||||
adt_parser(unsigned int cmd, const char *optarg, void *data)
|
||||
{
|
||||
struct ip_set_req_iptreemap *mydata = data;
|
||||
ip_set_ip_t mask;
|
||||
|
||||
char *saved = ipset_strdup(optarg);
|
||||
char *ptr, *tmp = saved;
|
||||
|
||||
if (strchr(tmp, '/')) {
|
||||
parse_ipandmask(tmp, &mydata->start, &mask);
|
||||
mydata->end = mydata->start | ~mask;
|
||||
} else {
|
||||
ptr = strsep(&tmp, ":");
|
||||
parse_ip(ptr, &mydata->start);
|
||||
|
||||
if (tmp) {
|
||||
parse_ip(tmp, &mydata->end);
|
||||
} else {
|
||||
mydata->end = mydata->start;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
initheader(struct set *set, const void *data)
|
||||
{
|
||||
const struct ip_set_req_iptreemap_create *header = data;
|
||||
struct ip_set_iptreemap *map = set->settype->header;
|
||||
|
||||
map->gc_interval = header->gc_interval;
|
||||
}
|
||||
|
||||
void
|
||||
printheader(struct set *set, unsigned int options)
|
||||
{
|
||||
struct ip_set_iptreemap *mysetdata = set->settype->header;
|
||||
|
||||
if (mysetdata->gc_interval)
|
||||
printf(" gc: %u", mysetdata->gc_interval);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void
|
||||
printips_sorted(struct set *set, void *data, size_t len, unsigned int options)
|
||||
{
|
||||
struct ip_set_req_iptreemap *req;
|
||||
size_t offset = 0;
|
||||
|
||||
while (len >= offset + sizeof(struct ip_set_req_iptreemap)) {
|
||||
req = data + offset;
|
||||
|
||||
printf("%s", ip_tostring(req->start, options));
|
||||
if (req->start != req->end)
|
||||
printf(":%s", ip_tostring(req->end, options));
|
||||
printf("\n");
|
||||
|
||||
offset += sizeof(struct ip_set_req_iptreemap);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
saveheader(struct set *set, unsigned int options)
|
||||
{
|
||||
struct ip_set_iptreemap *mysetdata = set->settype->header;
|
||||
|
||||
printf("-N %s %s", set->name, set->settype->typename);
|
||||
|
||||
if (mysetdata->gc_interval)
|
||||
printf(" --gc %u", mysetdata->gc_interval);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void
|
||||
saveips(struct set *set, void *data, size_t len, unsigned int options)
|
||||
{
|
||||
struct ip_set_req_iptreemap *req;
|
||||
size_t offset = 0;
|
||||
|
||||
while (len >= offset + sizeof(struct ip_set_req_iptreemap)) {
|
||||
req = data + offset;
|
||||
|
||||
printf("-A %s %s", set->name, ip_tostring(req->start, options));
|
||||
|
||||
if (req->start != req->end)
|
||||
printf(":%s", ip_tostring(req->end, options));
|
||||
|
||||
printf("\n");
|
||||
|
||||
offset += sizeof(struct ip_set_req_iptreemap);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
printf(
|
||||
"-N set iptreemap --gc interval\n"
|
||||
"-A set IP\n"
|
||||
"-D set IP\n"
|
||||
"-T set IP\n"
|
||||
);
|
||||
}
|
||||
|
||||
static struct settype settype_iptreemap = {
|
||||
.typename = SETTYPE_NAME,
|
||||
.protocol_version = IP_SET_PROTOCOL_VERSION,
|
||||
|
||||
.create_size = sizeof(struct ip_set_req_iptreemap_create),
|
||||
.create_init = &create_init,
|
||||
.create_parse = &create_parse,
|
||||
.create_final = &create_final,
|
||||
.create_opts = create_opts,
|
||||
|
||||
.adt_size = sizeof(struct ip_set_req_iptreemap),
|
||||
.adt_parser = &adt_parser,
|
||||
|
||||
.header_size = sizeof(struct ip_set_iptreemap),
|
||||
.initheader = &initheader,
|
||||
.printheader = &printheader,
|
||||
.printips = &printips_sorted,
|
||||
.printips_sorted = &printips_sorted,
|
||||
.saveheader = &saveheader,
|
||||
.saveips = &saveips,
|
||||
|
||||
.bindip_tostring = &binding_ip_tostring,
|
||||
.bindip_parse = &parse_ip,
|
||||
|
||||
.usage = &usage,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void iptreemap_init(void)
|
||||
{
|
||||
settype_register(&settype_iptreemap);
|
||||
}
|
339
extensions/ipset/ipset_macipmap.c
Normal file
339
extensions/ipset/ipset_macipmap.c
Normal file
@@ -0,0 +1,339 @@
|
||||
/* 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 <linux/if_ether.h>
|
||||
|
||||
#include "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,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void macipmap_init(void)
|
||||
{
|
||||
settype_register(&settype_macipmap);
|
||||
|
||||
}
|
350
extensions/ipset/ipset_nethash.c
Normal file
350
extensions/ipset/ipset_nethash.c
Normal file
@@ -0,0 +1,350 @@
|
||||
/* 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 <limits.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/types.h>
|
||||
|
||||
#include "ip_set_nethash.h"
|
||||
#include "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;
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void nethash_init(void)
|
||||
{
|
||||
settype_register(&settype_nethash);
|
||||
|
||||
}
|
244
extensions/ipset/ipset_portmap.c
Normal file
244
extensions/ipset/ipset_portmap.c
Normal file
@@ -0,0 +1,244 @@
|
||||
/* 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 "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,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void portmap_init(void)
|
||||
{
|
||||
settype_register(&settype_portmap);
|
||||
|
||||
}
|
Reference in New Issue
Block a user