Compare commits

..

45 Commits
v1.26 ... v1.29

Author SHA1 Message Date
Jan Engelhardt
14458b3a7e Xtables-addons 1.29 2010-09-29 02:51:48 +02:00
Jan Engelhardt
2d36632d4a build: add workaround for beoken linux-glibc-devel (2) 2010-09-29 02:51:26 +02:00
Jan Engelhardt
b5e2c7255a build: add workaround for broken linux-glibc-devel 2.6.34 userspace headers 2010-09-23 02:37:45 +02:00
Jan Engelhardt
376a89e7d1 build: support for Linux 2.6.36 2010-09-22 23:37:34 +02:00
Jan Engelhardt
03ec8a7696 TEE: resolve compile error with Linux 2.6.36-rc
xt_TEE.c:54:19: error: request for member "dst" in something not a
structure or union
xt_TEE.c:55:20: error: "struct rtable" has no member named "u"

Linux kernel commit v2.6.36-rc1~571^2~616 changed this.
2010-09-22 23:37:19 +02:00
Jan Engelhardt
442982f04e SYSRQ: resolve compile error with Linux 2.6.36-rc
xt_SYSRQ.c:156:3: error: too many arguments to function 'handle_sysrq'

Linux kernel commit v2.6.36-rc3~19^2~5 changed it and finally removed
the last unused argument.
2010-09-22 23:37:02 +02:00
Jan Engelhardt
98b853cea3 ipset: update to 4.3+git3 2010-09-22 22:41:24 +02:00
Jan Engelhardt
59401339b8 ipset: bump version number
Basically Xtables-addons's copy of ipset is already functionally equal
to ipset 4.3 thanks to our compat_xtables layer (and our modifications
in ipset/ to use it).
2010-09-22 22:32:50 +02:00
Jan Engelhardt
121836ce80 ipset: enable building of ip_set_ipport{ip,net}hash.ko 2010-09-22 22:30:58 +02:00
Jan Engelhardt
c23df41f6e compat_xtables: return bool for match_check and target_check (doc) 2010-09-22 22:30:10 +02:00
Jan Engelhardt
fb2eea69af compat_xtables: return bool for match_check and target_check in 2.6.23..34
Reported-by: Tomasz Pala <gotar@polanet.pl>
2010-09-01 15:02:04 +02:00
Jan Engelhardt
4815e3a8a6 doc: add API helper files
These files should be a very quick reference to the Xtables APIs of
previous Linux kernel versions and Xtables-addons. Their contents have
been reformatted so as to be usable with diff -u.
2010-09-01 12:06:27 +02:00
Jan Engelhardt
f9922c6f85 configure: pkglibexecdir requires automake >= 1.10.2 2010-08-28 13:56:12 +02:00
Jan Engelhardt
24491d55d7 Xtables-addons 1.28 2010-07-24 11:33:11 +02:00
Jan Engelhardt
7ab69a17fa geoip: add -D option to geoip_build_dir.pl
This option allows to specify a particular output directory. This help
Makefiles in that they do not need to use cd.
2010-07-24 11:22:37 +02:00
Jan Engelhardt
d2339410b2 geoip: add .gitignore 2010-07-24 11:22:37 +02:00
Jan Engelhardt
649caf61e8 geoip: rename original script to build_db 2010-07-24 11:22:37 +02:00
Jan Engelhardt
922a9be87d geoip: import scripts for building the xt_geoip database 2010-07-24 11:22:33 +02:00
Jan Engelhardt
4d48511f01 xt_length2: IPv6 jumbogram support 2010-07-24 10:57:03 +02:00
Jan Engelhardt
6dedbef3d4 doc: keep manpage ordered
`find` could return entries out of order.
2010-07-19 11:14:29 +02:00
Patrick McHardy
fe49f9b6a4 xt_CHECKSUM: use xtables_param_act 2010-07-15 12:21:16 +02:00
Patrick McHardy
283974cbbe xt_CHECKSUM: only use __u* in public header files 2010-07-15 12:21:16 +02:00
Patrick McHardy
7deca86132 xt_CHECKSUM: remove unnecessary header inclusions 2010-07-15 12:21:16 +02:00
Jan Engelhardt
7d6435f422 doc: update geoip db url
My hopto.org zone disappeared after I left it unattended...
2010-07-12 00:49:23 +02:00
Jan Engelhardt
748f5cfdd0 xt_CHECKSUM: remove pointless $ 2010-07-11 17:59:47 +02:00
Michael S. Tsirkin
d402cec807 xt_CHECKSUM: initial import
This adds a "CHECKSUM" target, which can be used in the iptables mangle
table.

You can use this target to compute and fill in the checksum in a packet
that lacks a checksum. This is particularly useful, if you need to work
around old applications such as dhcp clients, that do not work well with
checksum offloads, but don't want to disable checksum offload in your
device.

The problem happens in the field with virtualized applications. For
reference, see Red Hat bz 605555, as well as
http://www.spinics.net/lists/kvm/msg37660.html

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2010-07-11 17:54:54 +02:00
John Haxby
b42190c04b xt_SYSRQ: fix a couple of problems
The first problem is that the error response from crypto_alloc_hash()
should be extracted from the pointer before setting the pointer to NULL.

The second error is that only the first half of the password hash is
checked which slightly weakens the password checking.

Signed-off-by: John Haxby <john.haxby@oracle.com>
2010-06-25 12:20:26 +02:00
Jan Engelhardt
4dcefe4b95 xt_geoip: fix possible out-of-bounds access
It is possible for geoip_bsearch() to pick mid == sizeof(subnets).

Consider a set with a single entry and a "address to test"
higher than the range:

1st call: lo = 0, hi = 1 -> mid will be 0
2nd call: lo = 1, hi = 1 -> mid will be 1

On the 2nd call, we'll examine random data.

Reported-by: Florian Westphal <fw@strlen.de>
2010-06-13 10:40:07 +02:00
Jan Engelhardt
a2662b0121 RAWNAT: IPv6 variants erroneously rejected masks /33-/128 2010-06-12 09:23:59 +02:00
Jan Engelhardt
03354eed44 build: make configure CFLAGS=-ggdb3 have effect on .so files 2010-06-12 09:22:35 +02:00
Changli Gao
ddda6972a4 RAWNAT: fix incorrect mask in rawnat_ipv6_mask
I really think it is a typo mistake. :)

Signed-off-by: Changli Gao <xiaosuo@gmail.com>
2010-05-29 12:35:14 +02:00
Jan Engelhardt
8e7359bb92 Merge remote branch 'sf/master' 2010-05-29 10:16:04 +02:00
Jan Engelhardt
40786af1c0 build: update tarball target 2010-05-19 19:32:28 +02:00
Jan Engelhardt
f6e2fb815e Xtables-addons 1.27 2010-05-16 22:19:02 +02:00
Jan Engelhardt
f171a0f07e xa-d-m: remove superfluous protos 2010-05-14 13:03:16 +02:00
Jan Engelhardt
d17ddb9c94 Merge branch 'api35' 2010-05-14 11:52:18 +02:00
Jan Engelhardt
54d80a73b4 compat_xtables: more 2.6.35 support 2010-05-14 11:51:34 +02:00
Jan Engelhardt
43921c5834 compat_xtables: move to 2.6.35 xt_action_param (3/3)
Since the last merge of the "api35" branch, further changes were
included into nf-next. This set of three commits updates the
xtables-addons API to match that.
2010-05-13 19:45:56 +02:00
Jan Engelhardt
9a18a05d02 compat_xtables: move to 2.6.35 xt_action_param (2/3) 2010-05-13 19:45:52 +02:00
Jan Engelhardt
5b472be9bb compat_xtables: move to 2.6.35 xt_action_param (1/3) 2010-05-13 19:28:37 +02:00
Jan Engelhardt
4dd35fb564 compat_xtables: move 2.6.28+ xtnu_target_run code 2010-05-13 16:52:55 +02:00
Jan Engelhardt
b32d6dad90 compat_xtables: remove unused list member from xtnu_{match,target} 2010-05-13 16:03:05 +02:00
Jan Engelhardt
5b2cb97c06 compat_xtables: annotate struct xtnu_{match,target}->name 2010-05-13 15:58:50 +02:00
Jan Engelhardt
ca894d6687 compat_xtables: improve memory usage in struct xtnu_{match,target} 2010-05-13 15:51:54 +02:00
Jan Engelhardt
db717ec479 xt_quota2: reduce printf complexity 2010-05-13 15:39:29 +02:00
86 changed files with 1029 additions and 137 deletions

View File

