Compare commits

..

32 Commits
v1.19 ... v1.20

Author SHA1 Message Date
Jan Engelhardt
3c0397867b Xtables-addons 1.20 2009-11-19 12:14:26 +01:00
Jan Engelhardt
16e4968343 pknock: avoid compiler warnings for !PK_CRYPTO case
xt_pknock.c: In function "update_peer":
xt_pknock.c:890:3: warning: implicit declaration of function "pass_security"
xt_pknock.c: In function "pknock_mt":
xt_pknock.c:1030:5: warning: implicit declaration of function "is_close_knock"
2009-11-19 12:13:29 +01:00
Jan Engelhardt
8c910aa82b pknock: reverse control flow for next patch 2009-11-19 12:11:46 +01:00
Jan Engelhardt
6340d999d7 ipset: fast forward to v4.1 2009-11-15 16:34:05 +01:00
Jan Engelhardt
11af976e8b ipset/doc: clarify terms "ip" and "cidrsize"
IP refers to Internet Protocol; adding "address" is therefore beneficial.
The CIDR size is better known as "prefix length".

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
2009-11-11 13:52:04 +01:00
Jan Engelhardt
a4afc4159e ipset/doc: escape dashes in manpage
(Hyphens remain unescaped.)

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
2009-11-11 13:31:20 +01:00
Jan Engelhardt
24bb655130 ipset/doc: make emphasis markup consistent
Consistently apply markup so that only replaceable items are italic,
and only items to be typed verbatim are bold. Also apply the command
syntax "BNF" (where and when to use [], {}) that is used in the
iptables manpages to ipset.8.

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
2009-11-11 11:48:34 +01:00
Jan Engelhardt
2eaa5c5606 ipset/doc: fix an unbalanced tag
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
2009-11-11 11:29:44 +01:00
Jan Engelhardt
0593b96c2c ipset: fast forward to v4.0 2009-11-11 14:23:29 +01:00
Jan Engelhardt
6f1c1ef0ce ipset: do install manpage 2009-11-11 14:00:13 +01:00
Jan Engelhardt
d5ff452ea5 iptaccount: fix a compile warning
iptaccount.c: In function 'addr_to_dotted':
iptaccount.c:42: warning: implicit declaration of function 'htonl'
2009-11-09 16:00:25 +01:00
Jan Engelhardt
c012379e0b build: link to libxtables_LIBS
This should make AutoReqProv (or equivalent) do the dependencies
instead of manually having to specify it.
2009-11-07 21:04:53 +01:00
Jan Engelhardt
15de3beb63 build: consolidate xtables_CFLAGS and libxtables_CFLAGS
There was one variable too much around.
2009-11-07 21:03:04 +01:00
Jan Engelhardt
160e04d13e build: offer LDLIBS placeholder 2009-11-07 20:50:57 +01:00
Jan Engelhardt
359ecc7a8c ACCOUNT: transfer table data in host order
Make compatibility happy.
2009-11-04 23:37:34 +01:00
Jan Engelhardt
6ee71ed485 ACCOUNT: remove extra intrapositional negation check 2009-11-03 20:31:49 +01:00
Natanael Copa
7bd0157a9a build: fix --without-kbuild semantics
The --without-build option is useful when your distro has multiple
kernels and/or you want to build a common package for userspace stuff
only. Support this option properly.
2009-11-03 17:45:49 +01:00
Jan Engelhardt
6f8582eb5e Merge branch 'ACCOUNT' 2009-10-30 18:48:34 +01:00
Jan Engelhardt
df7168bb4d ACCOUNT: use more precise types and fix minor tidbits 2009-10-30 18:48:04 +01:00
Jan Engelhardt
0aa7be2f1d ACCOUNT: annotate source where BE is used 2009-10-30 18:42:40 +01:00
Jan Engelhardt
d9cd40e9fa pknock: switch allocations to GFP_KERNEL
All allocations currently using GFP_ATOMIC happen in user context, so
GFP_KERNEL is sufficient.
2009-10-30 18:40:52 +01:00
Jan Engelhardt
8bd6ef78f9 ACCOUNT: correctly account for network-order addresses on BE arches 2009-10-30 18:36:47 +01:00
Jan Engelhardt
578af6f726 ACCOUNT: move private struct declarations into .c file 2009-10-27 11:04:23 +01:00
Jan Engelhardt
22edc7a24d LOGMARK: remove non-existent options from manpage 2009-10-24 01:14:20 +02:00
Chris Blum
304e5e52ca ipp2p: lookup optimizations, spello fix 2009-10-16 16:37:32 +02:00
Chris Blum
3f7288abfe ipp2p: fix Gnutella line ending detection
There is another mistake in the code. I have checked the Gnutella
protocol specification -- looks like the line separation is 0x0d-0x0a
and not 0x0a-0x0d (it seemed obvious but I was not sure and thought
they cannot have possibly got that wrong...). It would certainly
explain why I have never seen a match on any of my systems.
2009-10-16 16:36:12 +02:00
Jan Engelhardt
aad0cafd19 pknock: move manpage into pknock's subdirectory 2009-10-14 21:18:08 +02:00
Chris Blum
17a0312848 ipp2p: add more boundary checks 2009-10-14 20:08:20 +02:00
Chris Blum
c66d291eb8 ipp2p: only pass UDP payload to subfunctions 2009-10-14 20:00:27 +02:00
Jan Engelhardt
cb407ce7c4 ipp2p: remove redundant local variables 2009-10-14 12:14:00 +02:00
Jan Engelhardt
3f426f3b43 build: reword warning message for x_tables.h absence 2009-10-14 15:19:57 +02:00
Jan Engelhardt
0b3ae22673 build: check for /usr/include/linux files 2009-10-13 11:45:12 +02:00
55 changed files with 1490 additions and 2280 deletions

View File

@@ -10,8 +10,9 @@ CC = @CC@
CCLD = ${CC}
regular_CFLAGS = @regular_CFLAGS@
xtables_CFLAGS = @xtables_CFLAGS@
AM_CFLAGS = ${regular_CFLAGS} ${xtables_CFLAGS}
libxtables_CFLAGS = @libxtables_CFLAGS@
libxtables_LIBS = @libxtables_LIBS@
AM_CFLAGS = ${regular_CFLAGS} ${libxtables_CFLAGS}
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
AM_DEFAULT_VERBOSITY = 0
@@ -53,7 +54,7 @@ clean:
rm -f *.oo *.so;
lib%.so: lib%.oo
${AM_V_CCLD}${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $<;
${AM_V_CCLD}${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $< ${libxtables_LIBS} ${LDLIBS};
%.oo: ${XA_SRCDIR}/%.c
${AM_V_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -DPIC -fPIC ${CFLAGS} -o $@ -c $<;

View File

@@ -1,5 +1,5 @@
AC_INIT([xtables-addons], [1.19])
AC_INIT([xtables-addons], [1.20])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AC_PROG_INSTALL
@@ -9,11 +9,18 @@ AM_PROG_CC_C_O
AC_DISABLE_STATIC
AC_PROG_LIBTOOL
kbuilddir="/lib/modules/$(uname -r)/build";
AC_ARG_WITH([kbuild],
AS_HELP_STRING([--with-kbuild=PATH],
[Path to kernel build directory [[/lib/modules/CURRENT/build]]]),
[kbuilddir="$withval"])
[kbuilddir="$withval"],
[kbuilddir="/lib/modules/$(uname -r)/build"])
#
# check for --without-kbuild
#
if [[ "$kbuilddir" == no ]]; then
kbuilddir="";
fi
AC_ARG_WITH([ksource],,[ksourcedir="$withval"])
AC_ARG_WITH([xtables],
AS_HELP_STRING([--with-xtables=PATH],
@@ -32,10 +39,10 @@ if [[ -n "$xtables_location" ]]; then
AC_MSG_CHECKING([xtables.h presence])
if [[ -f "$xtables_location/xtables.h" ]]; then
AC_MSG_RESULT([$xtables_location/xtables.h])
xtables_CFLAGS="-I $xtables_location";
libxtables_CFLAGS="-I $xtables_location";
elif [[ -f "$xtables_location/include/xtables.h" ]]; then
AC_MSG_RESULT([$xtables_location/include/xtables.h])
xtables_CFLAGS="-I $xtables_location/include";
libxtables_CFLAGS="-I $xtables_location/include";
fi;
if [[ -z "$xtables_CFLAGS" ]]; then
if [[ -f "$includedir/xtables.h" ]]; then
@@ -44,9 +51,14 @@ if [[ -n "$xtables_location" ]]; then
AC_MSG_RESULT([no])
fi;
fi;
libxtables_LIBS="-lxtables";
AC_SUBST([libxtables_CFLAGS])
AC_SUBST([libxtables_LIBS])
else
PKG_CHECK_MODULES([libxtables], [xtables >= 1.4.3])
fi;
AC_CHECK_HEADERS([linux/netfilter/x_tables.h], [],
[AC_MSG_ERROR([You need to have linux/netfilter/x_tables.h, either through /usr/include or the iptables directory (--with-xtables=)])])
regular_CFLAGS="-D_LARGEFILE_SOURCE=1 -D_LARGE_FILES -D_FILE_OFFSET_BITS=64 \
-D_REENTRANT -Wall -Waggregate-return -Wmissing-declarations \
@@ -95,7 +107,6 @@ elif test \( "$kmajor" -lt 2 -o "$kminor" -lt 6 -o "$kmicro" -lt 17 \) -o \
fi;
AC_SUBST([regular_CFLAGS])
AC_SUBST([xtables_CFLAGS])
AC_SUBST([kinclude_CFLAGS])
AC_SUBST([kbuilddir])
AC_SUBST([ksourcedir])

View File

@@ -3,6 +3,16 @@ HEAD
====
Xtables-addons 1.20 (November 19 2009)
======================================
- ipp2p: add more boundary checks
- ipp2p: fix Gnutelle line ending detection
- LOGMARK: remove unknown options from manpage
- ACCOUNT: endianess-correctness
- ipset: install manpage
- ipset: fast forward to v4.1
Xtables-addons 1.19 (October 12 2009)
=====================================
- build: compile fixes for 2.6.31-rt

View File

@@ -21,6 +21,8 @@
#include <getopt.h>
#include <signal.h>
#include <arpa/inet.h>
#include <linux/types.h>
#include <libxt_ACCOUNT_cl.h>
bool exit_now;
@@ -33,15 +35,14 @@ static void sig_term(int signr)
exit_now = true;
}
char *addr_to_dotted(unsigned int);
char *addr_to_dotted(unsigned int addr)
static char *addr_to_dotted(unsigned int addr)
{
static char buf[17];
static char buf[16];
const unsigned char *bytep;
addr = htonl(addr);
bytep = (const unsigned char *)&addr;
snprintf(buf, 16, "%u.%u.%u.%u", bytep[0], bytep[1], bytep[2], bytep[3]);
buf[16] = 0;
snprintf(buf, sizeof(buf), "%u.%u.%u.%u", bytep[0], bytep[1], bytep[2], bytep[3]);
return buf;
}
@@ -188,7 +189,7 @@ int main(int argc, char *argv[])
{
printf("Read failed: %s\n", ctx.error_str);
ipt_ACCOUNT_deinit(&ctx);
exit(-1);
return EXIT_FAILURE;
}
if (!doCSV)
@@ -219,5 +220,5 @@ int main(int argc, char *argv[])
printf("Finished.\n");
ipt_ACCOUNT_deinit(&ctx);
exit(0);
return EXIT_SUCCESS;
}

View File

@@ -2,6 +2,7 @@
Author: Intra2net AG <opensource@intra2net.com>
*/
#include <stdbool.h>
#include <stdio.h>
#include <netdb.h>
#include <string.h>
@@ -13,9 +14,9 @@
#include "xt_ACCOUNT.h"
static struct option account_tg_opts[] = {
{ .name = "addr", .has_arg = 1, .flag = 0, .val = 'a' },
{ .name = "tname", .has_arg = 1, .flag = 0, .val = 't' },
{ .name = 0 }
{.name = "addr", .has_arg = true, .val = 'a'},
{.name = "tname", .has_arg = true, .val = 't'},
{NULL},
};
/* Function which prints out usage message. */
@@ -56,10 +57,6 @@ static int account_tg_parse(int c, char **argv, int invert, unsigned int *flags,
xtables_error(PARAMETER_PROBLEM, "Can't specify --%s twice",
account_tg_opts[0].name);
if (xtables_check_inverse(optarg, &invert, NULL, 0))
xtables_error(PARAMETER_PROBLEM, "Unexpected `!' after --%s",
account_tg_opts[0].name);
xtables_ipparse_any(optarg, &addrs, &mask, &naddrs);
if (naddrs > 1)
xtables_error(PARAMETER_PROBLEM, "multiple IP addresses not allowed");
@@ -76,11 +73,6 @@ static int account_tg_parse(int c, char **argv, int invert, unsigned int *flags,
"Can't specify --%s twice",
account_tg_opts[1].name);
if (xtables_check_inverse(optarg, &invert, NULL, 0))
xtables_error(PARAMETER_PROBLEM,
"Unexpected `!' after --%s",
account_tg_opts[1].name);
if (strlen(optarg) > ACCOUNT_TABLE_NAME_LEN - 1)
xtables_error(PARAMETER_PROBLEM,
"Maximum table name length %u for --%s",
@@ -105,7 +97,7 @@ static void account_tg_check(unsigned int flags)
}
static void account_tg_print_it(const void *ip,
const struct xt_entry_target *target, char do_prefix)
const struct xt_entry_target *target, bool do_prefix)
{
const struct ipt_acc_info *accountinfo
= (const struct ipt_acc_info *)target->data;
@@ -137,18 +129,19 @@ account_tg_print(const void *ip,
const struct xt_entry_target *target,
int numeric)
{
account_tg_print_it(ip, target, 0);
account_tg_print_it(ip, target, false);
}
/* Saves the union ipt_targinfo in parsable form to stdout. */
static void
account_tg_save(const void *ip, const struct xt_entry_target *target)
{
account_tg_print_it(ip, target, 1);
account_tg_print_it(ip, target, true);
}
static struct xtables_target account_tg_reg = {
.name = "ACCOUNT",
.revision = 1,
.family = AF_INET,
.version = XTABLES_VERSION,
.size = XT_ALIGN(sizeof(struct ipt_acc_info)),

View File

@@ -42,6 +42,68 @@
#error "ipt_ACCOUNT needs at least a PAGE_SIZE of 4096"
#endif
/**
* Internal table structure, generated by check_entry()
* @name: name of the table
* @ip: base IP address of the network
* @mask: netmask of the network
* @depth: size of network (0: 8-bit, 1: 16-bit, 2: 24-bit)
* @refcount: refcount of the table; if zero, destroy it
* @itemcount: number of IP addresses in this table
* @data; pointer to the actual data, depending on netmask
*/
struct ipt_acc_table {
char name[ACCOUNT_TABLE_NAME_LEN];
__be32 ip;
__be32 netmask;
uint8_t depth;
uint32_t refcount;
uint32_t itemcount;
void *data;
};
/**
* Internal handle structure
* @ip: base IP address of the network. Used for caculating the final
* address during get_data().
* @depth: size of the network; see above
* @itemcount: number of addresses in this table
*/
struct ipt_acc_handle {
uint32_t ip;
uint8_t depth;
uint32_t itemcount;
void *data;
};
/* Used for every IP entry
Size is 16 bytes so that 256 (class C network) * 16
fits in one kernel (zero) page */
struct ipt_acc_ip {
uint32_t src_packets;
uint32_t src_bytes;
uint32_t dst_packets;
uint32_t dst_bytes;
};
/*
* The IP addresses are organized as an array so that direct slot
* calculations are possible.
* Only 8-bit networks are preallocated, 16/24-bit networks
* allocate their slots when needed -> very efficent.
*/
struct ipt_acc_mask_24 {
struct ipt_acc_ip ip[256];
};
struct ipt_acc_mask_16 {
struct ipt_acc_mask_24 *mask_24[256];
};
struct ipt_acc_mask_8 {
struct ipt_acc_mask_16 *mask_16[256];
};
static struct ipt_acc_table *ipt_acc_tables;
static struct ipt_acc_handle *ipt_acc_handles;
static void *ipt_acc_tmpbuf;
@@ -65,7 +127,7 @@ static void *ipt_acc_zalloc_page(void)
}
/* Recursive free of all data structures */
static void ipt_acc_data_free(void *data, unsigned char depth)
static void ipt_acc_data_free(void *data, uint8_t depth)
{
/* Empty data set */
if (!data)
@@ -117,7 +179,7 @@ static void ipt_acc_data_free(void *data, unsigned char depth)
/* Look for existing table / insert new one.
Return internal ID or -1 on error */
static int ipt_acc_table_insert(char *name, uint32_t ip, uint32_t netmask)
static int ipt_acc_table_insert(const char *name, __be32 ip, __be32 netmask)
{
unsigned int i;
@@ -265,12 +327,14 @@ static void ipt_acc_destroy(const struct xt_tgdtor_param *par)
}
static void ipt_acc_depth0_insert(struct ipt_acc_mask_24 *mask_24,
uint32_t net_ip, uint32_t netmask,
uint32_t src_ip, uint32_t dst_ip,
__be32 net_ip, __be32 netmask,
__be32 src_ip, __be32 dst_ip,
uint32_t size, uint32_t *itemcount)
{
unsigned char is_src = 0, is_dst = 0, src_slot, dst_slot;
char is_src_new_ip = 0, is_dst_new_ip = 0; /* Check if this entry is new */
uint8_t src_slot, dst_slot;
bool is_src = false, is_dst = false;
/* Check if this entry is new */
bool is_src_new_ip = false, is_dst_new_ip = false;
pr_debug("ACCOUNT: ipt_acc_depth0_insert: %u.%u.%u.%u/%u.%u.%u.%u "
"for net %u.%u.%u.%u/%u.%u.%u.%u, size: %u\n", NIPQUAD(src_ip),
@@ -278,12 +342,12 @@ static void ipt_acc_depth0_insert(struct ipt_acc_mask_24 *mask_24,
/* Check if src/dst is inside our network. */
/* Special: net_ip = 0.0.0.0/0 gets stored as src in slot 0 */
if (!netmask)
if (netmask == 0)
src_ip = 0;
if ((net_ip & netmask) == (src_ip & netmask))
is_src = 1;
if ((net_ip & netmask) == (dst_ip & netmask) && netmask)
is_dst = 1;
is_src = true;
if ((net_ip & netmask) == (dst_ip & netmask) && netmask != 0)
is_dst = true;
if (!is_src && !is_dst) {
pr_debug("ACCOUNT: Skipping packet %u.%u.%u.%u/%u.%u.%u.%u "
@@ -293,8 +357,8 @@ static void ipt_acc_depth0_insert(struct ipt_acc_mask_24 *mask_24,
}
/* Calculate array positions */
src_slot = (src_ip & 0xFF000000) >> 24;
dst_slot = (dst_ip & 0xFF000000) >> 24;
src_slot = ntohl(src_ip) & 0xFF;
dst_slot = ntohl(dst_ip) & 0xFF;
/* Increase size counters */
if (is_src) {
@@ -302,7 +366,7 @@ static void ipt_acc_depth0_insert(struct ipt_acc_mask_24 *mask_24,
pr_debug("ACCOUNT: Calculated SRC 8 bit network slot: %d\n", src_slot);
if (!mask_24->ip[src_slot].src_packets
&& !mask_24->ip[src_slot].dst_packets)
is_src_new_ip = 1;
is_src_new_ip = true;
mask_24->ip[src_slot].src_packets++;
mask_24->ip[src_slot].src_bytes += size;
@@ -311,7 +375,7 @@ static void ipt_acc_depth0_insert(struct ipt_acc_mask_24 *mask_24,
pr_debug("ACCOUNT: Calculated DST 8 bit network slot: %d\n", dst_slot);
if (!mask_24->ip[dst_slot].src_packets
&& !mask_24->ip[dst_slot].dst_packets)
is_dst_new_ip = 1;
is_dst_new_ip = true;
mask_24->ip[dst_slot].dst_packets++;
mask_24->ip[dst_slot].dst_bytes += size;
@@ -323,29 +387,29 @@ static void ipt_acc_depth0_insert(struct ipt_acc_mask_24 *mask_24,
if (is_src_new_ip || is_dst_new_ip) {
pr_debug("ACCOUNT: src_slot == dst_slot: %d, %d\n",
is_src_new_ip, is_dst_new_ip);
(*itemcount)++;
++*itemcount;
}
} else {
if (is_src_new_ip) {
pr_debug("ACCOUNT: New src_ip: %u.%u.%u.%u\n", NIPQUAD(src_ip));
(*itemcount)++;
++*itemcount;
}
if (is_dst_new_ip) {
pr_debug("ACCOUNT: New dst_ip: %u.%u.%u.%u\n", NIPQUAD(dst_ip));
(*itemcount)++;
++*itemcount;
}
}
pr_debug("ACCOUNT: Itemcounter after: %d\n", *itemcount);
}
static void ipt_acc_depth1_insert(struct ipt_acc_mask_16 *mask_16,
uint32_t net_ip, uint32_t netmask,
uint32_t src_ip, uint32_t dst_ip,
__be32 net_ip, __be32 netmask,
__be32 src_ip, __be32 dst_ip,
uint32_t size, uint32_t *itemcount)
{
/* Do we need to process src IP? */
if ((net_ip & netmask) == (src_ip & netmask)) {
unsigned char slot = (src_ip & 0x00FF0000) >> 16;
uint8_t slot = (ntohl(src_ip) & 0xFF00) >> 8;
pr_debug("ACCOUNT: Calculated SRC 16 bit network slot: %d\n", slot);
/* Do we need to create a new mask_24 bucket? */
@@ -361,7 +425,7 @@ static void ipt_acc_depth1_insert(struct ipt_acc_mask_16 *mask_16,
/* Do we need to process dst IP? */
if ((net_ip & netmask) == (dst_ip & netmask)) {
unsigned char slot = (dst_ip & 0x00FF0000) >> 16;
uint8_t slot = (ntohl(dst_ip) & 0xFF00) >> 8;
pr_debug("ACCOUNT: Calculated DST 16 bit network slot: %d\n", slot);
/* Do we need to create a new mask_24 bucket? */
@@ -377,13 +441,13 @@ static void ipt_acc_depth1_insert(struct ipt_acc_mask_16 *mask_16,
}
static void ipt_acc_depth2_insert(struct ipt_acc_mask_8 *mask_8,
uint32_t net_ip, uint32_t netmask,
uint32_t src_ip, uint32_t dst_ip,
__be32 net_ip, __be32 netmask,
__be32 src_ip, __be32 dst_ip,
uint32_t size, uint32_t *itemcount)
{
/* Do we need to process src IP? */
if ((net_ip & netmask) == (src_ip & netmask)) {
unsigned char slot = (src_ip & 0x0000FF00) >> 8;
uint8_t slot = (ntohl(src_ip) & 0xFF0000) >> 16;
pr_debug("ACCOUNT: Calculated SRC 24 bit network slot: %d\n", slot);
/* Do we need to create a new mask_24 bucket? */
@@ -399,7 +463,7 @@ static void ipt_acc_depth2_insert(struct ipt_acc_mask_8 *mask_8,
/* Do we need to process dst IP? */
if ((net_ip & netmask) == (dst_ip & netmask)) {
unsigned char slot = (dst_ip & 0x0000FF00) >> 8;
uint8_t slot = (ntohl(dst_ip) & 0xFF0000) >> 16;
pr_debug("ACCOUNT: Calculated DST 24 bit network slot: %d\n", slot);
/* Do we need to create a new mask_24 bucket? */
@@ -419,8 +483,8 @@ static unsigned int ipt_acc_target(struct sk_buff **pskb, const struct xt_target
const struct ipt_acc_info *info =
par->targinfo;
uint32_t src_ip = ip_hdr(*pskb)->saddr;
uint32_t dst_ip = ip_hdr(*pskb)->daddr;
__be32 src_ip = ip_hdr(*pskb)->saddr;
__be32 dst_ip = ip_hdr(*pskb)->daddr;
uint32_t size = ntohs(ip_hdr(*pskb)->tot_len);
spin_lock_bh(&ipt_acc_lock);
@@ -532,7 +596,7 @@ static int ipt_acc_handle_prepare_read(char *tablename,
struct ipt_acc_handle *dest, uint32_t *count)
{
int table_nr = -1;
unsigned char depth;
uint8_t depth;
for (table_nr = 0; table_nr < ACCOUNT_MAX_TABLES; table_nr++)
if (strncmp(ipt_acc_tables[table_nr].name, tablename,
@@ -682,7 +746,7 @@ static int ipt_acc_handle_copy_data(void *to_user, unsigned long *to_user_pos,
for (i = 0; i <= 255; i++) {
if (data->ip[i].src_packets || data->ip[i].dst_packets) {
handle_ip.ip = net_ip | net_OR_mask | (i << 24);
handle_ip.ip = net_ip | net_OR_mask | i;
handle_ip.src_packets = data->ip[i].src_packets;
handle_ip.src_bytes = data->ip[i].src_bytes;
@@ -713,7 +777,7 @@ static int ipt_acc_handle_get_data(uint32_t handle, void *to_user)
{
unsigned long to_user_pos = 0, tmpbuf_pos = 0;
uint32_t net_ip;
unsigned char depth;
uint8_t depth;
if (handle >= ACCOUNT_MAX_HANDLES) {
printk("ACCOUNT: invalid handle for ipt_acc_handle_get_data() "
@@ -726,7 +790,7 @@ static int ipt_acc_handle_get_data(uint32_t handle, void *to_user)
return -1;
}
net_ip = ipt_acc_handles[handle].ip;
net_ip = ntohl(ipt_acc_handles[handle].ip);
depth = ipt_acc_handles[handle].depth;
/* 8 bit network */
@@ -755,7 +819,7 @@ static int ipt_acc_handle_get_data(uint32_t handle, void *to_user)
struct ipt_acc_mask_24 *network =
network_16->mask_24[b];
if (ipt_acc_handle_copy_data(to_user, &to_user_pos,
&tmpbuf_pos, network, net_ip, (b << 16)))
&tmpbuf_pos, network, net_ip, (b << 8)))
return -1;
}
}
@@ -783,7 +847,7 @@ static int ipt_acc_handle_get_data(uint32_t handle, void *to_user)
network_16->mask_24[b];
if (ipt_acc_handle_copy_data(to_user,
&to_user_pos, &tmpbuf_pos,
network, net_ip, (a << 8) | (b << 16)))
network, net_ip, (a << 16) | (b << 8)))
return -1;
}
}
@@ -1017,6 +1081,7 @@ static int ipt_acc_get_ctl(struct sock *sk, int cmd, void *user, int *len)
static struct xt_target xt_acc_reg __read_mostly = {
.name = "ACCOUNT",
.revision = 1,
.family = AF_INET,
.target = ipt_acc_target,
.targetsize = sizeof(struct ipt_acc_info),

View File

@@ -35,38 +35,12 @@
/* Structure for the userspace part of ipt_ACCOUNT */
struct ipt_acc_info {
uint32_t net_ip;
uint32_t net_mask;
__be32 net_ip;
__be32 net_mask;
char table_name[ACCOUNT_TABLE_NAME_LEN];
int32_t table_nr;
};
/* Internal table structure, generated by check_entry() */
struct ipt_acc_table {
char name[ACCOUNT_TABLE_NAME_LEN]; /* name of the table */
uint32_t ip; /* base IP of network */
uint32_t netmask; /* netmask of the network */
unsigned char depth; /* size of network:
0: 8 bit, 1: 16bit, 2: 24 bit */
uint32_t refcount; /* refcount of this table.
if zero, destroy it */
uint32_t itemcount; /* number of IPs in this table */
void *data; /* pointer to the actual data,
depending on netmask */
};
/* Internal handle structure */
struct ipt_acc_handle {
uint32_t ip; /* base IP of network. Used for
caculating the final IP during
get_data() */
unsigned char depth; /* size of network. See above for
details */
uint32_t itemcount; /* number of IPs in this table */
void *data; /* pointer to the actual data,
depending on size */
};
/* Handle structure for communication with the userspace library */
struct ipt_acc_handle_sockopt {
uint32_t handle_nr; /* Used for HANDLE_FREE */
@@ -76,43 +50,15 @@ struct ipt_acc_handle_sockopt {
HANDLE_READ_FLUSH */
};
/* Used for every IP entry
Size is 16 bytes so that 256 (class C network) * 16
fits in one kernel (zero) page */
struct ipt_acc_ip {
uint32_t src_packets;
uint32_t src_bytes;
uint32_t dst_packets;
uint32_t dst_bytes;
};
/*
Used for every IP when returning data
*/
struct ipt_acc_handle_ip {
uint32_t ip;
__be32 ip;
uint32_t src_packets;
uint32_t src_bytes;
uint32_t dst_packets;
uint32_t dst_bytes;
};
/*
The IPs are organized as an array so that direct slot
calculations are possible.
Only 8 bit networks are preallocated, 16/24 bit networks
allocate their slots when needed -> very efficent.
*/
struct ipt_acc_mask_24 {
struct ipt_acc_ip ip[256];
};
struct ipt_acc_mask_16 {
struct ipt_acc_mask_24 *mask_24[256];
};
struct ipt_acc_mask_8 {
struct ipt_acc_mask_16 *mask_16[256];
};
#endif /* _IPT_ACCOUNT_H */

View File

@@ -7,3 +7,5 @@ include ../../Makefile.extra
sbin_PROGRAMS = ipset
ipset_LDADD = -ldl
ipset_LDFLAGS = -rdynamic
man_MANS = ipset.8

File diff suppressed because it is too large Load Diff

View File

@@ -48,7 +48,8 @@
/*
* Used so that the kernel module and ipset-binary can match their versions
*/
#define IP_SET_PROTOCOL_VERSION 3
#define IP_SET_PROTOCOL_UNALIGNED 3
#define IP_SET_PROTOCOL_VERSION 4
#define IP_SET_MAXNAMELEN 32 /* set names and set typenames */
@@ -236,7 +237,7 @@ struct ip_set_req_max_sets {
struct ip_set_req_setnames {
unsigned op;
ip_set_id_t index; /* set to list/save */
u_int32_t size; /* size to get setdata/bindings */
u_int32_t size; /* size to get setdata */
/* followed by sets number of struct ip_set_name_list */
};
@@ -310,6 +311,11 @@ static inline int bitmap_bytes(ip_set_ip_t a, ip_set_ip_t b)
/* General limit for the elements in a set */
#define MAX_RANGE 0x0000FFFF
/* Alignment: 'unsigned long' unsupported */
#define IPSET_ALIGNTO 4
#define IPSET_ALIGN(len) (((len) + IPSET_ALIGNTO - 1) & ~(IPSET_ALIGNTO - 1))
#define IPSET_VALIGN(len, old) ((old) ? (len) : IPSET_ALIGN(len))
#ifdef __KERNEL__
#include "ip_set_compat.h"
#include "ip_set_malloc.h"
@@ -358,16 +364,13 @@ struct ip_set_type {
*/
int (*testip_kernel) (struct ip_set *set,
const struct sk_buff * skb,
ip_set_ip_t *ip,
const u_int32_t *flags,
unsigned char index);
const u_int32_t *flags);
/* test for IP in set (userspace: ipset -T set IP)
* return 0 if not in set, 1 if in set.
*/
int (*testip) (struct ip_set *set,
const void *data, u_int32_t size,
ip_set_ip_t *ip);
const void *data, u_int32_t size);
/*
* Size of the data structure passed by when
@@ -381,8 +384,7 @@ struct ip_set_type {
* If the address was not already in the set, 0 is returned.
*/
int (*addip) (struct ip_set *set,
const void *data, u_int32_t size,
ip_set_ip_t *ip);
const void *data, u_int32_t size);
/* Add IP into set (kernel: iptables ... -j SET set src|dst)
* Return -EEXIST if the address is already in the set,
@@ -390,10 +392,8 @@ struct ip_set_type {
* If the address was not already in the set, 0 is returned.
*/
int (*addip_kernel) (struct ip_set *set,
const struct sk_buff * skb,
ip_set_ip_t *ip,
const u_int32_t *flags,
unsigned char index);
const struct sk_buff * skb,
const u_int32_t *flags);
/* remove IP from set (userspace: ipset -D set --entry x)
* Return -EEXIST if the address is NOT in the set,
@@ -401,8 +401,7 @@ struct ip_set_type {
* If the address really was in the set, 0 is returned.
*/
int (*delip) (struct ip_set *set,
const void *data, u_int32_t size,
ip_set_ip_t *ip);
const void *data, u_int32_t size);
/* remove IP from set (kernel: iptables ... -j SET --entry x)
* Return -EEXIST if the address is NOT in the set,
@@ -410,10 +409,8 @@ struct ip_set_type {
* If the address really was in the set, 0 is returned.
*/
int (*delip_kernel) (struct ip_set *set,
const struct sk_buff * skb,
ip_set_ip_t *ip,
const u_int32_t *flags,
unsigned char index);
const struct sk_buff * skb,
const u_int32_t *flags);
/* new set creation - allocated type specific items
*/
@@ -451,7 +448,7 @@ struct ip_set_type {
/* Listing: Get the size for the set members
*/
int (*list_members_size) (const struct ip_set *set);
int (*list_members_size) (const struct ip_set *set, char dont_align);
/* Listing: Get the set members
*
@@ -461,7 +458,7 @@ struct ip_set_type {
* correct.
*/
void (*list_members) (const struct ip_set *set,
void *data);
void *data, char dont_align);
char typename[IP_SET_MAXNAMELEN];
unsigned char features;
@@ -479,20 +476,11 @@ struct ip_set {
char name[IP_SET_MAXNAMELEN]; /* the name of the set */
rwlock_t lock; /* lock for concurrency control */
ip_set_id_t id; /* set id for swapping */
ip_set_id_t binding; /* default binding for the set */
atomic_t ref; /* in kernel and in hash references */
struct ip_set_type *type; /* the set types */
void *data; /* pooltype specific data */
};
/* Structure to bind set elements to sets */
struct ip_set_hash {
struct list_head list; /* list of clashing entries in hash */
ip_set_ip_t ip; /* ip from set */
ip_set_id_t id; /* set id */
ip_set_id_t binding; /* set we bind the element to */
};
/* register and unregister set references */
extern ip_set_id_t ip_set_get_byname(const char name[IP_SET_MAXNAMELEN]);
extern ip_set_id_t ip_set_get_byindex(ip_set_id_t index);
@@ -523,12 +511,11 @@ extern int ip_set_testip_kernel(ip_set_id_t id,
#define UADT0(type, adt, args...) \
static int \
FNAME(type,_u,adt)(struct ip_set *set, const void *data, u_int32_t size,\
ip_set_ip_t *hash_ip) \
FNAME(type,_u,adt)(struct ip_set *set, const void *data, u_int32_t size)\
{ \
const STRUCT(ip_set_req_,type) *req = data; \
\
return FNAME(type,_,adt)(set, hash_ip , ## args); \
return FNAME(type,_,adt)(set , ## args); \
}
#define UADT(type, adt, args...) \
@@ -538,14 +525,12 @@ FNAME(type,_u,adt)(struct ip_set *set, const void *data, u_int32_t size,\
static int \
FNAME(type,_k,adt)(struct ip_set *set, \
const struct sk_buff *skb, \
ip_set_ip_t *hash_ip, \
const u_int32_t *flags, \
unsigned char index) \
const u_int32_t *flags) \
{ \
ip_set_ip_t ip = getfn(skb, flags[index]); \
ip_set_ip_t ip = getfn(skb, flags); \
\
KADT_CONDITION \
return FNAME(type,_,adt)(set, hash_ip, ip , ##args); \
return FNAME(type,_,adt)(set, ip , ##args); \
}
#define REGISTER_MODULE(type) \
@@ -567,9 +552,9 @@ module_exit(ip_set_##type##_fini);
/* Common functions */
static inline ip_set_ip_t
ipaddr(const struct sk_buff *skb, u_int32_t flag)
ipaddr(const struct sk_buff *skb, const u_int32_t *flags)
{
return ntohl(flag & IPSET_SRC ? ip_hdr(skb)->saddr : ip_hdr(skb)->daddr);
return ntohl(flags[0] & IPSET_SRC ? ip_hdr(skb)->saddr : ip_hdr(skb)->daddr);
}
#define jhash_ip(map, i, ip) jhash_1word(ip, *(map->initval + i))
@@ -579,4 +564,6 @@ ipaddr(const struct sk_buff *skb, u_int32_t flag)
#endif /* __KERNEL__ */
#define UNUSED __attribute__ ((unused))
#endif /*_IP_SET_H*/

View File

@@ -77,22 +77,21 @@ type##_list_header(const struct ip_set *set, void *data) \
__##type##_list_header(map, header); \
}
#define BITMAP_LIST_MEMBERS_SIZE(type) \
#define BITMAP_LIST_MEMBERS_SIZE(type, dtype, sizeid, testfn) \
static int \
type##_list_members_size(const struct ip_set *set) \
type##_list_members_size(const struct ip_set *set, char dont_align) \
{ \
const struct ip_set_##type *map = set->data; \
ip_set_ip_t i, elements = 0; \
\
return map->size; \
}
#define BITMAP_LIST_MEMBERS(type) \
static void \
type##_list_members(const struct ip_set *set, void *data) \
{ \
const struct ip_set_##type *map = set->data; \
if (dont_align) \
return map->size; \
\
memcpy(data, map->members, map->size); \
for (i = 0; i < sizeid; i++) \
if (testfn) \
elements++; \
\
return elements * IPSET_ALIGN(sizeof(dtype)); \
}
#define IP_SET_TYPE(type, __features) \

View File

@@ -65,7 +65,28 @@ static inline void *kzalloc(size_t size, gfp_t flags)
#define KMEM_CACHE_CREATE(name, size) \
kmem_cache_create(name, size, 0, 0, NULL)
#endif
#ifndef NIPQUAD
#define NIPQUAD(addr) \
((unsigned char *)&addr)[0], \
((unsigned char *)&addr)[1], \
((unsigned char *)&addr)[2], \
((unsigned char *)&addr)[3]
#endif
#ifndef HIPQUAD
#if defined(__LITTLE_ENDIAN)
#define HIPQUAD(addr) \
((unsigned char *)&addr)[3], \
((unsigned char *)&addr)[2], \
((unsigned char *)&addr)[1], \
((unsigned char *)&addr)[0]
#elif defined(__BIG_ENDIAN)
#define HIPQUAD NIPQUAD
#else
#error "Please fix asm/byteorder.h"
#endif /* __LITTLE_ENDIAN */
#endif
#endif /* __KERNEL__ */
#endif /* _IP_SET_COMPAT_H */

View File

@@ -7,7 +7,7 @@
/* We must handle non-linear skbs */
static inline ip_set_ip_t
get_port(const struct sk_buff *skb, u_int32_t flags)
get_port(const struct sk_buff *skb, const u_int32_t *flags)
{
struct iphdr *iph = ip_hdr(skb);
u_int16_t offset = ntohs(iph->frag_off) & IP_OFFSET;
@@ -23,7 +23,7 @@ get_port(const struct sk_buff *skb, u_int32_t flags)
/* No choice either */
return INVALID_PORT;
return ntohs(flags & IPSET_SRC ?
return ntohs(flags[0] & IPSET_SRC ?
tcph.source : tcph.dest);
}
case IPPROTO_UDP: {
@@ -36,7 +36,7 @@ get_port(const struct sk_buff *skb, u_int32_t flags)
/* No choice either */
return INVALID_PORT;
return ntohs(flags & IPSET_SRC ?
return ntohs(flags[0] & IPSET_SRC ?
udph.source : udph.dest);
}
default:

View File

@@ -182,38 +182,46 @@ type##_list_header(const struct ip_set *set, void *data) \
#define HASH_LIST_MEMBERS_SIZE(type, dtype) \
static int \
type##_list_members_size(const struct ip_set *set) \
type##_list_members_size(const struct ip_set *set, char dont_align) \
{ \
const struct ip_set_##type *map = set->data; \
\
return (map->hashsize * sizeof(dtype)); \
return (map->elements * IPSET_VALIGN(sizeof(dtype), dont_align));\
}
#define HASH_LIST_MEMBERS(type, dtype) \
static void \
type##_list_members(const struct ip_set *set, void *data) \
type##_list_members(const struct ip_set *set, void *data, char dont_align)\
{ \
const struct ip_set_##type *map = set->data; \
dtype *elem; \
uint32_t i; \
dtype *elem, *d; \
uint32_t i, n = 0; \
\
for (i = 0; i < map->hashsize; i++) { \
elem = HARRAY_ELEM(map->members, dtype *, i); \
((dtype *)data)[i] = *elem; \
if (*elem) { \
d = data + n * IPSET_VALIGN(sizeof(dtype), dont_align);\
*d = *elem; \
n++; \
} \
} \
}
#define HASH_LIST_MEMBERS_MEMCPY(type, dtype) \
#define HASH_LIST_MEMBERS_MEMCPY(type, dtype, nonzero) \
static void \
type##_list_members(const struct ip_set *set, void *data) \
type##_list_members(const struct ip_set *set, void *data, char dont_align)\
{ \
const struct ip_set_##type *map = set->data; \
dtype *elem; \
uint32_t i; \
uint32_t i, n = 0; \
\
for (i = 0; i < map->hashsize; i++) { \
elem = HARRAY_ELEM(map->members, dtype *, i); \
memcpy((((dtype *)data)+i), elem, sizeof(dtype)); \
if (nonzero) { \
memcpy(data + n * IPSET_VALIGN(sizeof(dtype), dont_align),\
elem, sizeof(dtype)); \
n++; \
} \
} \
}

View File

@@ -25,22 +25,21 @@
static int limit = MAX_RANGE;
static inline __u32
iphash_id(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
iphash_id(struct ip_set *set, ip_set_ip_t ip)
{
struct ip_set_iphash *map = set->data;
__u32 id;
u_int16_t i;
ip_set_ip_t *elem;
*hash_ip = ip & map->netmask;
DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u, %u.%u.%u.%u",
set->name, HIPQUAD(ip), HIPQUAD(*hash_ip), HIPQUAD(map->netmask));
ip &= map->netmask;
DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip));
for (i = 0; i < map->probes; i++) {
id = jhash_ip(map, i, *hash_ip) % map->hashsize;
id = jhash_ip(map, i, ip) % map->hashsize;
DP("hash key: %u", id);
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
if (*elem == *hash_ip)
if (*elem == ip)
return id;
/* No shortcut - there can be deleted entries. */
}
@@ -48,9 +47,9 @@ iphash_id(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
}
static inline int
iphash_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
iphash_test(struct ip_set *set, ip_set_ip_t ip)
{
return (ip && iphash_id(set, hash_ip, ip) != UINT_MAX);
return (ip && iphash_id(set, ip) != UINT_MAX);
}
#define KADT_CONDITION
@@ -84,16 +83,15 @@ __iphash_add(struct ip_set_iphash *map, ip_set_ip_t *ip)
}
static inline int
iphash_add(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
iphash_add(struct ip_set *set, ip_set_ip_t ip)
{
struct ip_set_iphash *map = set->data;
if (!ip || map->elements >= limit)
return -ERANGE;
*hash_ip = ip & map->netmask;
return __iphash_add(map, hash_ip);
ip &= map->netmask;
return __iphash_add(map, &ip);
}
UADT(iphash, add)
@@ -108,7 +106,7 @@ __iphash_retry(struct ip_set_iphash *tmp, struct ip_set_iphash *map)
HASH_RETRY(iphash, ip_set_ip_t)
static inline int
iphash_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
iphash_del(struct ip_set *set, ip_set_ip_t ip)
{
struct ip_set_iphash *map = set->data;
ip_set_ip_t id, *elem;
@@ -116,7 +114,7 @@ iphash_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
if (!ip)
return -ERANGE;
id = iphash_id(set, hash_ip, ip);
id = iphash_id(set, ip);
if (id == UINT_MAX)
return -EEXIST;

View File

@@ -4,7 +4,7 @@
#include "ip_set.h"
#include "ip_set_hashes.h"
#define SETTYPE_NAME "iphash"
#define SETTYPE_NAME "iphash"
struct ip_set_iphash {
ip_set_ip_t *members; /* the iphash proper */

View File

@@ -22,21 +22,19 @@
static inline ip_set_ip_t
ip_to_id(const struct ip_set_ipmap *map, ip_set_ip_t ip)
{
return (ip - map->first_ip)/map->hosts;
return ((ip & map->netmask) - map->first_ip)/map->hosts;
}
static inline int
ipmap_test(const struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
ipmap_test(const struct ip_set *set, ip_set_ip_t ip)
{
const struct ip_set_ipmap *map = set->data;
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
*hash_ip = ip & map->netmask;
DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u",
set->name, HIPQUAD(ip), HIPQUAD(*hash_ip));
return !!test_bit(ip_to_id(map, *hash_ip), map->members);
DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip));
return !!test_bit(ip_to_id(map, ip), map->members);
}
#define KADT_CONDITION
@@ -45,16 +43,15 @@ UADT(ipmap, test)
KADT(ipmap, test, ipaddr)
static inline int
ipmap_add(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
ipmap_add(struct ip_set *set, ip_set_ip_t ip)
{
struct ip_set_ipmap *map = set->data;
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
*hash_ip = ip & map->netmask;
DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip));
if (test_and_set_bit(ip_to_id(map, *hash_ip), map->members))
DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip));
if (test_and_set_bit(ip_to_id(map, ip), map->members))
return -EEXIST;
return 0;
@@ -64,16 +61,15 @@ UADT(ipmap, add)
KADT(ipmap, add, ipaddr)
static inline int
ipmap_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
ipmap_del(struct ip_set *set, ip_set_ip_t ip)
{
struct ip_set_ipmap *map = set->data;
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
*hash_ip = ip & map->netmask;
DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip));
if (!test_and_clear_bit(ip_to_id(map, *hash_ip), map->members))
DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip));
if (!test_and_clear_bit(ip_to_id(map, ip), map->members))
return -EEXIST;
return 0;
@@ -130,8 +126,28 @@ __ipmap_list_header(const struct ip_set_ipmap *map,
}
BITMAP_LIST_HEADER(ipmap)
BITMAP_LIST_MEMBERS_SIZE(ipmap)
BITMAP_LIST_MEMBERS(ipmap)
BITMAP_LIST_MEMBERS_SIZE(ipmap, ip_set_ip_t, map->sizeid,
test_bit(i, map->members))
static void
ipmap_list_members(const struct ip_set *set, void *data, char dont_align)
{
const struct ip_set_ipmap *map = set->data;
uint32_t i, n = 0;
ip_set_ip_t *d;
if (dont_align) {
memcpy(data, map->members, map->size);
return;
}
for (i = 0; i < map->sizeid; i++)
if (test_bit(i, map->members)) {
d = data + n * IPSET_ALIGN(sizeof(ip_set_ip_t));
*d = map->first_ip + i * map->hosts;
n++;
}
}
IP_SET_TYPE(ipmap, IPSET_TYPE_IP | IPSET_DATA_SINGLE)

View File

@@ -4,7 +4,7 @@
#include "ip_set.h"
#include "ip_set_bitmaps.h"
#define SETTYPE_NAME "ipmap"
#define SETTYPE_NAME "ipmap"
struct ip_set_ipmap {
void *members; /* the ipmap proper */

View File

@@ -28,26 +28,23 @@
static int limit = MAX_RANGE;
static inline __u32
ipporthash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
ip_set_ip_t ip, ip_set_ip_t port)
ipporthash_id(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port)
{
struct ip_set_ipporthash *map = set->data;
__u32 id;
u_int16_t i;
ip_set_ip_t *elem;
*hash_ip = pack_ip_port(map, ip, port);
ip = pack_ip_port(map, ip, port);
DP("set: %s, ipport:%u.%u.%u.%u:%u, %u.%u.%u.%u",
set->name, HIPQUAD(ip), port, HIPQUAD(*hash_ip));
if (!*hash_ip)
if (!ip)
return UINT_MAX;
for (i = 0; i < map->probes; i++) {
id = jhash_ip(map, i, *hash_ip) % map->hashsize;
id = jhash_ip(map, i, ip) % map->hashsize;
DP("hash key: %u", id);
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
if (*elem == *hash_ip)
if (*elem == ip)
return id;
/* No shortcut - there can be deleted entries. */
}
@@ -55,24 +52,23 @@ ipporthash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
}
static inline int
ipporthash_test(struct ip_set *set, ip_set_ip_t *hash_ip,
ip_set_ip_t ip, ip_set_ip_t port)
ipporthash_test(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port)
{
struct ip_set_ipporthash *map = set->data;
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
return (ipporthash_id(set, hash_ip, ip, port) != UINT_MAX);
return (ipporthash_id(set, ip, port) != UINT_MAX);
}
#define KADT_CONDITION \
ip_set_ip_t port; \
\
if (flags[index+1] == 0) \
if (flags[1] == 0) \
return 0; \
\
port = get_port(skb, flags[index+1]); \
port = get_port(skb, flags++); \
\
if (port == INVALID_PORT) \
return 0;
@@ -106,8 +102,7 @@ __ipporthash_add(struct ip_set_ipporthash *map, ip_set_ip_t *ip)
}
static inline int
ipporthash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
ip_set_ip_t ip, ip_set_ip_t port)
ipporthash_add(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port)
{
struct ip_set_ipporthash *map = set->data;
if (map->elements > limit)
@@ -115,12 +110,12 @@ ipporthash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
*hash_ip = pack_ip_port(map, ip, port);
ip = pack_ip_port(map, ip, port);
if (!*hash_ip)
if (!ip)
return -ERANGE;
return __ipporthash_add(map, hash_ip);
return __ipporthash_add(map, &ip);
}
UADT(ipporthash, add, req->port)
@@ -137,8 +132,7 @@ __ipporthash_retry(struct ip_set_ipporthash *tmp,
HASH_RETRY(ipporthash, ip_set_ip_t)
static inline int
ipporthash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
ip_set_ip_t ip, ip_set_ip_t port)
ipporthash_del(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port)
{
struct ip_set_ipporthash *map = set->data;
ip_set_ip_t id;
@@ -147,7 +141,7 @@ ipporthash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
id = ipporthash_id(set, hash_ip, ip, port);
id = ipporthash_id(set, ip, port);
if (id == UINT_MAX)
return -EEXIST;

View File

@@ -4,7 +4,7 @@
#include "ip_set.h"
#include "ip_set_hashes.h"
#define SETTYPE_NAME "ipporthash"
#define SETTYPE_NAME "ipporthash"
struct ip_set_ipporthash {
ip_set_ip_t *members; /* the ipporthash proper */

View File

@@ -31,7 +31,7 @@ static int limit = MAX_RANGE;
jhash_2words(ipport, ip1, *(map->initval + i))
static inline __u32
ipportiphash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
ipportiphash_id(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
{
struct ip_set_ipportiphash *map = set->data;
@@ -39,17 +39,15 @@ ipportiphash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
u_int16_t i;
struct ipportip *elem;
*hash_ip = pack_ip_port(map, ip, port);
DP("set: %s, ipport:%u.%u.%u.%u:%u, %u.%u.%u.%u",
set->name, HIPQUAD(ip), port, HIPQUAD(*hash_ip));
if (!(*hash_ip || ip1))
ip = pack_ip_port(map, ip, port);
if (!(ip || ip1))
return UINT_MAX;
for (i = 0; i < map->probes; i++) {
id = jhash_ip2(map, i, *hash_ip, ip1) % map->hashsize;
id = jhash_ip2(map, i, ip, ip1) % map->hashsize;
DP("hash key: %u", id);
elem = HARRAY_ELEM(map->members, struct ipportip *, id);
if (elem->ip == *hash_ip && elem->ip1 == ip1)
if (elem->ip == ip && elem->ip1 == ip1)
return id;
/* No shortcut - there can be deleted entries. */
}
@@ -57,7 +55,7 @@ ipportiphash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
}
static inline int
ipportiphash_test(struct ip_set *set, ip_set_ip_t *hash_ip,
ipportiphash_test(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
{
struct ip_set_ipportiphash *map = set->data;
@@ -65,17 +63,17 @@ ipportiphash_test(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
return (ipportiphash_id(set, hash_ip, ip, port, ip1) != UINT_MAX);
return (ipportiphash_id(set, ip, port, ip1) != UINT_MAX);
}
#define KADT_CONDITION \
ip_set_ip_t port, ip1; \
\
if (flags[index+2] == 0) \
if (flags[2] == 0) \
return 0; \
\
port = get_port(skb, flags[index+1]); \
ip1 = ipaddr(skb, flags[index+2]); \
port = get_port(skb, flags++); \
ip1 = ipaddr(skb, flags++); \
\
if (port == INVALID_PORT) \
return 0;
@@ -85,23 +83,23 @@ KADT(ipportiphash, test, ipaddr, port, ip1)
static inline int
__ipportip_add(struct ip_set_ipportiphash *map,
ip_set_ip_t hash_ip, ip_set_ip_t ip1)
ip_set_ip_t ip, ip_set_ip_t ip1)
{
__u32 probe;
u_int16_t i;
struct ipportip *elem, *slot = NULL;
for (i = 0; i < map->probes; i++) {
probe = jhash_ip2(map, i, hash_ip, ip1) % map->hashsize;
probe = jhash_ip2(map, i, ip, ip1) % map->hashsize;
elem = HARRAY_ELEM(map->members, struct ipportip *, probe);
if (elem->ip == hash_ip && elem->ip1 == ip1)
if (elem->ip == ip && elem->ip1 == ip1)
return -EEXIST;
if (!(slot || elem->ip || elem->ip1))
slot = elem;
/* There can be deleted entries, must check all slots */
}
if (slot) {
slot->ip = hash_ip;
slot->ip = ip;
slot->ip1 = ip1;
map->elements++;
return 0;
@@ -118,7 +116,7 @@ __ipportiphash_add(struct ip_set_ipportiphash *map,
}
static inline int
ipportiphash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
ipportiphash_add(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
{
struct ip_set_ipportiphash *map = set->data;
@@ -128,11 +126,11 @@ ipportiphash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
*hash_ip = pack_ip_port(map, ip, port);
if (!(*hash_ip || ip1))
ip = pack_ip_port(map, ip, port);
if (!(ip || ip1))
return -ERANGE;
return __ipportip_add(map, *hash_ip, ip1);
return __ipportip_add(map, ip, ip1);
}
UADT(ipportiphash, add, req->port, req->ip1)
@@ -149,7 +147,7 @@ __ipportiphash_retry(struct ip_set_ipportiphash *tmp,
HASH_RETRY2(ipportiphash, struct ipportip)
static inline int
ipportiphash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
ipportiphash_del(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
{
struct ip_set_ipportiphash *map = set->data;
@@ -159,7 +157,7 @@ ipportiphash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
id = ipportiphash_id(set, hash_ip, ip, port, ip1);
id = ipportiphash_id(set, ip, port, ip1);
if (id == UINT_MAX)
return -EEXIST;
@@ -202,7 +200,8 @@ __ipportiphash_list_header(const struct ip_set_ipportiphash *map,
HASH_LIST_HEADER(ipportiphash)
HASH_LIST_MEMBERS_SIZE(ipportiphash, struct ipportip)
HASH_LIST_MEMBERS_MEMCPY(ipportiphash, struct ipportip)
HASH_LIST_MEMBERS_MEMCPY(ipportiphash, struct ipportip,
(elem->ip || elem->ip1))
IP_SET_RTYPE(ipportiphash, IPSET_TYPE_IP | IPSET_TYPE_PORT
| IPSET_TYPE_IP1 | IPSET_DATA_TRIPLE)

View File

@@ -4,7 +4,7 @@
#include "ip_set.h"
#include "ip_set_hashes.h"
#define SETTYPE_NAME "ipportiphash"
#define SETTYPE_NAME "ipportiphash"
struct ipportip {
ip_set_ip_t ip;

View File

@@ -31,7 +31,7 @@ static int limit = MAX_RANGE;
jhash_2words(ipport, ip1, *(map->initval + i))
static inline __u32
ipportnethash_id_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
ipportnethash_id_cidr(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port,
ip_set_ip_t ip1, uint8_t cidr)
{
@@ -40,18 +40,16 @@ ipportnethash_id_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
u_int16_t i;
struct ipportip *elem;
*hash_ip = pack_ip_port(map, ip, port);
DP("set: %s, ipport:%u.%u.%u.%u:%u, %u.%u.%u.%u",
set->name, HIPQUAD(ip), port, HIPQUAD(*hash_ip));
ip = pack_ip_port(map, ip, port);
ip1 = pack_ip_cidr(ip1, cidr);
if (!(*hash_ip || ip1))
if (!(ip || ip1))
return UINT_MAX;
for (i = 0; i < map->probes; i++) {
id = jhash_ip2(map, i, *hash_ip, ip1) % map->hashsize;
id = jhash_ip2(map, i, ip, ip1) % map->hashsize;
DP("hash key: %u", id);
elem = HARRAY_ELEM(map->members, struct ipportip *, id);
if (elem->ip == *hash_ip && elem->ip1 == ip1)
if (elem->ip == ip && elem->ip1 == ip1)
return id;
/* No shortcut - there can be deleted entries. */
}
@@ -59,7 +57,7 @@ ipportnethash_id_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
}
static inline __u32
ipportnethash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
ipportnethash_id(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
{
struct ip_set_ipportnethash *map = set->data;
@@ -67,8 +65,7 @@ ipportnethash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
int i;
for (i = 0; i < 30 && map->cidr[i]; i++) {
id = ipportnethash_id_cidr(set, hash_ip, ip, port, ip1,
map->cidr[i]);
id = ipportnethash_id_cidr(set, ip, port, ip1, map->cidr[i]);
if (id != UINT_MAX)
break;
}
@@ -76,7 +73,7 @@ ipportnethash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
}
static inline int
ipportnethash_test_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
ipportnethash_test_cidr(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port,
ip_set_ip_t ip1, uint8_t cidr)
{
@@ -85,12 +82,11 @@ ipportnethash_test_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
return (ipportnethash_id_cidr(set, hash_ip, ip, port, ip1,
cidr) != UINT_MAX);
return (ipportnethash_id_cidr(set, ip, port, ip1, cidr) != UINT_MAX);
}
static inline int
ipportnethash_test(struct ip_set *set, ip_set_ip_t *hash_ip,
ipportnethash_test(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
{
struct ip_set_ipportnethash *map = set->data;
@@ -98,32 +94,30 @@ ipportnethash_test(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
return (ipportnethash_id(set, hash_ip, ip, port, ip1) != UINT_MAX);
return (ipportnethash_id(set, ip, port, ip1) != UINT_MAX);
}
static int
ipportnethash_utest(struct ip_set *set, const void *data, u_int32_t size,
ip_set_ip_t *hash_ip)
ipportnethash_utest(struct ip_set *set, const void *data, u_int32_t size)
{
const struct ip_set_req_ipportnethash *req = data;
if (req->cidr <= 0 || req->cidr > 32)
return -EINVAL;
return (req->cidr == 32
? ipportnethash_test(set, hash_ip, req->ip, req->port,
req->ip1)
: ipportnethash_test_cidr(set, hash_ip, req->ip, req->port,
? ipportnethash_test(set, req->ip, req->port, req->ip1)
: ipportnethash_test_cidr(set, req->ip, req->port,
req->ip1, req->cidr));
}
#define KADT_CONDITION \
ip_set_ip_t port, ip1; \
\
if (flags[index+2] == 0) \
if (flags[2] == 0) \
return 0; \
\
port = get_port(skb, flags[index+1]); \
ip1 = ipaddr(skb, flags[index+2]); \
port = get_port(skb, flags++); \
ip1 = ipaddr(skb, flags++); \
\
if (port == INVALID_PORT) \
return 0;
@@ -132,23 +126,23 @@ KADT(ipportnethash, test, ipaddr, port, ip1)
static inline int
__ipportnet_add(struct ip_set_ipportnethash *map,
ip_set_ip_t hash_ip, ip_set_ip_t ip1)
ip_set_ip_t ip, ip_set_ip_t ip1)
{
__u32 probe;
u_int16_t i;
struct ipportip *elem, *slot = NULL;
for (i = 0; i < map->probes; i++) {
probe = jhash_ip2(map, i, hash_ip, ip1) % map->hashsize;
probe = jhash_ip2(map, i, ip, ip1) % map->hashsize;
elem = HARRAY_ELEM(map->members, struct ipportip *, probe);
if (elem->ip == hash_ip && elem->ip1 == ip1)
if (elem->ip == ip && elem->ip1 == ip1)
return -EEXIST;
if (!(slot || elem->ip || elem->ip1))
slot = elem;
/* There can be deleted entries, must check all slots */
}
if (slot) {
slot->ip = hash_ip;
slot->ip = ip;
slot->ip1 = ip1;
map->elements++;
return 0;
@@ -165,7 +159,7 @@ __ipportnethash_add(struct ip_set_ipportnethash *map,
}
static inline int
ipportnethash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
ipportnethash_add(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port,
ip_set_ip_t ip1, uint8_t cidr)
{
@@ -182,12 +176,12 @@ ipportnethash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
if (map->nets[cidr-1] == UINT16_MAX)
return -ERANGE;
*hash_ip = pack_ip_port(map, ip, port);
ip = pack_ip_port(map, ip, port);
ip1 = pack_ip_cidr(ip1, cidr);
if (!(*hash_ip || ip1))
if (!(ip || ip1))
return -ERANGE;
ret =__ipportnet_add(map, *hash_ip, ip1);
ret =__ipportnet_add(map, ip, ip1);
if (ret == 0) {
if (!map->nets[cidr-1]++)
add_cidr_size(map->cidr, cidr);
@@ -202,11 +196,11 @@ ipportnethash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
uint8_t cidr = map->cidr[0] ? map->cidr[0] : 31; \
ip_set_ip_t port, ip1; \
\
if (flags[index+2] == 0) \
if (flags[2] == 0) \
return 0; \
\
port = get_port(skb, flags[index+1]); \
ip1 = ipaddr(skb, flags[index+2]); \
port = get_port(skb, flags++); \
ip1 = ipaddr(skb, flags++); \
\
if (port == INVALID_PORT) \
return 0;
@@ -227,7 +221,7 @@ __ipportnethash_retry(struct ip_set_ipportnethash *tmp,
HASH_RETRY2(ipportnethash, struct ipportip)
static inline int
ipportnethash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
ipportnethash_del(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port,
ip_set_ip_t ip1, uint8_t cidr)
{
@@ -242,7 +236,7 @@ ipportnethash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
if (cidr <= 0 || cidr >= 32)
return -EINVAL;
id = ipportnethash_id_cidr(set, hash_ip, ip, port, ip1, cidr);
id = ipportnethash_id_cidr(set, ip, port, ip1, cidr);
if (id == UINT_MAX)
return -EEXIST;
@@ -290,7 +284,8 @@ __ipportnethash_list_header(const struct ip_set_ipportnethash *map,
HASH_LIST_HEADER(ipportnethash)
HASH_LIST_MEMBERS_SIZE(ipportnethash, struct ipportip)
HASH_LIST_MEMBERS_MEMCPY(ipportnethash, struct ipportip)
HASH_LIST_MEMBERS_MEMCPY(ipportnethash, struct ipportip,
(elem->ip || elem->ip1))
IP_SET_RTYPE(ipportnethash, IPSET_TYPE_IP | IPSET_TYPE_PORT
| IPSET_TYPE_IP1 | IPSET_DATA_TRIPLE)

View File

@@ -4,7 +4,7 @@
#include "ip_set.h"
#include "ip_set_hashes.h"
#define SETTYPE_NAME "ipportnethash"
#define SETTYPE_NAME "ipportnethash"
struct ipportip {
ip_set_ip_t ip;

View File

@@ -62,7 +62,7 @@ static __KMEM_CACHE_T__ *leaf_cachep;
} while (0)
static inline int
iptree_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
iptree_test(struct ip_set *set, ip_set_ip_t ip)
{
struct ip_set_iptree *map = set->data;
struct ip_set_iptreeb *btree;
@@ -73,8 +73,7 @@ iptree_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
if (!ip)
return -ERANGE;
*hash_ip = ip;
ABCD(a, b, c, d, hash_ip);
ABCD(a, b, c, d, &ip);
DP("%u %u %u %u timeout %u", a, b, c, d, map->timeout);
TESTIP_WALK(map, a, btree);
TESTIP_WALK(btree, b, ctree);
@@ -106,8 +105,7 @@ KADT(iptree, test, ipaddr)
} while (0)
static inline int
iptree_add(struct ip_set *set, ip_set_ip_t *hash_ip,
ip_set_ip_t ip, unsigned int timeout)
iptree_add(struct ip_set *set, ip_set_ip_t ip, unsigned int timeout)
{
struct ip_set_iptree *map = set->data;
struct ip_set_iptreeb *btree;
@@ -121,8 +119,7 @@ iptree_add(struct ip_set *set, ip_set_ip_t *hash_ip,
* but it's probably overkill */
return -ERANGE;
*hash_ip = ip;
ABCD(a, b, c, d, hash_ip);
ABCD(a, b, c, d, &ip);
DP("%u %u %u %u timeout %u", a, b, c, d, timeout);
ADDIP_WALK(map, a, btree, struct ip_set_iptreeb, branch_cachep);
ADDIP_WALK(btree, b, ctree, struct ip_set_iptreec, branch_cachep);
@@ -153,7 +150,7 @@ KADT(iptree, add, ipaddr, 0)
} while (0)
static inline int
iptree_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
iptree_del(struct ip_set *set, ip_set_ip_t ip)
{
struct ip_set_iptree *map = set->data;
struct ip_set_iptreeb *btree;
@@ -164,8 +161,7 @@ iptree_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
if (!ip)
return -ERANGE;
*hash_ip = ip;
ABCD(a, b, c, d, hash_ip);
ABCD(a, b, c, d, &ip);
DELIP_WALK(map, a, btree);
DELIP_WALK(btree, b, ctree);
DELIP_WALK(ctree, c, dtree);
@@ -364,7 +360,7 @@ iptree_list_header(const struct ip_set *set, void *data)
}
static int
iptree_list_members_size(const struct ip_set *set)
iptree_list_members_size(const struct ip_set *set, char dont_align)
{
const struct ip_set_iptree *map = set->data;
struct ip_set_iptreeb *btree;
@@ -386,20 +382,21 @@ iptree_list_members_size(const struct ip_set *set)
LOOP_WALK_END;
DP("members %u", count);
return (count * sizeof(struct ip_set_req_iptree));
return (count * IPSET_VALIGN(sizeof(struct ip_set_req_iptree), dont_align));
}
static void
iptree_list_members(const struct ip_set *set, void *data)
iptree_list_members(const struct ip_set *set, void *data, char dont_align)
{
const struct ip_set_iptree *map = set->data;
struct ip_set_iptreeb *btree;
struct ip_set_iptreec *ctree;
struct ip_set_iptreed *dtree;
unsigned int a,b,c,d;
size_t offset = 0;
size_t offset = 0, datasize;
struct ip_set_req_iptree *entry;
datasize = IPSET_VALIGN(sizeof(struct ip_set_req_iptree), dont_align);
LOOP_WALK_BEGIN(map, a, btree);
LOOP_WALK_BEGIN(btree, b, ctree);
LOOP_WALK_BEGIN(ctree, c, dtree);
@@ -410,7 +407,7 @@ iptree_list_members(const struct ip_set *set, void *data)
entry->ip = ((a << 24) | (b << 16) | (c << 8) | d);
entry->timeout = !map->timeout ? 0
: (dtree->expires[d] - jiffies)/HZ;
offset += sizeof(struct ip_set_req_iptree);
offset += datasize;
}
}
LOOP_WALK_END;

View File

@@ -3,7 +3,7 @@
#include "ip_set.h"
#define SETTYPE_NAME "iptree"
#define SETTYPE_NAME "iptree"
struct ip_set_iptreed {
unsigned long expires[256]; /* x.x.x.ADDR */

View File

@@ -251,7 +251,7 @@ free_b(struct ip_set_iptreemap_b *map)
}
static inline int
iptreemap_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
iptreemap_test(struct ip_set *set, ip_set_ip_t ip)
{
struct ip_set_iptreemap *map = set->data;
struct ip_set_iptreemap_b *btree;
@@ -259,9 +259,7 @@ iptreemap_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
struct ip_set_iptreemap_d *dtree;
unsigned char a, b, c, d;
*hash_ip = ip;
ABCD(a, b, c, d, hash_ip);
ABCD(a, b, c, d, &ip);
TESTIP_WALK(map, a, btree, fullbitmap_b);
TESTIP_WALK(btree, b, ctree, fullbitmap_c);
@@ -276,7 +274,7 @@ UADT(iptreemap, test)
KADT(iptreemap, test, ipaddr)
static inline int
__addip_single(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
__addip_single(struct ip_set *set, ip_set_ip_t ip)
{
struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data;
struct ip_set_iptreemap_b *btree;
@@ -284,9 +282,7 @@ __addip_single(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
struct ip_set_iptreemap_d *dtree;
unsigned char a, b, c, d;
*hash_ip = ip;
ABCD(a, b, c, d, hash_ip);
ABCD(a, b, c, d, &ip);
ADDIP_WALK(map, a, btree, struct ip_set_iptreemap_b, cachep_b, fullbitmap_b);
ADDIP_WALK(btree, b, ctree, struct ip_set_iptreemap_c, cachep_c, fullbitmap_c);
@@ -301,8 +297,7 @@ __addip_single(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
}
static inline int
iptreemap_add(struct ip_set *set, ip_set_ip_t *hash_ip,
ip_set_ip_t start, ip_set_ip_t end)
iptreemap_add(struct ip_set *set, ip_set_ip_t start, ip_set_ip_t end)
{
struct ip_set_iptreemap *map = set->data;
struct ip_set_iptreemap_b *btree;
@@ -313,9 +308,7 @@ iptreemap_add(struct ip_set *set, ip_set_ip_t *hash_ip,
unsigned char a2, b2, c2, d2;
if (start == end)
return __addip_single(set, hash_ip, start);
*hash_ip = start;
return __addip_single(set, start);
ABCD(a1, b1, c1, d1, &start);
ABCD(a2, b2, c2, d2, &end);
@@ -338,8 +331,7 @@ UADT0(iptreemap, add, min(req->ip, req->end), max(req->ip, req->end))
KADT(iptreemap, add, ipaddr, ip)
static inline int
__delip_single(struct ip_set *set, ip_set_ip_t *hash_ip,
ip_set_ip_t ip, gfp_t flags)
__delip_single(struct ip_set *set, ip_set_ip_t ip, gfp_t flags)
{
struct ip_set_iptreemap *map = set->data;
struct ip_set_iptreemap_b *btree;
@@ -347,9 +339,7 @@ __delip_single(struct ip_set *set, ip_set_ip_t *hash_ip,
struct ip_set_iptreemap_d *dtree;
unsigned char a,b,c,d;
*hash_ip = ip;
ABCD(a, b, c, d, hash_ip);
ABCD(a, b, c, d, &ip);
DELIP_WALK(map, a, btree, cachep_b, fullbitmap_b, flags);
DELIP_WALK(btree, b, ctree, cachep_c, fullbitmap_c, flags);
@@ -364,7 +354,7 @@ __delip_single(struct ip_set *set, ip_set_ip_t *hash_ip,
}
static inline int
iptreemap_del(struct ip_set *set, ip_set_ip_t *hash_ip,
iptreemap_del(struct ip_set *set,
ip_set_ip_t start, ip_set_ip_t end, gfp_t flags)
{
struct ip_set_iptreemap *map = set->data;
@@ -376,9 +366,7 @@ iptreemap_del(struct ip_set *set, ip_set_ip_t *hash_ip,
unsigned char a2, b2, c2, d2;
if (start == end)
return __delip_single(set, hash_ip, start, flags);
*hash_ip = start;
return __delip_single(set, start, flags);
ABCD(a1, b1, c1, d1, &start);
ABCD(a2, b2, c2, d2, &end);
@@ -518,6 +506,7 @@ static void
iptreemap_flush(struct ip_set *set)
{
struct ip_set_iptreemap *map = set->data;
unsigned int gc_interval = map->gc_interval;
while (!del_timer(&map->gc))
msleep(IPTREEMAP_DESTROY_SLEEP);
@@ -525,6 +514,7 @@ iptreemap_flush(struct ip_set *set)
__flush(map);
memset(map, 0, sizeof(*map));
map->gc_interval = gc_interval;
init_gc_timer(set);
}
@@ -539,7 +529,7 @@ iptreemap_list_header(const struct ip_set *set, void *data)
}
static int
iptreemap_list_members_size(const struct ip_set *set)
iptreemap_list_members_size(const struct ip_set *set, char dont_align)
{
struct ip_set_iptreemap *map = set->data;
struct ip_set_iptreemap_b *btree;
@@ -565,31 +555,30 @@ iptreemap_list_members_size(const struct ip_set *set)
if (inrange)
count++;
return (count * sizeof(struct ip_set_req_iptreemap));
return (count * IPSET_VALIGN(sizeof(struct ip_set_req_iptreemap), dont_align));
}
static inline u_int32_t
static inline void
add_member(void *data, size_t offset, ip_set_ip_t start, ip_set_ip_t end)
{
struct ip_set_req_iptreemap *entry = data + offset;
entry->ip = start;
entry->end = end;
return sizeof(*entry);
}
static void
iptreemap_list_members(const struct ip_set *set, void *data)
iptreemap_list_members(const struct ip_set *set, void *data, char dont_align)
{
struct ip_set_iptreemap *map = set->data;
struct ip_set_iptreemap_b *btree;
struct ip_set_iptreemap_c *ctree;
struct ip_set_iptreemap_d *dtree;
unsigned int a, b, c, d, inrange = 0;
size_t offset = 0;
size_t offset = 0, datasize;
ip_set_ip_t start = 0, end = 0, ip;
datasize = IPSET_VALIGN(sizeof(struct ip_set_req_iptreemap), dont_align);
LOOP_WALK_BEGIN(map, a, btree) {
LOOP_WALK_BEGIN(btree, b, ctree) {
LOOP_WALK_BEGIN(ctree, c, dtree) {
@@ -600,12 +589,14 @@ iptreemap_list_members(const struct ip_set *set, void *data)
inrange = 1;
start = ip;
} else if (end < ip - 1) {
offset += add_member(data, offset, start, end);
add_member(data, offset, start, end);
offset += datasize;
start = ip;
}
end = ip;
} else if (inrange) {
offset += add_member(data, offset, start, end);
add_member(data, offset, start, end);
offset += datasize;
inrange = 0;
}
}

View File

@@ -3,7 +3,7 @@
#include "ip_set.h"
#define SETTYPE_NAME "iptreemap"
#define SETTYPE_NAME "iptreemap"
#ifdef __KERNEL__
struct ip_set_iptreemap_d {

View File

@@ -22,8 +22,7 @@
#include "ip_set_macipmap.h"
static int
macipmap_utest(struct ip_set *set, const void *data, u_int32_t size,
ip_set_ip_t *hash_ip)
macipmap_utest(struct ip_set *set, const void *data, u_int32_t size)
{
const struct ip_set_macipmap *map = set->data;
const struct ip_set_macip *table = map->members;
@@ -32,9 +31,7 @@ macipmap_utest(struct ip_set *set, const void *data, u_int32_t size,
if (req->ip < map->first_ip || req->ip > map->last_ip)
return -ERANGE;
*hash_ip = req->ip;
DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u",
set->name, HIPQUAD(req->ip), HIPQUAD(*hash_ip));
DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(req->ip));
if (table[req->ip - map->first_ip].match) {
return (memcmp(req->ethernet,
&table[req->ip - map->first_ip].ethernet,
@@ -47,22 +44,18 @@ macipmap_utest(struct ip_set *set, const void *data, u_int32_t size,
static int
macipmap_ktest(struct ip_set *set,
const struct sk_buff *skb,
ip_set_ip_t *hash_ip,
const u_int32_t *flags,
unsigned char index)
const u_int32_t *flags)
{
const struct ip_set_macipmap *map = set->data;
const struct ip_set_macip *table = map->members;
ip_set_ip_t ip;
ip = ipaddr(skb, flags[index]);
ip = ipaddr(skb, flags);
if (ip < map->first_ip || ip > map->last_ip)
return 0;
*hash_ip = ip;
DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u",
set->name, HIPQUAD(ip), HIPQUAD(*hash_ip));
DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip));
if (table[ip - map->first_ip].match) {
/* Is mac pointer valid?
* If so, compare... */
@@ -78,7 +71,7 @@ macipmap_ktest(struct ip_set *set,
/* returns 0 on success */
static inline int
macipmap_add(struct ip_set *set, ip_set_ip_t *hash_ip,
macipmap_add(struct ip_set *set,
ip_set_ip_t ip, const unsigned char *ethernet)
{
struct ip_set_macipmap *map = set->data;
@@ -89,8 +82,7 @@ macipmap_add(struct ip_set *set, ip_set_ip_t *hash_ip,
if (table[ip - map->first_ip].match)
return -EEXIST;
*hash_ip = ip;
DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip));
DP("set: %s, ip: %u.%u.%u.%u", set->name, HIPQUAD(ip));
memcpy(&table[ip - map->first_ip].ethernet, ethernet, ETH_ALEN);
table[ip - map->first_ip].match = IPSET_MACIP_ISSET;
return 0;
@@ -105,7 +97,7 @@ UADT(macipmap, add, req->ethernet)
KADT(macipmap, add, ipaddr, eth_hdr(skb)->h_source)
static inline int
macipmap_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
macipmap_del(struct ip_set *set, ip_set_ip_t ip)
{
struct ip_set_macipmap *map = set->data;
struct ip_set_macip *table = map->members;
@@ -115,9 +107,8 @@ macipmap_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
if (!table[ip - map->first_ip].match)
return -EEXIST;
*hash_ip = ip;
table[ip - map->first_ip].match = 0;
DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip));
DP("set: %s, ip: %u.%u.%u.%u", set->name, HIPQUAD(ip));
return 0;
}
@@ -152,8 +143,32 @@ __macipmap_list_header(const struct ip_set_macipmap *map,
}
BITMAP_LIST_HEADER(macipmap)
BITMAP_LIST_MEMBERS_SIZE(macipmap)
BITMAP_LIST_MEMBERS(macipmap)
BITMAP_LIST_MEMBERS_SIZE(macipmap, struct ip_set_req_macipmap,
(map->last_ip - map->first_ip + 1),
((const struct ip_set_macip *)map->members)[i].match)
static void
macipmap_list_members(const struct ip_set *set, void *data, char dont_align)
{
const struct ip_set_macipmap *map = set->data;
const struct ip_set_macip *table = map->members;
uint32_t i, n = 0;
struct ip_set_req_macipmap *d;
if (dont_align) {
memcpy(data, map->members, map->size);
return;
}
for (i = 0; i < map->last_ip - map->first_ip + 1; i++)
if (table[i].match) {
d = data + n * IPSET_ALIGN(sizeof(struct ip_set_req_macipmap));
d->ip = map->first_ip + i;
memcpy(d->ethernet, &table[i].ethernet, ETH_ALEN);
n++;
}
}
IP_SET_TYPE(macipmap, IPSET_TYPE_IP | IPSET_DATA_SINGLE)

View File

@@ -4,7 +4,7 @@
#include "ip_set.h"
#include "ip_set_bitmaps.h"
#define SETTYPE_NAME "macipmap"
#define SETTYPE_NAME "macipmap"
/* general flags */
#define IPSET_MACIP_MATCHUNSET 1

View File

@@ -26,7 +26,6 @@ static int limit = MAX_RANGE;
static inline __u32
nethash_id_cidr(const struct ip_set_nethash *map,
ip_set_ip_t *hash_ip,
ip_set_ip_t ip,
uint8_t cidr)
{
@@ -34,15 +33,15 @@ nethash_id_cidr(const struct ip_set_nethash *map,
u_int16_t i;
ip_set_ip_t *elem;
*hash_ip = pack_ip_cidr(ip, cidr);
if (!*hash_ip)
ip = pack_ip_cidr(ip, cidr);
if (!ip)
return MAX_RANGE;
for (i = 0; i < map->probes; i++) {
id = jhash_ip(map, i, *hash_ip) % map->hashsize;
id = jhash_ip(map, i, ip) % map->hashsize;
DP("hash key: %u", id);
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
if (*elem == *hash_ip)
if (*elem == ip)
return id;
/* No shortcut - there can be deleted entries. */
}
@@ -50,14 +49,14 @@ nethash_id_cidr(const struct ip_set_nethash *map,
}
static inline __u32
nethash_id(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
nethash_id(struct ip_set *set, ip_set_ip_t ip)
{
const struct ip_set_nethash *map = set->data;
__u32 id = UINT_MAX;
int i;
for (i = 0; i < 30 && map->cidr[i]; i++) {
id = nethash_id_cidr(map, hash_ip, ip, map->cidr[i]);
id = nethash_id_cidr(map, ip, map->cidr[i]);
if (id != UINT_MAX)
break;
}
@@ -65,30 +64,28 @@ nethash_id(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
}
static inline int
nethash_test_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
ip_set_ip_t ip, uint8_t cidr)
nethash_test_cidr(struct ip_set *set, ip_set_ip_t ip, uint8_t cidr)
{
const struct ip_set_nethash *map = set->data;
return (nethash_id_cidr(map, hash_ip, ip, cidr) != UINT_MAX);
return (nethash_id_cidr(map, ip, cidr) != UINT_MAX);
}
static inline int
nethash_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
nethash_test(struct ip_set *set, ip_set_ip_t ip)
{
return (nethash_id(set, hash_ip, ip) != UINT_MAX);
return (nethash_id(set, ip) != UINT_MAX);
}
static int
nethash_utest(struct ip_set *set, const void *data, u_int32_t size,
ip_set_ip_t *hash_ip)
nethash_utest(struct ip_set *set, const void *data, u_int32_t size)
{
const struct ip_set_req_nethash *req = data;
if (req->cidr <= 0 || req->cidr > 32)
return -EINVAL;
return (req->cidr == 32 ? nethash_test(set, hash_ip, req->ip)
: nethash_test_cidr(set, hash_ip, req->ip, req->cidr));
return (req->cidr == 32 ? nethash_test(set, req->ip)
: nethash_test_cidr(set, req->ip, req->cidr));
}
#define KADT_CONDITION
@@ -121,8 +118,7 @@ __nethash_add(struct ip_set_nethash *map, ip_set_ip_t *ip)
}
static inline int
nethash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
ip_set_ip_t ip, uint8_t cidr)
nethash_add(struct ip_set *set, ip_set_ip_t ip, uint8_t cidr)
{
struct ip_set_nethash *map = set->data;
int ret;
@@ -132,12 +128,11 @@ nethash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
if (cidr <= 0 || cidr >= 32)
return -EINVAL;
*hash_ip = pack_ip_cidr(ip, cidr);
DP("%u.%u.%u.%u/%u, %u.%u.%u.%u", HIPQUAD(ip), cidr, HIPQUAD(*hash_ip));
if (!*hash_ip)
ip = pack_ip_cidr(ip, cidr);
if (!ip)
return -ERANGE;
ret = __nethash_add(map, hash_ip);
ret = __nethash_add(map, &ip);
if (ret == 0) {
if (!map->nets[cidr-1]++)
add_cidr_size(map->cidr, cidr);
@@ -165,8 +160,7 @@ __nethash_retry(struct ip_set_nethash *tmp, struct ip_set_nethash *map)
HASH_RETRY(nethash, ip_set_ip_t)
static inline int
nethash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
ip_set_ip_t ip, uint8_t cidr)
nethash_del(struct ip_set *set, ip_set_ip_t ip, uint8_t cidr)
{
struct ip_set_nethash *map = set->data;
ip_set_ip_t id, *elem;
@@ -174,7 +168,7 @@ nethash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
if (cidr <= 0 || cidr >= 32)
return -EINVAL;
id = nethash_id_cidr(map, hash_ip, ip, cidr);
id = nethash_id_cidr(map, ip, cidr);
if (id == UINT_MAX)
return -EEXIST;

View File

@@ -4,7 +4,7 @@
#include "ip_set.h"
#include "ip_set_hashes.h"
#define SETTYPE_NAME "nethash"
#define SETTYPE_NAME "nethash"
struct ip_set_nethash {
ip_set_ip_t *members; /* the nethash proper */

View File

@@ -23,16 +23,14 @@
#include "ip_set_getport.h"
static inline int
portmap_test(const struct ip_set *set, ip_set_ip_t *hash_port,
ip_set_ip_t port)
portmap_test(const struct ip_set *set, ip_set_ip_t port)
{
const struct ip_set_portmap *map = set->data;
if (port < map->first_ip || port > map->last_ip)
return -ERANGE;
*hash_port = port;
DP("set: %s, port:%u, %u", set->name, port, *hash_port);
DP("set: %s, port: %u", set->name, port);
return !!test_bit(port - map->first_ip, map->members);
}
@@ -44,7 +42,7 @@ UADT(portmap, test)
KADT(portmap, test, get_port)
static inline int
portmap_add(struct ip_set *set, ip_set_ip_t *hash_port, ip_set_ip_t port)
portmap_add(struct ip_set *set, ip_set_ip_t port)
{
struct ip_set_portmap *map = set->data;
@@ -52,9 +50,8 @@ portmap_add(struct ip_set *set, ip_set_ip_t *hash_port, ip_set_ip_t port)
return -ERANGE;
if (test_and_set_bit(port - map->first_ip, map->members))
return -EEXIST;
*hash_port = port;
DP("port %u", port);
DP("set: %s, port %u", set->name, port);
return 0;
}
@@ -62,7 +59,7 @@ UADT(portmap, add)
KADT(portmap, add, get_port)
static inline int
portmap_del(struct ip_set *set, ip_set_ip_t *hash_port, ip_set_ip_t port)
portmap_del(struct ip_set *set, ip_set_ip_t port)
{
struct ip_set_portmap *map = set->data;
@@ -70,9 +67,8 @@ portmap_del(struct ip_set *set, ip_set_ip_t *hash_port, ip_set_ip_t port)
return -ERANGE;
if (!test_and_clear_bit(port - map->first_ip, map->members))
return -EEXIST;
*hash_port = port;
DP("port %u", port);
DP("set: %s, port %u", set->name, port);
return 0;
}
@@ -102,8 +98,28 @@ __portmap_list_header(const struct ip_set_portmap *map,
}
BITMAP_LIST_HEADER(portmap)
BITMAP_LIST_MEMBERS_SIZE(portmap)
BITMAP_LIST_MEMBERS(portmap)
BITMAP_LIST_MEMBERS_SIZE(portmap, ip_set_ip_t, (map->last_ip - map->first_ip + 1),
test_bit(i, map->members))
static void
portmap_list_members(const struct ip_set *set, void *data, char dont_align)
{
const struct ip_set_portmap *map = set->data;
uint32_t i, n = 0;
ip_set_ip_t *d;
if (dont_align) {
memcpy(data, map->members, map->size);
return;
}
for (i = 0; i < map->last_ip - map->first_ip + 1; i++)
if (test_bit(i, map->members)) {
d = data + n * IPSET_ALIGN(sizeof(ip_set_ip_t));
*d = map->first_ip + i;
n++;
}
}
IP_SET_TYPE(portmap, IPSET_TYPE_PORT | IPSET_DATA_SINGLE)

View File

@@ -4,7 +4,7 @@
#include "ip_set.h"
#include "ip_set_bitmaps.h"
#define SETTYPE_NAME "portmap"
#define SETTYPE_NAME "portmap"
struct ip_set_portmap {
void *members; /* the portmap proper */

View File

@@ -28,8 +28,7 @@ next_index_eq(const struct ip_set_setlist *map, int i, ip_set_id_t index)
}
static int
setlist_utest(struct ip_set *set, const void *data, u_int32_t size,
ip_set_ip_t *hash_ip)
setlist_utest(struct ip_set *set, const void *data, u_int32_t size)
{
const struct ip_set_setlist *map = set->data;
const struct ip_set_req_setlist *req = data;
@@ -72,10 +71,8 @@ finish:
static int
setlist_ktest(struct ip_set *set,
const struct sk_buff *skb,
ip_set_ip_t *hash_ip,
const u_int32_t *flags,
unsigned char index)
const struct sk_buff *skb,
const u_int32_t *flags)
{
struct ip_set_setlist *map = set->data;
int i, res = 0;
@@ -107,8 +104,7 @@ insert_setlist(struct ip_set_setlist *map, int i, ip_set_id_t index)
}
static int
setlist_uadd(struct ip_set *set, const void *data, u_int32_t size,
ip_set_ip_t *hash_ip)
setlist_uadd(struct ip_set *set, const void *data, u_int32_t size)
{
struct ip_set_setlist *map = set->data;
const struct ip_set_req_setlist *req = data;
@@ -156,9 +152,7 @@ finish:
static int
setlist_kadd(struct ip_set *set,
const struct sk_buff *skb,
ip_set_ip_t *hash_ip,
const u_int32_t *flags,
unsigned char index)
const u_int32_t *flags)
{
struct ip_set_setlist *map = set->data;
int i, res = -EINVAL;
@@ -182,8 +176,7 @@ unshift_setlist(struct ip_set_setlist *map, int i)
}
static int
setlist_udel(struct ip_set *set, const void *data, u_int32_t size,
ip_set_ip_t *hash_ip)
setlist_udel(struct ip_set *set, const void *data, u_int32_t size)
{
struct ip_set_setlist *map = set->data;
const struct ip_set_req_setlist *req = data;
@@ -234,9 +227,7 @@ finish:
static int
setlist_kdel(struct ip_set *set,
const struct sk_buff *skb,
ip_set_ip_t *hash_ip,
const u_int32_t *flags,
unsigned char index)
const u_int32_t *flags)
{
struct ip_set_setlist *map = set->data;
int i, res = -EINVAL;
@@ -304,21 +295,24 @@ setlist_list_header(const struct ip_set *set, void *data)
}
static int
setlist_list_members_size(const struct ip_set *set)
setlist_list_members_size(const struct ip_set *set, char dont_align)
{
const struct ip_set_setlist *map = set->data;
return map->size * sizeof(ip_set_id_t);
return map->size * IPSET_VALIGN(sizeof(ip_set_id_t), dont_align);
}
static void
setlist_list_members(const struct ip_set *set, void *data)
setlist_list_members(const struct ip_set *set, void *data, char dont_align)
{
struct ip_set_setlist *map = set->data;
ip_set_id_t *d;
int i;
for (i = 0; i < map->size; i++)
*((ip_set_id_t *)data + i) = ip_set_id(map->index[i]);
for (i = 0; i < map->size; i++) {
d = data + i * IPSET_VALIGN(sizeof(ip_set_id_t), dont_align);
*d = ip_set_id(map->index[i]);
}
}
IP_SET_TYPE(setlist, IPSET_TYPE_SETNAME | IPSET_DATA_SINGLE)

View File

@@ -3,7 +3,7 @@
#include "ip_set.h"
#define SETTYPE_NAME "setlist"
#define SETTYPE_NAME "setlist"
#define IP_SET_SETLIST_ADD_AFTER 0
#define IP_SET_SETLIST_ADD_BEFORE 1

View File

@@ -18,21 +18,21 @@
.\"
.\"
.SH NAME
ipset \- administration tool for IP sets
ipset \(em 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 "
.PP
\fBipset \-N\fP \fIset\fP \fItype-specification\fP [\fIoptions\fP...]
.PP
\fBipset\fP {\fB\-F\fP|\fB\-H\fP|\fB\-L\fP|\fB\-S\fP|\fB\-X\fP} [\fIset\fP]
[\fIoptions\fP...]
.PP
\fBipset\fP {\fB\-E\fP|\fB\-W\fP} \fIfrom-set\fP \fIto-set\fP
.PP
\fBipset\fP {\fB\-A\fP|\fB\-D\fP|\fB\-T\fP} \fIset\fP \fIentry\fP
.PP
\fBipset \-R\fP
.PP
\fBipset\fP {\fB-V\fP|\fB\-v\fP}
.SH DESCRIPTION
.B ipset
is used to set up, maintain and inspect so called IP sets in the Linux
@@ -40,19 +40,9 @@ 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.
.P
.B
Please note, binding sets is a deprecated feature and will be removed in a later release. Switch to the multidata type of sets from using bindings.
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
@@ -65,134 +55,87 @@ 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"
\fB\-N\fP, \fB\-\-create\fP \fIsetname\fP \fItype\fP \fItype-specific-options\fP
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.
\fB\-X\fP, \fB\-\-destroy\fP [\fIsetname\fP]
Destroy the specified set or all the sets if none is given.
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.
\fB\-F\fP, \fB\-\-flush\fP [\fIsetname\fP]
Delete all entries from the specified set or flush
all sets if none is given.
.TP
.BI "-E, --rename " "\fIfrom-setname\fP \fIto-setname\fP"
\fB\-E\fP, \fB\-\-rename\fP \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"
\fB\-W\fP, \fB\-\-swap\fP \fIfrom-setname\fP \fIto-setname\fP
Swap the content of two sets, or in another words,
exchange the name of two sets. The referred sets must exist and
identical type of sets can be swapped only.
.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"
\fB\-L\fP, \fB\-\-list\fP [\fIsetname\fP]
List the entries for the specified set, or for
all sets if none is given. The
\fB\-r\fP/\fB\-\-resolve\fP
option can be used to force name lookups (which may be slow). When the
\fB\-s\fP/\fB\-\-sorted\fP
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.
\fB\-S\fP, \fB\-\-save\fP [\fIsetname\fP]
Save the given set, or all sets if none is given
to stdout in a format that \fB\-\-restore\fP can read.
.TP
.BI "-R, --restore "
Restore a saved session generated by --save. The saved session
\fB\-R\fP, \fB\-\-restore\fP
Restore a saved session generated by \fB\-\-save\fP. 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
(create set and add element) 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.
and so on. 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.
\fB\-A\fP, \fB\-\-add\fP \fIsetname\fP \fIentry\fP
Add an entry to a set.
.TP
.BI "-D, --del " "\fIsetname\fP \fIIP\fP"
Delete an IP from a set.
\fB\-D\fP, \fB\-\-del\fP \fIsetname\fP \fIentry\fP
Delete an entry 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
\fB-T\fP, \fB\-\-test\fP \fIsetname\fP \fIentry\fP
Test wether an entry is in a set or not. Exit status number is zero
if the tested entry 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]"
\fB\-H\fP, \fB\-\-help\fP [\fIsettype\fP]
Print help and settype specific help if settype specified.
.TP
\fB\-V\fP, \fB\-v\fP, \fB\-\-version\fP
Print program version and protocol version.
.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
\fB\-r\fP, \fB\-\-resolve\fP
When listing sets, enforce name lookup. The
program will try to display the IP entries resolved to
host names or services (whenever applicable), which can trigger
.B
slow
DNS
lookups.
.TP
.B "-q, --quiet"
\fB\-s\fP, \fB\-\-sorted\fP
Sorted output. When listing sets, entries are listed sorted.
.TP
\fB\-n\fP, \fB\-\-numeric\fP
Numeric output. When listing sets, IP addresses and
port numbers will be printed in numeric format. This is the default.
.TP
\fB\-q\fP, \fB\-\-quiet\fP
Suppress any output to stdout and stderr. ipset will still return
possible errors.
.SH SET TYPES
@@ -202,7 +145,7 @@ 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. If the optional
.B "--netmask"
\fB\-\-netmask\fP
parameter is specified with a CIDR netmask value between 1-31 then
network addresses are stored in the given set: i.e an
IP address will be in the set if the network address, which is resulted
@@ -210,52 +153,54 @@ 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
\fB\-\-from\fP \fIfrom-addr\fP
.TP
.BR "--to " to-IP
Create an ipmap set from the specified range.
\fB\-\-to\fP \fIto-addr\fP
Create an ipmap set from the specified address range.
.TP
.BR "--network " IP/mask
\fB\-\-network\fP \fIaddr\fP\fB/\fP\fImask\fP
Create an ipmap set from the specified network.
.TP
.BR "--netmask " CIDR-netmask
\fB\-\-netmask\fP \fIprefixlen\fP
When the optional
.B "--netmask"
\fB\-\-netmask\fP
parameter specified, network addresses will be
stored in the set instead of IP addresses, and the from-IP parameter
must be a network address. The CIDR-netmask value must be between 1-31.
stored in the set instead of IP addresses, and the \fIfrom-addr\fP parameter
must be a network address. The \fIprefixlen\fP value must be between 1-31.
.PP
Example:
.IP
ipset \-N test ipmap \-\-network 192.168.0.0/16
.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.
"\fIaddress\fP\fB,\fP\fImac\fP".
When deleting or testing macipmap entries, the
.I ,MAC
"\fB,\fP\fImac\fP"
part is not mandatory.
.P
Options to use when creating an macipmap set:
.TP
.BR "--from " from-IP
\fB\-\-from\fP \fIfrom-addr\fP
.TP
.BR "--to " to-IP
Create a macipmap set from the specified range.
\fB\-\-to\fP \fIto-addr\fP
Create a macipmap set from the specified address range.
.TP
.BR "--network " IP/mask
\fB\-\-network\fP \fIaddr\fP\fB/\fP\fImask\fP
Create a macipmap set from the specified network.
.TP
.BR "--matchunset"
\fB\-\-matchunset\fP
When the optional
.B "--matchunset"
\fB\-\-matchunset\fP
parameter specified, IP addresses which could be stored
in the set but not set yet, will always match.
.P
Please note, the
.I
set
"set"
and
.I
SET
"SET"
netfilter kernel modules
.B
always
@@ -268,42 +213,41 @@ The portmap set type is very fast and memory cheap.
.P
Options to use when creating an portmap set:
.TP
.BR "--from " from-port
\fB\-\-from\fP \fIfrom-port\fP
.TP
.BR "--to " to-port
Create a portmap set from the specified range.
\fB\-\-to\fP \fIto-port\fP
Create a portmap set from the specified port 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. If the optional
.B "--netmask"
parameter is specified with a CIDR netmask value between 1-31 then
\fB\-\-netmask\fP
parameter is specified with a CIDR prefix length value between 1-31 then
network addresses are stored in the given set: i.e an
IP address will be in the set if the network address, which is resulted
by masking the address with the specified netmask, can be found in the set.
.P
Options to use when creating an iphash set:
.TP
.BR "--hashsize " hashsize
\fB\-\-hashsize\fP \fIhashsize\fP
The initial hash size (default 1024)
.TP
.BR "--probes " probes
\fB\-\-probes\fP \fIprobes\fP
How many times try to resolve clashing at adding an IP to the hash
by double-hashing (default 8).
.TP
.BR "--resize " percent
\fB\-\-resize\fP \fIpercent\fP
Increase the hash size by this many percent (default 50) when adding
an IP to the hash could not be performed after
.B
probes
\fIprobes\fP
number of double-hashing.
.TP
.BR "--netmask " CIDR-netmask
\fB\-\-netmask\fP \fIprefixlen\fP
When the optional
.B "--netmask"
\fB\-\-netmask\fP
parameter specified, network addresses will be
stored in the set instead of IP addresses. The CIDR-netmask value must
stored in the set instead of IP addresses. The \fIprefixlen\fP value must
be between 1-31.
.P
The iphash type of sets can store up to 65536 entries. If a set is full,
@@ -312,35 +256,36 @@ no new entries can be added to it.
Sets created by zero valued resize parameter won't be resized at all.
The lookup time in an iphash type of set grows approximately linearly with
the value of the
.B
probes
\fIprobes\fP
parameter. In general higher
.B
probe
\fIprobes\fP
value results better utilized hash while smaller value
produces larger, sparser hash.
.PP
Example:
.IP
ipset \-N test iphash \-\-probes 2
.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.
entry
used in the ipset commands must be in the form
"\fIaddress\fP\fB/\fP\fIprefixlen\fP"
where prefixlen 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
\fB\-\-hashsize\fP \fIhashsize\fP
The initial hash size (default 1024)
.TP
.BR "--probes " probes
\fB\-\-probes\fP \fIprobes\fP
How many times try to resolve clashing at adding an IP to the hash
by double-hashing (default 4).
.TP
.BR "--resize " percent
\fB\-\-resize\fP \fIpercent\fP
Increase the hash size by this many percent (default 50) when adding
an IP to the hash could not be performed after
.P
@@ -352,15 +297,13 @@ netblocks added to the set. The matching always start from the smallest
size of netblock (most specific netmask) to the largest ones (least
specific netmasks). When adding/deleting IP addresses
to a nethash set by the
.I
SET
"SET"
netfilter kernel module, it will be added/deleted by the smallest
netblock size which can be found in the set, or by /31 if the set is empty.
.P
The lookup time in a nethash type of set grows approximately linearly
with the times of the
.B
probes
\fIprobes\fP
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.
@@ -371,39 +314,35 @@ 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".
"\fIaddress\fP\fB,\fP\fIport\fP".
.P
The ipporthash types of sets evaluates two src/dst parameters of the
.I
set
"set"
match and
.I
SET
"SET"
target.
.P
Options to use when creating an ipporthash set:
.TP
.BR "--from " from-IP
\fB\-\-from\fP \fIfrom-addr\fP
.TP
.BR "--to " to-IP
Create an ipporthash set from the specified range.
\fB\-\-to\fP \fIto-addr\fP
Create an ipporthash set from the specified address range.
.TP
.BR "--network " IP/mask
\fB\-\-network\fP \fIaddr\fP\fB/\fP\fImask\fP
Create an ipporthash set from the specified network.
.TP
.BR "--hashsize " hashsize
\fB\-\-hashsize\fP \fIhashsize\fP
The initial hash size (default 1024)
.TP
.BR "--probes " probes
\fB\-\-probes\fP \fIprobes\fP
How many times try to resolve clashing at adding an IP to the hash
by double-hashing (default 8).
.TP
.BR "--resize " percent
\fB\-\-resize\fP \fIpercent\fP
Increase the hash size by this many percent (default 50) when adding
an IP to the hash could not be performed after
.B
probes
\fIprobes\fP
number of double-hashing.
.P
The same resizing, speed and memory efficiency comments applies here
@@ -414,39 +353,35 @@ address triples. The first IP address must come form a maximum /16
sized network or range while the port number and the second IP address
parameters are arbitrary. When adding, deleting and testing values in an
ipportiphash type of set, the entries must be specified as
.B
"IP,port,IP".
"\fIaddress\fP\fB,\fP\fIport\fP\fB,\fP\fIaddress\fP".
.P
The ipportiphash types of sets evaluates three src/dst parameters of the
.I
set
"set"
match and
.I
SET
"SET"
target.
.P
Options to use when creating an ipportiphash set:
.TP
.BR "--from " from-IP
\fB\-\-from\fP \fIfrom-addr\fP
.TP
.BR "--to " to-IP
Create an ipportiphash set from the specified range.
\fB\-\-to\fP \fIto-addr\fP
Create an ipportiphash set from the specified address range.
.TP
.BR "--network " IP/mask
\fB\-\-network\fP \fIaddr\fP\fB/\fP\fImask\fP
Create an ipportiphash set from the specified network.
.TP
.BR "--hashsize " hashsize
\fB\-\-hashsize\fP \fIhashsize\fP
The initial hash size (default 1024)
.TP
.BR "--probes " probes
\fB\-\-probes\fP \fIprobes\fP
How many times try to resolve clashing at adding an IP to the hash
by double-hashing (default 8).
.TP
.BR "--resize " percent
\fB\-\-resize\fP \fIpercent\fP
Increase the hash size by this many percent (default 50) when adding
an IP to the hash could not be performed after
.B
probes
\fIprobes\fP
number of double-hashing.
.P
The same resizing, speed and memory efficiency comments applies here
@@ -459,39 +394,35 @@ parameters are arbitrary, but the size of the network address must be
between /1-/31. When adding, deleting
and testing values in an ipportnethash type of set, the entries must be
specified as
.B
"IP,port,IP/cidr-size".
"\fIaddress\fP\fB,\fP\fIport\fP\fB,\fP\fIaddress\fP\fB/\fP\fIprefixlen\fP".
.P
The ipportnethash types of sets evaluates three src/dst parameters of the
.I
set
"set"
match and
.I
SET
"SET"
target.
.P
Options to use when creating an ipportnethash set:
.TP
.BR "--from " from-IP
\fB\-\-from\fP \fIfrom-address\fP
.TP
.BR "--to " to-IP
\fB\-\-to\fP \fIto-address\fP
Create an ipporthash set from the specified range.
.TP
.BR "--network " IP/mask
\fB\-\-network\fP \fIaddress\fP\fB/\fP\fImask\fP
Create an ipporthash set from the specified network.
.TP
.BR "--hashsize " hashsize
\fB\-\-hashsize\fP \fIhashsize\fP
The initial hash size (default 1024)
.TP
.BR "--probes " probes
\fB\-\-probes\fP \fIprobes\fP
How many times try to resolve clashing at adding an IP to the hash
by double-hashing (default 8).
.TP
.BR "--resize " percent
\fB\-\-resize\fP \fIpercent\fP
Increase the hash size by this many percent (default 50) when adding
an IP to the hash could not be performed after
.B
probes
\fIprobes\fP
number of double-hashing.
.P
The same resizing, speed and memory efficiency comments applies here
@@ -502,14 +433,14 @@ with timeout values.
.P
Options to use when creating an iptree set:
.TP
.BR "--timeout " value
\fB\-\-timeout\fP \fIvalue\fP
The timeout value for the entries in seconds (default 0)
.P
If a set was created with a nonzero valued
.B "--timeout"
\fB\-\-timeout\fP
parameter then one may add IP addresses to the set with a specific
timeout value using the syntax
.I IP,timeout-value.
"\fIaddress\fP\fB,\fP\fItimeout-value\fP".
Similarly to the hash types, the iptree type of sets can store up to 65536
entries.
.SS iptreemap
@@ -517,37 +448,32 @@ 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
"\fIaddress1\fP\fB-\fP\fIaddress2\fP".
.P
Options to use when creating an iptreemap set:
.TP
.BR "--gc " value
\fB\-\-gc\fP \fIvalue\fP
How often the garbage collection should be called, in seconds (default 300)
.SS setlist
The setlist type uses a simple list in which you can store sets. By the
.I
ipset
command you can add, delete and test sets in a setlist type of set.
You can specify the sets as
.B
"setname[,after|before,setname]".
"\fIsetname\fP[\fB,\fP{\fBafter\fP|\fBbefore\fP},\fIsetname\fP]".
By default new sets are added after (appended to) the existing
elements. Setlist type of sets cannot be added to a setlist type of set.
.P
Options to use when creating a setlist type of set:
.TP
.BR "--size " size
\fB\-\-size\fP \fIsize\fP
Create a setlist type of set with the given size (default 8).
.P
.PP
By the
.I
set
"set"
match or
.I
SET
"SET"
target of
.I
iptables
\fBiptables\fP(8)
you can test, add or delete entries in the sets. The match
will try to find a matching IP address/port in the sets and
the target will try to add the IP address/port to the first set
@@ -562,8 +488,9 @@ and
.I
b
are setlist type of sets then in the command
.TP
iptables -m set --match-set a src,dst -j SET --add-set b src,dst
.IP
iptables \-m set \-\-match\-set a src,dst \-j SET \-\-add-set b src,dst
.PP
the match and target will skip any set in
.I a
and
@@ -574,7 +501,7 @@ data storage in
.I a
set and add src to the first single or src,dst to the first double
data storage set in
.I b.
\fIb\fP.
.P
You can imagine a setlist type of set as an ordered union of
the set elements.
@@ -589,6 +516,8 @@ use the iphash set type. If you have got random size of netblocks,
use nethash.
.P
Old separator tokens (':' and '%") are still accepted.
.P
Binding support is removed.
.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

View File

@@ -30,11 +30,15 @@
#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe"
#endif
#define IPSET_VERSION "3.2"
#define IPSET_VERSION "4.1"
char program_name[] = "ipset";
char program_version[] = IPSET_VERSION;
const char *ipset_libdir = IPSET_LIB_DIR;
static int protocol_version = 0;
#define STREQ(a,b) (strncmp(a,b,IP_SET_MAXNAMELEN) == 0)
#define DONT_ALIGN (protocol_version == IP_SET_PROTOCOL_UNALIGNED)
#define ALIGNED(len) IPSET_VALIGN(len, DONT_ALIGN)
/* The list of loaded set types */
static struct settype *all_settypes = NULL;
@@ -68,7 +72,7 @@ static unsigned int global_option_offset = 0;
static const char cmdflags[] = { ' ', /* CMD_NONE */
'N', 'X', 'F', 'E', 'W', 'L', 'S', 'R',
'A', 'D', 'T', 'B', 'U', 'H', 'V',
'A', 'D', 'T', 'H', 'V',
};
/* Options */
@@ -77,11 +81,10 @@ static const char cmdflags[] = { ' ', /* CMD_NONE */
#define OPT_SORTED 0x0002U /* -s */
#define OPT_QUIET 0x0004U /* -q */
#define OPT_DEBUG 0x0008U /* -z */
#define OPT_BINDING 0x0010U /* -b */
#define OPT_RESOLVE 0x0020U /* -r */
#define NUMBER_OF_OPT 6
#define NUMBER_OF_OPT 5
static const char optflags[] =
{ 'n', 's', 'q', 'z', 'b', 'r' };
{ 'n', 's', 'q', 'z', 'r' };
static struct option opts_long[] = {
/* set operations */
@@ -100,15 +103,10 @@ static struct option opts_long[] = {
{"del", 1, 0, 'D'},
{"test", 1, 0, 'T'},
/* binding operations */
{"bind", 1, 0, 'B'},
{"unbind", 1, 0, 'U'},
/* free options */
{"numeric", 0, 0, 'n'},
{"sorted", 0, 0, 's'},
{"quiet", 0, 0, 'q'},
{"binding", 1, 0, 'b'},
{"resolve", 0, 0, 'r'},
#ifdef IPSET_DEBUG
@@ -125,7 +123,7 @@ static struct option opts_long[] = {
};
static char opts_short[] =
"-N:X::F::E:W:L::S::RA:D:T:B:U:nrsqzb:Vh::H::";
"-N:X::F::E:W:L::S::RA:D:T:nrsqzvVh::H::";
/* Table of legal combinations of commands and options. If any of the
* given commands make an option legal, that option is legal.
@@ -136,22 +134,20 @@ static char opts_short[] =
*/
static char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] = {
/* -n -s -q -z -b */
/*CREATE*/ {'x', 'x', ' ', ' ', 'x', 'x'},
/*DESTROY*/ {'x', 'x', ' ', ' ', 'x', 'x'},
/*FLUSH*/ {'x', 'x', ' ', ' ', 'x', 'x'},
/*RENAME*/ {'x', 'x', ' ', ' ', 'x', 'x'},
/*SWAP*/ {'x', 'x', ' ', ' ', 'x', 'x'},
/*LIST*/ {' ', ' ', 'x', ' ', 'x', ' '},
/*SAVE*/ {'x', 'x', ' ', ' ', 'x', 'x'},
/*RESTORE*/ {'x', 'x', ' ', ' ', 'x', 'x'},
/*ADD*/ {'x', 'x', ' ', ' ', 'x', 'x'},
/*DEL*/ {'x', 'x', ' ', ' ', 'x', 'x'},
/*TEST*/ {'x', 'x', ' ', ' ', ' ', 'x'},
/*BIND*/ {'x', 'x', ' ', ' ', '+', 'x'},
/*UNBIND*/ {'x', 'x', ' ', ' ', 'x', 'x'},
/*HELP*/ {'x', 'x', 'x', ' ', 'x', 'x'},
/*VERSION*/ {'x', 'x', 'x', ' ', 'x', 'x'},
/* -n -s -q -z -r */
/*CREATE*/ {'x', 'x', ' ', ' ', 'x'},
/*DESTROY*/ {'x', 'x', ' ', ' ', 'x'},
/*FLUSH*/ {'x', 'x', ' ', ' ', 'x'},
/*RENAME*/ {'x', 'x', ' ', ' ', 'x'},
/*SWAP*/ {'x', 'x', ' ', ' ', 'x'},
/*LIST*/ {' ', ' ', 'x', ' ', ' '},
/*SAVE*/ {'x', 'x', ' ', ' ', 'x'},
/*RESTORE*/ {'x', 'x', ' ', ' ', 'x'},
/*ADD*/ {'x', 'x', ' ', ' ', 'x'},
/*DEL*/ {'x', 'x', ' ', ' ', 'x'},
/*TEST*/ {'x', 'x', ' ', ' ', 'x'},
/*HELP*/ {'x', 'x', 'x', ' ', 'x'},
/*VERSION*/ {'x', 'x', 'x', ' ', 'x'},
};
/* Main parser function */
@@ -454,25 +450,26 @@ static void check_protocolversion(void)
{
struct ip_set_req_version req_version;
socklen_t size = sizeof(struct ip_set_req_version);
int sockfd = kernel_getsocket();
int res;
req_version.op = IP_SET_OP_VERSION;
res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req_version, &size);
if (res != 0) {
ipset_printf("I'm of protocol version %u.\n"
"Kernel module is not loaded in, "
"cannot verify kernel version.",
IP_SET_PROTOCOL_VERSION);
if (protocol_version)
return;
}
if (req_version.version != IP_SET_PROTOCOL_VERSION)
req_version.op = IP_SET_OP_VERSION;
res = wrapped_getsockopt(&req_version, &size);
if (res != 0)
exit_error(OTHER_PROBLEM,
"Kernel ipset code is of protocol version %u."
"Couldn't verify kernel module version!");
if (!(req_version.version == IP_SET_PROTOCOL_VERSION
|| req_version.version == IP_SET_PROTOCOL_UNALIGNED))
exit_error(OTHER_PROBLEM,
"Kernel ip_set module is of protocol version %u."
"I'm of protocol version %u.\n"
"Please upgrade your kernel and/or ipset(8) utillity.",
req_version.version, IP_SET_PROTOCOL_VERSION);
protocol_version = req_version.version;
}
static void set_command(int *cmd, int newcmd)
@@ -594,11 +591,6 @@ char *ip_tostring(ip_set_ip_t ip, unsigned options)
return inet_ntoa(addr);
}
char *binding_ip_tostring(struct set *set UNUSED,
ip_set_ip_t ip, unsigned options)
{
return ip_tostring(ip, options);
}
char *ip_tostring_numeric(ip_set_ip_t ip)
{
return ip_tostring(ip, OPT_NUMERIC);
@@ -763,8 +755,7 @@ static struct settype *settype_find(const char *typename)
DP("%s", typename);
while (runner != NULL) {
if (strncmp(runner->typename, typename,
IP_SET_MAXNAMELEN) == 0)
if (STREQ(runner->typename, typename))
return runner;
runner = runner->next;
@@ -886,9 +877,7 @@ struct set *set_find_byname(const char *name)
ip_set_id_t i;
for (i = 0; i < max_sets; i++)
if (set_list[i]
&& strncmp(set_list[i]->name, name,
IP_SET_MAXNAMELEN) == 0) {
if (set_list[i] != NULL && STREQ(set_list[i]->name, name)) {
set = set_list[i];
break;
}
@@ -906,9 +895,7 @@ static ip_set_id_t set_find_free_index(const char *name)
if (idx == IP_SET_INVALID_ID
&& set_list[i] == NULL)
idx = i;
if (set_list[i] != NULL
&& strncmp(set_list[i]->name, name,
IP_SET_MAXNAMELEN) == 0)
if (set_list[i] != NULL && STREQ(set_list[i]->name, name))
exit_error(PARAMETER_PROBLEM,
"Set %s is already defined, cannot be restored",
name);
@@ -935,7 +922,7 @@ static void set_create(const char *name, struct settype *settype)
DP("%s %s", name, settype->typename);
req_create.op = IP_SET_OP_CREATE;
req_create.version = IP_SET_PROTOCOL_VERSION;
req_create.version = protocol_version;
strcpy(req_create.name, name);
strcpy(req_create.typename, settype->typename);
@@ -959,14 +946,14 @@ static void set_restore_create(const char *name, struct settype *settype)
{
struct set *set;
DP("%s %s %u %u %u %u", name, settype->typename,
DP("%s %s %zu %zu %u %u", name, settype->typename,
restore_offset, sizeof(struct ip_set_restore),
settype->create_size, restore_size);
/* Sanity checking */
if (restore_offset
+ sizeof(struct ip_set_restore)
+ settype->create_size > restore_size)
+ ALIGNED(sizeof(struct ip_set_restore))
+ ALIGNED(settype->create_size) > restore_size)
exit_error(PARAMETER_PROBLEM,
"Giving up, restore file is screwed up!");
@@ -985,11 +972,11 @@ static void set_restore_create(const char *name, struct settype *settype)
DP("name %s, restore index %u", restore_set->name, restore_set->index);
/* Add settype data */
memcpy(restore_data + restore_offset + sizeof(struct ip_set_restore),
settype->data, settype->create_size);
restore_offset += ALIGNED(sizeof(struct ip_set_restore));
memcpy(restore_data + restore_offset, settype->data, settype->create_size);
restore_offset += sizeof(struct ip_set_restore)
+ settype->create_size;
restore_offset += ALIGNED(settype->create_size);
DP("restore_offset: %zu", restore_offset);
/* Add set to set_list */
set = ipset_malloc(sizeof(struct set));
@@ -1009,7 +996,7 @@ static void set_destroy(const char *name, unsigned op, unsigned cmd)
DP("%s %s", cmd == CMD_DESTROY ? "destroy" : "flush", name);
req.op = op;
req.version = IP_SET_PROTOCOL_VERSION;
req.version = protocol_version;
strcpy(req.name, name);
kernel_sendto(cmd, &req, sizeof(struct ip_set_req_std));
@@ -1027,7 +1014,7 @@ static void set_rename(const char *name, const char *newname,
name, newname);
req.op = op;
req.version = IP_SET_PROTOCOL_VERSION;
req.version = protocol_version;
strcpy(req.name, name);
strcpy(req.typename, newname);
@@ -1065,7 +1052,7 @@ tryagain:
}
/* Get max_sets */
req_max_sets.op = IP_SET_OP_MAX_SETS;
req_max_sets.version = IP_SET_PROTOCOL_VERSION;
req_max_sets.version = protocol_version;
strcpy(req_max_sets.set.name, name);
size = sizeof(req_max_sets);
kernel_getfrom(CMD_MAX_SETS, &req_max_sets, &size);
@@ -1083,8 +1070,8 @@ tryagain:
return 0;
/* Get setnames */
size = req_size = sizeof(struct ip_set_req_setnames)
+ req_max_sets.sets * sizeof(struct ip_set_name_list);
size = req_size = ALIGNED(sizeof(struct ip_set_req_setnames))
+ req_max_sets.sets * ALIGNED(sizeof(struct ip_set_name_list));
data = ipset_malloc(size);
((struct ip_set_req_setnames *) data)->op = op;
((struct ip_set_req_setnames *) data)->index = *idx;
@@ -1102,8 +1089,8 @@ tryagain:
}
/* Load in setnames */
size = sizeof(struct ip_set_req_setnames);
while (size + sizeof(struct ip_set_name_list) <= req_size) {
size = ALIGNED(sizeof(struct ip_set_req_setnames));
while (size + ALIGNED(sizeof(struct ip_set_name_list)) <= req_size) {
name_list = (struct ip_set_name_list *)
(data + size);
set = ipset_malloc(sizeof(struct set));
@@ -1114,9 +1101,9 @@ tryagain:
set_list[name_list->index] = set;
DP("loaded %s, type %s, index %u",
set->name, set->settype->typename, set->index);
size += sizeof(struct ip_set_name_list);
size += ALIGNED(sizeof(struct ip_set_name_list));
}
/* Size to get set members, bindings */
/* Size to get set members */
size = ((struct ip_set_req_setnames *)data)->size;
free(data);
@@ -1126,36 +1113,7 @@ tryagain:
/*
* Save operation
*/
static size_t save_bindings(void *data, size_t offset, size_t len)
{
struct ip_set_hash_save *hash =
(struct ip_set_hash_save *) (data + offset);
struct set *set;
DP("offset %u, len %u", offset, len);
if (offset + sizeof(struct ip_set_hash_save) > len)
exit_error(OTHER_PROBLEM,
"Save operation failed, try again later.");
set = set_find_byid(hash->id);
if (!(set && set_list[hash->binding]))
exit_error(OTHER_PROBLEM,
"Save binding failed, try again later.");
if (!set->settype->bindip_tostring)
exit_error(OTHER_PROBLEM,
"Internal error, binding is not supported with set %s"
" of settype %s\n",
set->name, set->settype->typename);
printf("-B %s %s -b %s\n",
set->name,
set->settype->bindip_tostring(set, hash->ip, OPT_NUMERIC),
set_list[hash->binding]->name);
return sizeof(struct ip_set_hash_save);
}
static size_t save_set(void *data, int *bindings,
size_t offset, size_t len)
static size_t save_set(void *data, size_t offset, size_t len)
{
struct ip_set_save *set_save =
(struct ip_set_save *) (data + offset);
@@ -1163,12 +1121,12 @@ static size_t save_set(void *data, int *bindings,
struct settype *settype;
size_t used;
DP("offset %u (%u/%u/%u), len %u", offset,
DP("offset %zu (%zu/%u/%u), len %zu", offset,
sizeof(struct ip_set_save),
set_save->header_size, set_save->members_size,
len);
if (offset + sizeof(struct ip_set_save) > len
|| offset + sizeof(struct ip_set_save)
if (offset + ALIGNED(sizeof(struct ip_set_save)) > len
|| offset + ALIGNED(sizeof(struct ip_set_save))
+ set_save->header_size + set_save->members_size > len)
exit_error(OTHER_PROBLEM,
"Save operation failed, try again later.");
@@ -1176,8 +1134,7 @@ static size_t save_set(void *data, int *bindings,
DP("index: %u", set_save->index);
if (set_save->index == IP_SET_INVALID_ID) {
/* Marker */
*bindings = 1;
return sizeof(struct ip_set_save);
return ALIGNED(sizeof(struct ip_set_save));
}
set = set_list[set_save->index];
if (!set)
@@ -1186,7 +1143,7 @@ static size_t save_set(void *data, int *bindings,
settype = set->settype;
/* Init set header */
used = sizeof(struct ip_set_save);
used = ALIGNED(sizeof(struct ip_set_save));
settype->initheader(set, data + offset + used);
/* Print create set */
@@ -1195,44 +1152,18 @@ static size_t save_set(void *data, int *bindings,
/* Print add IPs */
used += set_save->header_size;
settype->saveips(set, data + offset + used,
set_save->members_size, OPT_NUMERIC);
set_save->members_size, OPT_NUMERIC,
DONT_ALIGN);
return (used + set_save->members_size);
}
static size_t save_default_bindings(void *data, int *bindings)
{
struct ip_set_save *set_save = (struct ip_set_save *) data;
struct set *set;
if (set_save->index == IP_SET_INVALID_ID) {
/* Marker */
*bindings = 1;
return sizeof(struct ip_set_save);
}
set = set_list[set_save->index];
DP("%s, binding %u", set->name, set_save->binding);
if (set_save->binding != IP_SET_INVALID_ID) {
if (!set_list[set_save->binding])
exit_error(OTHER_PROBLEM,
"Save set failed, try again later.");
printf("-B %s %s -b %s\n",
set->name, IPSET_TOKEN_DEFAULT,
set_list[set_save->binding]->name);
}
return (sizeof(struct ip_set_save)
+ set_save->header_size
+ set_save->members_size);
}
static int try_save_sets(const char name[IP_SET_MAXNAMELEN])
{
void *data = NULL;
socklen_t size, req_size = 0;
ip_set_id_t idx;
int res = 0, bindings = 0;
int res = 0;
time_t now = time(NULL);
/* Load set_list from kernel */
@@ -1240,15 +1171,17 @@ static int try_save_sets(const char name[IP_SET_MAXNAMELEN])
IP_SET_OP_SAVE_SIZE, CMD_SAVE);
if (size) {
/* Get sets, bindings and print them */
/* Get sets and print them */
/* Take into account marker */
req_size = (size += sizeof(struct ip_set_save));
req_size = (size += ALIGNED(sizeof(struct ip_set_save)));
data = ipset_malloc(size);
((struct ip_set_req_list *) data)->op = IP_SET_OP_SAVE;
((struct ip_set_req_list *) data)->index = idx;
res = kernel_getfrom_handleerrno(CMD_SAVE, data, &size);
if (res != 0 || size != req_size) {
DP("Try again: res: %i, size %u, req_size: %u",
res, size, req_size);
free(data);
return -EAGAIN;
}
@@ -1258,17 +1191,8 @@ static int try_save_sets(const char name[IP_SET_MAXNAMELEN])
size = 0;
while (size < req_size) {
DP("size: %u, req_size: %u", size, req_size);
if (bindings)
size += save_bindings(data, size, req_size);
else
size += save_set(data, &bindings, size, req_size);
size += save_set(data, size, req_size);
}
/* Re-read data to save default bindings */
bindings = 0;
size = 0;
while (size < req_size && bindings == 0)
size += save_default_bindings(data + size, &bindings);
printf("COMMIT\n");
now = time(NULL);
printf("# Completed on %s", ctime(&now));
@@ -1366,7 +1290,7 @@ static void set_restore(char *argv0)
char buffer[1024];
char *ptr, *name = NULL;
char cmd = ' ';
int first_pass, i, bindings = 0;
int first_pass, i;
struct settype *settype = NULL;
struct ip_set_req_setnames *header;
ip_set_id_t idx;
@@ -1381,8 +1305,7 @@ static void set_restore(char *argv0)
IP_SET_OP_LIST_SIZE, CMD_RESTORE);
restore_line = 0;
restore_size = sizeof(struct ip_set_req_setnames)/* header */
+ sizeof(struct ip_set_restore); /* marker */
restore_size = ALIGNED(sizeof(struct ip_set_req_setnames)); /* header */
DP("restore_size: %u", restore_size);
/* First pass: calculate required amount of data */
while (fgets(buffer, sizeof(buffer), in)) {
@@ -1429,13 +1352,9 @@ static void set_restore(char *argv0)
exit_error(PARAMETER_PROBLEM,
"Missing settype in line %u\n",
restore_line);
if (bindings)
exit_error(PARAMETER_PROBLEM,
"Invalid line %u: create must precede bindings\n",
restore_line);
settype = check_set_typename(ptr);
restore_size += sizeof(struct ip_set_restore)
+ settype->create_size;
restore_size += ALIGNED(sizeof(struct ip_set_restore))
+ ALIGNED(settype->create_size);
DP("restore_size (N): %u", restore_size);
break;
}
@@ -1446,20 +1365,10 @@ static void set_restore(char *argv0)
"Add IP to set %s in line %u without "
"preceding corresponding create set line\n",
ptr, restore_line);
if (bindings)
exit_error(PARAMETER_PROBLEM,
"Invalid line %u: adding entries must precede bindings\n",
restore_line);
restore_size += settype->adt_size;
restore_size += ALIGNED(settype->adt_size);
DP("restore_size (A): %u", restore_size);
break;
}
case 'B': {
bindings = 1;
restore_size += sizeof(struct ip_set_hash_save);
DP("restore_size (B): %u", restore_size);
break;
}
default: {
exit_error(PARAMETER_PROBLEM,
"Unrecognized restore command in line %u\n",
@@ -1471,12 +1380,13 @@ static void set_restore(char *argv0)
if (!restore)
exit_error(PARAMETER_PROBLEM,
"Missing COMMIT line\n");
restore_size += ALIGNED(sizeof(struct ip_set_restore)); /* marker */
DP("restore_size: %u", restore_size);
restore_data = ipset_malloc(restore_size);
header = (struct ip_set_req_setnames *) restore_data;
header->op = IP_SET_OP_RESTORE;
header->size = restore_size;
restore_offset = sizeof(struct ip_set_req_setnames);
restore_offset = ALIGNED(sizeof(struct ip_set_req_setnames));
/* Rewind to scan the file again */
fseek(in, 0L, SEEK_SET);
@@ -1508,17 +1418,15 @@ static void set_restore(char *argv0)
exit_error(PARAMETER_PROBLEM,
"Broken restore file\n");
do_restore:
if (bindings == 0
&& restore_size ==
(restore_offset + sizeof(struct ip_set_restore))) {
if (restore_size == (restore_offset + ALIGNED(sizeof(struct ip_set_restore)))) {
/* No bindings */
struct ip_set_restore *marker =
(struct ip_set_restore *) (restore_data + restore_offset);
DP("restore marker");
marker->index = IP_SET_INVALID_ID;
marker->header_size = marker->members_size = 0;
restore_offset += sizeof(struct ip_set_restore);
restore_offset += ALIGNED(sizeof(struct ip_set_restore));
DP("restore marker, restore_offset: %zu", restore_offset);
}
if (restore_size != restore_offset)
exit_error(PARAMETER_PROBLEM,
@@ -1550,8 +1458,10 @@ static struct set *set_adt_get(const char *name)
DP("%s", name);
check_protocolversion();
req_adt_get.op = IP_SET_OP_ADT_GET;
req_adt_get.version = IP_SET_PROTOCOL_VERSION;
req_adt_get.version = protocol_version;
strcpy(req_adt_get.set.name, name);
size = sizeof(struct ip_set_req_adt_get);
@@ -1579,15 +1489,15 @@ static int set_adtip(struct set *set, const char *adt,
DP("%s -> %s", set->name, adt);
/* Alloc memory for the data to send */
size = sizeof(struct ip_set_req_adt) + set->settype->adt_size ;
DP("alloc size %d", size);
size = ALIGNED(sizeof(struct ip_set_req_adt)) + set->settype->adt_size ;
DP("alloc size %zu", size);
data = ipset_malloc(size);
/* Fill out the request */
req_adt = (struct ip_set_req_adt *) data;
req_adt->op = op;
req_adt->index = set->index;
memcpy(data + sizeof(struct ip_set_req_adt),
memcpy(data + ALIGNED(sizeof(struct ip_set_req_adt)),
set->settype->data, set->settype->adt_size);
if (kernel_sendto_handleerrno(cmd, data, size) == -1)
@@ -1625,155 +1535,22 @@ static void set_restore_add(struct set *set, const char *adt UNUSED)
{
DP("%s %s", set->name, adt);
/* Sanity checking */
if (restore_offset + set->settype->adt_size > restore_size)
if (restore_offset + ALIGNED(set->settype->adt_size) > restore_size)
exit_error(PARAMETER_PROBLEM,
"Giving up, restore file is screwed up!");
memcpy(restore_data + restore_offset,
set->settype->data, set->settype->adt_size);
restore_set->members_size += set->settype->adt_size;
restore_offset += set->settype->adt_size;
}
restore_set->members_size += ALIGNED(set->settype->adt_size);
restore_offset += ALIGNED(set->settype->adt_size);
/*
* Send bind/unbind/test binding order to kernel for a set
*/
static int set_bind(struct set *set, const char *adt,
const char *binding,
unsigned op, unsigned cmd)
{
struct ip_set_req_bind *req_bind;
size_t size;
void *data;
int res = 0;
/* set may be null: '-U :all: :all:|:default:' */
DP("(%s, %s) -> %s", set ? set->name : IPSET_TOKEN_ALL, adt, binding);
/* Ugly */
if (set != NULL
&& ((strcmp(set->settype->typename, "iptreemap") == 0)
|| (strcmp(set->settype->typename, "ipportiphash") == 0)
|| (strcmp(set->settype->typename, "ipportnethash") == 0)
|| (strcmp(set->settype->typename, "setlist") == 0)))
exit_error(PARAMETER_PROBLEM,
"%s type of sets cannot be used at binding operations\n",
set->settype->typename);
/* Alloc memory for the data to send */
size = sizeof(struct ip_set_req_bind);
if (op != IP_SET_OP_UNBIND_SET && adt[0] == ':')
/* Set default binding */
size += IP_SET_MAXNAMELEN;
else if (!(op == IP_SET_OP_UNBIND_SET && set == NULL))
size += set->settype->adt_size;
DP("alloc size %d", size);
data = ipset_malloc(size);
/* Fill out the request */
req_bind = (struct ip_set_req_bind *) data;
req_bind->op = op;
req_bind->index = set ? set->index : IP_SET_INVALID_ID;
if (adt[0] == ':') {
/* ':default:' and ':all:' */
strncpy(req_bind->binding, adt, IP_SET_MAXNAMELEN);
if (op != IP_SET_OP_UNBIND_SET && adt[0] == ':')
strncpy(data + sizeof(struct ip_set_req_bind),
binding, IP_SET_MAXNAMELEN);
} else {
strncpy(req_bind->binding, binding, IP_SET_MAXNAMELEN);
memcpy(data + sizeof(struct ip_set_req_bind),
set->settype->data, set->settype->adt_size);
}
if (op == IP_SET_OP_TEST_BIND_SET) {
if (kernel_sendto_handleerrno(cmd, data, size) == -1) {
ipset_printf("%s in set %s is bound to %s.",
adt, set->name, binding);
res = 0;
} else {
ipset_printf("%s in set %s is NOT bound to %s.",
adt, set->name, binding);
res = 1;
}
} else
kernel_sendto(cmd, data, size);
free(data);
return res;
}
static void set_restore_bind(struct set *set,
const char *adt,
const char *binding)
{
struct ip_set_hash_save *hash_restore;
if (restore == 1) {
/* Marker */
struct ip_set_restore *marker =
(struct ip_set_restore *) (restore_data + restore_offset);
DP("restore marker");
if (restore_offset + sizeof(struct ip_set_restore)
> restore_size)
exit_error(PARAMETER_PROBLEM,
"Giving up, restore file is screwed up!");
marker->index = IP_SET_INVALID_ID;
marker->header_size = marker->members_size = 0;
restore_offset += sizeof(struct ip_set_restore);
restore = 2;
}
/* Sanity checking */
if (restore_offset + sizeof(struct ip_set_hash_save) > restore_size)
exit_error(PARAMETER_PROBLEM,
"Giving up, restore file is screwed up!");
hash_restore = (struct ip_set_hash_save *) (restore_data + restore_offset);
DP("%s -> %s", adt, binding);
if (strcmp(adt, IPSET_TOKEN_DEFAULT) == 0)
hash_restore->ip = 0;
else {
if (!set->settype->bindip_parse)
exit_error(OTHER_PROBLEM,
"Internal error, binding is not supported with set %s"
" of settype %s\n",
set->name, set->settype->typename);
set->settype->bindip_parse(adt, &hash_restore->ip);
}
hash_restore->id = set->index;
hash_restore->binding = (set_find_byname(binding))->index;
DP("id %u, ip %u, binding %u",
hash_restore->id, hash_restore->ip, hash_restore->binding);
restore_offset += sizeof(struct ip_set_hash_save);
DP("restore_offset: %zu", restore_offset);
}
/*
* Print operation
*/
static void print_bindings(struct set *set,
void *data, size_t size, unsigned options,
char * (*printip)(struct set *set,
ip_set_ip_t ip, unsigned options))
{
size_t offset = 0;
struct ip_set_hash_list *hash;
if (offset < size && !printip)
exit_error(OTHER_PROBLEM,
"Internal error, binding is not supported with set %s"
" of settype %s\n",
set->name, set->settype->typename);
while (offset < size) {
hash = (struct ip_set_hash_list *) (data + offset);
printf("%s -> %s\n",
printip(set, hash->ip, options),
set_list[hash->binding]->name);
offset += sizeof(struct ip_set_hash_list);
}
}
/* Help function to set_list() */
static size_t print_set(void *data, unsigned options)
{
@@ -1783,15 +1560,14 @@ static size_t print_set(void *data, unsigned options)
size_t offset;
/* Pretty print the set */
DP("header size: %u, members size: %u",
setlist->header_size, setlist->members_size);
printf("Name: %s\n", set->name);
printf("Type: %s\n", settype->typename);
printf("References: %d\n", setlist->ref);
printf("Default binding: %s\n",
setlist->binding == IP_SET_INVALID_ID ? ""
: set_list[setlist->binding]->name);
/* Init header */
offset = sizeof(struct ip_set_list);
offset = ALIGNED(sizeof(struct ip_set_list));
settype->initheader(set, data + offset);
/* Pretty print the type header */
@@ -1801,24 +1577,20 @@ static size_t print_set(void *data, unsigned options)
/* Pretty print all IPs */
printf("Members:\n");
offset += setlist->header_size;
DP("Aligned: %u, offset: %zu, members_size %u\n", !DONT_ALIGN, offset,
setlist->members_size);
if (options & OPT_SORTED)
settype->printips_sorted(set, data + offset,
setlist->members_size, options);
setlist->members_size, options,
DONT_ALIGN);
else
settype->printips(set, data + offset,
setlist->members_size, options);
/* Print bindings */
printf("Bindings:\n");
offset += setlist->members_size;
if (set->settype->bindip_tostring)
print_bindings(set,
data + offset, setlist->bindings_size, options,
settype->bindip_tostring);
setlist->members_size, options,
DONT_ALIGN);
printf("\n"); /* One newline between sets */
return (offset + setlist->bindings_size);
return (offset + setlist->members_size);
}
static int try_list_sets(const char name[IP_SET_MAXNAMELEN],
@@ -1889,9 +1661,9 @@ static void set_help(const struct settype *settype)
"Usage: %s -N new-set settype [options]\n"
" %s -[XFLSH] [set] [options]\n"
" %s -[EW] from-set to-set\n"
" %s -[ADTU] set IP\n"
" %s -B set IP option\n"
" %s -[ADT] set IP\n"
" %s -R\n"
" %s -v\n"
" %s -h (print this help information)\n\n",
program_name, program_version,
program_name, program_name, program_name,
@@ -1922,13 +1694,6 @@ static void set_help(const struct settype *settype)
" Deletes an IP from a set\n"
" --test -T setname IP \n"
" Tests if an IP exists in a set.\n"
" --bind -B setname IP|:default: -b bind-setname\n"
" Bind the IP in setname to bind-setname.\n"
" --unbind -U setname IP|:all:|:default:\n"
" Delete binding belonging to IP,\n"
" all bindings or default binding of setname.\n"
" --unbind -U :all: :all:|:default:\n"
" Delete all bindings or all default bindings.\n"
" --help -H [settype]\n"
" Prints this help, and settype specific help\n"
" --version -V\n"
@@ -1937,8 +1702,7 @@ static void set_help(const struct settype *settype)
" --sorted -s Numeric sort of the IPs in -L\n"
" --numeric -n Numeric output of addresses in a -L (default)\n"
" --resolve -r Try to resolve addresses in a -L\n"
" --quiet -q Suppress any output to stdout and stderr.\n"
" --binding -b Specifies the binding for -B\n");
" --quiet -q Suppress any output to stdout and stderr.\n");
#ifdef IPSET_DEBUG
printf(" --debug -z Enable debugging\n\n");
#else
@@ -1970,40 +1734,13 @@ static int parse_adt_cmdline(int command,
{
int res = 0;
/* -U :all: :all:|:default: */
if (command == CMD_UNBIND) {
if (strcmp(name, IPSET_TOKEN_ALL) == 0) {
if (strcmp(adt, IPSET_TOKEN_DEFAULT) == 0
|| strcmp(adt, IPSET_TOKEN_ALL) == 0) {
*set = NULL;
*settype = NULL;
return 1;
} else
exit_error(PARAMETER_PROBLEM,
"-U %s requires %s or %s as binding name",
IPSET_TOKEN_ALL,
IPSET_TOKEN_DEFAULT,
IPSET_TOKEN_ALL);
}
}
*set = restore ? set_find_byname(name)
: set_adt_get(name);
*set = restore ? set_find_byname(name) : set_adt_get(name);
/* Reset space for adt data */
*settype = (*set)->settype;
memset((*settype)->data, 0, (*settype)->adt_size);
if ((command == CMD_TEST
|| command == CMD_BIND
|| command == CMD_UNBIND)
&& (strcmp(adt, IPSET_TOKEN_DEFAULT) == 0
|| strcmp(adt, IPSET_TOKEN_ALL) == 0))
res = 1;
else
res = (*settype)->adt_parser(
command,
adt,
(*settype)->data);
res = (*settype)->adt_parser(command, adt, (*settype)->data);
return res;
}
@@ -2018,9 +1755,8 @@ int parse_commandline(int argc, char *argv[])
char *name = NULL; /* All except -H, -R */
char *newname = NULL; /* -E, -W */
char *adt = NULL; /* -A, -D, -T, -B, -U */
char *binding = NULL; /* -B */
struct set *set = NULL; /* -A, -D, -T, -B, -U */
char *adt = NULL; /* -A, -D, -T */
struct set *set = NULL; /* -A, -D, -T */
struct settype *settype = NULL; /* -N, -H */
char all_sets[] = IPSET_TOKEN_ALL;
@@ -2054,11 +1790,14 @@ int parse_commandline(int argc, char *argv[])
break;
}
case 'V':{ /* Version */
printf("%s v%s Protocol version %u.\n",
case 'V':
case 'v': { /* Version */
printf("%s v%s, protocol version %u.\n",
program_name, program_version,
IP_SET_PROTOCOL_VERSION);
check_protocolversion();
printf("Kernel module protocol version %u.\n",
protocol_version);
exit(0);
}
@@ -2067,7 +1806,7 @@ int parse_commandline(int argc, char *argv[])
name = check_set_name(optarg);
/* Protect reserved names (binding) */
/* Protect reserved names */
if (name[0] == ':')
exit_error(PARAMETER_PROBLEM,
"setname might not start with colon",
@@ -2142,9 +1881,7 @@ int parse_commandline(int argc, char *argv[])
case 'A': /* Add IP */
case 'D': /* Del IP */
case 'T': /* Test IP */
case 'B': /* Bind IP */
case 'U':{ /* Unbind IP */
case 'T':{ /* Test IP */
set_command(&command, find_cmd(c));
name = check_set_name(optarg);
@@ -2197,11 +1934,6 @@ int parse_commandline(int argc, char *argv[])
break;
#endif
case 'b':
add_option(&options, OPT_BINDING);
binding = check_set_name(optarg);
break;
case 1: /* non option */
printf("Bad argument `%s'\n", optarg);
exit_tryhelp(PARAMETER_PROBLEM);
@@ -2248,6 +1980,8 @@ int parse_commandline(int argc, char *argv[])
generic_opt_check(command, options);
DP("cmd: %c", cmd2char(command));
check_protocolversion();
switch (command) {
case CMD_CREATE:
@@ -2298,26 +2032,7 @@ int parse_commandline(int argc, char *argv[])
break;
case CMD_TEST:
if (binding)
res = set_bind(set, adt, binding,
IP_SET_OP_TEST_BIND_SET, CMD_TEST);
else
res = set_adtip(set, adt,
IP_SET_OP_TEST_IP, CMD_TEST);
break;
case CMD_BIND:
fprintf(stderr, "Warning: binding will be removed from the next release.\n"
"Please replace bindigs with sets of ipportmap and ipportiphash types\n");
if (restore)
set_restore_bind(set, adt, binding);
else
set_bind(set, adt, binding,
IP_SET_OP_BIND_SET, CMD_BIND);
break;
case CMD_UNBIND:
set_bind(set, adt, "", IP_SET_OP_UNBIND_SET, CMD_UNBIND);
res = set_adtip(set, adt, IP_SET_OP_TEST_IP, CMD_TEST);
break;
case CMD_HELP:

View File

@@ -56,8 +56,6 @@ enum set_commands {
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,
@@ -134,22 +132,19 @@ struct settype {
void (*printheader) (struct set *set, unsigned options);
/* Pretty print all IPs */
void (*printips) (struct set *set, void *data, u_int32_t len, unsigned options);
void (*printips) (struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align);
/* Pretty print all IPs sorted */
void (*printips_sorted) (struct set *set, void *data, u_int32_t len, unsigned options);
void (*printips_sorted) (struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align);
/* 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, u_int32_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);
void (*saveips) (struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align);
/* Print usage */
void (*usage) (void);
@@ -189,12 +184,12 @@ extern struct set *set_find_byid(ip_set_id_t id);
extern unsigned warn_once;
#define BITS_PER_LONG (8*sizeof(unsigned long))
#define BITS_PER_LONG (8*sizeof(ip_set_ip_t))
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
static inline int test_bit(int nr, const unsigned long *addr)
static inline int test_bit(int nr, const ip_set_ip_t *addr)
{
return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
return 1 & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
}
#define UNUSED __attribute__ ((unused))

View File

@@ -32,7 +32,7 @@
/* Initialize the create. */
static void
create_init(void *data)
iphash_create_init(void *data)
{
struct ip_set_req_iphash_create *mydata = data;
@@ -48,7 +48,7 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */
static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
iphash_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
{
struct ip_set_req_iphash_create *mydata =
(struct ip_set_req_iphash_create *) data;
@@ -117,7 +117,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */
static void
create_final(void *data UNUSED, unsigned int flags UNUSED)
iphash_create_final(void *data UNUSED, unsigned int flags UNUSED)
{
}
@@ -132,7 +132,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */
static ip_set_ip_t
adt_parser(int cmd UNUSED, const char *arg, void *data)
iphash_adt_parser(int cmd UNUSED, const char *arg, void *data)
{
struct ip_set_req_iphash *mydata = data;
@@ -149,7 +149,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/
static void
initheader(struct set *set, const void *data)
iphash_initheader(struct set *set, const void *data)
{
const struct ip_set_req_iphash_create *header = data;
struct ip_set_iphash *map = set->settype->header;
@@ -178,7 +178,7 @@ mask_to_bits(ip_set_ip_t mask)
}
static void
printheader(struct set *set, unsigned options UNUSED)
iphash_printheader(struct set *set, unsigned options UNUSED)
{
struct ip_set_iphash *mysetdata = set->settype->header;
@@ -192,7 +192,8 @@ printheader(struct set *set, unsigned options UNUSED)
}
static void
printips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
iphash_printips(struct set *set UNUSED, void *data, u_int32_t len,
unsigned options, char dont_align)
{
size_t offset = 0;
ip_set_ip_t *ip;
@@ -201,12 +202,12 @@ printips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
ip = data + offset;
if (*ip)
printf("%s\n", ip_tostring(*ip, options));
offset += sizeof(ip_set_ip_t);
offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
}
}
static void
saveheader(struct set *set, unsigned options UNUSED)
iphash_saveheader(struct set *set, unsigned options UNUSED)
{
struct ip_set_iphash *mysetdata = set->settype->header;
@@ -221,7 +222,8 @@ saveheader(struct set *set, unsigned options UNUSED)
/* Print save for an IP */
static void
saveips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
iphash_saveips(struct set *set UNUSED, void *data, u_int32_t len,
unsigned options, char dont_align)
{
size_t offset = 0;
ip_set_ip_t *ip;
@@ -231,11 +233,12 @@ saveips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
if (*ip)
printf("-A %s %s\n", set->name,
ip_tostring(*ip, options));
offset += sizeof(ip_set_ip_t);
offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
}
}
static void usage(void)
static void
iphash_usage(void)
{
printf
("-N set iphash [--hashsize hashsize] [--probes probes ]\n"
@@ -251,29 +254,25 @@ static struct settype settype_iphash = {
/* Create */
.create_size = sizeof(struct ip_set_req_iphash_create),
.create_init = &create_init,
.create_parse = &create_parse,
.create_final = &create_final,
.create_init = iphash_create_init,
.create_parse = iphash_create_parse,
.create_final = iphash_create_final,
.create_opts = create_opts,
/* Add/del/test */
.adt_size = sizeof(struct ip_set_req_iphash),
.adt_parser = &adt_parser,
.adt_parser = iphash_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,
.initheader = iphash_initheader,
.printheader = iphash_printheader,
.printips = iphash_printips,
.printips_sorted = iphash_printips,
.saveheader = iphash_saveheader,
.saveips = iphash_saveips,
/* Bindings */
.bindip_tostring = &binding_ip_tostring,
.bindip_parse = &parse_ip,
.usage = &usage,
.usage = iphash_usage,
};
CONSTRUCTOR(iphash)

View File

@@ -35,7 +35,7 @@
/* Initialize the create. */
static void
create_init(void *data)
ipmap_create_init(void *data)
{
struct ip_set_req_ipmap_create *mydata = data;
@@ -45,7 +45,7 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */
static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
ipmap_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
{
struct ip_set_req_ipmap_create *mydata = data;
unsigned int bits;
@@ -115,7 +115,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */
static void
create_final(void *data, unsigned int flags)
ipmap_create_final(void *data, unsigned int flags)
{
struct ip_set_req_ipmap_create *mydata = data;
ip_set_ip_t range;
@@ -188,7 +188,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */
static ip_set_ip_t
adt_parser(int cmd UNUSED, const char *arg, void *data)
ipmap_adt_parser(int cmd UNUSED, const char *arg, void *data)
{
struct ip_set_req_ipmap *mydata = data;
@@ -205,7 +205,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/
static void
initheader(struct set *set, const void *data)
ipmap_initheader(struct set *set, const void *data)
{
const struct ip_set_req_ipmap_create *header = data;
struct ip_set_ipmap *map = set->settype->header;
@@ -234,7 +234,7 @@ initheader(struct set *set, const void *data)
}
static void
printheader(struct set *set, unsigned options)
ipmap_printheader(struct set *set, unsigned options)
{
struct ip_set_ipmap *mysetdata = set->settype->header;
@@ -246,9 +246,9 @@ printheader(struct set *set, unsigned options)
printf(" netmask: %d\n", mask_to_bits(mysetdata->netmask));
}
static void
printips_sorted(struct set *set, void *data,
u_int32_t len UNUSED, unsigned options)
static inline void
__ipmap_printips_sorted(struct set *set, void *data,
u_int32_t len UNUSED, unsigned options)
{
struct ip_set_ipmap *mysetdata = set->settype->header;
ip_set_ip_t id;
@@ -262,7 +262,26 @@ printips_sorted(struct set *set, void *data,
}
static void
saveheader(struct set *set, unsigned options)
ipmap_printips_sorted(struct set *set, void *data,
u_int32_t len, unsigned options,
char dont_align)
{
ip_set_ip_t *ip;
size_t offset = 0;
if (dont_align)
return __ipmap_printips_sorted(set, data, len, options);
while (offset < len) {
DP("offset: %zu, len %u\n", offset, len);
ip = data + offset;
printf("%s\n", ip_tostring(*ip, options));
offset += IPSET_ALIGN(sizeof(ip_set_ip_t));
}
}
static void
ipmap_saveheader(struct set *set, unsigned options)
{
struct ip_set_ipmap *mysetdata = set->settype->header;
@@ -278,8 +297,9 @@ saveheader(struct set *set, unsigned options)
mask_to_bits(mysetdata->netmask));
}
static void
saveips(struct set *set, void *data, u_int32_t len UNUSED, unsigned options)
static inline void
__ipmap_saveips(struct set *set, void *data, u_int32_t len UNUSED,
unsigned options)
{
struct ip_set_ipmap *mysetdata = set->settype->header;
ip_set_ip_t id;
@@ -294,7 +314,25 @@ saveips(struct set *set, void *data, u_int32_t len UNUSED, unsigned options)
options));
}
static void usage(void)
static void
ipmap_saveips(struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align)
{
ip_set_ip_t *ip;
size_t offset = 0;
if (dont_align)
return __ipmap_saveips(set, data, len, options);
while (offset < len) {
ip = data + offset;
printf("-A %s %s\n", set->name, ip_tostring(*ip, options));
offset += IPSET_ALIGN(sizeof(ip_set_ip_t));
}
}
static void
ipmap_usage(void)
{
printf
("-N set ipmap --from IP --to IP [--netmask CIDR-netmask]\n"
@@ -310,29 +348,25 @@ static struct settype settype_ipmap = {
/* Create */
.create_size = sizeof(struct ip_set_req_ipmap_create),
.create_init = &create_init,
.create_parse = &create_parse,
.create_final = &create_final,
.create_init = ipmap_create_init,
.create_parse = ipmap_create_parse,
.create_final = ipmap_create_final,
.create_opts = create_opts,
/* Add/del/test */
.adt_size = sizeof(struct ip_set_req_ipmap),
.adt_parser = &adt_parser,
.adt_parser = ipmap_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,
.initheader = ipmap_initheader,
.printheader = ipmap_printheader,
.printips = ipmap_printips_sorted,
.printips_sorted = ipmap_printips_sorted,
.saveheader = ipmap_saveheader,
.saveips = ipmap_saveips,
/* Bindings */
.bindip_tostring = &binding_ip_tostring,
.bindip_parse = &parse_ip,
.usage = &usage,
.usage = ipmap_usage,
};
CONSTRUCTOR(ipmap)

View File

@@ -32,7 +32,7 @@
/* Initialize the create. */
static void
create_init(void *data)
ipporthash_create_init(void *data)
{
struct ip_set_req_ipporthash_create *mydata = data;
@@ -46,7 +46,8 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */
static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
ipporthash_create_parse(int c, char *argv[] UNUSED, void *data,
unsigned *flags)
{
struct ip_set_req_ipporthash_create *mydata = data;
ip_set_ip_t value;
@@ -137,7 +138,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */
static void
create_final(void *data, unsigned int flags)
ipporthash_create_final(void *data, unsigned int flags)
{
struct ip_set_req_ipporthash_create *mydata = data;
@@ -189,7 +190,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */
static ip_set_ip_t
adt_parser(int cmd UNUSED, const char *arg, void *data)
ipporthash_adt_parser(int cmd UNUSED, const char *arg, void *data)
{
struct ip_set_req_ipporthash *mydata = data;
char *saved = ipset_strdup(arg);
@@ -222,7 +223,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/
static void
initheader(struct set *set, const void *data)
ipporthash_initheader(struct set *set, const void *data)
{
const struct ip_set_req_ipporthash_create *header = data;
struct ip_set_ipporthash *map = set->settype->header;
@@ -236,7 +237,7 @@ initheader(struct set *set, const void *data)
}
static void
printheader(struct set *set, unsigned options)
ipporthash_printheader(struct set *set, unsigned options)
{
struct ip_set_ipporthash *mysetdata = set->settype->header;
@@ -248,7 +249,8 @@ printheader(struct set *set, unsigned options)
}
static void
printips(struct set *set, void *data, u_int32_t len, unsigned options)
ipporthash_printips(struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align)
{
struct ip_set_ipporthash *mysetdata = set->settype->header;
size_t offset = 0;
@@ -264,12 +266,12 @@ printips(struct set *set, void *data, u_int32_t len, unsigned options)
ip_tostring(ip, options),
port_tostring(port, options));
}
offset += sizeof(ip_set_ip_t);
offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
}
}
static void
saveheader(struct set *set, unsigned options)
ipporthash_saveheader(struct set *set, unsigned options)
{
struct ip_set_ipporthash *mysetdata = set->settype->header;
@@ -284,7 +286,8 @@ saveheader(struct set *set, unsigned options)
/* Print save for an IP */
static void
saveips(struct set *set, void *data, u_int32_t len, unsigned options)
ipporthash_saveips(struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align)
{
struct ip_set_ipporthash *mysetdata = set->settype->header;
size_t offset = 0;
@@ -300,27 +303,12 @@ saveips(struct set *set, void *data, u_int32_t len, unsigned options)
ip_tostring(ip, options),
port_tostring(port, options));
}
offset += sizeof(ip_set_ip_t);
offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
}
}
static char buffer[22];
static char *
unpack_ipport_tostring(struct set *set, ip_set_ip_t bip, unsigned options)
{
struct ip_set_ipporthash *mysetdata = 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;
}
static void usage(void)
static void
ipporthash_usage(void)
{
printf
("-N set ipporthash --from IP --to IP\n"
@@ -338,29 +326,25 @@ static struct settype settype_ipporthash = {
/* Create */
.create_size = sizeof(struct ip_set_req_ipporthash_create),
.create_init = &create_init,
.create_parse = &create_parse,
.create_final = &create_final,
.create_init = ipporthash_create_init,
.create_parse = ipporthash_create_parse,
.create_final = ipporthash_create_final,
.create_opts = create_opts,
/* Add/del/test */
.adt_size = sizeof(struct ip_set_req_ipporthash),
.adt_parser = &adt_parser,
.adt_parser = ipporthash_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,
.initheader = ipporthash_initheader,
.printheader = ipporthash_printheader,
.printips = ipporthash_printips,
.printips_sorted = ipporthash_printips,
.saveheader = ipporthash_saveheader,
.saveips = ipporthash_saveips,
/* Bindings */
.bindip_tostring = &unpack_ipport_tostring,
.bindip_parse = &parse_ip,
.usage = &usage,
.usage = ipporthash_usage,
};
CONSTRUCTOR(ipporthash)

View File

@@ -32,7 +32,7 @@
/* Initialize the create. */
static void
create_init(void *data)
ipportiphash_create_init(void *data)
{
struct ip_set_req_ipportiphash_create *mydata = data;
@@ -46,7 +46,8 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */
static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
ipportiphash_create_parse(int c, char *argv[] UNUSED, void *data,
unsigned *flags)
{
struct ip_set_req_ipportiphash_create *mydata = data;
ip_set_ip_t value;
@@ -137,7 +138,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */
static void
create_final(void *data, unsigned int flags)
ipportiphash_create_final(void *data, unsigned int flags)
{
struct ip_set_req_ipportiphash_create *mydata = data;
@@ -189,7 +190,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */
static ip_set_ip_t
adt_parser(int cmd UNUSED, const char *arg, void *data)
ipportiphash_adt_parser(int cmd UNUSED, const char *arg, void *data)
{
struct ip_set_req_ipportiphash *mydata = data;
char *saved = ipset_strdup(arg);
@@ -227,7 +228,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/
static void
initheader(struct set *set, const void *data)
ipportiphash_initheader(struct set *set, const void *data)
{
const struct ip_set_req_ipportiphash_create *header = data;
struct ip_set_ipportiphash *map = set->settype->header;
@@ -241,7 +242,7 @@ initheader(struct set *set, const void *data)
}
static void
printheader(struct set *set, unsigned options)
ipportiphash_printheader(struct set *set, unsigned options)
{
struct ip_set_ipportiphash *mysetdata = set->settype->header;
@@ -253,7 +254,8 @@ printheader(struct set *set, unsigned options)
}
static void
printips(struct set *set, void *data, u_int32_t len, unsigned options)
ipportiphash_printips(struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align)
{
struct ip_set_ipportiphash *mysetdata = set->settype->header;
size_t offset = 0;
@@ -272,12 +274,12 @@ printips(struct set *set, void *data, u_int32_t len, unsigned options)
printf("%s\n",
ip_tostring(ipptr->ip1, options));
}
offset += sizeof(struct ipportip);
offset += IPSET_VALIGN(sizeof(struct ipportip), dont_align);
}
}
static void
saveheader(struct set *set, unsigned options)
ipportiphash_saveheader(struct set *set, unsigned options)
{
struct ip_set_ipportiphash *mysetdata = set->settype->header;
@@ -292,7 +294,8 @@ saveheader(struct set *set, unsigned options)
/* Print save for an IP */
static void
saveips(struct set *set, void *data, u_int32_t len, unsigned options)
ipportiphash_saveips(struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align)
{
struct ip_set_ipportiphash *mysetdata = set->settype->header;
size_t offset = 0;
@@ -311,11 +314,12 @@ saveips(struct set *set, void *data, u_int32_t len, unsigned options)
printf("%s\n",
ip_tostring(ipptr->ip1, options));
}
offset += sizeof(struct ipportip);
offset += IPSET_VALIGN(sizeof(struct ipportip), dont_align);
}
}
static void usage(void)
static void
ipportiphash_usage(void)
{
printf
("-N set ipportiphash --from IP --to IP\n"
@@ -333,25 +337,25 @@ static struct settype settype_ipportiphash = {
/* Create */
.create_size = sizeof(struct ip_set_req_ipportiphash_create),
.create_init = &create_init,
.create_parse = &create_parse,
.create_final = &create_final,
.create_init = ipportiphash_create_init,
.create_parse = ipportiphash_create_parse,
.create_final = ipportiphash_create_final,
.create_opts = create_opts,
/* Add/del/test */
.adt_size = sizeof(struct ip_set_req_ipportiphash),
.adt_parser = &adt_parser,
.adt_parser = ipportiphash_adt_parser,
/* Printing */
.header_size = sizeof(struct ip_set_ipportiphash),
.initheader = &initheader,
.printheader = &printheader,
.printips = &printips, /* We only have the unsorted version */
.printips_sorted = &printips,
.saveheader = &saveheader,
.saveips = &saveips,
.initheader = ipportiphash_initheader,
.printheader = ipportiphash_printheader,
.printips = ipportiphash_printips,
.printips_sorted = ipportiphash_printips,
.saveheader = ipportiphash_saveheader,
.saveips = ipportiphash_saveips,
.usage = &usage,
.usage = ipportiphash_usage,
};
CONSTRUCTOR(ipportiphash)

View File

@@ -32,7 +32,7 @@
/* Initialize the create. */
static void
create_init(void *data)
ipportnethash_create_init(void *data)
{
struct ip_set_req_ipportnethash_create *mydata = data;
@@ -46,7 +46,8 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */
static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
ipportnethash_create_parse(int c, char *argv[] UNUSED, void *data,
unsigned *flags)
{
struct ip_set_req_ipportnethash_create *mydata = data;
ip_set_ip_t value;
@@ -137,7 +138,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */
static void
create_final(void *data, unsigned int flags)
ipportnethash_create_final(void *data, unsigned int flags)
{
struct ip_set_req_ipportnethash_create *mydata = data;
@@ -189,7 +190,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */
static ip_set_ip_t
adt_parser(int cmd, const char *arg, void *data)
ipportnethash_adt_parser(int cmd, const char *arg, void *data)
{
struct ip_set_req_ipportnethash *mydata = data;
char *saved = ipset_strdup(arg);
@@ -238,7 +239,7 @@ adt_parser(int cmd, const char *arg, void *data)
*/
static void
initheader(struct set *set, const void *data)
ipportnethash_initheader(struct set *set, const void *data)
{
const struct ip_set_req_ipportnethash_create *header = data;
struct ip_set_ipportnethash *map = set->settype->header;
@@ -252,7 +253,7 @@ initheader(struct set *set, const void *data)
}
static void
printheader(struct set *set, unsigned options)
ipportnethash_printheader(struct set *set, unsigned options)
{
struct ip_set_ipportnethash *mysetdata = set->settype->header;
@@ -318,7 +319,8 @@ unpack_ip_tostring(ip_set_ip_t ip, unsigned options UNUSED)
}
static void
printips(struct set *set, void *data, u_int32_t len, unsigned options)
ipportnethash_printips(struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align)
{
struct ip_set_ipportnethash *mysetdata = set->settype->header;
size_t offset = 0;
@@ -337,12 +339,12 @@ printips(struct set *set, void *data, u_int32_t len, unsigned options)
printf("%s\n",
unpack_ip_tostring(ipptr->ip1, options));
}
offset += sizeof(struct ipportip);
offset += IPSET_VALIGN(sizeof(struct ipportip), dont_align);
}
}
static void
saveheader(struct set *set, unsigned options)
ipportnethash_saveheader(struct set *set, unsigned options)
{
struct ip_set_ipportnethash *mysetdata = set->settype->header;
@@ -357,7 +359,8 @@ saveheader(struct set *set, unsigned options)
/* Print save for an IP */
static void
saveips(struct set *set, void *data, u_int32_t len, unsigned options)
ipportnethash_saveips(struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align)
{
struct ip_set_ipportnethash *mysetdata = set->settype->header;
size_t offset = 0;
@@ -376,11 +379,12 @@ saveips(struct set *set, void *data, u_int32_t len, unsigned options)
printf("%s\n",
unpack_ip_tostring(ipptr->ip, options));
}
offset += sizeof(struct ipportip);
offset += IPSET_VALIGN(sizeof(struct ipportip), dont_align);
}
}
static void usage(void)
static void
ipportnethash_usage(void)
{
printf
("-N set ipportnethash --from IP --to IP\n"
@@ -398,25 +402,25 @@ static struct settype settype_ipportnethash = {
/* Create */
.create_size = sizeof(struct ip_set_req_ipportnethash_create),
.create_init = &create_init,
.create_parse = &create_parse,
.create_final = &create_final,
.create_init = ipportnethash_create_init,
.create_parse = ipportnethash_create_parse,
.create_final = ipportnethash_create_final,
.create_opts = create_opts,
/* Add/del/test */
.adt_size = sizeof(struct ip_set_req_ipportnethash),
.adt_parser = &adt_parser,
.adt_parser = ipportnethash_adt_parser,
/* Printing */
.header_size = sizeof(struct ip_set_ipportnethash),
.initheader = &initheader,
.printheader = &printheader,
.printips = &printips, /* We only have the unsorted version */
.printips_sorted = &printips,
.saveheader = &saveheader,
.saveips = &saveips,
.initheader = ipportnethash_initheader,
.printheader = ipportnethash_printheader,
.printips = ipportnethash_printips,
.printips_sorted = ipportnethash_printips,
.saveheader = ipportnethash_saveheader,
.saveips = ipportnethash_saveips,
.usage = &usage,
.usage = ipportnethash_usage,
};
CONSTRUCTOR(ipportnethash)

View File

@@ -29,7 +29,7 @@
/* Initialize the create. */
static void
create_init(void *data)
iptree_create_init(void *data)
{
struct ip_set_req_iptree_create *mydata = data;
@@ -39,7 +39,7 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */
static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
iptree_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
{
struct ip_set_req_iptree_create *mydata = data;
@@ -63,7 +63,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */
static void
create_final(void *data UNUSED, unsigned int flags UNUSED)
iptree_create_final(void *data UNUSED, unsigned int flags UNUSED)
{
}
@@ -75,7 +75,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */
static ip_set_ip_t
adt_parser(int cmd UNUSED, const char *arg, void *data)
iptree_adt_parser(int cmd UNUSED, const char *arg, void *data)
{
struct ip_set_req_iptree *mydata = data;
char *saved = ipset_strdup(arg);
@@ -104,7 +104,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/
static void
initheader(struct set *set, const void *data)
iptree_initheader(struct set *set, const void *data)
{
const struct ip_set_req_iptree_create *header = data;
struct ip_set_iptree *map = set->settype->header;
@@ -113,7 +113,7 @@ initheader(struct set *set, const void *data)
}
static void
printheader(struct set *set, unsigned options UNUSED)
iptree_printheader(struct set *set, unsigned options UNUSED)
{
struct ip_set_iptree *mysetdata = set->settype->header;
@@ -123,7 +123,8 @@ printheader(struct set *set, unsigned options UNUSED)
}
static void
printips_sorted(struct set *set, void *data, u_int32_t len, unsigned options)
iptree_printips_sorted(struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align)
{
struct ip_set_iptree *mysetdata = set->settype->header;
struct ip_set_req_iptree *req;
@@ -136,12 +137,12 @@ printips_sorted(struct set *set, void *data, u_int32_t len, unsigned options)
req->timeout);
else
printf("%s\n", ip_tostring(req->ip, options));
offset += sizeof(struct ip_set_req_iptree);
offset += IPSET_VALIGN(sizeof(struct ip_set_req_iptree), dont_align);
}
}
static void
saveheader(struct set *set, unsigned options UNUSED)
iptree_saveheader(struct set *set, unsigned options UNUSED)
{
struct ip_set_iptree *mysetdata = set->settype->header;
@@ -155,7 +156,8 @@ saveheader(struct set *set, unsigned options UNUSED)
}
static void
saveips(struct set *set, void *data, u_int32_t len, unsigned options)
iptree_saveips(struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align)
{
struct ip_set_iptree *mysetdata = set->settype->header;
struct ip_set_req_iptree *req;
@@ -174,11 +176,12 @@ saveips(struct set *set, void *data, u_int32_t len, unsigned options)
printf("-A %s %s\n",
set->name,
ip_tostring(req->ip, options));
offset += sizeof(struct ip_set_req_iptree);
offset += IPSET_VALIGN(sizeof(struct ip_set_req_iptree), dont_align);
}
}
static void usage(void)
static void
iptree_usage(void)
{
printf
("-N set iptree [--timeout value]\n"
@@ -193,29 +196,25 @@ static struct settype settype_iptree = {
/* Create */
.create_size = sizeof(struct ip_set_req_iptree_create),
.create_init = &create_init,
.create_parse = &create_parse,
.create_final = &create_final,
.create_init = iptree_create_init,
.create_parse = iptree_create_parse,
.create_final = iptree_create_final,
.create_opts = create_opts,
/* Add/del/test */
.adt_size = sizeof(struct ip_set_req_iptree),
.adt_parser = &adt_parser,
.adt_parser = iptree_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,
.initheader = iptree_initheader,
.printheader = iptree_printheader,
.printips = iptree_printips_sorted, /* We only have sorted version */
.printips_sorted = iptree_printips_sorted,
.saveheader = iptree_saveheader,
.saveips = iptree_saveips,
/* Bindings */
.bindip_tostring = &binding_ip_tostring,
.bindip_parse = &parse_ip,
.usage = &usage,
.usage = iptree_usage,
};
CONSTRUCTOR(iptree)

View File

@@ -26,7 +26,7 @@
#define OPT_CREATE_GC 0x1
static void
create_init(void *data)
iptreemap_create_init(void *data)
{
struct ip_set_req_iptreemap_create *mydata = data;
@@ -34,7 +34,8 @@ create_init(void *data)
}
static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned int *flags)
iptreemap_create_parse(int c, char *argv[] UNUSED, void *data,
unsigned int *flags)
{
struct ip_set_req_iptreemap_create *mydata = data;
@@ -53,7 +54,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned int *flags)
}
static void
create_final(void *data UNUSED, unsigned int flags UNUSED)
iptreemap_create_final(void *data UNUSED, unsigned int flags UNUSED)
{
}
@@ -63,7 +64,7 @@ static const struct option create_opts[] = {
};
static ip_set_ip_t
adt_parser(int cmd UNUSED, const char *arg, void *data)
iptreemap_adt_parser(int cmd UNUSED, const char *arg, void *data)
{
struct ip_set_req_iptreemap *mydata = data;
ip_set_ip_t mask;
@@ -94,7 +95,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
}
static void
initheader(struct set *set, const void *data)
iptreemap_initheader(struct set *set, const void *data)
{
const struct ip_set_req_iptreemap_create *header = data;
struct ip_set_iptreemap *map = set->settype->header;
@@ -103,7 +104,7 @@ initheader(struct set *set, const void *data)
}
static void
printheader(struct set *set, unsigned int options UNUSED)
iptreemap_printheader(struct set *set, unsigned int options UNUSED)
{
struct ip_set_iptreemap *mysetdata = set->settype->header;
@@ -114,8 +115,8 @@ printheader(struct set *set, unsigned int options UNUSED)
}
static void
printips_sorted(struct set *set UNUSED, void *data,
u_int32_t len, unsigned int options)
iptreemap_printips_sorted(struct set *set UNUSED, void *data,
u_int32_t len, unsigned int options, char dont_align)
{
struct ip_set_req_iptreemap *req;
size_t offset = 0;
@@ -128,12 +129,12 @@ printips_sorted(struct set *set UNUSED, void *data,
printf("-%s", ip_tostring(req->end, options));
printf("\n");
offset += sizeof(struct ip_set_req_iptreemap);
offset += IPSET_VALIGN(sizeof(struct ip_set_req_iptreemap), dont_align);
}
}
static void
saveheader(struct set *set, unsigned int options UNUSED)
iptreemap_saveheader(struct set *set, unsigned int options UNUSED)
{
struct ip_set_iptreemap *mysetdata = set->settype->header;
@@ -146,8 +147,8 @@ saveheader(struct set *set, unsigned int options UNUSED)
}
static void
saveips(struct set *set UNUSED, void *data,
u_int32_t len, unsigned int options)
iptreemap_saveips(struct set *set UNUSED, void *data,
u_int32_t len, unsigned int options, char dont_align)
{
struct ip_set_req_iptreemap *req;
size_t offset = 0;
@@ -162,12 +163,12 @@ saveips(struct set *set UNUSED, void *data,
printf("\n");
offset += sizeof(struct ip_set_req_iptreemap);
offset += IPSET_VALIGN(sizeof(struct ip_set_req_iptreemap), dont_align);
}
}
static void
usage(void)
iptreemap_usage(void)
{
printf(
"-N set iptreemap --gc interval\n"
@@ -182,26 +183,23 @@ static struct settype settype_iptreemap = {
.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_init = iptreemap_create_init,
.create_parse = iptreemap_create_parse,
.create_final = iptreemap_create_final,
.create_opts = create_opts,
.adt_size = sizeof(struct ip_set_req_iptreemap),
.adt_parser = &adt_parser,
.adt_parser = iptreemap_adt_parser,
.header_size = sizeof(struct ip_set_iptreemap),
.initheader = &initheader,
.printheader = &printheader,
.printips = &printips_sorted,
.printips_sorted = &printips_sorted,
.saveheader = &saveheader,
.saveips = &saveips,
.initheader = iptreemap_initheader,
.printheader = iptreemap_printheader,
.printips = iptreemap_printips_sorted,
.printips_sorted = iptreemap_printips_sorted,
.saveheader = iptreemap_saveheader,
.saveips = iptreemap_saveips,
.bindip_tostring = &binding_ip_tostring,
.bindip_parse = &parse_ip,
.usage = &usage,
.usage = iptreemap_usage,
};
CONSTRUCTOR(iptreemap)

View File

@@ -39,7 +39,7 @@
/* Initialize the create. */
static void
create_init(void *data UNUSED)
macipmap_create_init(void *data UNUSED)
{
DP("create INIT");
/* Nothing */
@@ -47,7 +47,7 @@ create_init(void *data UNUSED)
/* Function which parses command options; returns true if it ate an option */
static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
macipmap_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
{
struct ip_set_req_macipmap_create *mydata = data;
@@ -107,7 +107,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */
static void
create_final(void *data, unsigned int flags)
macipmap_create_final(void *data, unsigned int flags)
{
struct ip_set_req_macipmap_create *mydata = data;
@@ -176,7 +176,7 @@ parse_mac(const char *mac, unsigned char *ethernet)
/* Add, del, test parser */
static ip_set_ip_t
adt_parser(int cmd UNUSED, const char *arg, void *data)
macipmap_adt_parser(int cmd UNUSED, const char *arg, void *data)
{
struct ip_set_req_macipmap *mydata = data;
char *saved = ipset_strdup(arg);
@@ -209,7 +209,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/
static void
initheader(struct set *set, const void *data)
macipmap_initheader(struct set *set, const void *data)
{
const struct ip_set_req_macipmap_create *header = data;
struct ip_set_macipmap *map = set->settype->header;
@@ -221,7 +221,7 @@ initheader(struct set *set, const void *data)
}
static void
printheader(struct set *set, unsigned options)
macipmap_printheader(struct set *set, unsigned options)
{
struct ip_set_macipmap *mysetdata = set->settype->header;
@@ -243,9 +243,9 @@ print_mac(unsigned char macaddress[ETH_ALEN])
printf(":%02X", macaddress[i]);
}
static void
printips_sorted(struct set *set, void *data,
u_int32_t len UNUSED, unsigned options)
static inline void
__macipmap_printips_sorted(struct set *set, void *data,
u_int32_t len UNUSED, unsigned options)
{
struct ip_set_macipmap *mysetdata = set->settype->header;
struct ip_set_macip *table = data;
@@ -263,7 +263,27 @@ printips_sorted(struct set *set, void *data,
}
static void
saveheader(struct set *set, unsigned options)
macipmap_printips_sorted(struct set *set, void *data,
u_int32_t len, unsigned options,
char dont_align)
{
struct ip_set_req_macipmap *d;
size_t offset = 0;
if (dont_align)
return __macipmap_printips_sorted(set, data, len, options);
while (offset < len) {
d = data + offset;
printf("%s,", ip_tostring(d->ip, options));
print_mac(d->ethernet);
printf("\n");
offset += IPSET_ALIGN(sizeof(struct ip_set_req_macipmap));
}
}
static void
macipmap_saveheader(struct set *set, unsigned options)
{
struct ip_set_macipmap *mysetdata = set->settype->header;
@@ -277,9 +297,9 @@ saveheader(struct set *set, unsigned options)
printf("\n");
}
static void
saveips(struct set *set, void *data,
u_int32_t len UNUSED, unsigned options)
static inline void
__macipmap_saveips(struct set *set, void *data,
u_int32_t len UNUSED, unsigned options)
{
struct ip_set_macipmap *mysetdata = set->settype->header;
struct ip_set_macip *table = data;
@@ -297,7 +317,28 @@ saveips(struct set *set, void *data,
}
}
static void usage(void)
static void
macipmap_saveips(struct set *set, void *data,
u_int32_t len, unsigned options,
char dont_align)
{
struct ip_set_req_macipmap *d;
size_t offset = 0;
if (dont_align)
return __macipmap_saveips(set, data, len, options);
while (offset < len) {
d = data + offset;
printf("-A %s %s,", set->name, ip_tostring(d->ip, options));
print_mac(d->ethernet);
printf("\n");
offset += IPSET_ALIGN(sizeof(struct ip_set_req_macipmap));
}
}
static void
macipmap_usage(void)
{
printf
("-N set macipmap --from IP --to IP [--matchunset]\n"
@@ -313,29 +354,25 @@ static struct settype settype_macipmap = {
/* Create */
.create_size = sizeof(struct ip_set_req_macipmap_create),
.create_init = &create_init,
.create_parse = &create_parse,
.create_final = &create_final,
.create_init = macipmap_create_init,
.create_parse = macipmap_create_parse,
.create_final = macipmap_create_final,
.create_opts = create_opts,
/* Add/del/test */
.adt_size = sizeof(struct ip_set_req_macipmap),
.adt_parser = &adt_parser,
.adt_parser = macipmap_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,
.initheader = macipmap_initheader,
.printheader = macipmap_printheader,
.printips = macipmap_printips_sorted,
.printips_sorted = macipmap_printips_sorted,
.saveheader = macipmap_saveheader,
.saveips = macipmap_saveips,
/* Bindings */
.bindip_tostring = &binding_ip_tostring,
.bindip_parse = &parse_ip,
.usage = &usage,
.usage = macipmap_usage,
};
CONSTRUCTOR(macipmap)

View File

@@ -31,7 +31,7 @@
/* Initialize the create. */
static void
create_init(void *data)
nethash_create_init(void *data)
{
struct ip_set_req_nethash_create *mydata = data;
@@ -45,7 +45,7 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */
static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
nethash_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
{
struct ip_set_req_nethash_create *mydata = data;
ip_set_ip_t value;
@@ -97,7 +97,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */
static void
create_final(void *data UNUSED, unsigned int flags UNUSED)
nethash_create_final(void *data UNUSED, unsigned int flags UNUSED)
{
}
@@ -111,7 +111,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */
static ip_set_ip_t
adt_parser(int cmd, const char *arg, void *data)
nethash_adt_parser(int cmd, const char *arg, void *data)
{
struct ip_set_req_nethash *mydata = data;
char *saved = ipset_strdup(arg);
@@ -148,7 +148,7 @@ adt_parser(int cmd, const char *arg, void *data)
*/
static void
initheader(struct set *set, const void *data)
nethash_initheader(struct set *set, const void *data)
{
const struct ip_set_req_nethash_create *header = data;
struct ip_set_nethash *map = set->settype->header;
@@ -160,7 +160,7 @@ initheader(struct set *set, const void *data)
}
static void
printheader(struct set *set, unsigned options UNUSED)
nethash_printheader(struct set *set, unsigned options UNUSED)
{
struct ip_set_nethash *mysetdata = set->settype->header;
@@ -224,7 +224,8 @@ unpack_ip_tostring(ip_set_ip_t ip, unsigned options UNUSED)
}
static void
printips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
nethash_printips(struct set *set UNUSED, void *data, u_int32_t len,
unsigned options, char dont_align)
{
size_t offset = 0;
ip_set_ip_t *ip;
@@ -233,12 +234,12 @@ printips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
ip = data + offset;
if (*ip)
printf("%s\n", unpack_ip_tostring(*ip, options));
offset += sizeof(ip_set_ip_t);
offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
}
}
static void
saveheader(struct set *set, unsigned options UNUSED)
nethash_saveheader(struct set *set, unsigned options UNUSED)
{
struct ip_set_nethash *mysetdata = set->settype->header;
@@ -249,7 +250,8 @@ saveheader(struct set *set, unsigned options UNUSED)
/* Print save for an IP */
static void
saveips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
nethash_saveips(struct set *set UNUSED, void *data, u_int32_t len,
unsigned options, char dont_align)
{
size_t offset = 0;
ip_set_ip_t *ip;
@@ -259,40 +261,12 @@ saveips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
if (*ip)
printf("-A %s %s\n", set->name,
unpack_ip_tostring(*ip, options));
offset += sizeof(ip_set_ip_t);
offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
}
}
static char *
net_tostring(struct set *set UNUSED, 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 = ipset_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);
ipset_free(saved);
*ip = pack_ip_cidr(*ip, cidr);
}
static void usage(void)
nethash_usage(void)
{
printf
("-N set nethash [--hashsize hashsize] [--probes probes ]\n"
@@ -308,29 +282,25 @@ static struct settype settype_nethash = {
/* Create */
.create_size = sizeof(struct ip_set_req_nethash_create),
.create_init = &create_init,
.create_parse = &create_parse,
.create_final = &create_final,
.create_init = nethash_create_init,
.create_parse = nethash_create_parse,
.create_final = nethash_create_final,
.create_opts = create_opts,
/* Add/del/test */
.adt_size = sizeof(struct ip_set_req_nethash),
.adt_parser = &adt_parser,
.adt_parser = nethash_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,
.initheader = nethash_initheader,
.printheader = nethash_printheader,
.printips = nethash_printips,
.printips_sorted = nethash_printips,
.saveheader = nethash_saveheader,
.saveips = nethash_saveips,
/* Bindings */
.bindip_tostring = &net_tostring,
.bindip_parse = &parse_net,
.usage = &usage,
.usage = nethash_usage,
};
CONSTRUCTOR(nethash)

View File

@@ -32,7 +32,7 @@
/* Initialize the create. */
static void
create_init(void *data UNUSED)
portmap_create_init(void *data UNUSED)
{
DP("create INIT");
/* Nothing */
@@ -40,7 +40,7 @@ create_init(void *data UNUSED)
/* Function which parses command options; returns true if it ate an option */
static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
portmap_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
{
struct ip_set_req_portmap_create *mydata = data;
@@ -76,7 +76,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */
static void
create_final(void *data, unsigned int flags)
portmap_create_final(void *data, unsigned int flags)
{
struct ip_set_req_portmap_create *mydata = data;
@@ -113,7 +113,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */
static ip_set_ip_t
adt_parser(int cmd UNUSED, const char *arg, void *data)
portmap_adt_parser(int cmd UNUSED, const char *arg, void *data)
{
struct ip_set_req_portmap *mydata = data;
@@ -128,7 +128,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/
static void
initheader(struct set *set, const void *data)
portmap_initheader(struct set *set, const void *data)
{
const struct ip_set_req_portmap_create *header = data;
struct ip_set_portmap *map = set->settype->header;
@@ -139,7 +139,7 @@ initheader(struct set *set, const void *data)
}
static void
printheader(struct set *set, unsigned options)
portmap_printheader(struct set *set, unsigned options)
{
struct ip_set_portmap *mysetdata = set->settype->header;
@@ -147,12 +147,12 @@ printheader(struct set *set, unsigned options)
printf(" to: %s\n", port_tostring(mysetdata->last_ip, options));
}
static void
printports_sorted(struct set *set, void *data,
u_int32_t len UNUSED, unsigned options)
static inline void
__portmap_printips_sorted(struct set *set, void *data,
u_int32_t len UNUSED, unsigned options)
{
struct ip_set_portmap *mysetdata = set->settype->header;
u_int32_t addr = mysetdata->first_ip;
ip_set_ip_t addr = mysetdata->first_ip;
DP("%u -- %u", mysetdata->first_ip, mysetdata->last_ip);
while (addr <= mysetdata->last_ip) {
@@ -162,15 +162,26 @@ printports_sorted(struct set *set, void *data,
}
}
static char *
binding_port_tostring(struct set *set UNUSED,
ip_set_ip_t ip, unsigned options)
static void
portmap_printips_sorted(struct set *set, void *data,
u_int32_t len, unsigned options,
char dont_align)
{
return port_tostring(ip, options);
ip_set_ip_t *ip;
size_t offset = 0;
if (dont_align)
return __portmap_printips_sorted(set, data, len, options);
while (offset < len) {
ip = data + offset;
printf("%s\n", port_tostring(*ip, options));
offset += IPSET_ALIGN(sizeof(ip_set_ip_t));
}
}
static void
saveheader(struct set *set, unsigned options)
portmap_saveheader(struct set *set, unsigned options)
{
struct ip_set_portmap *mysetdata = set->settype->header;
@@ -182,14 +193,15 @@ saveheader(struct set *set, unsigned options)
port_tostring(mysetdata->last_ip, options));
}
static void
saveports(struct set *set, void *data,
u_int32_t len UNUSED, unsigned options)
static inline void
__portmap_saveips(struct set *set, void *data,
u_int32_t len UNUSED, unsigned options)
{
struct ip_set_portmap *mysetdata = set->settype->header;
u_int32_t addr = mysetdata->first_ip;
ip_set_ip_t addr = mysetdata->first_ip;
while (addr <= mysetdata->last_ip) {
DP("addr: %lu, last_ip %lu", (long unsigned)addr, (long unsigned)mysetdata->last_ip);
if (test_bit(addr - mysetdata->first_ip, data))
printf("-A %s %s\n",
set->name,
@@ -198,7 +210,26 @@ saveports(struct set *set, void *data,
}
}
static void usage(void)
static void
portmap_saveips(struct set *set, void *data,
u_int32_t len, unsigned options,
char dont_align)
{
ip_set_ip_t *ip;
size_t offset = 0;
if (dont_align)
return __portmap_saveips(set, data, len, options);
while (offset < len) {
ip = data + offset;
printf("-A %s %s\n", set->name, port_tostring(*ip, options));
offset += IPSET_ALIGN(sizeof(ip_set_ip_t));
}
}
static void
portmap_usage(void)
{
printf
("-N set portmap --from PORT --to PORT\n"
@@ -213,29 +244,25 @@ static struct settype settype_portmap = {
/* Create */
.create_size = sizeof(struct ip_set_req_portmap_create),
.create_init = &create_init,
.create_parse = &create_parse,
.create_final = &create_final,
.create_init = portmap_create_init,
.create_parse = portmap_create_parse,
.create_final = portmap_create_final,
.create_opts = create_opts,
/* Add/del/test */
.adt_size = sizeof(struct ip_set_req_portmap),
.adt_parser = &adt_parser,
.adt_parser = portmap_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,
.initheader = portmap_initheader,
.printheader = portmap_printheader,
.printips = portmap_printips_sorted,
.printips_sorted = portmap_printips_sorted,
.saveheader = portmap_saveheader,
.saveips = portmap_saveips,
/* Bindings */
.bindip_tostring = &binding_port_tostring,
.bindip_parse = &parse_port,
.usage = &usage,
.usage = portmap_usage,
};
CONSTRUCTOR(portmap)

View File

@@ -27,7 +27,7 @@
/* Initialize the create. */
static void
create_init(void *data)
setlist_create_init(void *data)
{
struct ip_set_req_setlist_create *mydata = data;
@@ -36,7 +36,8 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */
static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags UNUSED)
setlist_create_parse(int c, char *argv[] UNUSED, void *data,
unsigned *flags UNUSED)
{
struct ip_set_req_setlist_create *mydata = data;
unsigned int size;
@@ -57,7 +58,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags UNUSED)
/* Final check; exit if not ok. */
static void
create_final(void *data UNUSED, unsigned int flags UNUSED)
setlist_create_final(void *data UNUSED, unsigned int flags UNUSED)
{
}
@@ -67,7 +68,8 @@ static const struct option create_opts[] = {
{NULL},
};
static void check_setname(const char *name)
static void
check_setname(const char *name)
{
if (strlen(name) > IP_SET_MAXNAMELEN - 1)
exit_error(PARAMETER_PROBLEM,
@@ -77,7 +79,7 @@ static void check_setname(const char *name)
/* Add, del, test parser */
static ip_set_ip_t
adt_parser(int cmd UNUSED, const char *arg, void *data)
setlist_adt_parser(int cmd UNUSED, const char *arg, void *data)
{
struct ip_set_req_setlist *mydata = data;
char *saved = ipset_strdup(arg);
@@ -115,7 +117,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/
static void
initheader(struct set *set, const void *data)
setlist_initheader(struct set *set, const void *data)
{
const struct ip_set_req_setlist_create *header = data;
struct ip_set_setlist *map = set->settype->header;
@@ -125,7 +127,7 @@ initheader(struct set *set, const void *data)
}
static void
printheader(struct set *set, unsigned options UNUSED)
setlist_printheader(struct set *set, unsigned options UNUSED)
{
struct ip_set_setlist *mysetdata = set->settype->header;
@@ -133,25 +135,29 @@ printheader(struct set *set, unsigned options UNUSED)
}
static void
printips_sorted(struct set *set, void *data,
u_int32_t len UNUSED, unsigned options UNUSED)
setlist_printips_sorted(struct set *set, void *data,
u_int32_t len UNUSED, unsigned options UNUSED,
char dont_align)
{
struct ip_set_setlist *mysetdata = set->settype->header;
int i;
ip_set_id_t id;
int i, asize;
ip_set_id_t *id;
struct set *elem;
asize = IPSET_VALIGN(sizeof(ip_set_id_t), dont_align);
for (i = 0; i < mysetdata->size; i++ ) {
id = *((ip_set_id_t *)data + i);
if (id == IP_SET_INVALID_ID)
DP("Try %u", i);
id = (ip_set_id_t *)(data + i * asize);
DP("Try %u, check", i);
if (*id == IP_SET_INVALID_ID)
return;
elem = set_find_byid(id);
elem = set_find_byid(*id);
printf("%s\n", elem->name);
}
}
static void
saveheader(struct set *set, unsigned options UNUSED)
setlist_saveheader(struct set *set, unsigned options UNUSED)
{
struct ip_set_setlist *mysetdata = set->settype->header;
@@ -161,24 +167,26 @@ saveheader(struct set *set, unsigned options UNUSED)
}
static void
saveips(struct set *set, void *data,
u_int32_t len UNUSED, unsigned options UNUSED)
setlist_saveips(struct set *set, void *data,
u_int32_t len UNUSED, unsigned options UNUSED, char dont_align)
{
struct ip_set_setlist *mysetdata = set->settype->header;
int i;
ip_set_id_t id;
int i, asize;
ip_set_id_t *id;
struct set *elem;
asize = IPSET_VALIGN(sizeof(ip_set_id_t), dont_align);
for (i = 0; i < mysetdata->size; i++ ) {
id = *((ip_set_id_t *)data + i);
if (id == IP_SET_INVALID_ID)
id = (ip_set_id_t *)(data + i * asize);
if (*id == IP_SET_INVALID_ID)
return;
elem = set_find_byid(id);
elem = set_find_byid(*id);
printf("-A %s %s\n", set->name, elem->name);
}
}
static void usage(void)
static void
setlist_usage(void)
{
printf
("-N set setlist --size size\n"
@@ -193,25 +201,25 @@ static struct settype settype_setlist = {
/* Create */
.create_size = sizeof(struct ip_set_req_setlist_create),
.create_init = &create_init,
.create_parse = &create_parse,
.create_final = &create_final,
.create_init = setlist_create_init,
.create_parse = setlist_create_parse,
.create_final = setlist_create_final,
.create_opts = create_opts,
/* Add/del/test */
.adt_size = sizeof(struct ip_set_req_setlist),
.adt_parser = &adt_parser,
.adt_parser = setlist_adt_parser,
/* Printing */
.header_size = sizeof(struct ip_set_setlist),
.initheader = &initheader,
.printheader = &printheader,
.printips = &printips_sorted, /* We only have sorted version */
.printips_sorted = &printips_sorted,
.saveheader = &saveheader,
.saveips = &saveips,
.initheader = setlist_initheader,
.printheader = setlist_printheader,
.printips = setlist_printips_sorted,
.printips_sorted = setlist_printips_sorted,
.saveheader = setlist_saveheader,
.saveips = setlist_saveips,
.usage = &usage,
.usage = setlist_usage,
};
CONSTRUCTOR(setlist)

View File

@@ -6,12 +6,3 @@ A logging level between 0 and 8 (inclusive).
\fB\-\-log\-prefix\fR \fIstring\fR
Prefix log messages with the specified prefix; up to 29 bytes long, and useful
for distinguishing messages in the logs.
.TP
\fB\-\-log\-nfmark\fR
Include the packet mark in the log.
.TP
\fB\-\-log\-ctmark\fR
Include the connection mark in the log.
.TP
\fB\-\-log\-secmark\fR
Include the packet secmark in the log.

View File

@@ -162,7 +162,7 @@ alloc_hashtable(unsigned int size)
struct list_head *hash;
unsigned int i;
hash = kmalloc(sizeof(*hash) * size, GFP_ATOMIC);
hash = kmalloc(sizeof(*hash) * size, GFP_KERNEL);
if (hash == NULL)
return NULL;
for (i = 0; i < size; ++i)
@@ -470,7 +470,7 @@ add_rule(struct xt_pknock_mtinfo *info)
}
}
rule = kmalloc(sizeof(*rule), GFP_ATOMIC);
rule = kmalloc(sizeof(*rule), GFP_KERNEL);
if (rule == NULL)
return false;
@@ -823,6 +823,7 @@ has_secret(const unsigned char *secret, unsigned int secret_len, uint32_t ipsrc,
kfree(hexresult);
return fret;
}
#endif /* PK_CRYPTO */
/**
* If the peer pass the security policy.
@@ -845,15 +846,16 @@ pass_security(struct peer *peer, const struct xt_pknock_mtinfo *info,
pk_debug("DENIED (anti-spoof protection)", peer);
return false;
}
#ifdef PK_CRYPTO
/* Check for OPEN secret */
if (!has_secret(info->open_secret,
if (has_secret(info->open_secret,
info->open_secret_len, peer->ip,
payload, payload_len))
return false;
return true;
#endif
return true;
return false;
}
#endif /* PK_CRYPTO */
/**
* Validates the peer and updates the peer status for an initiating or
@@ -928,7 +930,6 @@ update_peer(struct peer *peer, const struct xt_pknock_mtinfo *info,
return false;
}
#ifdef PK_CRYPTO
/**
* Make the peer no more ALLOWED sending a payload with a special secret for
* closure.
@@ -943,6 +944,7 @@ static bool
is_close_knock(const struct peer *peer, const struct xt_pknock_mtinfo *info,
const unsigned char *payload, unsigned int payload_len)
{
#ifdef PK_CRYPTO
/* Check for CLOSE secret. */
if (has_secret(info->close_secret,
info->close_secret_len, peer->ip,
@@ -951,9 +953,9 @@ is_close_knock(const struct peer *peer, const struct xt_pknock_mtinfo *info,
pk_debug("BLOCKED", peer);
return true;
}
#endif
return false;
}
#endif /* PK_CRYPTO */
static bool pknock_mt(const struct sk_buff *skb,
const struct xt_match_param *par)

View File

@@ -21,10 +21,10 @@ MODULE_LICENSE("GPL");
/* Search for UDP eDonkey/eMule/Kad commands */
static unsigned int
udp_search_edk(const unsigned char *haystack, const unsigned int packet_len)
udp_search_edk(const unsigned char *t, const unsigned int packet_len)
{
const unsigned char *t = haystack;
t += 8;
if (packet_len < 4)
return 0;
switch (t[0]) {
case 0xe3:
@@ -32,20 +32,20 @@ udp_search_edk(const unsigned char *haystack, const unsigned int packet_len)
switch (t[1]) {
/* client -> server status request */
case 0x96:
if (packet_len == 14)
if (packet_len == 6)
return IPP2P_EDK * 100 + 50;
break;
/* server -> client status request */
case 0x97:
if (packet_len == 42)
if (packet_len == 34)
return IPP2P_EDK * 100 + 51;
break;
/* server description request */
/* e3 2a ff f0 .. | size == 6 */
case 0xa2:
if (packet_len == 14 &&
if (packet_len == 6 &&
get_u16(t, 2) == __constant_htons(0xfff0))
return IPP2P_EDK * 100 + 52;
break;
@@ -59,12 +59,12 @@ udp_search_edk(const unsigned char *haystack, const unsigned int packet_len)
*/
case 0x9a:
if (packet_len == 26)
if (packet_len == 18)
return IPP2P_EDK * 100 + 54;
break;
case 0x92:
if (packet_len == 18)
if (packet_len == 10)
return IPP2P_EDK * 100 + 55;
break;
}
@@ -72,63 +72,63 @@ udp_search_edk(const unsigned char *haystack, const unsigned int packet_len)
case 0xe4:
switch (t[1]) {
/* e4 20 .. | size == 43 */
/* e4 20 .. | size == 35 */
case 0x20:
if (packet_len == 43 && t[2] != 0x00 && t[34] != 0x00)
if (packet_len == 35 && t[2] != 0x00 && t[34] != 0x00)
return IPP2P_EDK * 100 + 60;
break;
/* e4 00 .. 00 | size == 35 ? */
/* e4 00 .. 00 | size == 27 ? */
case 0x00:
if (packet_len == 35 && t[26] == 0x00)
if (packet_len == 27 && t[26] == 0x00)
return IPP2P_EDK * 100 + 61;
break;
/* e4 10 .. 00 | size == 35 ? */
/* e4 10 .. 00 | size == 27 ? */
case 0x10:
if (packet_len == 35 && t[26] == 0x00)
if (packet_len == 27 && t[26] == 0x00)
return IPP2P_EDK * 100 + 62;
break;
/* e4 18 .. 00 | size == 35 ? */
/* e4 18 .. 00 | size == 27 ? */
case 0x18:
if (packet_len == 35 && t[26] == 0x00)
if (packet_len == 27 && t[26] == 0x00)
return IPP2P_EDK * 100 + 63;
break;
/* e4 52 .. | size = 44 */
/* e4 52 .. | size = 36 */
case 0x52:
if (packet_len == 44)
if (packet_len == 36)
return IPP2P_EDK * 100 + 64;
break;
/* e4 58 .. | size == 6 */
case 0x58:
if (packet_len == 14)
if (packet_len == 6)
return IPP2P_EDK * 100 + 65;
break;
/* e4 59 .. | size == 2 */
case 0x59:
if (packet_len == 10)
if (packet_len == 2)
return IPP2P_EDK * 100 + 66;
break;
/* e4 28 .. | packet_len == 52,77,102,127... */
/* e4 28 .. | packet_len == 49,69,94,119... */
case 0x28:
if ((packet_len - 52) % 25 == 0)
if ((packet_len - 44) % 25 == 0)
return IPP2P_EDK * 100 + 67;
break;
/* e4 50 xx xx | size == 4 */
case 0x50:
if (packet_len == 12)
if (packet_len == 4)
return IPP2P_EDK * 100 + 68;
break;
/* e4 40 xx xx | size == 48 */
case 0x40:
if (packet_len == 56)
if (packet_len == 48)
return IPP2P_EDK * 100 + 69;
break;
}
@@ -139,44 +139,36 @@ udp_search_edk(const unsigned char *haystack, const unsigned int packet_len)
/* Search for UDP Gnutella commands */
static unsigned int
udp_search_gnu(const unsigned char *haystack, const unsigned int packet_len)
udp_search_gnu(const unsigned char *t, const unsigned int packet_len)
{
const unsigned char *t = haystack;
t += 8;
if (memcmp(t, "GND", 3) == 0)
if (packet_len >= 3 && memcmp(t, "GND", 3) == 0)
return IPP2P_GNU * 100 + 51;
if (memcmp(t, "GNUTELLA ", 9) == 0)
if (packet_len >= 9 && memcmp(t, "GNUTELLA ", 9) == 0)
return IPP2P_GNU * 100 + 52;
return 0;
}
/* Search for UDP KaZaA commands */
static unsigned int
udp_search_kazaa(const unsigned char *haystack, const unsigned int packet_len)
udp_search_kazaa(const unsigned char *t, const unsigned int packet_len)
{
const unsigned char *t = haystack;
if (t[packet_len-1] == 0x00) {
t += packet_len - 6;
if (memcmp(t, "KaZaA", 5) == 0)
return IPP2P_KAZAA * 100 + 50;
}
if (packet_len < 6)
return 0;
if (memcmp(t + packet_len - 6, "KaZaA\x00", 6) == 0)
return IPP2P_KAZAA * 100 + 50;
return 0;
}
/* Search for UDP DirectConnect commands */
static unsigned int udp_search_directconnect(const unsigned char *haystack,
static unsigned int udp_search_directconnect(const unsigned char *t,
const unsigned int packet_len)
{
const unsigned char *t = haystack;
if (*(t + 8) == 0x24 && *(t + packet_len - 1) == 0x7c) {
t += 8;
if (memcmp(t, "SR ", 3) == 0)
if (packet_len < 5)
return 0;
if (t[0] == 0x24 && t[packet_len-1] == 0x7c) {
if (memcmp(&t[1], "SR ", 3) == 0)
return IPP2P_DC * 100 + 60;
if (memcmp(t, "Ping ", 5) == 0)
if (packet_len >= 7 && memcmp(&t[1], "Ping ", 5) == 0)
return IPP2P_DC * 100 + 61;
}
return 0;
@@ -187,77 +179,78 @@ static unsigned int
udp_search_bit(const unsigned char *haystack, const unsigned int packet_len)
{
switch (packet_len) {
case 24:
case 16:
/* ^ 00 00 04 17 27 10 19 80 */
if (ntohl(get_u32(haystack, 8)) == 0x00000417 &&
ntohl(get_u32(haystack, 12)) == 0x27101980)
if (ntohl(get_u32(haystack, 0)) == 0x00000417 &&
ntohl(get_u32(haystack, 4)) == 0x27101980)
return IPP2P_BIT * 100 + 50;
break;
case 44:
if (get_u32(haystack, 16) == __constant_htonl(0x00000400) &&
get_u32(haystack, 36) == __constant_htonl(0x00000104))
case 36:
if (get_u32(haystack, 8) == __constant_htonl(0x00000400) &&
get_u32(haystack, 28) == __constant_htonl(0x00000104))
return IPP2P_BIT * 100 + 51;
if (get_u32(haystack, 16) == __constant_htonl(0x00000400))
if (get_u32(haystack, 8) == __constant_htonl(0x00000400))
return IPP2P_BIT * 100 + 61;
break;
case 65:
if (get_u32(haystack, 16) == __constant_htonl(0x00000404) &&
get_u32(haystack, 36) == __constant_htonl(0x00000104))
case 57:
if (get_u32(haystack, 8) == __constant_htonl(0x00000404) &&
get_u32(haystack, 28) == __constant_htonl(0x00000104))
return IPP2P_BIT * 100 + 52;
if (get_u32(haystack, 16) == __constant_htonl(0x00000404))
if (get_u32(haystack, 8) == __constant_htonl(0x00000404))
return IPP2P_BIT * 100 + 62;
break;
case 67:
if (get_u32(haystack, 16) == __constant_htonl(0x00000406) && get_u32(haystack, 36) == __constant_htonl(0x00000104))
case 59:
if (get_u32(haystack, 8) == __constant_htonl(0x00000406) &&
get_u32(haystack, 28) == __constant_htonl(0x00000104))
return (IPP2P_BIT * 100 + 53);
if (get_u32(haystack, 16) == __constant_htonl(0x00000406))
if (get_u32(haystack, 8) == __constant_htonl(0x00000406))
return (IPP2P_BIT * 100 + 63);
break;
case 211:
if (get_u32(haystack, 8) == __constant_htonl(0x00000405))
case 203:
if (get_u32(haystack, 0) == __constant_htonl(0x00000405))
return IPP2P_BIT * 100 + 54;
break;
case 29:
if (get_u32(haystack, 8) == __constant_htonl(0x00000401))
case 21:
if (get_u32(haystack, 0) == __constant_htonl(0x00000401))
return IPP2P_BIT * 100 + 55;
break;
case 52:
if (get_u32(haystack, 8) == __constant_htonl(0x00000827) &&
get_u32(haystack, 12) == __constant_htonl(0x37502950))
case 44:
if (get_u32(haystack, 0) == __constant_htonl(0x00000827) &&
get_u32(haystack, 4) == __constant_htonl(0x37502950))
return IPP2P_BIT * 100 + 80;
break;
default:
/* this packet does not have a constant size */
if (packet_len >= 40 &&
get_u32(haystack, 16) == __constant_htonl(0x00000402) &&
get_u32(haystack, 36) == __constant_htonl(0x00000104))
if (packet_len >= 32 &&
get_u32(haystack, 8) == __constant_htonl(0x00000402) &&
get_u32(haystack, 28) == __constant_htonl(0x00000104))
return IPP2P_BIT * 100 + 56;
break;
}
/* some extra-bitcomet rules: "d1:" [a|r] "d2:id20:" */
if (packet_len > 30 && get_u8(haystack, 8) == 'd' &&
get_u8(haystack, 9) == '1' && get_u8(haystack, 10) == ':')
if (get_u8(haystack, 11) == 'a' ||
get_u8(haystack, 11) == 'r')
if (memcmp(haystack + 12, "d2:id20:", 8) == 0)
if (packet_len > 22 && get_u8(haystack, 0) == 'd' &&
get_u8(haystack, 1) == '1' && get_u8(haystack, 2) == ':')
if (get_u8(haystack, 3) == 'a' ||
get_u8(haystack, 3) == 'r')
if (memcmp(haystack + 4, "d2:id20:", 8) == 0)
return IPP2P_BIT * 100 + 57;
#if 0
/* bitlord rules */
/* packetlen must be bigger than 40 */
/* packetlen must be bigger than 32 */
/* first 4 bytes are zero */
if (packet_len > 40 && get_u32(haystack, 8) == 0x00000000) {
if (packet_len > 32 && get_u32(haystack, 0) == 0x00000000) {
/* first rule: 00 00 00 00 01 00 00 xx xx xx xx 00 00 00 00*/
if (get_u32(haystack, 12) == 0x00000000 &&
get_u32(haystack, 16) == 0x00010000 &&
get_u32(haystack, 24) == 0x00000000)
if (get_u32(haystack, 4) == 0x00000000 &&
get_u32(haystack, 8) == 0x00010000 &&
get_u32(haystack, 16) == 0x00000000)
return IPP2P_BIT * 100 + 71;
/* 00 01 00 00 0d 00 00 xx xx xx xx 00 00 00 00*/
if (get_u32(haystack, 12) == 0x00000001 &&
get_u32(haystack, 16) == 0x000d0000 &&
get_u32(haystack, 24) == 0x00000000)
if (get_u32(haystack, 4) == 0x00000001 &&
get_u32(haystack, 8) == 0x000d0000 &&
get_u32(haystack, 16) == 0x00000000)
return IPP2P_BIT * 100 + 71;
}
#endif
@@ -269,6 +262,8 @@ udp_search_bit(const unsigned char *haystack, const unsigned int packet_len)
static unsigned int
search_ares(const unsigned char *payload, const unsigned int plen)
{
if (plen < 3)
return 0;
/* all ares packets start with */
if (payload[1] == 0 && plen - payload[0] == 3) {
switch (payload[2]) {
@@ -319,6 +314,8 @@ search_ares(const unsigned char *payload, const unsigned int plen)
static unsigned int
search_soul(const unsigned char *payload, const unsigned int plen)
{
if (plen < 8)
return 0;
/* match: xx xx xx xx | xx = sizeof(payload) - 4 */
if (get_u32(payload, 0) == plen - 4) {
const uint32_t m = get_u32(payload, 4);
@@ -525,7 +522,7 @@ search_bittorrent(const unsigned char *payload, const unsigned int plen)
} else {
/* bitcomet encryptes the first packet, so we have to detect another
* one later in the flow */
/* first try failed, too many missdetections */
/* first try failed, too many false positives */
/*
if (size == 5 && get_u32(t, 0) == __constant_htonl(1) &&
t[4] < 3)
@@ -547,6 +544,8 @@ search_bittorrent(const unsigned char *payload, const unsigned int plen)
static unsigned int
search_kazaa(const unsigned char *payload, const unsigned int plen)
{
if (plen < 13)
return 0;
if (payload[plen-2] == 0x0d && payload[plen-1] == 0x0a &&
memcmp(payload, "GET /.hash=", 11) == 0)
return IPP2P_DATA_KAZAA * 100;
@@ -558,10 +557,12 @@ search_kazaa(const unsigned char *payload, const unsigned int plen)
static unsigned int
search_gnu(const unsigned char *payload, const unsigned int plen)
{
if (plen < 11)
return 0;
if (payload[plen-2] == 0x0d && payload[plen-1] == 0x0a) {
if (memcmp(payload, "GET /get/", 9) == 0)
return IPP2P_DATA_GNU * 100 + 1;
if (memcmp(payload, "GET /uri-res/", 13) == 0)
if (plen >= 15 && memcmp(payload, "GET /uri-res/", 13) == 0)
return IPP2P_DATA_GNU * 100 + 2;
}
return 0;
@@ -571,26 +572,25 @@ search_gnu(const unsigned char *payload, const unsigned int plen)
static unsigned int
search_all_gnu(const unsigned char *payload, const unsigned int plen)
{
if (plen < 11)
return 0;
if (payload[plen-2] == 0x0d && payload[plen-1] == 0x0a) {
if (memcmp(payload, "GNUTELLA CONNECT/", 17) == 0)
if (plen >= 19 && memcmp(payload, "GNUTELLA CONNECT/", 17) == 0)
return IPP2P_GNU * 100 + 1;
if (memcmp(payload, "GNUTELLA/", 9) == 0)
return IPP2P_GNU * 100 + 2;
if (memcmp(payload, "GET /get/", 9) == 0 ||
memcmp(payload, "GET /uri-res/", 13) == 0)
if (plen >= 22 && (memcmp(payload, "GET /get/", 9) == 0 ||
memcmp(payload, "GET /uri-res/", 13) == 0))
{
uint16_t c = 8;
const uint16_t end = plen - 22;
unsigned int c;
while (c < end) {
if (payload[c] == 0x0a &&
payload[c+1] == 0x0d &&
for (c = 0; c < plen - 22; ++c)
if (payload[c] == 0x0d &&
payload[c+1] == 0x0a &&
(memcmp(&payload[c+2], "X-Gnutella-", 11) == 0 ||
memcmp(&payload[c+2], "X-Queue:", 8) == 0))
return IPP2P_GNU * 100 + 3;
c++;
}
}
}
return 0;
@@ -603,17 +603,10 @@ search_all_kazaa(const unsigned char *payload, const unsigned int plen)
{
uint16_t c, end, rem;
if (plen < 5)
if (plen < 7)
/* too short for anything we test for - early bailout */
return 0;
if (plen >= 65535) {
/* Something seems _really_ fishy */
printk(KERN_WARNING KBUILD_MODNAME ": %s: plen (%u) >= 65535\n",
__func__, plen);
return 0;
}
if (payload[plen-2] != 0x0d || payload[plen-1] != 0x0a)
return 0;
@@ -649,6 +642,8 @@ search_all_kazaa(const unsigned char *payload, const unsigned int plen)
static unsigned int
search_edk(const unsigned char *payload, const unsigned int plen)
{
if (plen < 6)
return 0;
if (payload[0] != 0xe3) {
return 0;
} else {
@@ -663,11 +658,12 @@ search_edk(const unsigned char *payload, const unsigned int plen)
static unsigned int
search_all_edk(const unsigned char *payload, const unsigned int plen)
{
if (plen < 6)
return 0;
if (payload[0] != 0xe3) {
return 0;
} else {
//t += head_len;
const uint16_t cmd = get_u16(payload, 1);
unsigned int cmd = get_u16(payload, 1);
if (cmd == plen - 5) {
switch (payload[5]) {
@@ -687,6 +683,8 @@ search_all_edk(const unsigned char *payload, const unsigned int plen)
static unsigned int
search_dc(const unsigned char *payload, const unsigned int plen)
{
if (plen < 6)
return 0;
if (payload[0] != 0x24) {
return 0;
} else {
@@ -701,6 +699,8 @@ search_dc(const unsigned char *payload, const unsigned int plen)
static unsigned int
search_all_dc(const unsigned char *payload, const unsigned int plen)
{
if (plen < 7)
return 0;
if (payload[0] == 0x24 && payload[plen-1] == 0x7c) {
const unsigned char *t = &payload[1];
@@ -712,7 +712,7 @@ search_all_dc(const unsigned char *payload, const unsigned int plen)
* Client-Client-Protocol, some are already recognized by
* client-hub (like lock)
*/
if (memcmp(t, "MyNick ", 7) == 0)
if (plen >= 9 && memcmp(t, "MyNick ", 7) == 0)
return IPP2P_DC * 100 + 38;
}
return 0;
@@ -872,6 +872,15 @@ ipp2p_mt(const struct sk_buff *skb, const struct xt_match_param *par)
{
const struct udphdr *udph = (const void *)ip + ip_hdrlen(skb);
haystack += sizeof(*udph);
if (sizeof(*udph) > hlen) {
if (info->debug)
pr_info("UDP header indicated packet larger than it is\n");
hlen = 0;
} else {
hlen -= sizeof(*udph);
}
while (udp_list[i].command) {
if ((info->cmd & udp_list[i].command) == udp_list[i].command &&
hlen > udp_list[i].packet_len)

View File

@@ -1,4 +1,4 @@
.TH xtables-addons 8 "v1.19 (2009-10-12)" "" "v1.19 (2009-10-12)"
.TH xtables-addons 8 "v1.20 (2009-11-19)" "" "v1.20 (2009-11-19)"
.SH Name
Xtables-addons \(em additional extensions for iptables, ip6tables, etc.
.SH Targets