@@ -1,7 +1,7 @@
# -*- Makefile -*-
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = extensions
SUBDIRS = extensions geoip
man_MANS := xtables-addons.8
@@ -16,10 +16,15 @@ install-exec-hook:
config.status: Makefile.iptrules.in
tmpdir := $(shell mktemp -dtu)
packer = xz
packext = .tar.xz
.PHONY: tarball
tarball:
rm -Rf /tmp/xtables-addons-${PACKAGE_VERSION};
pushd ${top_srcdir} && git archive --prefix=xtables-addons-${PACKAGE_VERSION}/ HEAD | tar -C /tmp -x && popd;
pushd /tmp/xtables-addons-${PACKAGE_VERSION} && ./autogen.sh && popd;
tar -C /tmp -cjf xtables-addons-${PACKAGE_VERSION}.tar.bz2 --owner=root --group=root xtables-addons-${PACKAGE_VERSION}/;
rm -Rf /tmp/xtables-addons-${PACKAGE_VERSION};
# do not use mkdir_p here.
mkdir ${tmpdir}
pushd ${top_srcdir} && git archive --prefix=${PACKAGE_NAME}-${PACKAGE_VERSION}/ HEAD | tar -C ${tmpdir} -x && popd;
pushd ${tmpdir}/${PACKAGE_NAME}-${PACKAGE_VERSION} && ./autogen.sh && popd;
tar --use=${packer} -C ${tmpdir} -cf ${PACKAGE_NAME}-${PACKAGE_VERSION}${packext} --owner=root --group=root ${PACKAGE_NAME}-${PACKAGE_VERSION}/;
rm -Rf ${tmpdir};

View File

@@ -1,6 +1,8 @@
# -*- Makefile -*-
# MANUAL
abs_top_srcdir = @abs_top_srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
libexecdir = @libexecdir@
@@ -8,11 +10,12 @@ xtlibdir = @xtlibdir@
CC = @CC@
CCLD = ${CC}
CFLAGS = @CFLAGS@
regular_CFLAGS = @regular_CFLAGS@
libxtables_CFLAGS = @libxtables_CFLAGS@
libxtables_LIBS = @libxtables_LIBS@
AM_CFLAGS = ${regular_CFLAGS} ${libxtables_CFLAGS}
AM_CFLAGS = ${regular_CFLAGS} ${libxtables_CFLAGS} -I${abs_top_srcdir}/extensions
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
AM_DEFAULT_VERBOSITY = 0

View File

@@ -3,8 +3,8 @@
srcdir := @srcdir@
wcman_matches := $(shell find "${srcdir}" -name 'libxt_[a-z]*.man')
wcman_targets := $(shell find "${srcdir}" -name 'libxt_[A-Z]*.man')
wcman_matches := $(shell find "${srcdir}" -name 'libxt_[a-z]*.man' | sort)
wcman_targets := $(shell find "${srcdir}" -name 'libxt_[A-Z]*.man' | sort)
wlist_matches := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_matches})
wlist_targets := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_targets})

View File

@@ -1,9 +1,9 @@
AC_INIT([xtables-addons], [1.26])
AC_INIT([xtables-addons], [1.29])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AC_PROG_INSTALL
AM_INIT_AUTOMAKE([1.10 -Wall foreign subdir-objects])
AM_INIT_AUTOMAKE([1.10.2 -Wall foreign subdir-objects])
AC_PROG_CC
AM_PROG_CC_C_O
AC_DISABLE_STATIC
@@ -62,7 +62,7 @@ else
fi;
fi;
echo "Found kernel version $kmajor.$kminor.$kmicro.$kstable in $kbuilddir";
if test "$kmajor" -gt 2 -o "$kminor" -gt 6 -o "$kmicro" -gt 34; then
if test "$kmajor" -gt 2 -o "$kminor" -gt 6 -o "$kmicro" -gt 36; then
echo "WARNING: You are trying a newer kernel. Results may vary. :-)";
elif test \( "$kmajor" -lt 2 -o "$kminor" -lt 6 -o "$kmicro" -lt 17 \) -o \
\( "$kmajor" -eq 2 -a "$kminor" -eq 6 -a "$kmicro" -eq 18 -a \
@@ -74,7 +74,7 @@ fi;
AC_SUBST([regular_CFLAGS])
AC_SUBST([kbuilddir])
AC_SUBST([xtlibdir])
AC_CONFIG_FILES([Makefile Makefile.iptrules Makefile.mans
AC_CONFIG_FILES([Makefile Makefile.iptrules Makefile.mans geoip/Makefile
extensions/Makefile extensions/ACCOUNT/Makefile
extensions/ipset/Makefile extensions/pknock/Makefile])
AC_OUTPUT

64
doc/api/2.6.17.c Normal file
View File

@@ -0,0 +1,64 @@
match:
/* true/false */
int
(*match)(
const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const struct xt_match *match,
const void *matchinfo,
int offset,
unsigned int protoff,
int *hotdrop,
);
/* error code */
int
(*checkentry)(
const char *tablename,
const void *ip,
const struct xt_match *match,
void *matchinfo,
unsigned int matchinfosize,
unsigned int hook_mask,
);
void
(*destroy)(
const struct xt_match *match,
void *matchinfo,
unsigned int matchinfosize,
);
target:
/* verdict */
unsigned int
(*target)(
struct sk_buff **pskb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const struct xt_target *target,
const void *targinfo,
void *userdata,
);
/* error code */
int
(*checkentry)(
const char *tablename,
const void *entry,
const struct xt_target *target,
void *targinfo,
unsigned int targinfosize,
unsigned int hook_mask,
);
void
(*destroy)(
const struct xt_target *target,
void *targinfo,
unsigned int targinfosize,
);

59
doc/api/2.6.19.c Normal file
View File

@@ -0,0 +1,59 @@
match:
/* true/false */
int
(*match)(
const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const struct xt_match *match,
const void *matchinfo,
int offset,
unsigned int protoff,
int *hotdrop,
);
/* error code */
int
(*checkentry)(
const char *tablename,
const void *ip,
const struct xt_match *match,
void *matchinfo,
unsigned int hook_mask,
);
void
(*destroy)(
const struct xt_match *match,
void *matchinfo,
);
target:
/* verdict */
unsigned int
(*target)(
struct sk_buff **pskb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const struct xt_target *target,
const void *targinfo,
);
/* error code */
int
(*checkentry)(
const char *tablename,
const void *entry,
const struct xt_target *target,
void *targinfo,
unsigned int hook_mask,
);
void
(*destroy)(
const struct xt_target *target,
void *targinfo,
);

59
doc/api/2.6.23.c Normal file
View File

@@ -0,0 +1,59 @@
match:
/* true/false */
bool
(*match)(
const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const struct xt_match *match,
const void *matchinfo,
int offset,
unsigned int protoff,
bool *hotdrop,
);
/* true/false */
bool
(*checkentry)(
const char *tablename,
const void *ip,
const struct xt_match *match,
void *matchinfo,
unsigned int hook_mask,
);
void
(*destroy)(
const struct xt_match *match,
void *matchinfo,
);
target:
/* verdict */
unsigned int
(*target)(
struct sk_buff **pskb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const struct xt_target *target,
const void *targinfo,
);
/* true/false */
bool
(*checkentry)(
const char *tablename,
const void *entry,
const struct xt_target *target,
void *targinfo,
unsigned int hook_mask,
);
void
(*destroy)(
const struct xt_target *target,
void *targinfo,
);

59
doc/api/2.6.24.c Normal file
View File

@@ -0,0 +1,59 @@
match:
/* true/false */
bool
(*match)(
const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const struct xt_match *match,
const void *matchinfo,
int offset,
unsigned int protoff,
bool *hotdrop,
);
/* true/false */
bool
(*checkentry)(
const char *tablename,
const void *ip,
const struct xt_match *match,
void *matchinfo,
unsigned int hook_mask,
);
void
(*destroy)(
const struct xt_match *match,
void *matchinfo,
);
target:
/* verdict */
unsigned int
(*target)(
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const struct xt_target *target,
const void *targinfo,
);
/* true/false */
bool
(*checkentry)(
const char *tablename,
const void *entry,
const struct xt_target *target,
void *targinfo,
unsigned int hook_mask,
);
void
(*destroy)(
const struct xt_target *target,
void *targinfo,
);

39
doc/api/2.6.28.c Normal file
View File

@@ -0,0 +1,39 @@
match:
/* true/false */
bool
(*match)(
const struct sk_buff *skb,
const struct xt_match_param *,
);
/* true/false */
bool
(*checkentry)(
const struct xt_mtchk_param *,
);
void
(*destroy)(
const struct xt_mtdtor_param *,
);
target:
/* verdict */
unsigned int
(*target)(
struct sk_buff *skb,
const struct xt_target_param *,
);
/* true/false */
bool
(*checkentry)(
const struct xt_tgchk_param *,
);
void
(*destroy)(
const struct xt_tgdtor_param *,
);

38
doc/api/2.6.31.c Normal file
View File

@@ -0,0 +1,38 @@
match:
/* true/false */
bool
(*match)(
const struct sk_buff *skb,
const struct xt_match_param *,
);
/* true/false */
bool
(*checkentry)(
const struct xt_mtchk_param *,
);
void
(*destroy)(
const struct xt_mtdtor_param *,
);
target:
unsigned int
(*target)(
struct sk_buff *skb,
const struct xt_target_param *,
);
/* true/false */
bool
(*checkentry)(
const struct xt_tgchk_param *,
);
void
(*destroy)(
const struct xt_tgdtor_param *,
);

39
doc/api/2.6.32.c Normal file
View File

@@ -0,0 +1,39 @@
match:
/* true/false */
bool
(*match)(
const struct sk_buff *skb,
const struct xt_match_param *,
);
/* true/false */
bool
(*checkentry)(
const struct xt_mtchk_param *,
);
void
(*destroy)(
const struct xt_mtdtor_param *,
);
target:
/* verdict */
unsigned int
(*target)(
struct sk_buff *skb,
const struct xt_target_param *,
);
/* true/false */
bool
(*checkentry)(
const struct xt_tgchk_param *,
);
void
(*destroy)(
const struct xt_tgdtor_param *,
);

39
doc/api/2.6.35.c Normal file
View File

@@ -0,0 +1,39 @@
match:
/* true/false */
bool
(*match)(
const struct sk_buff *skb,
struct xt_action_param *,
);
/* error code */
int
(*checkentry)(
const struct xt_mtchk_param *,
);
void
(*destroy)(
const struct xt_mtdtor_param *,
);
target:
/* verdict */
unsigned int
(*target)(
struct sk_buff *skb,
const struct xt_action_param *,
);
/* error code */
int
(*checkentry)(
const struct xt_tgchk_param *,
);
void
(*destroy)(
const struct xt_tgdtor_param *,
);

39
doc/api/xt-a.c Normal file
View File

@@ -0,0 +1,39 @@
match:
/* true/false */
bool
(*match)(
const struct sk_buff *skb,
struct xt_action_param *,
);
/* error code */
int
(*checkentry)(
const struct xt_mtchk_param *,
);
void
(*destroy)(
const struct xt_mtdtor_param *,
);
target:
/* verdict */
unsigned int
(*target)(
struct sk_buff **pskb,
const struct xt_action_param *,
);
/* error code */
int
(*checkentry)(
const struct xt_tgchk_param *,
);
void
(*destroy)(
const struct xt_tgdtor_param *,
);

View File

@@ -3,6 +3,31 @@ HEAD
====
v1.29 (September 29 2010)
=========================
- compat_xtables: return bool for match_check and target_check in 2.6.23..34
- ipset: enable building of ip_set_ipport{ip,net}hash.ko
- support for Linux 2.6.36
- SYSRQ: resolve compile error with Linux 2.6.36
- TEE: resolve compile error with Linux 2.6.36
- add workaround for broken linux-glibc-devel 2.6.34 userspace headers
("implicit declaration of function 'ALIGN'")
Xtables-addons 1.28 (July 24 2010)
==================================
- RAWNAT: IPv6 variants erroneously rejected masks /33-/128
- new target xt_CHECKSUM
- xt_length2: add support for IPv6 jumbograms
- xt_geoip: fix possible out-of-bounds access
- import xt_geoip database scripts
Xtables-addons 1.27 (May 16 2010)
=================================
- further updates for the upcoming 2.6.35 changes
Xtables-addons 1.26 (April 30 2010)
===================================
- compat_xtables: fix 2.6.34 compile error due to a typo

View File

@@ -12,6 +12,7 @@
#include <stddef.h>
#include <xtables.h>
#include "xt_ACCOUNT.h"
#include "compat_user.h"
static struct option account_tg_opts[] = {
{.name = "addr", .has_arg = true, .val = 'a'},

View File

@@ -478,7 +478,7 @@ static void ipt_acc_depth2_insert(struct ipt_acc_mask_8 *mask_8,
}
}
static unsigned int ipt_acc_target(struct sk_buff **pskb, const struct xt_target_param *par)
static unsigned int ipt_acc_target(struct sk_buff **pskb, const struct xt_action_param *par)
{
const struct ipt_acc_info *info =
par->targinfo;

View File

@@ -7,6 +7,7 @@ obj-m += compat_xtables.o
obj-${build_ACCOUNT} += ACCOUNT/
obj-${build_CHAOS} += xt_CHAOS.o
obj-${build_CHECKSUM} += xt_CHECKSUM.o
obj-${build_DELUDE} += xt_DELUDE.o
obj-${build_DHCPMAC} += xt_DHCPMAC.o
obj-${build_ECHO} += xt_ECHO.o

View File

@@ -2,6 +2,7 @@
obj-${build_ACCOUNT} += ACCOUNT/
obj-${build_CHAOS} += libxt_CHAOS.so
obj-${build_CHECKSUM} += libxt_CHECKSUM.so
obj-${build_DELUDE} += libxt_DELUDE.so
obj-${build_DHCPMAC} += libxt_DHCPMAC.so libxt_dhcpmac.so
obj-${build_ECHO} += libxt_ECHO.so

12
extensions/compat_user.h Normal file
View File

@@ -0,0 +1,12 @@
/*
* Userspace-level compat hacks
*/
#ifndef _XTABLES_COMPAT_USER_H
#define _XTABLES_COMPAT_USER_H 1
/* linux-glibc-devel 2.6.34 header screwup */
#ifndef ALIGN
# define ALIGN(s, n) (((s) + ((n) - 1)) & ~((n) - 1))
#endif
#endif /* _XTABLES_COMPAT_USER_H */

View File

@@ -1,6 +1,6 @@
/*
* API compat layer
* written by Jan Engelhardt <jengelh [at] medozas de>, 2008
* written by Jan Engelhardt <jengelh [at] medozas de>, 2008 - 2010
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License, either
@@ -34,25 +34,49 @@ static bool xtnu_match_run(const struct sk_buff *skb,
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
{
struct xtnu_match *nm = xtcompat_numatch(cm);
bool lo_drop = false, lo_ret;
struct xt_match_param local_par = {
.in = in,
.out = out,
.match = cm,
.matchinfo = matchinfo,
.fragoff = offset,
.thoff = protoff,
.hotdrop = &lo_drop,
.family = NFPROTO_UNSPEC, /* don't have that info */
};
bool lo_ret;
struct xt_action_param local_par;
local_par.in = in;
local_par.out = out;
local_par.match = cm;
local_par.matchinfo = matchinfo;
local_par.fragoff = offset;
local_par.thoff = protoff;
local_par.hotdrop = false;
local_par.family = NFPROTO_UNSPEC; /* don't have that info */
if (nm == NULL || nm->match == NULL)
return false;
lo_ret = nm->match(skb, &local_par);
*hotdrop = lo_drop;
*hotdrop = local_par.hotdrop;
return lo_ret;
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) && \
LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
static bool xtnu_match_run(const struct sk_buff *skb,
const struct xt_match_param *par)
{
struct xtnu_match *nm = xtcompat_numatch(par->match);
struct xt_action_param local_par;
bool ret;
local_par.in = par->in;
local_par.out = par->out;
local_par.match = par->match;
local_par.matchinfo = par->matchinfo;
local_par.fragoff = par->fragoff;
local_par.thoff = par->thoff;
local_par.hotdrop = false;
local_par.family = par->family;
if (nm == NULL || nm->match == NULL)
return false;
ret = nm->match(skb, &local_par);
*par->hotdrop = local_par.hotdrop;
return ret;
}
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
static int xtnu_match_check(const char *table, const void *entry,
@@ -81,7 +105,11 @@ static bool xtnu_match_check(const char *table, const void *entry,
return false;
if (nm->checkentry == NULL)
return true;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
return nm->checkentry(&local_par);
#else
return nm->checkentry(&local_par) == 0;
#endif
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) && \
@@ -94,7 +122,7 @@ static bool xtnu_match_check(const struct xt_mtchk_param *par)
return false;
if (nm->checkentry == NULL)
return true;
return nm->checkentry(par) == 0 ? true : false;
return nm->checkentry(par) == 0;
}
#endif
@@ -144,6 +172,10 @@ int xtnu_register_match(struct xtnu_match *nt)
ct->match = xtnu_match_run;
ct->checkentry = xtnu_match_check;
ct->destroy = xtnu_match_destroy;
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
ct->match = xtnu_match_run;
ct->checkentry = xtnu_match_check;
ct->destroy = nt->destroy;
#else
ct->match = nt->match;
ct->checkentry = xtnu_match_check;
@@ -207,35 +239,55 @@ static unsigned int xtnu_target_run(struct sk_buff **pskb,
static unsigned int xtnu_target_run(struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
unsigned int hooknum, const struct xt_target *ct, const void *targinfo)
#else
static unsigned int
xtnu_target_run(struct sk_buff *skb, const struct xt_target_param *par)
#endif
{
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
{
struct xtnu_target *nt = xtcompat_nutarget(ct);
struct xt_target_param local_par = {
.in = in,
.out = out,
.hooknum = hooknum,
.target = ct,
.targinfo = targinfo,
.family = NFPROTO_UNSPEC,
};
#else
struct xtnu_target *nt = xtcompat_nutarget(par->target);
#endif
struct xt_action_param local_par;
local_par.in = in;
local_par.out = out;
local_par.hooknum = hooknum;
local_par.target = ct;
local_par.targinfo = targinfo;
local_par.family = NFPROTO_UNSPEC;
if (nt != NULL && nt->target != NULL)
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
return nt->target(pskb, &local_par);
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
return nt->target(&skb, &local_par);
#else
return nt->target(&skb, par);
#endif
return XT_CONTINUE;
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) && \
LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
static unsigned int
xtnu_target_run(struct sk_buff *skb, const struct xt_target_param *par)
{
struct xtnu_target *nt = xtcompat_nutarget(par->target);
struct xt_action_param local_par;
local_par.in = par->in;
local_par.out = par->out;
local_par.hooknum = par->hooknum;
local_par.target = par->target;
local_par.targinfo = par->targinfo;
local_par.family = par->family;
return nt->target(&skb, &local_par);
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
static unsigned int
xtnu_target_run(struct sk_buff *skb, const struct xt_action_param *par)
{
struct xtnu_target *nt = xtcompat_nutarget(par->target);
return nt->target(&skb, par);
}
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
static int xtnu_target_check(const char *table, const void *entry,
@@ -265,7 +317,11 @@ static bool xtnu_target_check(const char *table, const void *entry,
if (nt->checkentry == NULL)
/* this is valid, just like if there was no function */
return true;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
return nt->checkentry(&local_par);
#else
return nt->checkentry(&local_par) == 0;
#endif
}
#endif
@@ -279,7 +335,7 @@ static bool xtnu_target_check(const struct xt_tgchk_param *par)
return false;
if (nt->checkentry == NULL)
return true;
return nt->checkentry(par) == 0 ? true : false;
return nt->checkentry(par) == 0;
}
#endif

View File

@@ -86,6 +86,11 @@
# define ip6t_unregister_table(tbl) ip6t_unregister_table(tbl)
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
# define rt_dst(rt) (&(rt)->dst)
#else
# define rt_dst(rt) (&(rt)->u.dst)
#endif
#if !defined(NIP6) && !defined(NIP6_FMT)
# define NIP6(addr) \

View File

@@ -32,16 +32,6 @@ enum {
NFPROTO_NUMPROTO,
};
struct xt_match_param {
const struct net_device *in, *out;
const struct xt_match *match;
const void *matchinfo;
int fragoff;
unsigned int thoff;
bool *hotdrop;
u_int8_t family;
};
struct xt_mtchk_param {
const char *table;
const void *entryinfo;
@@ -81,33 +71,52 @@ struct xt_tgdtor_param {
};
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
struct xt_action_param {
union {
const struct xt_match *match;
const struct xt_target *target;
};
union {
const void *matchinfo, *targinfo;
};
const struct net_device *in, *out;
int fragoff;
unsigned int thoff, hooknum;
u_int8_t family;
bool hotdrop;
};
#endif
struct xtnu_match {
struct list_head list;
char name[XT_FUNCTION_MAXNAMELEN - 1 - sizeof(void *)];
bool (*match)(const struct sk_buff *, const struct xt_match_param *);
/*
* Making it smaller by sizeof(void *) on purpose to catch
* lossy translation, if any.
*/
char name[sizeof(((struct xt_match *)NULL)->name) - 1 - sizeof(void *)];
uint8_t revision;
bool (*match)(const struct sk_buff *, struct xt_action_param *);
int (*checkentry)(const struct xt_mtchk_param *);
void (*destroy)(const struct xt_mtdtor_param *);
struct module *me;
const char *table;
unsigned int matchsize, hooks;
unsigned short proto, family;
uint8_t revision;
void *__compat_match;
};
struct xtnu_target {
struct list_head list;
char name[XT_FUNCTION_MAXNAMELEN - 1 - sizeof(void *)];
char name[sizeof(((struct xt_target *)NULL)->name) - 1 - sizeof(void *)];
uint8_t revision;
unsigned int (*target)(struct sk_buff **,
const struct xt_target_param *);
const struct xt_action_param *);
int (*checkentry)(const struct xt_tgchk_param *);
void (*destroy)(const struct xt_tgdtor_param *);
struct module *me;
const char *table;
unsigned int targetsize, hooks;
unsigned short proto, family;
uint8_t revision;
void *__compat_target;
};

View File

@@ -3,4 +3,5 @@
obj-m += ipt_set.o ipt_SET.o
obj-m += ip_set.o ip_set_ipmap.o ip_set_portmap.o ip_set_macipmap.o
obj-m += ip_set_iphash.o ip_set_nethash.o ip_set_ipporthash.o
obj-m += ip_set_ipportiphash.o ip_set_ipportnethash.o
obj-m += ip_set_iptree.o ip_set_iptreemap.o ip_set_setlist.o

View File

@@ -929,11 +929,11 @@ ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len)
}
if (copy_from_user(data, user, len) != 0) {
res = -EFAULT;
goto done;
goto cleanup;
}
if (down_interruptible(&ip_set_app_mutex)) {
res = -EINTR;
goto done;
goto cleanup;
}
op = (unsigned *)data;
@@ -1109,6 +1109,7 @@ ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len)
done:
up(&ip_set_app_mutex);
cleanup:
vfree(data);
if (res > 0)
res = 0;
@@ -1142,11 +1143,11 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
}
if (copy_from_user(data, user, *len) != 0) {
res = -EFAULT;
goto done;
goto cleanup;
}
if (down_interruptible(&ip_set_app_mutex)) {
res = -EINTR;
goto done;
goto cleanup;
}
op = (unsigned *) data;
@@ -1439,6 +1440,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
done:
up(&ip_set_app_mutex);
cleanup:
vfree(data);
if (res > 0)
res = 0;

View File

@@ -502,9 +502,13 @@ data storage in
set and add src to the first single or src,dst to the first double
data storage set in
\fIb\fP.
.P
You can imagine a setlist type of set as an ordered union of
the set elements.
.P
Please note: by the ipset command you can add, delete and
.B test
the setnames in a setlist type of set, and not the presence of
a set's member (such as an IP address).
.SH GENERAL RESTRICTIONS
Setnames starting with colon (:) cannot be defined. Zero valued set
entries cannot be used with hash type of sets.

View File

@@ -30,7 +30,7 @@
#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe"
#endif
#define IPSET_VERSION "4.2"
#define IPSET_VERSION "4.3"
char program_name[] = "ipset";
char program_version[] = IPSET_VERSION;

View File

@@ -29,7 +29,7 @@
#include "../compat_xtables.h"
static unsigned int
target(struct sk_buff **pskb, const struct xt_target_param *par)
target(struct sk_buff **pskb, const struct xt_action_param *par)
{
const struct ipt_set_info_target *info = par->targinfo;

View File

@@ -38,7 +38,7 @@ match_set(const struct ipt_set_info *info,
}
static bool
match(const struct sk_buff *skb, const struct xt_match_param *par)
match(const struct sk_buff *skb, struct xt_action_param *par)
{
const struct ipt_set_info_match *info = par->matchinfo;

View File

@@ -16,6 +16,7 @@
#include <xtables.h>
#include <linux/netfilter/x_tables.h>
#include "xt_CHAOS.h"
#include "compat_user.h"
enum {
F_DELUDE = 1 << 0,

View File

@@ -0,0 +1,94 @@
/*
* (C) 2002 by Harald Welte <laforge@gnumonks.org>
* (C) 2010 by Red Hat, Inc
* Author: Michael S. Tsirkin <mst@redhat.com>
*
* This program is distributed under the terms of GNU GPL v2, 1991
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <xtables.h>
#include "xt_CHECKSUM.h"
#include "compat_user.h"
static void CHECKSUM_help(void)
{
printf(
"CHECKSUM target options\n"
" --checksum-fill Fill in packet checksum.\n");
}
static const struct option CHECKSUM_opts[] = {
{ "checksum-fill", 0, NULL, 'F' },
{ .name = NULL }
};
static int CHECKSUM_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_target **target)
{
struct xt_CHECKSUM_info *einfo
= (struct xt_CHECKSUM_info *)(*target)->data;
switch (c) {
case 'F':
xtables_param_act(XTF_ONLY_ONCE, "CHECKSUM", "--checksum-fill",
*flags & XT_CHECKSUM_OP_FILL);
einfo->operation = XT_CHECKSUM_OP_FILL;
*flags |= XT_CHECKSUM_OP_FILL;
break;
default:
return 0;
}
return 1;
}
static void CHECKSUM_check(unsigned int flags)
{
if (!flags)
xtables_error(PARAMETER_PROBLEM,
"CHECKSUM target: Parameter --checksum-fill is required");
}
static void CHECKSUM_print(const void *ip, const struct xt_entry_target *target,
int numeric)
{
const struct xt_CHECKSUM_info *einfo =
(const struct xt_CHECKSUM_info *)target->data;
printf("CHECKSUM ");
if (einfo->operation & XT_CHECKSUM_OP_FILL)
printf("fill ");
}
static void CHECKSUM_save(const void *ip, const struct xt_entry_target *target)
{
const struct xt_CHECKSUM_info *einfo =
(const struct xt_CHECKSUM_info *)target->data;
if (einfo->operation & XT_CHECKSUM_OP_FILL)
printf("--checksum-fill ");
}
static struct xtables_target checksum_tg_reg = {
.name = "CHECKSUM",
.version = XTABLES_VERSION,
.family = NFPROTO_UNSPEC,
.size = XT_ALIGN(sizeof(struct xt_CHECKSUM_info)),
.userspacesize = XT_ALIGN(sizeof(struct xt_CHECKSUM_info)),
.help = CHECKSUM_help,
.parse = CHECKSUM_parse,
.final_check = CHECKSUM_check,
.print = CHECKSUM_print,
.save = CHECKSUM_save,
.extra_opts = CHECKSUM_opts,
};
static __attribute__((constructor)) void _init(void)
{
xtables_register_target(&checksum_tg_reg);
}

View File

@@ -0,0 +1,8 @@
This target allows to selectively work around broken/old applications.
It can only be used in the mangle table.
.TP
\fB\-\-checksum\-fill\fP
Compute and fill in the checksum in a packet that lacks a checksum.
This is particularly useful, if you need to work around old applications
such as dhcp clients, that do not work well with checksum offloads,
but don't want to disable checksum offload in your device.

View File

@@ -13,6 +13,7 @@
#include <xtables.h>
#include <linux/netfilter/x_tables.h>
#include "compat_user.h"
static void delude_tg_help(void)
{

View File

@@ -17,6 +17,7 @@
#include <xtables.h>
#include "xt_DHCPMAC.h"
#include "mac.c"
#include "compat_user.h"
enum {
F_MAC = 1 << 0,

View File

@@ -10,6 +10,7 @@
#include <stdio.h>
#include <getopt.h>
#include <xtables.h>
#include "compat_user.h"
static void echo_tg_help(void)
{

View File

@@ -14,6 +14,7 @@
#include <string.h>
#include <xtables.h>
#include "xt_IPMARK.h"
#include "compat_user.h"
enum {
FL_ADDR_USED = 1 << 0,

View File

@@ -13,6 +13,7 @@
#include <string.h>
#include <xtables.h>
#include "xt_LOGMARK.h"
#include "compat_user.h"
enum {
F_LEVEL = 1 << 0,

View File

@@ -15,6 +15,7 @@
#include <xtables.h>
#include <linux/netfilter.h>
#include "xt_RAWNAT.h"
#include "compat_user.h"
enum {
FLAGS_TO = 1 << 0,
@@ -79,7 +80,7 @@ rawdnat_tg6_parse(int c, char **argv, int invert, unsigned int *flags,
end = strchr(optarg, '/');
if (end != NULL) {
*end++ = '\0';
if (!xtables_strtoui(end, NULL, &mask, 0, 32))
if (!xtables_strtoui(end, NULL, &mask, 0, 128))
xtables_param_act(XTF_BAD_VALUE, "RAWDNAT",
"--to-destination", optarg);
info->mask = mask;

View File

@@ -15,6 +15,7 @@
#include <xtables.h>
#include <linux/netfilter.h>
#include "xt_RAWNAT.h"
#include "compat_user.h"
enum {
FLAGS_TO = 1 << 0,
@@ -79,7 +80,7 @@ rawsnat_tg6_parse(int c, char **argv, int invert, unsigned int *flags,
end = strchr(optarg, '/');
if (end != NULL) {
*end++ = '\0';
if (!xtables_strtoui(end, NULL, &mask, 0, 32))
if (!xtables_strtoui(end, NULL, &mask, 0, 128))
xtables_param_act(XTF_BAD_VALUE, "RAWSNAT",
"--to-source", optarg);
info->mask = mask;

View File

@@ -1,5 +1,6 @@
#include <stdio.h>
#include <xtables.h>
#include "compat_user.h"
static void steal_tg_help(void)
{

View File

@@ -5,6 +5,7 @@
#include <stdio.h>
#include <getopt.h>
#include <xtables.h>
#include "compat_user.h"
static void sysrq_tg_help(void)
{

View File

@@ -5,6 +5,7 @@
#include <stdio.h>
#include <getopt.h>
#include <xtables.h>
#include "compat_user.h"
static void tarpit_tg_help(void)
{

View File

@@ -23,6 +23,7 @@
#include <linux/netfilter.h>
#include <linux/netfilter/x_tables.h>
#include "xt_TEE.h"
#include "compat_user.h"
enum {
FLAG_GATEWAY = 1 << 0,

View File

@@ -16,6 +16,7 @@
#include <getopt.h>
#include <xtables.h>
#include "xt_condition.h"
#include "compat_user.h"
static void condition_help(void)
{

View File

@@ -16,6 +16,7 @@
#include <xtables.h>
#include "xt_DHCPMAC.h"
#include "mac.c"
#include "compat_user.h"
enum {
F_MAC = 1 << 0,

View File

@@ -15,6 +15,7 @@
#include <string.h>
#include <xtables.h>
#include "xt_fuzzy.h"
#include "compat_user.h"
static void fuzzy_mt_help(void)
{

View File

@@ -24,6 +24,7 @@
#include <unistd.h>
#include <xtables.h>
#include "xt_geoip.h"
#include "compat_user.h"
#define GEOIP_DB_DIR "/usr/share/xt_geoip"
static void geoip_help(void)

View File

@@ -10,8 +10,8 @@ NOTE:
The country is inputed by its ISO-3166 code.
.PP
The extra files you will need is the binary database files. They are generated
from a country-subnet database with the geoip_csv_iv0.pl tool, available at
http://jengelh.hopto.org/files/geoip/ . The files MUST be moved to
/usr/share/xt_geoip/
from a country-subnet database with the geoip_csv_iv0.pl tool that should be
available in /usr/lib(exec)/xtables-addons/ . The resulting files MUST be moved
to /usr/share/xt_geoip/
as the shared library is statically looking for this pathname (e.g.
/usr/share/xt_geoip/LE/de.iv0).

View File

@@ -15,6 +15,7 @@
#include <xtables.h>
#include "xt_iface.h"
#include "compat_user.h"
static const struct option iface_mt_opts[] = {
{.name = "iface", .has_arg = true, .val = 'i'},

View File

@@ -17,6 +17,7 @@
#include <ctype.h>
#include <xtables.h>
#include "xt_ipp2p.h"
#include "compat_user.h"
#define param_act(t, s, f) xtables_param_act((t), "ipp2p", (s), (f))
static void ipp2p_mt_help(void)

View File

@@ -14,6 +14,7 @@
#include <string.h>
#include <xtables.h>
#include "xt_ipv4options.h"
#include "compat_user.h"
/*
* Overview from http://www.networksorcery.com/enp/protocol/ip.htm

View File

@@ -5,6 +5,7 @@
#include <string.h>
#include <xtables.h>
#include "xt_length2.h"
#include "compat_user.h"
enum {
F_LAYER = 1 << 0,

View File

@@ -17,6 +17,7 @@
#include <xtables.h>
#include <linux/netfilter/x_tables.h>
#include "xt_lscan.h"
#include "compat_user.h"
static const struct option lscan_mt_opts[] = {
{.name = "stealth", .has_arg = false, .val = 'x'},

View File

@@ -28,6 +28,7 @@
#include <xtables.h>
#include <linux/netfilter/x_tables.h>
#include "xt_psd.h"
#include "compat_user.h"
/* Function which prints out usage message. */
static void psd_mt_help(void) {

View File

@@ -15,6 +15,7 @@
#include <string.h>
#include <xtables.h>
#include "xt_quota2.h"
#include "compat_user.h"
enum {
FL_QUOTA = 1 << 0,

View File

@@ -16,6 +16,7 @@
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include "xt_pknock.h"
#include "compat_user.h"
static const struct option pknock_mt_opts[] = {
/* .name, .has_arg, .flag, .val */

View File

@@ -958,7 +958,7 @@ is_close_knock(const struct peer *peer, const struct xt_pknock_mtinfo *info,
}
static bool pknock_mt(const struct sk_buff *skb,
const struct xt_match_param *par)
struct xt_action_param *par)
{
const struct xt_pknock_mtinfo *info = par->matchinfo;
struct xt_pknock_rule *rule;
@@ -975,7 +975,7 @@ static bool pknock_mt(const struct sk_buff *skb,
/* We've been asked to examine this packet, and we
* can't. Hence, no choice but to drop.
*/
*par->hotdrop = true;
par->hotdrop = true;
return false;
}

View File

@@ -45,7 +45,7 @@ static const struct xt_tcp tcp_params = {
/* CHAOS functions */
static void
xt_chaos_total(struct sk_buff *skb, const struct xt_target_param *par)
xt_chaos_total(struct sk_buff *skb, const struct xt_action_param *par)
{
const struct xt_chaos_tginfo *info = par->targinfo;
const struct iphdr *iph = ip_hdr(skb);
@@ -62,7 +62,7 @@ xt_chaos_total(struct sk_buff *skb, const struct xt_target_param *par)
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
ret = xm_tcp->match(skb, par->in, par->out, xm_tcp, &tcp_params,
fragoff, thoff, &hotdrop);
#else
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
{
struct xt_match_param local_par = {
.in = par->in,
@@ -75,6 +75,19 @@ xt_chaos_total(struct sk_buff *skb, const struct xt_target_param *par)
};
ret = xm_tcp->match(skb, &local_par);
}
#else
{
struct xt_action_param local_par;
local_par.in = par->in,
local_par.out = par->out,
local_par.match = xm_tcp;
local_par.matchinfo = &tcp_params;
local_par.fragoff = fragoff;
local_par.thoff = thoff;
local_par.hotdrop = false;
ret = xm_tcp->match(skb, &local_par);
hotdrop = local_par.hotdrop;
}
#endif
if (!ret || hotdrop || (unsigned int)net_random() > delude_percentage)
return;
@@ -86,17 +99,34 @@ xt_chaos_total(struct sk_buff *skb, const struct xt_target_param *par)
destiny->target(&skb, par->in, par->out, par->hooknum, destiny, NULL);
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
destiny->target(skb, par->in, par->out, par->hooknum, destiny, NULL);
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
{
struct xt_target_param local_par = {
.in = par->in,
.out = par->out,
.hooknum = par->hooknum,
.target = destiny,
.targinfo = par->targinfo,
.family = par->family,
};
destiny->target(skb, &local_par);
}
#else
{
struct xt_target_param local_par = *par;
local_par.target = destiny;
struct xt_action_param local_par;
local_par.in = par->in;
local_par.out = par->out;
local_par.hooknum = par->hooknum;
local_par.target = destiny;
local_par.targinfo = par->targinfo;
local_par.family = par->family;
destiny->target(skb, &local_par);
}
#endif
}
static unsigned int
chaos_tg(struct sk_buff **pskb, const struct xt_target_param *par)
chaos_tg(struct sk_buff **pskb, const struct xt_action_param *par)
{
/*
* Equivalent to:
@@ -120,7 +150,7 @@ chaos_tg(struct sk_buff **pskb, const struct xt_target_param *par)
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
return xt_reject->target(skb, par->in, par->out, par->hooknum,
xt_reject, &reject_params);
#else
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
struct xt_target_param local_par = {
.in = par->in,
.out = par->out,
@@ -129,6 +159,14 @@ chaos_tg(struct sk_buff **pskb, const struct xt_target_param *par)
.targinfo = &reject_params,
};
return xt_reject->target(skb, &local_par);
#else
struct xt_action_param local_par;
local_par.in = par->in;
local_par.out = par->out;
local_par.hooknum = par->hooknum;
local_par.target = xt_reject;
local_par.targinfo = &reject_params;
return xt_reject->target(skb, &local_par);
#endif
}

72
extensions/xt_CHECKSUM.c Normal file
View File

@@ -0,0 +1,72 @@
/*
* (C) 2002 by Harald Welte <laforge@netfilter.org>
* (C) 2010 Red Hat, Inc.
*
* Author: Michael S. Tsirkin <mst@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter/x_tables.h>
#include "xt_CHECKSUM.h"
#include "compat_xtables.h"
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Michael S. Tsirkin <mst@redhat.com>");
MODULE_DESCRIPTION("Xtables: checksum modification");
MODULE_ALIAS("ipt_CHECKSUM");
MODULE_ALIAS("ip6t_CHECKSUM");
static unsigned int
checksum_tg(struct sk_buff **pskb, const struct xt_action_param *par)
{
struct sk_buff *skb = *pskb;
if (skb->ip_summed == CHECKSUM_PARTIAL)
skb_checksum_help(skb);
return XT_CONTINUE;
}
static int checksum_tg_check(const struct xt_tgchk_param *par)
{
const struct xt_CHECKSUM_info *einfo = par->targinfo;
if (einfo->operation & ~XT_CHECKSUM_OP_FILL) {
pr_info("unsupported CHECKSUM operation %x\n", einfo->operation);
return -EINVAL;
}
if (!einfo->operation) {
pr_info("no CHECKSUM operation enabled\n");
return -EINVAL;
}
return 0;
}
static struct xt_target checksum_tg_reg __read_mostly = {
.name = "CHECKSUM",
.family = NFPROTO_UNSPEC,
.target = checksum_tg,
.targetsize = sizeof(struct xt_CHECKSUM_info),
.table = "mangle",
.checkentry = checksum_tg_check,
.me = THIS_MODULE,
};
static int __init checksum_tg_init(void)
{
return xt_register_target(&checksum_tg_reg);
}
static void __exit checksum_tg_exit(void)
{
xt_unregister_target(&checksum_tg_reg);
}
module_init(checksum_tg_init);
module_exit(checksum_tg_exit);

18
extensions/xt_CHECKSUM.h Normal file
View File

@@ -0,0 +1,18 @@
/* Header file for iptables ipt_CHECKSUM target
*
* (C) 2002 by Harald Welte <laforge@gnumonks.org>
* (C) 2010 Red Hat Inc
* Author: Michael S. Tsirkin <mst@redhat.com>
*
* This software is distributed under GNU GPL v2, 1991
*/
#ifndef _IPT_CHECKSUM_TARGET_H
#define _IPT_CHECKSUM_TARGET_H
#define XT_CHECKSUM_OP_FILL 0x01 /* fill in checksum in IP header */
struct xt_CHECKSUM_info {
__u8 operation; /* bitset of operations */
};
#endif /* _IPT_CHECKSUM_TARGET_H */

View File

@@ -143,7 +143,7 @@ static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
}
static unsigned int
delude_tg(struct sk_buff **pskb, const struct xt_target_param *par)
delude_tg(struct sk_buff **pskb, const struct xt_action_param *par)
{
/* WARNING: This code causes reentry within iptables.
This means that the iptables jump stack is now crap. We

View File

@@ -69,7 +69,7 @@ static bool ether_cmp(const unsigned char *lh, const unsigned char *rh,
}
static bool
dhcpmac_mt(const struct sk_buff *skb, const struct xt_match_param *par)
dhcpmac_mt(const struct sk_buff *skb, struct xt_action_param *par)
{
const struct dhcpmac_info *info = par->matchinfo;
const struct dhcp_message *dh;
@@ -89,7 +89,7 @@ dhcpmac_mt(const struct sk_buff *skb, const struct xt_match_param *par)
}
static unsigned int
dhcpmac_tg(struct sk_buff **pskb, const struct xt_target_param *par)
dhcpmac_tg(struct sk_buff **pskb, const struct xt_action_param *par)
{
const struct dhcpmac_info *info = par->targinfo;
struct dhcp_message dhcpbuf, *dh;

View File

@@ -21,7 +21,7 @@
#include "compat_xtables.h"
static unsigned int
echo_tg4(struct sk_buff **poldskb, const struct xt_target_param *par)
echo_tg4(struct sk_buff **poldskb, const struct xt_action_param *par)
{
const struct sk_buff *oldskb = *poldskb;
const struct udphdr *oldudp;

View File

@@ -25,7 +25,7 @@ MODULE_ALIAS("ipt_IPMARK");
MODULE_ALIAS("ip6t_IPMARK");
static unsigned int
ipmark_tg4(struct sk_buff **pskb, const struct xt_target_param *par)
ipmark_tg4(struct sk_buff **pskb, const struct xt_action_param *par)
{
const struct xt_ipmark_tginfo *ipmarkinfo = par->targinfo;
const struct sk_buff *skb = *pskb;
@@ -61,7 +61,7 @@ static __u32 ipmark_from_ip6(const struct in6_addr *a, unsigned int s)
}
static unsigned int
ipmark_tg6(struct sk_buff **pskb, const struct xt_target_param *par)
ipmark_tg6(struct sk_buff **pskb, const struct xt_action_param *par)
{
const struct xt_ipmark_tginfo *info = par->targinfo;
const struct sk_buff *skb = *pskb;

View File

@@ -30,7 +30,7 @@ static const char *const dir_names[] = {
};
static unsigned int
logmark_tg(struct sk_buff **pskb, const struct xt_target_param *par)
logmark_tg(struct sk_buff **pskb, const struct xt_action_param *par)
{
const struct sk_buff *skb = *pskb;
const struct xt_logmark_tginfo *info = par->targinfo;

View File

@@ -48,7 +48,7 @@ rawnat_ipv6_mask(__be32 *addr, const __be32 *repl, unsigned int mask)
break;
case 33 ... 63:
addr[0] = repl[0];
addr[1] = remask(addr[1], repl[1], mask - 64);
addr[1] = remask(addr[1], repl[1], mask - 32);
break;
case 64:
addr[0] = repl[0];
@@ -57,7 +57,7 @@ rawnat_ipv6_mask(__be32 *addr, const __be32 *repl, unsigned int mask)
case 65 ... 95:
addr[0] = repl[0];
addr[1] = repl[1];
addr[2] = remask(addr[2], repl[2], mask - 96);
addr[2] = remask(addr[2], repl[2], mask - 64);
case 96:
addr[0] = repl[0];
addr[1] = repl[1];
@@ -67,7 +67,7 @@ rawnat_ipv6_mask(__be32 *addr, const __be32 *repl, unsigned int mask)
addr[0] = repl[0];
addr[1] = repl[1];
addr[2] = repl[2];
addr[3] = remask(addr[3], repl[3], mask - 128);
addr[3] = remask(addr[3], repl[3], mask - 96);
break;
case 128:
addr[0] = repl[0];
@@ -125,7 +125,7 @@ static unsigned int rawnat4_writable_part(const struct iphdr *iph)
}
static unsigned int
rawsnat_tg4(struct sk_buff **pskb, const struct xt_target_param *par)
rawsnat_tg4(struct sk_buff **pskb, const struct xt_action_param *par)
{
const struct xt_rawnat_tginfo *info = par->targinfo;
struct iphdr *iph;
@@ -147,7 +147,7 @@ rawsnat_tg4(struct sk_buff **pskb, const struct xt_target_param *par)
}
static unsigned int
rawdnat_tg4(struct sk_buff **pskb, const struct xt_target_param *par)
rawdnat_tg4(struct sk_buff **pskb, const struct xt_action_param *par)
{
const struct xt_rawnat_tginfo *info = par->targinfo;
struct iphdr *iph;
@@ -241,7 +241,7 @@ static void rawnat6_update_l4(struct sk_buff *skb, unsigned int l4proto,
}
static unsigned int
rawsnat_tg6(struct sk_buff **pskb, const struct xt_target_param *par)
rawsnat_tg6(struct sk_buff **pskb, const struct xt_action_param *par)
{
const struct xt_rawnat_tginfo *info = par->targinfo;
unsigned int l4offset, l4proto;
@@ -262,7 +262,7 @@ rawsnat_tg6(struct sk_buff **pskb, const struct xt_target_param *par)
}
static unsigned int
rawdnat_tg6(struct sk_buff **pskb, const struct xt_target_param *par)
rawdnat_tg6(struct sk_buff **pskb, const struct xt_action_param *par)
{
const struct xt_rawnat_tginfo *info = par->targinfo;
unsigned int l4offset, l4proto;

View File

@@ -8,7 +8,7 @@
#include "compat_xtables.h"
static unsigned int
steal_tg(struct sk_buff **pskb, const struct xt_target_param *par)
steal_tg(struct sk_buff **pskb, const struct xt_action_param *par)
{
kfree_skb(*pskb);
return NF_STOLEN;

View File

@@ -135,13 +135,13 @@ static unsigned int sysrq_tg(const void *pdata, uint16_t len)
"0123456789abcdef"[sysrq_digest[i] & 0xf];
}
sysrq_hexdigest[2*sysrq_digest_size] = '\0';
if (len - n < sysrq_digest_size) {
if (len - n < sysrq_digest_size * 2) {
if (sysrq_debug)
printk(KERN_INFO KBUILD_MODNAME ": Short digest,"
" expected %s\n", sysrq_hexdigest);
return NF_DROP;
}
if (strncmp(data + n, sysrq_hexdigest, sysrq_digest_size) != 0) {
if (strncmp(data + n, sysrq_hexdigest, sysrq_digest_size * 2) != 0) {
if (sysrq_debug)
printk(KERN_INFO KBUILD_MODNAME ": Bad digest,"
" expected %s\n", sysrq_hexdigest);
@@ -152,7 +152,9 @@ static unsigned int sysrq_tg(const void *pdata, uint16_t len)
sysrq_seqno = new_seqno;
for (i = 0; i < len && data[i] != ','; ++i) {
printk(KERN_INFO KBUILD_MODNAME ": SysRq %c\n", data[i]);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
handle_sysrq(data[i]);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
handle_sysrq(data[i], NULL);
#else
handle_sysrq(data[i], NULL, NULL);
@@ -187,7 +189,9 @@ static unsigned int sysrq_tg(const void *pdata, uint16_t len)
return NF_DROP;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
handle_sysrq(c);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
handle_sysrq(c, NULL);
#else
handle_sysrq(c, NULL, NULL);
@@ -197,7 +201,7 @@ static unsigned int sysrq_tg(const void *pdata, uint16_t len)
#endif
static unsigned int
sysrq_tg4(struct sk_buff **pskb, const struct xt_target_param *par)
sysrq_tg4(struct sk_buff **pskb, const struct xt_action_param *par)
{
struct sk_buff *skb = *pskb;
const struct iphdr *iph;
@@ -224,7 +228,7 @@ sysrq_tg4(struct sk_buff **pskb, const struct xt_target_param *par)
#ifdef WITH_IPV6
static unsigned int
sysrq_tg6(struct sk_buff **pskb, const struct xt_target_param *par)
sysrq_tg6(struct sk_buff **pskb, const struct xt_action_param *par)
{
struct sk_buff *skb = *pskb;
const struct ipv6hdr *iph;
@@ -324,8 +328,8 @@ static int __init sysrq_crypto_init(void)
printk(KERN_WARNING KBUILD_MODNAME
": Error: Could not find or load %s hash\n",
sysrq_hash);
sysrq_tfm = NULL;
ret = PTR_ERR(sysrq_tfm);
sysrq_tfm = NULL;
goto fail;
}
sysrq_digest_size = crypto_hash_digestsize(sysrq_tfm);

View File

@@ -73,7 +73,7 @@ static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
/* Rate-limit replies to !SYN,ACKs */
#if 0
if (!oth->syn && oth->ack)
if (!xrlim_allow(&ort->u.dst, HZ))
if (!xrlim_allow(rt_dst(ort), HZ))
return;
#endif
@@ -188,7 +188,7 @@ static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
}
static unsigned int
tarpit_tg(struct sk_buff **pskb, const struct xt_target_param *par)
tarpit_tg(struct sk_buff **pskb, const struct xt_action_param *par)
{
const struct sk_buff *skb = *pskb;
const struct iphdr *iph = ip_hdr(skb);

View File

@@ -51,8 +51,8 @@ tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info)
return false;
dst_release(skb_dst(skb));
skb_dst_set(skb, &rt->u.dst);
skb->dev = rt->u.dst.dev;
skb_dst_set(skb, rt_dst(rt));
skb->dev = rt_dst(rt)->dev;
skb->protocol = htons(ETH_P_IP);
return true;
}
@@ -103,7 +103,7 @@ static void tee_tg_send(struct sk_buff *skb)
}
static unsigned int
tee_tg4(struct sk_buff **pskb, const struct xt_target_param *par)
tee_tg4(struct sk_buff **pskb, const struct xt_action_param *par)
{
const struct xt_tee_tginfo *info = par->targinfo;
struct sk_buff *skb = *pskb;
@@ -205,7 +205,7 @@ tee_tg_route6(struct sk_buff *skb, const struct xt_tee_tginfo *info)
}
static unsigned int
tee_tg6(struct sk_buff **pskb, const struct xt_target_param *par)
tee_tg6(struct sk_buff **pskb, const struct xt_action_param *par)
{
const struct xt_tee_tginfo *info = par->targinfo;
struct sk_buff *skb = *pskb;

View File

@@ -96,7 +96,7 @@ static int condition_proc_write(struct file *file, const char __user *buffer,
}
static bool
condition_mt(const struct sk_buff *skb, const struct xt_match_param *par)
condition_mt(const struct sk_buff *skb, struct xt_action_param *par)
{
const struct xt_condition_mtinfo *info = par->matchinfo;
const struct condition_variable *var = info->condvar;

View File

@@ -60,7 +60,7 @@ static uint8_t mf_low(uint32_t tx, uint32_t mini, uint32_t maxi)
}
static bool
fuzzy_mt(const struct sk_buff *skb, const struct xt_match_param *par)
fuzzy_mt(const struct sk_buff *skb, struct xt_action_param *par)
{
struct xt_fuzzy_mtinfo *info = (void *)par->matchinfo;
unsigned long amount;

View File

@@ -126,13 +126,13 @@ static bool geoip_bsearch(const struct geoip_subnet *range,
{
int mid;
if (hi < lo)
if (hi <= lo)
return false;
mid = (lo + hi) / 2;
if (range[mid].begin <= addr && addr <= range[mid].end)
return true;
if (range[mid].begin > addr)
return geoip_bsearch(range, addr, lo, mid - 1);
return geoip_bsearch(range, addr, lo, mid);
else if (range[mid].end < addr)
return geoip_bsearch(range, addr, mid + 1, hi);
@@ -141,7 +141,7 @@ static bool geoip_bsearch(const struct geoip_subnet *range,
}
static bool
xt_geoip_mt(const struct sk_buff *skb, const struct xt_match_param *par)
xt_geoip_mt(const struct sk_buff *skb, struct xt_action_param *par)
{
const struct xt_geoip_match_info *info = par->matchinfo;
const struct geoip_country_kernel *node;

View File

@@ -41,7 +41,7 @@ static const struct xt_iface_flag_pairs xt_iface_lookup[] =
};
static bool xt_iface_mt(const struct sk_buff *skb,
const struct xt_match_param *par)
struct xt_action_param *par)
{
const struct xt_iface_mtinfo *info = par->matchinfo;
struct net_device *dev;

View File

@@ -808,7 +808,7 @@ static const struct {
};
static bool
ipp2p_mt(const struct sk_buff *skb, const struct xt_match_param *par)
ipp2p_mt(const struct sk_buff *skb, struct xt_action_param *par)
{
const struct ipt_p2p_info *info = par->matchinfo;
const unsigned char *haystack;

View File

@@ -29,7 +29,7 @@ static uint32_t ipv4options_rd(const uint8_t *data, int len)
}
static bool ipv4options_mt(const struct sk_buff *skb,
const struct xt_match_param *par)
struct xt_action_param *par)
{
const struct xt_ipv4options_mtinfo1 *info = par->matchinfo;
const struct iphdr *iph = ip_hdr(skb);

View File

@@ -137,7 +137,7 @@ static bool xtlength_layer7(unsigned int *length, const struct sk_buff *skb,
}
static bool
length2_mt(const struct sk_buff *skb, const struct xt_match_param *par)
length2_mt(const struct sk_buff *skb, struct xt_action_param *par)
{
const struct xt_length_mtinfo2 *info = par->matchinfo;
const struct iphdr *iph = ip_hdr(skb);
@@ -198,7 +198,7 @@ llayer4_proto(const struct sk_buff *skb, unsigned int *offset, bool *hotdrop)
}
static bool
length2_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
length2_mt6(const struct sk_buff *skb, struct xt_action_param *par)
{
const struct xt_length_mtinfo2 *info = par->matchinfo;
const struct ipv6hdr *iph = ipv6_hdr(skb);
@@ -207,9 +207,13 @@ length2_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
bool hit = true;
if (info->flags & XT_LENGTH_LAYER3) {
len = sizeof(struct ipv6hdr) + ntohs(iph->payload_len);
if (iph->payload_len == 0)
/* Jumbogram */
len = skb->len;
else
len = sizeof(struct ipv6hdr) + ntohs(iph->payload_len);
} else {
l4proto = llayer4_proto(skb, &thoff, par->hotdrop);
l4proto = llayer4_proto(skb, &thoff, &par->hotdrop);
if (l4proto == NEXTHDR_MAX)
return false;
if (info->flags & XT_LENGTH_LAYER4)

View File

@@ -171,7 +171,7 @@ static inline unsigned int lscan_mt_full(int mark,
}
static bool
lscan_mt(const struct sk_buff *skb, const struct xt_match_param *par)
lscan_mt(const struct sk_buff *skb, struct xt_action_param *par)
{
const struct xt_lscan_mtinfo *info = par->matchinfo;
enum ip_conntrack_info ctstate;

View File

@@ -100,7 +100,7 @@ static inline int hashfunc(struct in_addr addr)
}
static bool
xt_psd_match(const struct sk_buff *pskb, const struct xt_match_param *match)
xt_psd_match(const struct sk_buff *pskb, struct xt_action_param *match)
{
const struct iphdr *iph;
const struct tcphdr *tcph;

View File

@@ -153,15 +153,13 @@ static int quota_mt2_check(const struct xt_mtchk_param *par)
q->name[sizeof(q->name)-1] = '\0';
if (*q->name == '.' || strchr(q->name, '/') != NULL) {
printk(KERN_ERR "xt_quota<%u>: illegal name\n",
par->match->revision);
printk(KERN_ERR "xt_quota.3: illegal name\n");
return -EINVAL;
}
q->master = q2_get_counter(q);
if (q->master == NULL) {
printk(KERN_ERR "xt_quota<%u>: memory alloc failure\n",
par->match->revision);
printk(KERN_ERR "xt_quota.3: memory alloc failure\n");
return -ENOMEM;
}
@@ -191,7 +189,7 @@ static void quota_mt2_destroy(const struct xt_mtdtor_param *par)
}
static bool
quota_mt2(const struct sk_buff *skb, const struct xt_match_param *par)
quota_mt2(const struct sk_buff *skb, struct xt_action_param *par)
{
struct xt_quota_mtinfo2 *q = (void *)par->matchinfo;
struct xt_quota_counter *e = q->master;

6
geoip/.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
/BE
/LE
/GeoIPCountryCSV.zip
/GeoIPCountryWhois.csv
/GeoIPv6.csv
/GeoIPv6.csv.gz

3
geoip/Makefile.am Normal file
View File

@@ -0,0 +1,3 @@
# -*- Makefile -*-
pkglibexec_SCRIPTS = geoip_build_db.pl geoip_download.sh

54
geoip/geoip_build_db.pl Executable file
View File

@@ -0,0 +1,54 @@
#!/usr/bin/perl
#
# Converter for MaxMind CSV database to binary, for xt_geoip
# Copyright © Jan Engelhardt <jengelh@medozas.de>, 2008
#
# Use -b argument to create big-endian tables.
#
use Getopt::Long;
use IO::Handle;
use Text::CSV_XS; # or trade for Text::CSV
use strict;
my %country;
my %names;
my $csv = Text::CSV_XS->new({binary => 0, eol => $/}); # or Text::CSV
my $mode = "VV";
my $target_dir = ".";
&Getopt::Long::Configure(qw(bundling));
&GetOptions(
"D=s" => \$target_dir,
"b" => sub { $mode = "NN"; },
);
if (!-d $target_dir) {
print STDERR "Target directory $target_dir does not exist.\n";
exit 1;
}
while (my $row = $csv->getline(*ARGV)) {
if (!defined($country{$row->[4]})) {
$country{$row->[4]} = [];
$names{$row->[4]} = $row->[5];
}
my $c = $country{$row->[4]};
push(@$c, [$row->[2], $row->[3]]);
if ($. % 4096 == 0) {
print STDERR "\r\e[2K$. entries";
}
}
print STDERR "\r\e[2K$. entries total\n";
foreach my $iso_code (sort keys %country) {
printf "%5u ranges for %s %s\n",
scalar(@{$country{$iso_code}}),
$iso_code, $names{$iso_code};
open(my $fh, "> $target_dir/".uc($iso_code).".iv0");
foreach my $range (@{$country{$iso_code}}) {
print $fh pack($mode, $range->[0], $range->[1]);
}
close $fh;
}

8
geoip/geoip_download.sh Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/sh
rm -f GeoIPv6.csv{,.gz} GeoIPCountryCSV.zip GeoIPCountryWhois.csv;
wget \
http://geolite.maxmind.com/download/geoip/database/GeoIPv6.csv.gz \
http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip;
gzip -d GeoIPv6.csv.gz;
unzip GeoIPCountryCSV.zip;

View File

@@ -2,6 +2,7 @@
#
build_ACCOUNT=m
build_CHAOS=m
build_CHECKSUM=m
build_DELUDE=m
build_DHCPMAC=m
build_ECHO=

View File

@@ -6,7 +6,7 @@ use strict;
&main(\@ARGV);
sub main ($)
sub main
{
local *FH;
@@ -30,7 +30,7 @@ sub main ($)
close FH;
}
sub process_index ($)
sub process_index
{
my $top = shift @_;
my($agent, $res, $url);
@@ -68,14 +68,14 @@ sub process_index ($)
}
}
sub slash_remove ($)
sub slash_remove
{
my $s = shift @_;
$s =~ s{(\w+://)(.*)}{$1.&slash_remove2($2)}eg;
return $s;
}
sub slash_remove2 ($)
sub slash_remove2
{
my $s = shift @_;
$s =~ s{/+}{/}g;

View File

@@ -1,4 +1,4 @@
.TH xtables-addons 8 "v1.26 (2010-04-30)" "" "v1.26 (2010-04-30)"
.TH xtables-addons 8 "v1.29 (2010-09-29)" "" "v1.29 (2010-09-29)"
.SH Name
Xtables-addons \(em additional extensions for iptables, ip6tables, etc.
.SH Targets