Compare commits

..

158 Commits
v1.17 ... v1.19

Author SHA1 Message Date
Jan Engelhardt
bc5a7d8e3a Xtables-addons 1.19 2009-10-12 18:57:08 +02:00
Jan Engelhardt
0628857068 Merge branch 'pknock' 2009-10-12 18:56:10 +02:00
Jan Engelhardt
de4f6e8994 pknlusr: fix up standard errors in pknlusr 2009-10-12 18:53:03 +02:00
Jan Engelhardt
439dd913f1 pknock: fix pknlusr compile warnings
pknlusr.c: In function "main":
pknlusr.c:81:25: warning: cast to pointer from integer of different size
pknlusr.c:81:7: warning: cast to pointer from integer of different size
2009-10-12 18:52:02 +02:00
Jan Rafaj
9568747d94 pknock: import userspace netlink listener program 2009-10-12 18:49:02 +02:00
Jan Engelhardt
20365cf762 pknock: manpage writing style updates 2009-10-12 18:49:02 +02:00
Jan Rafaj
fa601c0fa7 pknock: add manpage for pknock 2009-10-12 18:49:01 +02:00
Jan Engelhardt
00573d0172 Merge branch 'pknock' 2009-10-12 18:46:53 +02:00
Jan Engelhardt
c7036a88f1 doc: pknock changelog 2009-10-12 18:40:34 +02:00
Jan Rafaj
af21c1d369 pknock: preserve time/autoclose values for rules added in arbitrary order
Handle specific case when someone put a (master) --opensecret
--closesecret rule after a --checkip rule with the same name.

Signed-off-by: Jan Rafaj <jr+netfilter-devel@cedric.unob.cz>
2009-10-12 18:36:24 +02:00
Jan Rafaj
b132101b63 pknock: check interknock time only for !ST_ALLOWED peers
Fixes a bug whereby an ST_ALLOWED peer existing for a time greater
than gc_expir_time would be gc-deleted, because both
!has_logged_during_this_minute(peer) and
is_interknock_time_exceeded(peer, rule->max_time) would be satisfied
for ST_ALLOWED hosts.

We also no longer test for !has_logged_during_this_minute(peer) in
peer_gc(), since there is really no need for this: the anti-spoof
minute check is performed (and subsequent remove_peer(peer) called if
needed) for each passing UDP-mode peer with expired autoclose in
pknock_mt(), given that --autoclose has been specified. If autoclose
has not been set, it will be subject to reset_knock_status(peer)
called from knock_mt() upon receiving the first closing secret - so it
is still guaranteed to disappear at the closest opportunity.

Signed-off-by: Jan Rafaj <jr+netfilter-devel@cedric.unob.cz>
2009-10-12 17:21:32 +02:00
Jan Rafaj
71beab548d pknock: change comments and debug statements to give more appropriate help
Renames:
	update_rule_timer() -> update_gc_rule_timer()
	is_time_exceeded()  -> is_interknock_time_exceeded()

Changed some debug messages and comments to give more appropriate meanings.

Signed-off-by: Jan Rafaj <jr+netfilter-devel@cedric.unob.cz>
2009-10-12 17:18:29 +02:00
Jan Engelhardt
6de54e5fcd pknock: shrink struct peer 2009-10-12 17:01:10 +02:00
Jan Rafaj
a921427746 pknock: display only pknock mode and state relevant information in procfs
Signed-off-by: Jan Rafaj <jr+netfilter-devel@cedric.unob.cz>
2009-10-12 16:58:31 +02:00
Jan Rafaj
2b2b6246f0 pknock: Make non-zero time mandatory for TCP mode
This avoids DDoS on the first-in-sequence TCP knockport, which would
otherwise fill up the peer table permanently - especially if the user
does not specify --autoclose - and would thus cause permanent pknock
DoS.

Signed-off-by: Jan Rafaj <jr+netfilter-devel@cedric.unob.cz>
2009-10-12 01:24:41 +02:00
Jan Engelhardt
98e5dfd6ef pknock: remove some #ifdef PK_CRYPTO guards
A number of guarded places do not use any crypto functions. So the
userspace does not pass in an info with --opensecret/--closesecret
defined.
2009-10-12 01:21:26 +02:00
Jan Rafaj
9e5c2e7ee9 pknock: implement automatic closing
Added the optional "--autoclose" parameter (takes minutes) that
closes the pknock-opened rule in a specified time.

Signed-off-by: Jan Rafaj <jr+netfilter-devel@cedric.unob.cz>
2009-10-12 01:13:00 +02:00
Jan Rafaj
284c0e9493 pknock: provide better help text for --time option
Signed-off-by: Jan Rafaj <jr+netfilter-devel@cedric.unob.cz>
2009-10-12 00:58:32 +02:00
Jan Engelhardt
5284b5db92 pknock: remove redundant final check for any-option
Just below the check that was just removed, the presence of --name is
tested for, as --name is always required. That makes the (flags == 0)
check superfluous, because non-zeroness is ensured by the name check.
2009-10-12 00:56:55 +02:00
Jan Rafaj
36035d52d3 pknock: purge void --secure option from help text
Signed-off-by: Jan Rafaj <jr+netfilter-devel@cedric.unob.cz>
2009-10-12 00:51:41 +02:00
Jan Engelhardt
4d94687c15 pknock: use C99 initializers for pknock_mt_opts 2009-10-12 00:50:55 +02:00
Jan Engelhardt
7070678ab4 pknock: remove redundant --chkip parameter
Similar to commit v1.18-56-g35b00f8, one option for one thing
really is enough.
2009-10-12 00:48:37 +02:00
Jan Rafaj
f6281d498c pknock: use kernel's get_seconds() directly instead of wrapper
Use kernel's get_seconds() directly instead of the
get_epoch_minute() wrapper.

Signed-off-by: Jan Rafaj <jr+netfilter-devel@cedric.unob.cz>
2009-10-12 00:46:02 +02:00
Jan Rafaj
2cab32596a pknock: replace id_port_knocked with accepted_knock_count
Gives a better sense of the member's use.

Signed-off-by: Jan Rafaj <jr+netfilter-devel@cedric.unob.cz>
2009-10-12 00:43:50 +02:00
Jan Rafaj
08f6a82bdc pknock: avoid fillup of peer table during DDoS
In TCP --strict mode, forget the peer which sent the wrong knock in a
sequence, rather than resetting its status to ST_INIT. This avoids
filling up the peer table (which would lead to pknock DoS) in case of
a DDoS attack performed by a set of port-scanning malicious hosts.
2009-10-11 01:48:20 +02:00
Jan Engelhardt
82a8524f1a pknock: add CONNECTOR guards 2009-10-09 18:15:27 +02:00
Jan Engelhardt
6bb354d3f0 pknock: add Kconfig file 2009-10-09 18:11:49 +02:00
Jan Engelhardt
5184176c3b pknock: move into separate directory
There will be a number of pknock-related tools, e.g. the trigger
programs, so move that out to its own directory.
2009-10-09 17:50:05 +02:00
Jan Engelhardt
430723ece1 ipp2p: try to address underflows
Report by: Christian Blum <chrblum@users.sourceforge.net>

"I have found that they panic in an interrupt within xt_ipp2p, function
search_all_gnu(). It's a bounds checking problem; when I add this [a
check for plen >= 65535] at the beginning [of the function] the
servers run fine (very similar to find_all_kazaa())."
2009-10-08 17:26:36 +02:00
Jan Engelhardt
f1dc7f960c pknock: peer can never be NULL in the hash iterator
Given that pos is non-NULL, list_entry won't make it NULL.
2009-10-07 23:59:44 +02:00
Jan Engelhardt
370f47b000 pknock: reduce indent in remove_rule 2009-10-07 23:59:05 +02:00
Jan Engelhardt
8e812620f0 pknock: avoid crash on memory allocation failure and fix memleak
If rule->peer_head==NULL due to an unsuccessful allocation, peer_gc
(and perhaps other places) may crash when they try to access it.
Since I see no deferred retry for allocation, the only option is to
fail in add_rule, clean it up, and return false instead.
Independent of that problem, it also needs to free peer_head in case
the status_proc allocation fails.
2009-10-07 01:12:03 +02:00
Jan Engelhardt
204b612e23 pknock: add_rule must happen after info struct checks
This avoids unnecessarily creating pknock rules if there is an error
with any of the match parameters.
2009-10-07 01:12:03 +02:00
Jan Engelhardt
c2c86f4b3d pknock: remove old-style intraposition negation support 2009-10-07 01:12:03 +02:00
Jan Engelhardt
379e685b0f doc: update changelog
Sometimes I forget to adjust it with the particular commit and then
this piles up a little..
2009-10-07 00:10:45 +02:00
Jan Engelhardt
69dd0686e2 doc: remove --with-ksource from help text
--with-ksource should almost never be needed, so do not visibily
offer it.
2009-10-07 00:07:24 +02:00
Jan Engelhardt
48325a209e build: support for Linux 2.6.32 2009-10-07 00:02:56 +02:00
Jan Engelhardt
96f501ab89 ACCOUNT: move Kconfig file 2009-10-06 23:56:38 +02:00
Jan Engelhardt
3c1bf73e8e ACCOUNT: mark reg structure __read_mostly 2009-10-06 23:42:48 +02:00
Jan Rafaj
e0276b4875 pknock: disallow running peer_gc too early
It is no longer possible to specify gc_expir_time with a time lower
than its default value (65000 msecs). This is to avoid running
peer_gc() earlier than 1 minute [well, 65 s actually] in the future,
which would otherwise render anti-spoof protection in SPA mode
non-functional.
2009-10-04 21:00:04 +02:00
Jan Rafaj
1bc7f1be67 pknock: add module parameter descriptions 2009-10-04 21:00:04 +02:00
Jan Engelhardt
3c3adcbd07 pknock: remove some extraneous messages and source lines
- $Id$ in a comment is pointless.
- remove unneeded/commented-out includes.
- remove warning messages on allocation failure
  (if that happens it is almost too late anyway;
  not wanting to spam the logs)
- remove warning messages about unhandled packets
  (attacker filling up logs)
2009-10-04 21:00:01 +02:00
Jan Engelhardt
da6a9b932c pknock: use NIPQUAD_FMT 2009-10-04 00:42:13 +02:00
Jan Engelhardt
5f290cd4a0 pknock: mark peer address as __be32
Since the address is now stored in its original network byte order,
let's annotate that this is indeed the case.
2009-10-04 00:42:13 +02:00
Jan Rafaj
181a9cab43 pknock: store peer address in network byte order
The conversions from and to host order can be saved, as nothing
really depends on them.
2009-10-04 00:42:13 +02:00
Jan Rafaj
a819458cba pknock: do call sg_init_table 2009-10-04 00:42:13 +02:00
Jan Engelhardt
654862af21 pknock: use more efficient method to obtain seconds 2009-10-04 00:42:13 +02:00
Jan Rafaj
0d8ae29a60 pknock: "strict" and "checkip" flags were not displayed in iptables -L 2009-10-04 00:42:13 +02:00
Jan Engelhardt
e05a4d9586 pknock: use sizeof() where meaningful 2009-10-04 00:42:11 +02:00
Jan Engelhardt
0541154a5e doc: properly escape non-hyphens 2009-10-03 21:41:29 +02:00
Jan Rafaj
00199427ac pknock: rename symbols in libxt_pknock 2009-10-03 13:30:56 +02:00
Jan Engelhardt
35b00f8c3f pknock: remove redundant --t parameter
One can already specify --t on the command line as a synonym for
--time because getopt already allows unambiguous abbrevations.
2009-10-03 13:08:26 +02:00
Jan Engelhardt
1f3150bdf9 pknock: remove trailing whitespace 2009-10-03 01:43:00 +02:00
Jan Engelhardt
13c73af796 pknock: remove unneeded braces 2009-10-03 01:26:31 +02:00
Jan Engelhardt
ba9a3efec1 pknock: use preincrements where possible
Preincrements are much less error-prone and even do not need extra
parentheses.
2009-10-03 01:26:31 +02:00
Jan Engelhardt
f474c7d4d4 pknock: rename IPT_PKNOCK_* -> XT_PKNOCK_* 2009-10-03 01:26:31 +02:00
Jan Engelhardt
4a350ddd03 pknock: move more kernel parts from include file to .c
All of this does not seem to have a userspace part.
2009-10-03 01:26:31 +02:00
Jan Engelhardt
628d137f12 pknock: rename struct ipt_pknock -> xt_pknock_mtinfo
Streamline symbols; use xt_*_mtinfo as other modules do.
2009-10-03 01:26:31 +02:00
Jan Engelhardt
28ecf45548 pknock: redo inline hints
The compiler is usually smart enough to decide this on its own.
Some functions however do not warrant even the hint keyword.
2009-10-03 01:26:31 +02:00
Jan Engelhardt
58839b9b86 pknock: use bools for two-state ints 2009-10-03 01:26:31 +02:00
Jan Engelhardt
e436948ebd pknock: use explicit tests for non-bool types 2009-10-03 01:26:30 +02:00
Jan Engelhardt
79d54ebd7c pknock: split long instructions, esp. allocations in if() 2009-10-03 01:26:28 +02:00
Jan Engelhardt
0b64b27172 build: ignore srcdir layout on install
Kbuild would install the .ko module files relative to their source
directory, i.e.

  extensions/xt_quota.ko
  -> /lib/modules/%/extra/xt_quota.ko
  extensions/ACCOUNT/xt_ACCOUNT.ko
  -> /lib/modules/%/extra/ACCOUNT/xt_ACCOUNT.ko

Add a hack to Makefile.am so that it all goes into extra/ only,
without any further subdirectories created. This is strictly a hack
as it pokes with Kbuild internals.

Putting the ext-mod-dir override into extensions/Kbuild would not do,
it is overridden by $linux/scripts/Makefile.modinst, so a higher
priority override is needed (make command line by means of
Makefile.am invoking make).
2009-10-01 00:08:33 +02:00
Jan Engelhardt
d116000784 pknock: fix return values and memleak in has_secret
First, there is a memory leak - when the crypto functions fail,
hexresult was not freed. Second, in that error case, the return value
is simply passed up to the caller, ignoring the different meanings of
0 and 1 between crypto and pknock.
2009-09-30 01:19:59 +02:00
Jan Engelhardt
4b5f0b12d9 pknock: remove initialization of data where not needed
bss will be set to zero anyway.
For automatic variables, the preinit is not always needed
(gcc will warn about it).
2009-09-30 01:19:58 +02:00
Jan Engelhardt
c8dde526f2 pknock: use unsigned qualifiers where they are due 2009-09-30 01:19:39 +02:00
Jan Engelhardt
3058e42a21 pknock: remove pointless casts 2009-09-30 00:49:30 +02:00
Jan Engelhardt
40b30f7f27 pknock: add const qualifiers 2009-09-30 00:49:29 +02:00
Jan Engelhardt
aaad5f53ac pknock: remove pointless sizeof(char)
sizeof(char) is defined to be 1, anyway.
2009-09-30 00:09:07 +02:00
Jan Engelhardt
db1057158f pknock: return -ENXIO for problems during init
Some functions like the crypto init or proc_mkdir do not return an
error value. Replace the -1, which is actually EPERM, and looks a
little out of place, and use ENXIO instead. (After all, the requested
objects were not there after the request of initialization.)
2009-09-30 00:05:42 +02:00
Jan Rafaj
713c31e8f7 pknock: guard off crypto code from kernels before 2.6.19 2009-09-29 23:47:03 +02:00
Jan Engelhardt
e5ffb39750 pknock: rename DEBUGP to pk_debug and always enable
Since pr_debug depends on #if DEBUG anyway, there is no need to
contain DEBUGP/pk_debug within a further if. Rename from DEBUGP to
pk_debug, because DEBUGP is flagged by Xtables-addons (- and that's
good so, because often DEBUGPs should have been pr_debug instead).
2009-09-29 23:45:29 +02:00
Jan Rafaj
19067393b6 pknock: replace printks by pr_debug
The printk calls were protected using #if DEBUG anyway, so they can
just be changed to pr_debug. pr_debug also depends on #if DEBUG, and
takes care of the module prefix.
2009-09-29 23:45:29 +02:00
Jan Engelhardt
1de82a88a1 pknock: avoid accidental deletion of rules
If DEBUG was not defined, and no rule was effectively found, the
"rule" variable may still be non-NULL, and possibly cause deletion.
Therefore, always check for the rule having been found.
2009-09-29 23:45:29 +02:00
Jan Engelhardt
9928c864ab pknock: drop evil-tinygram warning messages
The duprintf macro then also becomes unneeded.
2009-09-29 23:45:28 +02:00
Jan Engelhardt
45515a0afd pknock: bump internal match revision number
Do this so that previous iptables installations do not mistakenly
operate with our new xt_pknock.
2009-09-29 23:45:28 +02:00
Jan Engelhardt
75f80fa8f8 pknock: move struct ipt_pknock_crypto to xt_pknock.c
It is only used in xt_pknock.c, and only once, so also make it an
anonymous struct.
2009-09-29 23:45:28 +02:00
Jan Engelhardt
d8dc72d151 pknock: only use size-fixated types
Types with variadic size are a no-no.
2009-09-29 23:36:53 +02:00
Jan Engelhardt
cee3d25d49 pknock: improve sizeof(struct ipt_pknock) by relayouting members
Stuffing struct holes as reported by pahole(1).
2009-09-29 19:36:14 +02:00
Jan Engelhardt
afbeb2fb47 pknock: improve sizeof(struct ipt_pknock) by using "even" field sizes
The field sizes were 33, which makes for lots of padding holes.
2009-09-29 19:36:14 +02:00
Jan Rafaj
c0dc0858de pknock: renaming of functions and prefix-name 2009-09-29 19:36:01 +02:00
Jan Rafaj
b04317576b pknock: add MODULE_ALIAS for pknock
Needed for autoloading.
2009-09-29 15:05:05 +02:00
Jan Rafaj
af2bbf0352 pknock: fit to Xtables-addons API 2009-09-29 15:03:45 +02:00
Jan Engelhardt
db9bb2778d pknock: import pknock trunk@463 2009-09-29 14:00:59 +02:00
Jan Engelhardt
674560d2d9 Merge branch 'psd' 2009-09-26 00:19:57 +02:00
Jan Engelhardt
7ab033e64c Update .gitignore files 2009-09-26 00:13:15 +02:00
Jan Engelhardt
3131448443 build: require at least automake 1.10
Automake 1.10 seems to be the first to set abs_srcdir and such.
2009-09-26 00:11:35 +02:00
Jan Engelhardt
71322e614c build: restore parallel build capability
It seems that ${MAKE} must be in the first expansion level.
2009-09-25 21:18:09 +02:00
Jan Engelhardt
d3fdfe08dd Merge branch 'ACCOUNT' 2009-09-25 15:07:46 +02:00
Jan Engelhardt
46f9ddbf59 ACCOUNT: move manpage into ACCOUNT/ directory 2009-09-24 01:52:42 +02:00
Jan Engelhardt
e37985b527 ACCOUNT/userspace: use bool type 2009-09-24 01:48:16 +02:00
Jan Engelhardt
0ccd55abd9 ACCOUNT/userspace: remove pointless casts 2009-09-24 01:46:56 +02:00
Jan Engelhardt
60123a8c07 ACCOUNT/userspace: remove static zero initializers 2009-09-24 01:46:56 +02:00
Jan Engelhardt
504f1089fb ACCOUNT/userspace: simple reformat, use tabs instead of spaces 2009-09-24 01:46:55 +02:00
Jan Engelhardt
e119350000 ACCOUNT/userspace: remove trailing whitespace 2009-09-24 01:35:45 +02:00
Jan Rafaj
a260e3349f ACCOUNT: import userspace utilities 2009-09-24 01:27:11 +02:00
Jan Engelhardt
5cb36ed213 ACCOUNT: move xt_ACCOUNT into its own subdirectory
Will be adding related userspace programs shortly, and an extra
directory for the same reason it is for ipset/.
2009-09-24 01:00:15 +02:00
Jan Engelhardt
1a5b9f0e02 Merge branch 'master' into ACCOUNT 2009-09-24 01:00:10 +02:00
Jan Engelhardt
2c53605084 build: enable automake for extensions/ directory
Because we are likely to be having more userspace programs soon, and
reproducing manual makefiles is a bad idea, make extensions/ ready
for automake traversal. The build pattern now is:

1.  toplevel Makefile.am starts off with extensions/Makefile.am

2.  Makefile.am

    a.  builds programs in current directory

    b.  runs Kbuild
        - only from extensions/Makefile.am
          (so it does not get reinvoked from case 2cII)
        - Kbuild recurses on its own

    c.  runs Mbuild
        I.  builds iptables shared libraries in current directory
        II. runs Makefile.am in each subdir (goto step 2.)
2009-09-24 00:59:59 +02:00
Jan Engelhardt
537f25dbad build: use automake in ipset/ 2009-09-19 20:11:59 +02:00
Jan Rafaj
63a1e5329f ACCOUNT: add Kconfig file 2009-09-18 15:46:39 +02:00
Jan Engelhardt
b0a6111054 build: stable version number detection fix 2009-09-12 02:42:40 +02:00
Jan Engelhardt
b07434386b ipset: fix compile error on 2.6.31-rt
ip_set.c:42:8: warning: type defaults to 'int' in declaration of
'DECLARE_MUTEX'

2.6.31-rt has cleaned up the naming mess in semaphore.h. Without
making use of #if hackery, we can use struct semaphore as declaration
plus an explicit sema_init() call.
2009-09-12 02:41:36 +02:00
Jan Engelhardt
0c963dee06 ACCOUNT: fix pre-2.6.27 compilation error
xt_ACCOUNT.c:33:29: fatal error: linux/semaphore.h: No such file or
directory compilation terminated.
2009-09-12 02:27:26 +02:00
Jan Engelhardt
09bfb8496e condition: fix compile error on 2.6.31-rt
xt_condition.c:58:8: warning: type defaults to 'int' in declaration
of 'DECLARE_MUTEX'
2009-09-12 02:24:13 +02:00
Jan Engelhardt
9d1afc4268 ACCOUNT: fix compile error on realtime kernels
xt_ACCOUNT.c:1040: error: implicit declaration of function 'init_MUTEX'
2009-09-12 01:19:22 +02:00
Florian Westphal
342ccf62b2 psd: byteswap constant value instead
htons(CONSTANT) is computed at compile time.
reduces .text by 4 bytes on x86.

Signed-off-by: Florian Westphal <fwestphal@astaro.com>
2009-09-11 21:38:23 +02:00
Florian Westphal
adabd647b1 psd: use skb_header_pointer
Do not rely on tcphdr being in the linear area.

Signed-off-by: Florian Westphal <fwestphal@astaro.com>
2009-09-11 21:38:00 +02:00
Jan Engelhardt
26f25a43a9 Xtables-addons 1.18 2009-09-09 17:37:07 +02:00
Jan Engelhardt
bcda21a2b0 Merge branch 'psd' 2009-09-09 17:27:28 +02:00
Jan Engelhardt
4e6bc8af95 Merge branch 'ACCOUNT' 2009-09-09 17:26:00 +02:00
Jan Engelhardt
bd4be0d991 ACCOUNT: remove pointless casts 2009-09-05 04:39:00 +02:00
Jan Engelhardt
1f736c8203 ACCOUNT: remove static initializers to zero
These are not needed, .bss is zeroed.
2009-09-05 04:39:00 +02:00
Jan Rafaj
90fa3ab9e2 ACCOUNT: tweak base ctl number for setsockopts
IPT_BASE_CTL+3 is already used IPT_SO_GET_REVISION_TARGET and
therefore must not be used by extensions.
2009-09-05 04:38:57 +02:00
Jan Engelhardt
fd82a312d6 Merge branch 'ipset' 2009-09-05 03:49:47 +02:00
Jan Engelhardt
27c1676821 ipset: fix compile error with 2.6.20
$e/ipset/ip_set_iptree.c: In function "iptree_test":
$e/ipset/ip_set_iptree.c:84:6: warning: implicit declaration of
function "time_after"
$e/ipset/ip_set_iptree.c:84:39: error: "jiffies" undeclared (first
use in this function)
$e/ipset/ip_set_iptree.c:84:39: error: (Each undeclared identifier is
reported only once
$e/ipset/ip_set_iptree.c:84:39: error: for each function it appears
in.)
$e/ipset/ip_set_iptree.c: In function "iptree_add":
$e/ipset/ip_set_iptree.c:130:57: error: "jiffies" undeclared (first
use in this function)
$e/ipset/ip_set_iptree.c:134:48: error: "HZ" undeclared (first use in
this function)
$e/ipset/ip_set_iptree.c: In function "ip_tree_gc":
$e/ipset/ip_set_iptree.c:214:8: warning: implicit declaration of
function "time_before"
$e/ipset/ip_set_iptree.c:214:42: error: "jiffies" undeclared (first
use in this function)
$e/ipset/ip_set_iptree.c:258:49: error: "HZ" undeclared (first use in
this function)
$e/ipset/ip_set_iptree.c: In function "init_gc_timer":
$e/ipset/ip_set_iptree.c:274:20: error: "jiffies" undeclared (first
use in this function)
$e/ipset/ip_set_iptree.c:274:49: error: "HZ" undeclared (first use in
this function)
$e/ipset/ip_set_iptree.c: In function "iptree_list_members_size":
$e/ipset/ip_set_iptree.c:380:58: error: "jiffies" undeclared (first
use in this function)
$e/ipset/ip_set_iptree.c: In function "iptree_list_members":
$e/ipset/ip_set_iptree.c:407:58: error: "jiffies" undeclared (first
use in this function)
$e/ipset/ip_set_iptree.c:411:37: error: "HZ" undeclared (first use in
this function)

$e/ipset/ip_set_iptreemap.c: In function "gc":
$e/ipset/ip_set_iptreemap.c:456:20: error: "jiffies" undeclared
(first use in this function)
$e/ipset/ip_set_iptreemap.c:456:20: error: (Each undeclared
identifier is reported only once
$e/ipset/ip_set_iptreemap.c:456:20: error: for each function it
appears in.)
$e/ipset/ip_set_iptreemap.c:456:49: error: "HZ" undeclared (first use
in this function)
$e/ipset/ip_set_iptreemap.c: In function "init_gc_timer":
$e/ipset/ip_set_iptreemap.c:468:20: error: "jiffies" undeclared
(first use in this function)
$e/ipset/ip_set_iptreemap.c:468:49: error: "HZ" undeclared (first use
in this function)
2009-09-05 03:49:37 +02:00
Jan Engelhardt
3e26335cbd ipset: fast forward to v3.2 2009-09-05 03:49:37 +02:00
Jan Rafaj
f4b96672ef ACCOUNT: add kernel module metadata and alias 2009-09-05 03:40:47 +02:00
Jan Engelhardt
c3d080f21a ACCOUNT: manpage updates
- expand "f.e."
- escape dashes where appropriate
- fB/fI formatting
2009-09-05 03:40:47 +02:00
Jan Rafaj
cb268031b7 ACCOUNT: supply manpage 2009-09-05 03:40:47 +02:00
Jan Engelhardt
ac44a5a1fe ACCOUNT: direct-inline two short functions 2009-09-05 03:40:47 +02:00
Jan Rafaj
a3baa78ae2 ACCOUNT: remove compat glue from libxt_ACCOUNT 2009-09-05 03:40:47 +02:00
Jan Rafaj
47e002127c ACCOUNT: use non-clashing function names
[jengelh: It is just impossible to set a breakpoint right on functions
if all modules call or/use the same symbol name.]
2009-09-05 03:40:47 +02:00
Jan Rafaj
03363a528a ACCOUNT: utilize compat_xtables.h for backwards compatibility 2009-09-05 03:40:47 +02:00
Jan Rafaj
58b016f0af ACCOUNT: replace own DEBUGP by kernel's pr_debug 2009-09-05 03:40:47 +02:00
Jan Rafaj
8d64e7bd50 ACCOUNT: remove manual compat support 2009-09-05 03:40:47 +02:00
Jan Engelhardt
dd6cb27da4 ACCOUNT: simple reformat, use tabs instead of spaces
The result is not perfect, but at more manageable.
2009-09-05 03:40:46 +02:00
Jan Engelhardt
06c01131e8 ACCOUNT: remove trailing whitespace 2009-09-05 03:38:58 +02:00
Jan Engelhardt
a44c4e4b1d Import ACCOUNT kernel and iptables modules
Reference: git://developer.intra2net.com/ipt_ACCOUNT # v1.15-1-gfb4dd1a
2009-09-05 03:38:31 +02:00
Jan Engelhardt
1fb6f187d3 build: enable fully parallel builds
Make make happy by using ${MAKE} instead of make.
2009-08-28 12:32:52 +02:00
Jan Engelhardt
83e474f9ab psd: move pr_ prefix into pr_fmt 2009-08-28 12:32:23 +02:00
Jan Engelhardt
efd4c91557 psd: style: remove braces for single statements in ifs 2009-08-16 12:40:44 +02:00
Jan Engelhardt
65a257a67d psd: style: add explicit comparisons where not used in bool context 2009-08-14 20:26:37 +02:00
Jan Engelhardt
5b07e04600 psd: style: break double statements 2009-08-14 20:24:36 +02:00
Jan Engelhardt
6b175b40cb psd: jiffies is an unsigned long, fix compiler warning
"jiffies" has always been unsigned long, not clock_t.

xt_psd.c:176:7: warning: comparison of distinct pointer types lacks a cast
2009-08-14 20:19:13 +02:00
Jan Engelhardt
0887365f8b psd: remove whitespace at EOL 2009-08-14 20:15:00 +02:00
Jan Engelhardt
cebadbfcd7 psd: merge into main configuration files
When psd is included in the main tree, it can use the main
configuration files.
2009-08-14 20:12:43 +02:00
Mohd Nawawi Mohamad Jamili
380b1b6997 psd: fix revision mismatch 2009-08-13 13:11:18 +02:00
Jan Engelhardt
8e5219636a psd: tag match reg struct as __read_mostly 2009-08-13 01:04:26 +02:00
Jan Engelhardt
760edd3db6 psd: use fixated types in info struct 2009-08-13 00:52:46 +02:00
Jan Engelhardt
502c1c05aa psd: return correct status from init 2009-08-13 00:46:33 +02:00
Jan Engelhardt
a7ceccc0f4 psd: bss is always zero-initialized 2009-08-13 00:45:52 +02:00
Jan Engelhardt
10bd08d0f3 psd: remove empty checkentry function 2009-08-13 00:44:39 +02:00
Jan Engelhardt
1e5315d338 psd: replace open-coded access by skb handling functions
pskb->network_header would not even compile under older kernels.

This also fixes the compile warning:
xt_psd.c:116:18: warning: cast to pointer from integer of different size
2009-08-13 00:42:01 +02:00
Jan Engelhardt
579484ed70 psd: avoid shadowing of function
ip_hdr and tcp_hdr are actually functions. Because we need them means
they must not be shadowed by variables.
2009-08-13 00:38:39 +02:00
Mohd Nawawi Mohamad Jamili
2aa32d4bce psd: import 20090807 code base 2009-08-12 21:59:33 +02:00
Jan Engelhardt
5aee8738ed quota2: fix invalid page access in cleanup function 2009-08-07 10:35:52 +02:00
Jan Engelhardt
1111edfd85 quota2: change max name length from 31 to 15 2009-07-10 17:21:27 +02:00
Jan Engelhardt
0d47cb8b37 quota2: direct-code XT_QUOTA_COUNTER_NAME_LENGTH 2009-07-10 17:21:12 +02:00
Jan Engelhardt
1c55aec64a quota2: use strtoull instead of strtoul 2009-07-10 17:18:48 +02:00
Jan Engelhardt
dd26ab476c quota2: extend locked period during cleanup 2009-07-04 02:11:25 +02:00
Jan Engelhardt
4bf667d8eb quota2: reduce memory footprint for anonymous counters
48/64 bytes (32/64-bit arch, resp.) per counter.
2009-07-04 01:53:35 +02:00
Jan Engelhardt
0a88bd3435 quota2: consolidate spinlocking calls 2009-07-04 01:31:13 +02:00
Jan Engelhardt
62fb261265 quota2: prefix internal struct name with xt_ 2009-07-04 01:29:32 +02:00
Jan Engelhardt
d97f77a8f5 TEE: spello fix 2009-07-02 04:16:14 +02:00
Jan Engelhardt
822c6bebe2 quota2: support nameless counters 2009-07-02 02:21:11 +02:00
Jan Engelhardt
fdf42a3a50 build: support for Linux 2.6.31-rc1 2009-07-02 01:51:40 +02:00
Jan Engelhardt
6b2ca78af7 build: fix kernel version info 2009-07-02 01:04:48 +02:00
82 changed files with 4861 additions and 442 deletions

7
.gitignore vendored
View File

@@ -6,10 +6,15 @@
.libs
Makefile
Makefile.in
GNUmakefile
/downloads
/Makefile.iptrules
/Makefile.mans
/.*.lst
/matches.man
/targets.man
/aclocal.m4
/autom4te*.cache
/compile

16
INSTALL
View File

@@ -19,6 +19,8 @@ Supported configurations for this release
- CONFIG_NF_CONNTRACK or CONFIG_IP_NF_CONNTRACK
- CONFIG_NF_CONNTRACK_MARK or CONFIG_IP_NF_CONNTRACK_MARK
enabled =y or as module (=m)
- CONFIG_CONNECTOR y/m if you wish to receive userspace
notifications from pknock through netlink/connector
Extra notes:
@@ -46,6 +48,9 @@ Configuring and compiling
/lib/modules/$(running version)/build, which usually points to
the right directory. (If not, you need to install something.)
For RPM building, it should be /usr/src/linux-obj/...
or whatever location the distro makes use of.
--with-xtables=
Specifies the path to the directory where we may find
@@ -55,11 +60,11 @@ Configuring and compiling
include/xtables.h. (The latter to support both standard
/usr/include and the iptables source root.)
--with-libxtdir=
--with-xtlibdir=
Specifies the path to where the newly built extensions should
be installed when `make install` is run. It uses the same
default as the Xtables package, ${libexecdir}/xtables.
default as the Xtables/iptables package, ${libexecdir}/xtables.
If you want to enable debugging, use
@@ -72,15 +77,10 @@ much easier.)
Build-time options
==================
V= controls the kernel's make verbosity.
V= controls the verbosity of make commands.
V=0 "silent" (output filename)
V=1 "verbose" (entire gcc command line)
VU= controls the Xt-a make verbosity.
VU=0 output filename
VU=1 output filename and source file
VU=2 entire gcc command line
Note to distribution packagers
==============================

View File

@@ -5,16 +5,16 @@ SUBDIRS = extensions
man_MANS := xtables-addons.8
xtables-addons.8: ${srcdir}/xtables-addons.8.in extensions/matches.man extensions/targets.man
${am__verbose_GEN}sed -e '/@MATCHES@/ r extensions/matches.man' -e '/@TARGET@/ r extensions/targets.man' $< >$@;
.PHONY: FORCE
FORCE:
extensions/%:
${MAKE} ${AM_MAKEFLAGS} -C $(@D) $(@F)
xtables-addons.8: FORCE
${MAKE} -f Makefile.mans all;
install-exec-local:
install-exec-hook:
depmod -a || :;
config.status: extensions/GNUmakefile.in
config.status: Makefile.iptrules.in
.PHONY: tarball
tarball:

29
Makefile.extra Normal file
View File

@@ -0,0 +1,29 @@
# -*- Makefile -*-
# AUTOMAKE
XA_SRCDIR = ${srcdir}
XA_TOPSRCDIR = ${top_srcdir}
XA_ABSTOPSRCDIR = ${abs_top_srcdir}
export XA_SRCDIR
export XA_TOPSRCDIR
export XA_ABSTOPSRCDIR
_mcall = -f ${top_builddir}/Makefile.iptrules
all-local: user-all-local
install-exec-local: user-install-local
clean-local: user-clean-local
user-all-local:
${MAKE} ${_mcall} all;
# Have no user-install-data-local ATM
user-install-local: user-install-exec-local
user-install-exec-local:
${MAKE} ${_mcall} install;
user-clean-local:
${MAKE} ${_mcall} clean;

59
Makefile.iptrules.in Normal file
View File

@@ -0,0 +1,59 @@
# -*- Makefile -*-
# MANUAL
prefix = @prefix@
exec_prefix = @exec_prefix@
libexecdir = @libexecdir@
xtlibdir = @xtlibdir@
CC = @CC@
CCLD = ${CC}
regular_CFLAGS = @regular_CFLAGS@
xtables_CFLAGS = @xtables_CFLAGS@
AM_CFLAGS = ${regular_CFLAGS} ${xtables_CFLAGS}
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
AM_DEFAULT_VERBOSITY = 0
am__v_CC_0 = @echo " CC " $@;
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_GEN_0 = @echo " GEN " $@;
am__v_SILENT_0 = @
am__v_CC_ = ${am__v_CC_${AM_DEFAULT_VERBOSITY}}
am__v_CCLD_ = ${am__v_CCLD_${AM_DEFAULT_VERBOSITY}}
am__v_GEN_ = ${am__v_GEN_${AM_DEFAULT_VERBOSITY}}
am__v_SILENT_ = ${am__v_SILENT_${AM_DEFAULT_VERBOSITY}}
AM_V_CC = ${am__v_CC_${V}}
AM_V_CCLD = ${am__v_CCLD_${V}}
AM_V_GEN = ${am__v_GEN_${V}}
AM_V_silent = ${am__v_GEN_${V}}
include ${XA_TOPSRCDIR}/mconfig
-include ${XA_TOPSRCDIR}/mconfig.*
include ${XA_SRCDIR}/Mbuild
-include ${XA_SRCDIR}/Mbuild.*
targets := $(filter-out %/,${obj-m})
subdirs_list := $(filter %/,${obj-m})
.SECONDARY:
.PHONY: all install clean
all: ${targets}
@for i in ${subdirs_list}; do ${MAKE} -C $$i; done;
install: ${targets}
@for i in ${subdirs_list}; do ${MAKE} -C $$i $@; done;
install -dm0755 "${DESTDIR}/${xtlibdir}";
install -pm0755 $^ "${DESTDIR}/${xtlibdir}";
clean:
@for i in ${subdirs_list}; do ${MAKE} -C $$i $@; done;
rm -f *.oo *.so;
lib%.so: lib%.oo
${AM_V_CCLD}${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $<;
%.oo: ${XA_SRCDIR}/%.c
${AM_V_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -DPIC -fPIC ${CFLAGS} -o $@ -c $<;

40
Makefile.mans.in Normal file
View File

@@ -0,0 +1,40 @@
# -*- Makefile -*-
# MANUAL
srcdir := @srcdir@
wcman_matches := $(shell find "${srcdir}" -name 'libxt_[a-z]*.man')
wcman_targets := $(shell find "${srcdir}" -name 'libxt_[A-Z]*.man')
wlist_matches := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_matches})
wlist_targets := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_targets})
.PHONY: FORCE
FORCE:
.manpages.lst: FORCE
@echo "${wlist_targets} ${wlist_matches}" >$@.tmp; \
cmp -s $@ $@.tmp || mv $@.tmp $@; \
rm -f $@.tmp;
man_run = \
${AM_V_GEN}for ext in $(1); do \
name="$${ext%.man}"; \
name="$${name\#\#*/libxt_}"; \
if [ -f "$$ext" ]; then \
echo ".SS $$name"; \
cat "$$ext"; \
continue; \
fi; \
done >$@;
all: xtables-addons.8
xtables-addons.8: ${srcdir}/xtables-addons.8.in matches.man targets.man
${AM_V_GEN}sed -e '/@MATCHES@/ r matches.man' -e '/@TARGET@/ r targets.man' $< >$@;
matches.man: .manpages.lst ${wcman_matches}
$(call man_run,${wlist_matches})
targets.man: .manpages.lst ${wcman_targets}
$(call man_run,${wlist_targets})

View File

@@ -1,9 +1,9 @@
AC_INIT([xtables-addons], [1.17])
AC_INIT([xtables-addons], [1.19])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AC_PROG_INSTALL
AM_INIT_AUTOMAKE([-Wall foreign subdir-objects])
AM_INIT_AUTOMAKE([1.10 -Wall foreign subdir-objects])
AC_PROG_CC
AM_PROG_CC_C_O
AC_DISABLE_STATIC
@@ -14,10 +14,7 @@ AC_ARG_WITH([kbuild],
AS_HELP_STRING([--with-kbuild=PATH],
[Path to kernel build directory [[/lib/modules/CURRENT/build]]]),
[kbuilddir="$withval"])
AC_ARG_WITH([ksource],
AS_HELP_STRING([--with-ksource=PATH],
[Path to kernel source directory [[/lib/modules/CURRENT/source]]]),
[ksourcedir="$withval"])
AC_ARG_WITH([ksource],,[ksourcedir="$withval"])
AC_ARG_WITH([xtables],
AS_HELP_STRING([--with-xtables=PATH],
[Path to the Xtables includes [[none]]]),
@@ -79,13 +76,16 @@ krel="${krel#*.}";
kminor="${krel%%.*}";
krel="${krel#*.}";
kmicro="${krel%%.*}";
krel="${krel#*.}";
kstable="${krel%%.*}";
if test -z "$kstable"; then
if test "$kmicro" = "$krel"; then
kstable=0;
else
kstable="${krel#*.}";
if test -z "$kstable"; then
kstable=0;
fi;
fi;
echo "Found kernel version $kmajor.$kminor.$kmicro.$kstable in $kbuilddir";
if test "$kmajor" -gt 2 -o "$kminor" -gt 6 -o "$kmicro" -gt 30; then
if test "$kmajor" -gt 2 -o "$kminor" -gt 6 -o "$kmicro" -gt 32; 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 \
@@ -100,5 +100,7 @@ AC_SUBST([kinclude_CFLAGS])
AC_SUBST([kbuilddir])
AC_SUBST([ksourcedir])
AC_SUBST([xtlibdir])
AC_CONFIG_FILES([Makefile extensions/GNUmakefile extensions/ipset/GNUmakefile])
AC_CONFIG_FILES([Makefile Makefile.iptrules Makefile.mans
extensions/Makefile extensions/ACCOUNT/Makefile
extensions/ipset/Makefile extensions/pknock/Makefile])
AC_OUTPUT

4
doc/README.psd Normal file
View File

@@ -0,0 +1,4 @@
PSD (Portscan Detection) External extensions for Xtables-addons
Example:
iptables -A INPUT -m psd --psd-weight-threshold 21 --psd-delay-threshold 300 --psd-lo-ports-weight 1 --psd-hi-ports-weight 10 -j LOG --log-prefix "PSD: "

View File

@@ -1,4 +1,42 @@
HEAD
====
Xtables-addons 1.19 (October 12 2009)
=====================================
- build: compile fixes for 2.6.31-rt
- build: support for Linux 2.6.32
- ipp2p: try to address underflows
- psd: avoid potential crash when dealing with non-linear skbs
- merge xt_ACCOUNT userspace utilities
- added reworked xt_pknock module
Changes from pknock v0.5:
- pknock: "strict" and "checkip" flags were not displayed in `iptables -L`
- pknock: the GC expire time's lower bound is now the default gc time
(65000 msec) to avoid rendering anti-spoof protection in SPA mode useless
- pknock: avoid crash on memory allocation failure and fix memleak
- pknock: avoid fillup of peer table during DDoS
- pknock: automatic closing of ports
- pknock: make non-zero time mandatory for TCP mode
- pknock: display only pknock mode and state relevant information in procfs
- pknock: check interknock time only for !ST_ALLOWED peers
- pknock: preserve time/autoclose values for rules added in
reverse/arbitrary order
- pknock: add a manpage
Xtables-addons 1.18 (September 09 2009)
=======================================
- build: support for Linux 2.6.31
- ipset: fast forward to v3.2
- quota2: support anonymous counters
- quota2: reduce memory footprint for anonymous counters
- quota2: extend locked period during cleanup (locking bugfix)
- quota2: use strtoull instead of strtoul
- merged xt_ACCOUNT module
- merged xt_psd module
Xtables-addons 1.17 (June 16 2009)
==================================

View File

@@ -8,8 +8,5 @@ Module.symvers
Modules.symvers
modules.order
/*.so
/*.oo
/matches.man
/targets.man
/.manpages.lst
*.so
*.oo

1
extensions/ACCOUNT/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/iptaccount

View File

@@ -0,0 +1,5 @@
# -*- Makefile -*-
EXTRA_CFLAGS = -I${src}/..
obj-m += xt_ACCOUNT.o

View File

@@ -0,0 +1,8 @@
# -*- Makefile -*-
include ../../Makefile.extra
sbin_PROGRAMS = iptaccount
iptaccount_LDADD = libxt_ACCOUNT_cl.la
lib_LTLIBRARIES = libxt_ACCOUNT_cl.la

View File

@@ -0,0 +1,3 @@
# -*- Makefile -*-
obj-${build_ACCOUNT} += libxt_ACCOUNT.so

View File

@@ -0,0 +1,223 @@
/***************************************************************************
* Copyright (C) 2004-2006 by Intra2net AG *
* opensource@intra2net.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License *
* version 2.1 as published by the Free Software Foundation; *
* *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>
#include <signal.h>
#include <libxt_ACCOUNT_cl.h>
bool exit_now;
static void sig_term(int signr)
{
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
exit_now = true;
}
char *addr_to_dotted(unsigned int);
char *addr_to_dotted(unsigned int addr)
{
static char buf[17];
const unsigned char *bytep;
bytep = (const unsigned char *)&addr;
snprintf(buf, 16, "%u.%u.%u.%u", bytep[0], bytep[1], bytep[2], bytep[3]);
buf[16] = 0;
return buf;
}
static void show_usage(void)
{
printf("Unknown command line option. Try: [-u] [-h] [-a] [-f] [-c] [-s] [-l name]\n");
printf("[-u] show kernel handle usage\n");
printf("[-h] free all kernel handles (experts only!)\n\n");
printf("[-a] list all table names\n");
printf("[-l name] show data in table <name>\n");
printf("[-f] flush data after showing\n");
printf("[-c] loop every second (abort with CTRL+C)\n");
printf("[-s] CSV output (for spreadsheet import)\n");
printf("\n");
}
int main(int argc, char *argv[])
{
struct ipt_ACCOUNT_context ctx;
struct ipt_acc_handle_ip *entry;
int i;
char optchar;
bool doHandleUsage = false, doHandleFree = false, doTableNames = false;
bool doFlush = false, doContinue = false, doCSV = false;
char *table_name = NULL;
const char *name;
printf("\nlibxt_ACCOUNT_cl userspace accounting tool v%s\n\n",
LIBXT_ACCOUNT_VERSION);
if (argc == 1)
{
show_usage();
exit(0);
}
while ((optchar = getopt(argc, argv, "uhacfsl:")) != -1)
{
switch (optchar)
{
case 'u':
doHandleUsage = true;
break;
case 'h':
doHandleFree = true;
break;
case 'a':
doTableNames = true;
break;
case 'f':
doFlush = true;
break;
case 'c':
doContinue = true;
break;
case 's':
doCSV = true;
break;
case 'l':
table_name = strdup(optarg);
break;
case '?':
default:
show_usage();
exit(0);
break;
}
}
// install exit handler
if (signal(SIGTERM, sig_term) == SIG_ERR)
{
printf("can't install signal handler for SIGTERM\n");
exit(-1);
}
if (signal(SIGINT, sig_term) == SIG_ERR)
{
printf("can't install signal handler for SIGINT\n");
exit(-1);
}
if (signal(SIGQUIT, sig_term) == SIG_ERR)
{
printf("can't install signal handler for SIGQUIT\n");
exit(-1);
}
if (ipt_ACCOUNT_init(&ctx))
{
printf("Init failed: %s\n", ctx.error_str);
exit(-1);
}
// Get handle usage?
if (doHandleUsage)
{
int rtn = ipt_ACCOUNT_get_handle_usage(&ctx);
if (rtn < 0)
{
printf("get_handle_usage failed: %s\n", ctx.error_str);
exit(-1);
}
printf("Current kernel handle usage: %d\n", ctx.handle.itemcount);
}
if (doHandleFree)
{
int rtn = ipt_ACCOUNT_free_all_handles(&ctx);
if (rtn < 0)
{
printf("handle_free_all failed: %s\n", ctx.error_str);
exit(-1);
}
printf("Freed all handles in kernel space\n");
}
if (doTableNames)
{
int rtn = ipt_ACCOUNT_get_table_names(&ctx);
if (rtn < 0)
{
printf("get_table_names failed: %s\n", ctx.error_str);
exit(-1);
}
while ((name = ipt_ACCOUNT_get_next_name(&ctx)) != 0)
printf("Found table: %s\n", name);
}
if (table_name)
{
// Read out data
if (doCSV)
printf("IP;SRC packets;SRC bytes;DST packets;DST bytes\n");
else
printf("Showing table: %s\n", table_name);
i = 0;
while (!exit_now)
{
// Get entries from table test
if (ipt_ACCOUNT_read_entries(&ctx, table_name, !doFlush))
{
printf("Read failed: %s\n", ctx.error_str);
ipt_ACCOUNT_deinit(&ctx);
exit(-1);
}
if (!doCSV)
printf("Run #%d - %u %s found\n", i, ctx.handle.itemcount,
ctx.handle.itemcount == 1 ? "item" : "items");
// Output and free entries
while ((entry = ipt_ACCOUNT_get_next_entry(&ctx)) != NULL)
{
if (doCSV)
printf("%s;%u;%u;%u;%u\n",
addr_to_dotted(entry->ip), entry->src_packets, entry->src_bytes,
entry->dst_packets, entry->dst_bytes);
else
printf("IP: %s SRC packets: %u bytes: %u DST packets: %u bytes: %u\n",
addr_to_dotted(entry->ip), entry->src_packets, entry->src_bytes,
entry->dst_packets, entry->dst_bytes);
}
if (doContinue)
{
sleep(1);
i++;
} else
exit_now = true;
}
}
printf("Finished.\n");
ipt_ACCOUNT_deinit(&ctx);
exit(0);
}

View File

@@ -0,0 +1,168 @@
/* Shared library add-on to iptables to add ACCOUNT(ing) support.
Author: Intra2net AG <opensource@intra2net.com>
*/
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <syslog.h>
#include <getopt.h>
#include <stddef.h>
#include <xtables.h>
#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 }
};
/* Function which prints out usage message. */
static void account_tg_help(void)
{
printf(
"ACCOUNT target options:\n"
" --%s ip/netmask\t\tBase network IP and netmask used for this table\n"
" --%s name\t\t\tTable name for the userspace library\n",
account_tg_opts[0].name, account_tg_opts[1].name);
}
/* Initialize the target. */
static void
account_tg_init(struct xt_entry_target *t)
{
struct ipt_acc_info *accountinfo = (struct ipt_acc_info *)t->data;
accountinfo->table_nr = -1;
}
#define IPT_ACCOUNT_OPT_ADDR 0x01
#define IPT_ACCOUNT_OPT_TABLE 0x02
/* Function which parses command options; returns true if it
ate an option */
static int account_tg_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_target **target)
{
struct ipt_acc_info *accountinfo = (struct ipt_acc_info *)(*target)->data;
struct in_addr *addrs = NULL, mask;
unsigned int naddrs = 0;
switch (c) {
case 'a':
if (*flags & IPT_ACCOUNT_OPT_ADDR)
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");
accountinfo->net_ip = addrs[0].s_addr;
accountinfo->net_mask = mask.s_addr;
*flags |= IPT_ACCOUNT_OPT_ADDR;
break;
case 't':
if (*flags & IPT_ACCOUNT_OPT_TABLE)
xtables_error(PARAMETER_PROBLEM,
"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",
ACCOUNT_TABLE_NAME_LEN - 1,
account_tg_opts[1].name);
strcpy(accountinfo->table_name, optarg);
*flags |= IPT_ACCOUNT_OPT_TABLE;
break;
default:
return 0;
}
return 1;
}
static void account_tg_check(unsigned int flags)
{
if (!(flags & IPT_ACCOUNT_OPT_ADDR) || !(flags & IPT_ACCOUNT_OPT_TABLE))
xtables_error(PARAMETER_PROBLEM, "ACCOUNT: needs --%s and --%s",
account_tg_opts[0].name, account_tg_opts[1].name);
}
static void account_tg_print_it(const void *ip,
const struct xt_entry_target *target, char do_prefix)
{
const struct ipt_acc_info *accountinfo
= (const struct ipt_acc_info *)target->data;
struct in_addr a;
if (!do_prefix)
printf("ACCOUNT ");
// Network information
if (do_prefix)
printf("--");
printf("%s ", account_tg_opts[0].name);
a.s_addr = accountinfo->net_ip;
printf("%s", xtables_ipaddr_to_numeric(&a));
a.s_addr = accountinfo->net_mask;
printf("%s", xtables_ipmask_to_numeric(&a));
printf(" ");
if (do_prefix)
printf("--");
printf("%s %s", account_tg_opts[1].name, accountinfo->table_name);
}
static void
account_tg_print(const void *ip,
const struct xt_entry_target *target,
int numeric)
{
account_tg_print_it(ip, target, 0);
}
/* 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);
}
static struct xtables_target account_tg_reg = {
.name = "ACCOUNT",
.family = AF_INET,
.version = XTABLES_VERSION,
.size = XT_ALIGN(sizeof(struct ipt_acc_info)),
.userspacesize = offsetof(struct ipt_acc_info, table_nr),
.help = account_tg_help,
.init = account_tg_init,
.parse = account_tg_parse,
.final_check = account_tg_check,
.print = account_tg_print,
.save = account_tg_save,
.extra_opts = account_tg_opts,
};
static __attribute__((constructor)) void account_tg_ldr(void)
{
xtables_register_target(&account_tg_reg);
}

View File

@@ -0,0 +1,72 @@
The ACCOUNT target is a high performance accounting system for large
local networks. It allows per-IP accounting in whole prefixes of IPv4
addresses with size of up to /8 without the need to add individual
accouting rule for each IP address.
.PP
The ACCOUNT is designed to be queried for data every second or at
least every ten seconds. It is written as kernel module to handle high
bandwidths without packet loss.
.PP
The largest possible subnet size is 24 bit, meaning for example 10.0.0.0/8
network. ACCOUNT uses fixed internal data structures
which speeds up the processing of each packet. Furthermore,
accounting data for one complete 192.168.1.X/24 network takes 4 KB of
memory. Memory for 16 or 24 bit networks is only allocated when
needed.
.PP
To optimize the kernel<->userspace data transfer a bit more, the
kernel module only transfers information about IPs, where the src/dst
packet counter is not 0. This saves precious kernel time.
.PP
There is no /proc interface as it would be too slow for continuous access.
The read-and-flush query operation is the fastest, as no internal data
snapshot needs to be created&copied for all data. Use the "read"
operation without flush only for debugging purposes!
.PP
Usage:
.PP
ACCOUNT takes two mandatory parameters:
.TP
\fB\-\-addr\fR \fInetwork\fP\fB/\fP\fInetmask\fR
where \fInetwork\fP\fB/\fP\fInetmask\fP is the subnet to account for, in CIDR syntax
.TP
\fB\-\-tname\fP \fINAME\fP
where \fINAME\fP is the name of the table where the accounting information
should be stored
.PP
The subnet 0.0.0.0/0 is a special case: all data are then stored in the src_bytes
and src_packets structure of slot "0". This is useful if you want
to account the overall traffic to/from your internet provider.
.PP
The data can be queried using the userspace libxt_ACCOUNT_cl library,
and by the reference implementation to show usage of this library,
the \fBiptaccount\fP(8) tool, which features following options:
.PP
[\fB\-u\fP] show kernel handle usage
.PP
[\fB\-h\fP] free all kernel handles (experts only!)
.PP
[\fB\-a\fP] list all table names
.PP
[\fB\-l\fP \fIname\fP] show data in table \fIname\fP
.PP
[\fB\-f\fP] flush data after showing
.PP
[\fB\-c\fP] loop every second (abort with CTRL+C)
.PP
Here is an example of use:
.PP
iptables \-A FORWARD \-j ACCOUNT \-\-addr 0.0.0.0/0 \-\-tname all_outgoing;
iptables \-A FORWARD \-j ACCOUNT \-\-addr 192.168.1.0/24 \-\-tname sales;
.PP
This creates two tables called "all_outgoing" and "sales" which can be
queried using the userspace library/iptaccount tool.
.PP
Note that this target is non-terminating \(em the packet destined to it
will continue traversing the chain in which it has been used.
.PP
Also note that once a table has been defined for specific CIDR address/netmask
block, it can be referenced multiple times using \-j ACCOUNT, provided
that both the original table name and address/netmask block are specified.
.PP
For more information go to http://www.intra2net.com/en/developer/ipt_ACCOUNT/

View File

@@ -0,0 +1,199 @@
/***************************************************************************
* Copyright (C) 2004 by Intra2net AG *
* opensource@intra2net.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License *
* version 2.1 as published by the Free Software Foundation; *
* *
***************************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <linux/if.h>
#include <libxt_ACCOUNT_cl.h>
int ipt_ACCOUNT_init(struct ipt_ACCOUNT_context *ctx)
{
memset(ctx, 0, sizeof(struct ipt_ACCOUNT_context));
ctx->handle.handle_nr = -1;
ctx->sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (ctx->sockfd < 0) {
ctx->sockfd = -1;
ctx->error_str = "Can't open socket to kernel. "
"Permission denied or ipt_ACCOUNT module not loaded";
return -1;
}
// 4096 bytes default buffer should save us from reallocations
// as it fits 200 concurrent active clients
if ((ctx->data = malloc(IPT_ACCOUNT_MIN_BUFSIZE)) == NULL) {
close(ctx->sockfd);
ctx->sockfd = -1;
ctx->error_str = "Out of memory for data buffer";
return -1;
}
ctx->data_size = IPT_ACCOUNT_MIN_BUFSIZE;
return 0;
}
void ipt_ACCOUNT_free_entries(struct ipt_ACCOUNT_context *ctx)
{
if (ctx->handle.handle_nr != -1) {
setsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_SET_ACCOUNT_HANDLE_FREE,
&ctx->handle, sizeof(struct ipt_acc_handle_sockopt));
ctx->handle.handle_nr = -1;
}
ctx->handle.itemcount = 0;
ctx->pos = 0;
}
void ipt_ACCOUNT_deinit(struct ipt_ACCOUNT_context *ctx)
{
free(ctx->data);
ctx->data = NULL;
ipt_ACCOUNT_free_entries(ctx);
close(ctx->sockfd);
ctx->sockfd = -1;
}
int ipt_ACCOUNT_read_entries(struct ipt_ACCOUNT_context *ctx,
const char *table, char dont_flush)
{
unsigned int s = sizeof(struct ipt_acc_handle_sockopt);
unsigned int new_size;
int rtn;
strncpy(ctx->handle.name, table, ACCOUNT_TABLE_NAME_LEN-1);
// Get table information
if (!dont_flush)
rtn = getsockopt(ctx->sockfd, IPPROTO_IP,
IPT_SO_GET_ACCOUNT_PREPARE_READ_FLUSH, &ctx->handle, &s);
else
rtn = getsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_GET_ACCOUNT_PREPARE_READ,
&ctx->handle, &s);
if (rtn < 0) {
ctx->error_str = "Can't get table information from kernel. "
"Does it exist?";
return -1;
}
// Check data buffer size
ctx->pos = 0;
new_size = ctx->handle.itemcount * sizeof(struct ipt_acc_handle_ip);
// We want to prevent reallocations all the time
if (new_size < IPT_ACCOUNT_MIN_BUFSIZE)
new_size = IPT_ACCOUNT_MIN_BUFSIZE;
// Reallocate if it's too small or twice as big
if (ctx->data_size < new_size || ctx->data_size > new_size * 2) {
// Free old buffer
free(ctx->data);
ctx->data_size = 0;
if ((ctx->data = malloc(new_size)) == NULL) {
ctx->error_str = "Out of memory for data buffer";
ipt_ACCOUNT_free_entries(ctx);
return -1;
}
ctx->data_size = new_size;
}
// Copy data from kernel
memcpy(ctx->data, &ctx->handle, sizeof(struct ipt_acc_handle_sockopt));
rtn = getsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_GET_ACCOUNT_GET_DATA,
ctx->data, &ctx->data_size);
if (rtn < 0) {
ctx->error_str = "Can't get data from kernel. "
"Check /var/log/messages for details.";
ipt_ACCOUNT_free_entries(ctx);
return -1;
}
// Free kernel handle but don't reset pos/itemcount
setsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_SET_ACCOUNT_HANDLE_FREE,
&ctx->handle, sizeof(struct ipt_acc_handle_sockopt));
ctx->handle.handle_nr = -1;
return 0;
}
struct ipt_acc_handle_ip *ipt_ACCOUNT_get_next_entry(struct ipt_ACCOUNT_context *ctx)
{
struct ipt_acc_handle_ip *rtn;
// Empty or no more items left to return?
if (!ctx->handle.itemcount || ctx->pos >= ctx->handle.itemcount)
return NULL;
// Get next entry
rtn = (struct ipt_acc_handle_ip *)(ctx->data + ctx->pos
* sizeof(struct ipt_acc_handle_ip));
ctx->pos++;
return rtn;
}
int ipt_ACCOUNT_get_handle_usage(struct ipt_ACCOUNT_context *ctx)
{
unsigned int s = sizeof(struct ipt_acc_handle_sockopt);
if (getsockopt(ctx->sockfd, IPPROTO_IP,
IPT_SO_GET_ACCOUNT_GET_HANDLE_USAGE, &ctx->handle, &s) < 0) {
ctx->error_str = "Can't get handle usage information from kernel";
return -1;
}
ctx->handle.handle_nr = -1;
return ctx->handle.itemcount;
}
int ipt_ACCOUNT_free_all_handles(struct ipt_ACCOUNT_context *ctx)
{
if (setsockopt(ctx->sockfd, IPPROTO_IP,
IPT_SO_SET_ACCOUNT_HANDLE_FREE_ALL, NULL, 0) < 0) {
ctx->error_str = "Can't free all kernel handles";
return -1;
}
return 0;
}
int ipt_ACCOUNT_get_table_names(struct ipt_ACCOUNT_context *ctx)
{
int rtn = getsockopt(ctx->sockfd, IPPROTO_IP,
IPT_SO_GET_ACCOUNT_GET_TABLE_NAMES,
ctx->data, &ctx->data_size);
if (rtn < 0) {
ctx->error_str = "Can't get table names from kernel. Out of memory, "
"MINBUFISZE too small?";
return -1;
}
ctx->pos = 0;
return 0;
}
const char *ipt_ACCOUNT_get_next_name(struct ipt_ACCOUNT_context *ctx)
{
const char *rtn;
if (((char *)ctx->data)[ctx->pos] == 0)
return 0;
rtn = ctx->data + ctx->pos;
ctx->pos += strlen(ctx->data + ctx->pos) + 1;
return rtn;
}

View File

@@ -0,0 +1,60 @@
/***************************************************************************
* Copyright (C) 2004 by Intra2net AG *
* opensource@intra2net.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License *
* version 2.1 as published by the Free Software Foundation; *
* *
***************************************************************************/
#ifndef _xt_ACCOUNT_cl_H
#define _xt_ACCOUNT_cl_H
#include <xt_ACCOUNT.h>
#define LIBXT_ACCOUNT_VERSION "1.3"
/* Don't set this below the size of struct ipt_account_handle_sockopt */
#define IPT_ACCOUNT_MIN_BUFSIZE 4096
struct ipt_ACCOUNT_context
{
int sockfd;
struct ipt_acc_handle_sockopt handle;
unsigned int data_size;
void *data;
unsigned int pos;
char *error_str;
};
#ifdef __cplusplus
extern "C" {
#endif
int ipt_ACCOUNT_init(struct ipt_ACCOUNT_context *ctx);
void ipt_ACCOUNT_deinit(struct ipt_ACCOUNT_context *ctx);
void ipt_ACCOUNT_free_entries(struct ipt_ACCOUNT_context *ctx);
int ipt_ACCOUNT_read_entries(struct ipt_ACCOUNT_context *ctx,
const char *table, char dont_flush);
struct ipt_acc_handle_ip *ipt_ACCOUNT_get_next_entry(
struct ipt_ACCOUNT_context *ctx);
/* ipt_ACCOUNT_free_entries is for internal use only function as this library
is constructed to be used in a loop -> Don't allocate memory all the time.
The data buffer is freed on deinit() */
int ipt_ACCOUNT_get_handle_usage(struct ipt_ACCOUNT_context *ctx);
int ipt_ACCOUNT_free_all_handles(struct ipt_ACCOUNT_context *ctx);
int ipt_ACCOUNT_get_table_names(struct ipt_ACCOUNT_context *ctx);
const char *ipt_ACCOUNT_get_next_name(struct ipt_ACCOUNT_context *ctx);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,13 @@
config NETFILTER_XT_TARGET_ACCOUNT
tristate "ACCOUNT target support"
depends on NETFILTER_XTABLES
---help---
This module implements an ACCOUNT target
The ACCOUNT target is a high performance accounting system for large
local networks. It allows per-IP accounting in whole prefixes of IPv4
addresses with size of up to /8 without the need to add individual
accouting rule for each IP address.
For more information go to:
http://www.intra2net.com/de/produkte/opensource/ipt_account/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,118 @@
/***************************************************************************
* Copyright (C) 2004-2006 by Intra2net AG *
* opensource@intra2net.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; *
* *
***************************************************************************/
#ifndef _IPT_ACCOUNT_H
#define _IPT_ACCOUNT_H
/*
* Socket option interface shared between kernel (xt_ACCOUNT) and userspace
* library (libxt_ACCOUNT_cl). Hopefully we are unique at least within our
* kernel & xtables-addons space.
*/
#define SO_ACCOUNT_BASE_CTL 90
#define IPT_SO_SET_ACCOUNT_HANDLE_FREE (SO_ACCOUNT_BASE_CTL + 1)
#define IPT_SO_SET_ACCOUNT_HANDLE_FREE_ALL (SO_ACCOUNT_BASE_CTL + 2)
#define IPT_SO_SET_ACCOUNT_MAX IPT_SO_SET_ACCOUNT_HANDLE_FREE_ALL
#define IPT_SO_GET_ACCOUNT_PREPARE_READ (SO_ACCOUNT_BASE_CTL + 4)
#define IPT_SO_GET_ACCOUNT_PREPARE_READ_FLUSH (SO_ACCOUNT_BASE_CTL + 5)
#define IPT_SO_GET_ACCOUNT_GET_DATA (SO_ACCOUNT_BASE_CTL + 6)
#define IPT_SO_GET_ACCOUNT_GET_HANDLE_USAGE (SO_ACCOUNT_BASE_CTL + 7)
#define IPT_SO_GET_ACCOUNT_GET_TABLE_NAMES (SO_ACCOUNT_BASE_CTL + 8)
#define IPT_SO_GET_ACCOUNT_MAX IPT_SO_GET_ACCOUNT_GET_TABLE_NAMES
#define ACCOUNT_MAX_TABLES 128
#define ACCOUNT_TABLE_NAME_LEN 32
#define ACCOUNT_MAX_HANDLES 10
/* Structure for the userspace part of ipt_ACCOUNT */
struct ipt_acc_info {
uint32_t net_ip;
uint32_t 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 */
char name[ACCOUNT_TABLE_NAME_LEN]; /* Used for HANDLE_PREPARE_READ/
HANDLE_READ_FLUSH */
uint32_t itemcount; /* Used for HANDLE_PREPARE_READ/
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;
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

@@ -1,141 +0,0 @@
# -*- Makefile -*-
top_srcdir := @top_srcdir@
srcdir := @srcdir@
abstop_srcdir := $(shell readlink -f ${top_srcdir})
abssrcdir := $(shell readlink -f ${srcdir})
ifeq (${abstop_srcdir},)
$(error Path resolution of ${top_srcdir} failed)
endif
ifeq (${abssrcdir},)
$(error Path resolution of ${srcdir} failed)
endif
prefix := @prefix@
exec_prefix := @exec_prefix@
libdir := @libdir@
libexecdir := @libexecdir@
xtlibdir := @xtlibdir@
kbuilddir := @kbuilddir@
CC := @CC@
CCLD := ${CC}
CFLAGS := @CFLAGS@
LDFLAGS := @LDFLAGS@
regular_CFLAGS := @regular_CFLAGS@
kinclude_CFLAGS := @kinclude_CFLAGS@
xtables_CFLAGS := @xtables_CFLAGS@
AM_CFLAGS := ${regular_CFLAGS} -I${top_srcdir}/include ${xtables_CFLAGS} ${kinclude_CFLAGS}
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
VU := 0
am__v_CC_0 = @echo " CC " $@;
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_GEN_0 = @echo " GEN " $@;
am__v_SILENT_0 = @
AM_V_CC = ${am__v_CC_${VU}}
AM_V_CCLD = ${am__v_CCLD_${VU}}
AM_V_GEN = ${am__v_GEN_${VU}}
AM_V_silent = ${am__v_GEN_${VU}}
#
# Wildcard module list
#
include ${top_srcdir}/mconfig
-include ${top_srcdir}/mconfig.*
include ${srcdir}/Mbuild
-include ${srcdir}/Mbuild.*
-include ${srcdir}/*.Mbuild
#
# Building blocks
#
targets := $(filter-out %/,${obj-m})
targets_install := ${targets}
subdirs_list := $(filter %/,${obj-m})
.SECONDARY:
.PHONY: all install clean distclean FORCE
all: subdirs modules user matches.man targets.man
subdirs:
@for i in ${subdirs_list}; do ${MAKE} -C $$i; done;
subdirs-install:
@for i in ${subdirs_list}; do ${MAKE} -C $$i install; done;
user: ${targets}
install: modules_install subdirs-install ${targets_install}
@mkdir -p "${DESTDIR}${xtlibdir}";
install -pm0755 ${targets_install} "${DESTDIR}${xtlibdir}/";
clean: clean_modules
@for i in ${subdirs_list}; do make -C $$i clean; done;
rm -f *.oo *.so;
distclean: clean
rm -f .*.d .manpages.lst;
-include .*.d
#
# Call out to kbuild
#
.PHONY: modules modules_install clean_modules
modules:
${AM_V_silent}if [ -n "${kbuilddir}" ]; then make -C ${kbuilddir} M=${abssrcdir} XA_TOPSRCDIR=${abstop_srcdir} modules; fi;
modules_install:
${AM_V_silent}if [ -n "${kbuilddir}" ]; then make -C ${kbuilddir} M=${abssrcdir} XA_TOPSRCDIR=${abstop_srcdir} INSTALL_MOD_PATH=${DESTDIR} modules_install; fi;
clean_modules:
${AM_V_silent}if [ -n "${kbuilddir}" ]; then make -C ${kbuilddir} M=${abssrcdir} XA_TOPSRCDIR=${abstop_srcdir} clean; fi;
#
# Shared libraries
#
lib%.so: lib%.oo
${AM_V_CCLD}${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $<;
lib%.oo: ${srcdir}/lib%.c
${AM_V_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -D_INIT=lib$*_init -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
#
# Manpages
#
wcman_matches := $(wildcard ${srcdir}/libxt_[a-z]*.man)
wcman_targets := $(wildcard ${srcdir}/libxt_[A-Z]*.man)
wlist_matches := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_matches})
wlist_targets := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_targets})
.manpages.lst: FORCE
@echo "${wlist_targets} ${wlist_matches}" >$@.tmp; \
cmp -s $@ $@.tmp || mv $@.tmp $@; \
rm -f $@.tmp;
man_run = \
${AM_V_GEN}for ext in $(1); do \
f="${srcdir}/libxt_$$ext.man"; \
if [ -f "$$f" ]; then \
echo ".SS $$ext"; \
cat "$$f"; \
continue; \
fi; \
done >$@;
matches.man: .manpages.lst ${wcman_matches}
$(call man_run,${wlist_matches})
targets.man: .manpages.lst ${wcman_targets}
$(call man_run,${wlist_targets})

View File

@@ -1,10 +1,11 @@
# -*- Makefile -*-
include ${XA_TOPSRCDIR}/mconfig
-include ${XA_TOPSRCDIR}/mconfig.*
include ${XA_ABSTOPSRCDIR}/mconfig
-include ${XA_ABSTOPSRCDIR}/mconfig.*
obj-m += compat_xtables.o
obj-${build_ACCOUNT} += ACCOUNT/
obj-${build_CHAOS} += xt_CHAOS.o
obj-${build_DELUDE} += xt_DELUDE.o
obj-${build_DHCPMAC} += xt_DHCPMAC.o
@@ -25,6 +26,8 @@ obj-${build_ipset} += ipset/
obj-${build_ipv4options} += xt_ipv4options.o
obj-${build_length2} += xt_length2.o
obj-${build_lscan} += xt_lscan.o
obj-${build_pknock} += pknock/
obj-${build_psd} += xt_psd.o
obj-${build_quota2} += xt_quota2.o
-include ${M}/*.Kbuild

24
extensions/Makefile.am Normal file
View File

@@ -0,0 +1,24 @@
# -*- Makefile -*-
# AUTOMAKE
# Not having Kbuild in Makefile.extra because it will already recurse
.PHONY: modules modules_install clean_modules
_kcall = -C ${kbuilddir} M=${abs_srcdir}
modules:
${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} ${_kcall} modules; fi;
modules_install:
${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} ${_kcall} INSTALL_MOD_PATH=${DESTDIR} ext-mod-dir='$${INSTALL_MOD_DIR}' modules_install; fi;
clean_modules:
${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} ${_kcall} clean; fi;
all-local: modules
install-exec-local: modules_install
clean-local: clean_modules
include ../Makefile.extra

View File

@@ -1,3 +1,6 @@
# -*- Makefile -*-
obj-${build_ACCOUNT} += ACCOUNT/
obj-${build_CHAOS} += libxt_CHAOS.so
obj-${build_DELUDE} += libxt_DELUDE.so
obj-${build_DHCPMAC} += libxt_DHCPMAC.so libxt_dhcpmac.so
@@ -18,4 +21,6 @@ obj-${build_ipset} += ipset/
obj-${build_ipv4options} += libxt_ipv4options.so
obj-${build_length2} += libxt_length2.so
obj-${build_lscan} += libxt_lscan.so
obj-${build_pknock} += pknock/
obj-${build_psd} += libxt_psd.so
obj-${build_quota2} += libxt_quota2.so

View File

@@ -4,6 +4,23 @@
struct tcphdr;
struct udphdr;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 30)
static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst)
{
skb->dst = dst;
}
static inline struct dst_entry *skb_dst(const struct sk_buff *skb)
{
return skb->dst;
}
static inline struct rtable *skb_rtable(const struct sk_buff *skb)
{
return (void *)skb->dst;
}
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
# define skb_ifindex(skb) \
(((skb)->input_dev != NULL) ? (skb)->input_dev->ifindex : 0)

View File

@@ -1,3 +1 @@
*.oo
*.so
/ipset

View File

@@ -1,85 +0,0 @@
# -*- Makefile -*-
top_srcdir := @top_srcdir@
srcdir := @srcdir@
datarootdir := @datarootdir@
abstop_srcdir := $(shell readlink -f ${top_srcdir})
abssrcdir := $(shell readlink -f ${srcdir})
ifeq (${abstop_srcdir},)
$(error Path resolution of ${top_srcdir} failed)
endif
ifeq (${abssrcdir},)
$(error Path resolution of ${srcdir} failed)
endif
prefix := @prefix@
exec_prefix := @exec_prefix@
sbindir := @sbindir@
libdir := @libdir@
libexecdir := @libexecdir@
xtlibdir := @xtlibdir@
kbuilddir := @kbuilddir@
man8dir := @mandir@/man8
CC := @CC@
CCLD := ${CC}
CFLAGS := @CFLAGS@
LDFLAGS := @LDFLAGS@
regular_CFLAGS := @regular_CFLAGS@
kinclude_CFLAGS := @kinclude_CFLAGS@
xtables_CFLAGS := @xtables_CFLAGS@
AM_CFLAGS := ${regular_CFLAGS} -I${top_srcdir}/include ${xtables_CFLAGS} ${kinclude_CFLAGS} -DIPSET_LIB_DIR=\"${xtlibdir}\"
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
VU := 0
am__1verbose_CC_0 = @echo " CC " $@;
am__1verbose_CCLD_0 = @echo " CCLD " $@;
am__1verbose_CC_1 = @echo " CC " $@ "<-" $<;
am__1verbose_CCLD_1 = @echo " CCLD " $@ "<-" $^;
am__verbose_CC = ${am__1verbose_CC_${VU}}
am__verbose_CCLD = ${am__1verbose_CCLD_${VU}}
#
# Building blocks
#
targets := $(addsuffix .so,$(addprefix libipset_, \
iphash ipmap ipporthash ipportiphash ipportnethash iptree \
iptreemap macipmap nethash portmap setlist))
.SECONDARY:
.PHONY: all install clean distclean FORCE
all: ipset ${targets}
install: all
@mkdir -p "${DESTDIR}${sbindir}" "${DESTDIR}${xtlibdir}" "${DESTDIR}${man8dir}";
install -pm0755 ipset "${DESTDIR}${sbindir}/";
install -pm0755 ${targets} "${DESTDIR}${xtlibdir}/";
install -pm0644 ipset.8 "${DESTDIR}${man8dir}/";
clean:
rm -f *.oo *.so *.o ipset;
distclean: clean
rm -f .*.d;
-include .*.d
ipset: ipset.o
${am__verbose_CCLD}${CCLD} ${AM_LDFLAGS} ${LDFLAGS} -o $@ $< -ldl -rdynamic;
#
# Shared libraries
#
lib%.so: lib%.oo
${am__verbose_CCLD}${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $<;
libipset_%.oo: ${srcdir}/ipset_%.c
${am__verbose_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
%.o: %.c
${am__verbose_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} ${CFLAGS} -o $@ -c $<;

View File

@@ -0,0 +1,9 @@
# -*- Makefile -*-
AM_CFLAGS = ${regular_CFLAGS} -DIPSET_LIB_DIR=\"${xtlibdir}\"
include ../../Makefile.extra
sbin_PROGRAMS = ipset
ipset_LDADD = -ldl
ipset_LDFLAGS = -rdynamic

7
extensions/ipset/Mbuild Normal file
View File

@@ -0,0 +1,7 @@
# -*- Makefile -*-
obj-m += $(addprefix lib,$(patsubst %.c,%.so,$(notdir \
$(wildcard ${XA_SRCDIR}/ipset_*.c))))
libipset_%.oo: ${XA_SRCDIR}/ipset_%.c
${AM_V_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -DPIC -fPIC ${CFLAGS} -o $@ -c $<;

View File

@@ -39,7 +39,7 @@
static struct list_head set_type_list; /* all registered sets */
static struct ip_set **ip_set_list; /* all individual sets */
static DEFINE_RWLOCK(ip_set_lock); /* protects the lists and the hash */
static DECLARE_MUTEX(ip_set_app_mutex); /* serializes user access */
static struct semaphore ip_set_app_mutex; /* serializes user access */
static ip_set_id_t ip_set_max = CONFIG_IP_NF_SET_MAX;
static ip_set_id_t ip_set_bindings_hash_size = CONFIG_IP_NF_SET_HASHSIZE;
static struct list_head *ip_set_hash; /* hash of bindings */
@@ -1911,13 +1911,23 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
res = -ENOENT;
goto done;
}
#define SETLIST(set) (strcmp(set->type->typename, "setlist") == 0)
used = 0;
if (index == IP_SET_INVALID_ID) {
/* Save all sets */
/* Save all sets: ugly setlist type dependency */
int setlist = 0;
setlists:
for (i = 0; i < ip_set_max && res == 0; i++) {
if (ip_set_list[i] != NULL)
if (ip_set_list[i] != NULL
&& !(setlist ^ SETLIST(ip_set_list[i])))
res = ip_set_save_set(i, data, &used, *len);
}
if (!setlist) {
setlist = 1;
goto setlists;
}
} else {
/* Save an individual set */
res = ip_set_save_set(index, data, &used, *len);
@@ -2006,6 +2016,7 @@ static int __init ip_set_init(void)
int res;
ip_set_id_t i;
sema_init(&ip_set_app_mutex, 1);
get_random_bytes(&ip_set_hash_random, 4);
if (max_sets)
ip_set_max = max_sets;

View File

@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/ip.h>
#include <linux/jiffies.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/delay.h>

View File

@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/ip.h>
#include <linux/jiffies.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/delay.h>
@@ -338,7 +339,7 @@ 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, unsigned int __nocast flags)
ip_set_ip_t ip, gfp_t flags)
{
struct ip_set_iptreemap *map = set->data;
struct ip_set_iptreemap_b *btree;
@@ -364,7 +365,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,
ip_set_ip_t start, ip_set_ip_t end, unsigned int __nocast flags)
ip_set_ip_t start, ip_set_ip_t end, gfp_t flags)
{
struct ip_set_iptreemap *map = set->data;
struct ip_set_iptreemap_b *btree;

View File

@@ -40,7 +40,7 @@ struct harray {
};
static inline void *
__harray_malloc(size_t hashsize, size_t typesize, int flags)
__harray_malloc(size_t hashsize, size_t typesize, gfp_t flags)
{
struct harray *harray;
size_t max_elements, size, i, j;
@@ -88,7 +88,7 @@ __harray_malloc(size_t hashsize, size_t typesize, int flags)
}
static inline void *
harray_malloc(size_t hashsize, size_t typesize, int flags)
harray_malloc(size_t hashsize, size_t typesize, gfp_t flags)
{
void *harray;

View File

@@ -21,7 +21,7 @@
* after ==> ref, index
*/
static inline bool
static inline int
next_index_eq(const struct ip_set_setlist *map, int i, ip_set_id_t index)
{
return i < map->size && map->index[i] == index;
@@ -38,18 +38,16 @@ setlist_utest(struct ip_set *set, const void *data, u_int32_t size,
struct ip_set *s;
if (req->before && req->ref[0] == '\0')
return -EINVAL;
return 0;
index = __ip_set_get_byname(req->name, &s);
if (index == IP_SET_INVALID_ID)
return -EEXIST;
return 0;
if (req->ref[0] != '\0') {
ref = __ip_set_get_byname(req->ref, &s);
if (ref == IP_SET_INVALID_ID) {
res = -EEXIST;
if (ref == IP_SET_INVALID_ID)
goto finish;
}
}
for (i = 0; i < map->size
&& map->index[i] != IP_SET_INVALID_ID; i++) {
if (req->before && map->index[i] == index) {
@@ -172,7 +170,7 @@ setlist_kadd(struct ip_set *set,
return res;
}
static inline bool
static inline int
unshift_setlist(struct ip_set_setlist *map, int i)
{
int j;

View File

@@ -50,6 +50,9 @@ 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.
.SH OPTIONS
The options that are recognized by
.B ipset

View File

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

View File

@@ -1,13 +1,13 @@
Causes confusion on the other end by doing odd things with incoming packets.
CHAOS will randomly reply (or not) with one of its configurable subtargets:
.TP
\fB--delude\fP
\fB\-\-delude\fP
Use the REJECT and DELUDE targets as a base to do a sudden or deferred
connection reset, fooling some network scanners to return non-deterministic
(randomly open/closed) results, and in case it is deemed open, it is actually
closed/filtered.
.TP
\fB--tarpit\fP
\fB\-\-tarpit\fP
Use the REJECT and TARPIT target as a base to hold the connection until it
times out. This consumes conntrack entries when connection tracking is loaded
(which usually is on most machines), and routers inbetween you and the Internet

View File

@@ -4,7 +4,7 @@ VMware does not allow to set a non-VMware MAC address before an operating
system is booted (and the MAC be changed with `ip link set eth0 address
aa:bb..`).
.TP
\fB--set-mac\fP \fIaa:bb:cc:dd:ee:ff\fP[\fB/\fP\fImask\fP]
\fB\-\-set\-mac\fP \fIaa:bb:cc:dd:ee:ff\fP[\fB/\fP\fImask\fP]
Replace the client host MAC address field in the DHCP message with the given
MAC address. This option is mandatory. The \fImask\fP parameter specifies the
prefix length of bits to change.
@@ -12,13 +12,13 @@ prefix length of bits to change.
EXAMPLE, replacing all addresses from one of VMware's assigned vendor IDs
(00:50:56) addresses with something else:
.PP
iptables -t mangle -A FORWARD -p udp --dport 67 -m physdev --physdev-in vmnet1
-m dhcpmac --mac 00:50:56:00:00:00/24 -j DHCPMAC --set-mac
ab:cd:ef:00:00:00/24
iptables \-t mangle \-A FORWARD \-p udp \-\-dport 67 \-m physdev
\-\-physdev\-in vmnet1 \-m dhcpmac \-\-mac 00:50:56:00:00:00/24 \-j DHCPMAC
\-\-set\-mac ab:cd:ef:00:00:00/24
.PP
iptables -t mangle -A FORWARD -p udp --dport 68 -m physdev --physdev-out vmnet1
-m dhcpmac --mac ab:cd:ef:00:00:00/24 -j DHCPMAC --set-mac
00:50:56:00:00:00/24
iptables \-t mangle \-A FORWARD \-p udp \-\-dport 68 \-m physdev
\-\-physdev\-out vmnet1 \-m dhcpmac \-\-mac ab:cd:ef:00:00:00/24 \-j DHCPMAC
\-\-set\-mac 00:50:56:00:00:00/24
.PP
(This assumes there is a bridge interface that has vmnet1 as a port. You will
also need to add appropriate ebtables rules to change the MAC address of the

View File

@@ -4,16 +4,16 @@ firewall based classifier.
This target is to be used inside the \fBmangle\fP table.
.TP
\fB--addr\fP {\fBsrc\fP|\fBdst\fP}
\fB\-\-addr\fP {\fBsrc\fP|\fBdst\fP}
Select source or destination IP address as a basis for the mark.
.TP
\fB--and-mask\fP \fImask\fP
\fB\-\-and\-mask\fP \fImask\fP
Perform bitwise AND on the IP address and this bitmask.
.TP
\fB--or-mask\fP \fImask\fP
\fB\-\-or\-mask\fP \fImask\fP
Perform bitwise OR on the IP address and this bitmask.
.TP
\fB--shift\fP \fIvalue\fP
\fB\-\-shift\fP \fIvalue\fP
Shift addresses to the right by the given number of bits before taking it
as a mark. (This is done before ANDing or ORing it.) This option is needed
to select part of an IPv6 address, because marks are only 32 bits in size.
@@ -34,16 +34,16 @@ tc filter add dev eth3 parent 1:0 protocol ip fw
.PP
Earlier we had many rules just like below:
.IP
iptables -t mangle -A POSTROUTING -o eth3 -d 192.168.5.2 -j MARK
--set-mark 0x10502
iptables \-t mangle \-A POSTROUTING \-o eth3 \-d 192.168.5.2 \-j MARK
\-\-set\-mark 0x10502
.IP
iptables -t mangle -A POSTROUTING -o eth3 -d 192.168.5.3 -j MARK
--set-mark 0x10503
iptables \-t mangle \-A POSTROUTING \-o eth3 \-d 192.168.5.3 \-j MARK
\-\-set\-mark 0x10503
.PP
Using IPMARK target we can replace all the mangle/mark rules with only one:
.IP
iptables -t mangle -A POSTROUTING -o eth3 -j IPMARK --addr dst
--and-mask 0xffff --or-mask 0x10000
iptables \-t mangle \-A POSTROUTING \-o eth3 \-j IPMARK \-\-addr dst
\-\-and\-mask 0xffff \-\-or\-mask 0x10000
.PP
On the routers with hundreds of users there should be significant load
decrease (e.g. twice).
@@ -52,5 +52,5 @@ decrease (e.g. twice).
2001:db8:45:1d:20d:93ff:fe9b:e443 and the resulting mark should be 0x93ff,
then a right-shift of 16 is needed first:
.IP
-t mangle -A PREROUTING -s 2001:db8::/32 -j IPMARK --addr src --shift 16
--and-mask 0xFFFF
\-t mangle \-A PREROUTING \-s 2001:db8::/32 \-j IPMARK \-\-addr src \-\-shift
16 \-\-and\-mask 0xFFFF

View File

@@ -1,17 +1,17 @@
The LOGMARK target will log packet and connection marks to syslog.
.TP
\fB--log-level\fR \fIlevel\fR
\fB\-\-log\-level\fR \fIlevel\fR
A logging level between 0 and 8 (inclusive).
.TP
\fB--log-prefix\fR \fIstring\fR
\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
\fB\-\-log\-nfmark\fR
Include the packet mark in the log.
.TP
\fB--log-ctmark\fR
\fB\-\-log\-ctmark\fR
Include the connection mark in the log.
.TP
\fB--log-secmark\fR
\fB\-\-log\-secmark\fR
Include the packet secmark in the log.

View File

@@ -1,7 +1,7 @@
The \fBRAWDNAT\fR target will rewrite the destination address in the IP header,
much like the \fBNETMAP\fR target.
.TP
\fB--to-destination\fR \fIaddr\fR[\fB/\fR\fImask\fR]
\fB\-\-to\-destination\fR \fIaddr\fR[\fB/\fR\fImask\fR]
Network address to map to. The resulting address will be constructed the
following way: All 'one' bits in the \fImask\fR are filled in from the new
\fIaddress\fR. All bits that are zero in the mask are filled in from the

View File

@@ -8,7 +8,7 @@ which makes it possible to change the source address either when the packet
enters the machine or when it leaves it. The reason for this table constraint
is that RAWNAT must happen outside of connection tracking.
.TP
\fB--to-source\fR \fIaddr\fR[\fB/\fR\fImask\fR]
\fB\-\-to\-source\fR \fIaddr\fR[\fB/\fR\fImask\fR]
Network address to map to. The resulting address will be constructed the
following way: All 'one' bits in the \fImask\fR are filled in from the new
\fIaddress\fR. All bits that are zero in the mask are filled in from the
@@ -17,13 +17,13 @@ original address.
As an example, changing the destination for packets forwarded from an internal
LAN to the internet:
.IP
-t raw -A PREROUTING -i lan0 -d 212.201.100.135 -j RAWDNAT --to-destination 199.181.132.250
-t rawpost -A POSTROUTING -o lan0 -s 199.181.132.250 -j RAWSNAT --to-source 212.201.100.135
\-t raw \-A PREROUTING \-i lan0 \-d 212.201.100.135 \-j RAWDNAT \-\-to\-destination 199.181.132.250;
\-t rawpost \-A POSTROUTING \-o lan0 \-s 199.181.132.250 \-j RAWSNAT \-\-to\-source 212.201.100.135;
.PP
Note that changing addresses may influence the route selection! Specifically,
it statically NATs packets, not connections, like the normal DNAT/SNAT targets
would do. Also note that it can transform already-NATed connections -- as said,
it is completely external to Netfilter's connection tracking/NAT.
would do. Also note that it can transform already-NATed connections \(em as
said, it is completely external to Netfilter's connection tracking/NAT.
.PP
If the machine itself generates packets that are to be rawnat'ed, you need a
rule in the OUTPUT chain instead, just like you would with the stateful NAT

View File

@@ -1,7 +1,7 @@
The SYSRQ target allows to remotely trigger sysrq on the local machine over the
network. This can be useful when vital parts of the machine hang, for example
an oops in a filesystem causing locks to be not released and processes to get
stuck as a result - if still possible, use /proc/sysrq-trigger. Even when
stuck as a result \(em if still possible, use /proc/sysrq-trigger. Even when
processes are stuck, interrupts are likely to be still processed, and as such,
sysrq can be triggered through incoming network packets.
.PP
@@ -11,30 +11,30 @@ requests. The initial sequence number comes from the time of day so you will
have a small window of vulnerability should time go backwards at a reboot.
However, the file /sys/module/xt_SYSREQ/seqno can be used to both query and
update the current sequence number. Also, you should limit as to who can issue
commands using \fB-s\fP and/or \fB-m mac\fP, and also that the destination is
correct using \fB-d\fP (to protect against potential broadcast packets), noting
that it is still short of MAC/IP spoofing:
commands using \fB\-s\fP and/or \fB\-m mac\fP, and also that the destination is
correct using \fB\-d\fP (to protect against potential broadcast packets),
noting that it is still short of MAC/IP spoofing:
.IP
-A INPUT -s 10.10.25.1 -m mac --mac-source aa:bb:cc:dd:ee:ff -d 10.10.25.7
-p udp --dport 9 -j SYSRQ
\-A INPUT \-s 10.10.25.1 \-m mac \-\-mac\-source aa:bb:cc:dd:ee:ff \-d
10.10.25.7 \-p udp \-\-dport 9 \-j SYSRQ
.IP
(with IPsec) -A INPUT -s 10.10.25.1 -d 10.10.25.7 -m policy --dir in --pol
ipsec --proto esp --tunnel-src 10.10.25.1 --tunnel-dst 10.10.25.7
-p udp --dport 9 -j SYSRQ
(with IPsec) \-A INPUT \-s 10.10.25.1 \-d 10.10.25.7 \-m policy \-\-dir in
\-\-pol ipsec \-\-proto esp \-\-tunnel\-src 10.10.25.1 \-\-tunnel\-dst
10.10.25.7 \-p udp \-\-dport 9 \-j SYSRQ
.PP
You should also limit the rate at which connections can be received to limit
the CPU time taken by illegal requests, for example:
.IP
-A INPUT -s 10.10.25.1 -m mac --mac-source aa:bb:cc:dd:ee:ff -d 10.10.25.7
-p udp --dport 9 -m limit --limit 5/minute -j SYSRQ
\-A INPUT \-s 10.10.25.1 \-m mac \-\-mac\-source aa:bb:cc:dd:ee:ff \-d
10.10.25.7 \-p udp \-\-dport 9 \-m limit \-\-limit 5/minute \-j SYSRQ
.PP
This extension does not take any options. The \fB-p udp\fP options are
This extension does not take any options. The \fB\-p udp\fP options are
required.
.PP
The SYSRQ password can be changed through
/sys/module/xt_SYSRQ/parameters/password, for example:
.IP
echo -n "password" >/sys/module/xt_SYSRQ/parameters/password
echo \-n "password" >/sys/module/xt_SYSRQ/parameters/password
.PP
Alternatively, the password may be specified at modprobe time, but this is
insecure as people can possible see it through ps(1). You can use an option
@@ -59,13 +59,13 @@ sysrq_key="s" # the SysRq key(s)
password="password"
seqno="$(date +%s)"
salt="$(dd bs=12 count=1 if=/dev/urandom 2>/dev/null |
openssl enc -base64)"
openssl enc \-base64)"
req="$sysrq_key,$seqno,$salt"
req="$req,$(echo -n "$req,$password" | sha1sum | cut -c1-40)"
req="$req,$(echo \-n "$req,$password" | sha1sum | cut \-c1\-40)"
echo "$req" | socat stdin udp-sendto:10.10.25.7:9
echo "$req" | socat stdin udp\-sendto:10.10.25.7:9
# or
echo "$req" | netcat -uw1 10.10.25.7 9
echo "$req" | netcat \-uw1 10.10.25.7 9
.fi
.PP
See the Linux docs for possible sysrq keys. Important ones are: re(b)oot,

View File

@@ -11,16 +11,16 @@ tarpit.
To tarpit connections to TCP port 80 destined for the current machine:
.IP
-A INPUT -p tcp -m tcp --dport 80 -j TARPIT
.P
\-A INPUT \-p tcp \-m tcp \-\-dport 80 \-j TARPIT
.PP
To significantly slow down Code Red/Nimda-style scans of unused address space,
forward unused ip addresses to a Linux box not acting as a router (e.g. "ip
route 10.0.0.0 255.0.0.0 ip.of.linux.box" on a Cisco), enable IP forwarding on
the Linux box, and add:
.IP
-A FORWARD -p tcp -j TARPIT
\-A FORWARD \-p tcp \-j TARPIT
.IP
-A FORWARD -j DROP
\-A FORWARD \-j DROP
.PP
NOTE:
If you use the conntrack module while you are using TARPIT, you should also use
@@ -28,6 +28,6 @@ the NOTRACK target, or the kernel will unnecessarily allocate resources for
each TARPITted connection. To TARPIT incoming connections to the standard IRC
port while using conntrack, you could:
.IP
-t raw -A PREROUTING -p tcp --dport 6667 -j NOTRACK
\-t raw \-A PREROUTING \-p tcp \-\-dport 6667 \-j NOTRACK
.IP
-A INPUT -p tcp --dport 6667 -j TARPIT
\-A INPUT \-p tcp \-\-dport 6667 \-j TARPIT

View File

@@ -3,6 +3,6 @@ machine on the \fBlocal\fP network segment. In other words, the nexthop
must be the target, or you will have to configure the nexthop to forward it
further if so desired.
.TP
\fB--gw\fP \fIipaddr\fP
\fB\-\-gw\fP \fIipaddr\fP
Send the cloned packet to the host reachable at the given IP address.
Use of 0.0.0.0 (for IPv4 packets) or :: (IPv6) is invalid.

View File

@@ -1,4 +1,4 @@
This matches if a specific condition variable is (un)set.
.TP
[\fB!\fP] \fB--condition\fP \fIname\fP
[\fB!\fP] \fB\-\-condition\fP \fIname\fP
Match on boolean value stored in /proc/net/nf_condition/\fIname\fP.

View File

@@ -1,4 +1,4 @@
.TP
\fB--mac\fP \fIaa:bb:cc:dd:ee:ff\fP[\fB/\fP\fImask\fP]
\fB\-\-mac\fP \fIaa:bb:cc:dd:ee:ff\fP[\fB/\fP\fImask\fP]
Matches the DHCP "Client Host" address (a MAC address) in a DHCP message.
\fImask\fP specifies the prefix length of the initial portion to match.

View File

@@ -1,7 +1,7 @@
This module matches a rate limit based on a fuzzy logic controller (FLC).
.TP
\fB--lower-limit\fP \fInumber\fP
\fB\-\-lower\-limit\fP \fInumber\fP
Specifies the lower limit, in packets per second.
.TP
\fB--upper-limit\fP \fInumber\fP
\fB\-\-upper\-limit\fP \fInumber\fP
Specifies the upper limit, also in packets per second.

View File

@@ -1,9 +1,9 @@
Match a packet by its source or destination country.
.TP
[\fB!\fP] \fB--src-cc\fP, \fB--source-country\fP \fIcountry\fP[\fB,\fP\fIcountry\fP\fB...\fP]
[\fB!\fP] \fB\-\-src\-cc\fP, \fB\-\-source\-country\fP \fIcountry\fP[\fB,\fP\fIcountry\fP\fB...\fP]
Match packet coming from (one of) the specified country(ies)
.TP
[\fB!\fP] \fB--dst-cc\fP, \fB--destination-country\fP \fIcountry\fP[\fB,\fP\fIcountry\fP\fB...\fP]
[\fB!\fP] \fB\-\-dst\-cc\fP, \fB\-\-destination\-country\fP \fIcountry\fP[\fB,\fP\fIcountry\fP\fB...\fP]
Match packet going to (one of) the specified country(ies)
.TP
NOTE:

View File

@@ -30,7 +30,7 @@ Check the MULTICAST flag.
[\fB!\fP] \fB\-\-dynamic\fP
Check the DYNAMIC flag.
.TP
[\fB!\fP] \fB\-\-lower-up\fP
[\fB!\fP] \fB\-\-lower\-up\fP
Check the LOWER_UP flag.
.TP
[\fB!\fP] \fB\-\-dormant\fP

View File

@@ -1,41 +1,41 @@
This module matches certain packets in P2P flows. It is not
designed to match all packets belonging to a P2P connection -
designed to match all packets belonging to a P2P connection \(em
use IPP2P together with CONNMARK for this purpose.
.PP
Use it together with -p tcp or -p udp to search these protocols
only or without -p switch to search packets of both protocols.
Use it together with \-p tcp or \-p udp to search these protocols
only or without \-p switch to search packets of both protocols.
.PP
IPP2P provides the following options, of which one or more may be specified
on the command line:
.TP
.B "--edk "
\fB\-\-edk\fP
Matches as many eDonkey/eMule packets as possible.
.TP
.B "--kazaa "
\fB\-\-kazaa\fP
Matches as many KaZaA packets as possible.
.TP
.B "--gnu "
\fB\-\-gnu\fP
Matches as many Gnutella packets as possible.
.TP
.B "--dc "
\fB\-\-dc\fP
Matches as many Direct Connect packets as possible.
.TP
.B "--bit "
\fB\-\-bit\fP
Matches BitTorrent packets.
.TP
.B "--apple "
\fB\-\-apple\fP
Matches AppleJuice packets.
.TP
.B "--soul "
\fB\-\-soul\fP
Matches some SoulSeek packets. Considered as beta, use careful!
.TP
.B "--winmx "
\fB\-\-winmx\fP
Matches some WinMX packets. Considered as beta, use careful!
.TP
.B "--ares "
Matches Ares and AresLite packets. Use together with -j DROP only.
\fB\-\-ares\fP
Matches Ares and AresLite packets. Use together with \-j DROP only.
.TP
.B "--debug "
\fB\-\-debug\fP
Prints some information about each hit into kernel logfile. May
produce huge logfiles so beware!
.PP
@@ -44,5 +44,5 @@ exchanged as a result of running filesharing programs.
.PP
There is more information on http://ipp2p.org/ , but it has not been updated
since September 2006, and the syntax there is different from the ipp2p.c
provided in Xtables-addons; most importantly, the --ipp2p flag was removed due
to its ambiguity to match "all known" protocols.
provided in Xtables-addons; most importantly, the \-\-ipp2p flag was removed
due to its ambiguity to match "all known" protocols.

View File

@@ -13,25 +13,25 @@ where only at least one symbol spec must be true.
.PP
Known symbol names (and their number):
.PP
1 - \fBnop\fP
1 \(em \fBnop\fP
.PP
2 - \fBsecurity\fP - RFC 1108
2 \(em \fBsecurity\fP \(em RFC 1108
.PP
3 - \fBlsrr\fP - Loose Source Routing, RFC 791
3 \(em \fBlsrr\fP \(em Loose Source Routing, RFC 791
.PP
4 - \fBtimestamp\fP - RFC 781, 791
4 \(em \fBtimestamp\fP \(em RFC 781, 791
.PP
7 - \fBrecord\-route\fP - RFC 791
7 \(em \fBrecord\-route\fP \em RFC 791
.PP
9 - \fBssrr\fP - Strict Source Routing, RFC 791
9 \(em \fBssrr\fP \(em Strict Source Routing, RFC 791
.PP
11 - \fBmtu\-probe\fP - RFC 1063
11 \(em \fBmtu\-probe\fP \(em RFC 1063
.PP
12 - \fBmtu\-reply\fP - RFC 1063
12 \(em \fBmtu\-reply\fP \(em RFC 1063
.PP
18 - \fBtraceroute\fP - RFC 1393
18 \(em \fBtraceroute\fP \(em RFC 1393
.PP
20 - \fBrouter-alert\fP - RFC 2113
20 \(em \fBrouter-alert\fP \(em RFC 2113
.PP
Examples:
.PP

View File

@@ -1,18 +1,19 @@
This module matches the length of a packet against a specific value or range of
values.
.TP
[\fB!\fR] \fB--length\fR \fIlength\fR[\fB:\fR\fIlength\fR]
[\fB!\fR] \fB\-\-length\fR \fIlength\fR[\fB:\fR\fIlength\fR]
Match exact length or length range.
.TP
\fB--layer3\fR
\fB\-\-layer3\fR
Match the layer3 frame size (e.g. IPv4/v6 header plus payload).
.TP
\fB--layer4\fR
\fB\-\-layer4\fR
Match the layer4 frame size (e.g. TCP/UDP header plus payload).
.TP
\fB--layer5\fR
\fB\-\-layer5\fR
Match the layer5 frame size (e.g. TCP/UDP payload, often called layer7).
.PP
If no --layer* option is given, --layer3 is assumed by default. Note that using
--layer5 may not match a packet if it is not one of the recognized types
(currently TCP, UDP, UDPLite, ICMP, AH and ESP) or which has no 5th layer.
If no \-\-layer* option is given, \-\-layer3 is assumed by default. Note that
using \-\-layer5 may not match a packet if it is not one of the recognized
types (currently TCP, UDP, UDPLite, ICMP, AH and ESP) or which has no 5th
layer.

View File

@@ -6,19 +6,19 @@ out, but this information can be used in conjunction with other rules to block
the remote host's future connections. So this match module will match on the
(probably) last packet the remote side will send to your machine.
.TP
\fB--stealth\fR
\fB\-\-stealth\fR
Match if the packet did not belong to any known TCP connection
(Stealth/FIN/XMAS/NULL scan).
.TP
\fB--synscan\fR
\fB\-\-synscan\fR
Match if the connection was a TCP half-open discovery (SYN scan), i.e. the
connection was torn down after the 2nd packet in the 3-way handshake.
.TP
\fB--cnscan\fR
\fB\-\-cnscan\fR
Match if the connection was a TCP full open discovery (connect scan), i.e. the
connection was torn down after completion of the 3-way handshake.
.TP
\fB--grscan\fR
\fB\-\-grscan\fR
Match if data in the connection only flew in the direction of the remote side,
e.g. if the connection was terminated after a locally running daemon sent its
identification. (E.g. openssh, smtp, ftpd.) This may falsely trigger on

113
extensions/libxt_pknock.man Normal file
View File

@@ -0,0 +1,113 @@
Pknock match implements so-called "port knocking", a stealthy system
for network authentication: a client sends packets to selected
ports in a specific sequence (= simple mode, see example 1 below), or a HMAC
payload to a single port (= complex mode, see example 2 below),
to a target machine that has pknock rule(s) installed. The target machine
then decides whether to unblock or block (again) the pknock-protected port(s).
This can be used, for instance, to avoid brute force
attacks on ssh or ftp services.
.PP
Example prerequisites:
.IP
modprobe cn
.IP
modprobe xt_pknock
.PP
Example 1 (TCP mode, manual closing of opened port not possible):
.IP
iptables -P INPUT DROP
.IP
iptables -A INPUT -p tcp -m pknock --knockports 4002,4001,4004 --strict
--name SSH --time 10 --autoclose 60 --dport 22 -j ACCEPT
.PP
The rule will allow tcp port 22 for the attempting IP address after the successful reception of TCP SYN packets
to ports 4002, 4001 and 4004, in this order (a.k.a. port-knocking).
Port numbers in the connect sequence must follow the exact specification, no
other ports may be "knocked" inbetween. The rule is named '\fBSSH\fP' \(em a file of
the same name for tracking port knocking states will be created in
\fB/proc/net/xt_pknock\fP .
Successive port knocks must occur with delay of at most 10 seconds. Port 22 (from the example) will
be automatiaclly dropped after 60 minutes after it was previously allowed.
.PP
Example 2 (UDP mode \(em non-replayable and non-spoofable, manual closing
of opened port possible, secure, also called "SPA" = Secure Port
Authorization):
.IP
iptables -A INPUT -p udp -m pknock --knockports 4000 --name FTP
--opensecret foo --closesecret bar --autoclose 240 -j DROP
.IP
iptables -A INPUT -p tcp -m pknock --checkip --name FTP --dport 21 -j ACCEPT
.PP
The first rule will create an "ALLOWED" record in /proc/net/xt_pknock/FTP after
the successful reception of an UDP packet to port 4000. The packet payload must be
constructed as a HMAC256 using "foo" as a key. The HMAC content is the particular client's IP address as a 32-bit network byteorder quantity,
plus the number of minutes since the Unix epoch, also as a 32-bit value.
(This is known as Simple Packet Authorization, also called "SPA".)
In such case, any subsequent attempt to connect to port 21 from the client's IP
address will cause such packets to be accepted in the second rule.
.PP
Similarly, upon reception of an UDP packet constructed the same way, but with
the key "bar", the first rule will remove a previously installed "ALLOWED" state
record from /proc/net/xt_pknock/FTP, which means that the second rule will
stop matching for subsequent connection attempts to port 21.
In case no close-secret packet is received within 4 hours, the first rule
will remove "ALLOWED" record from /proc/net/xt_pknock/FTP itself.
.PP
Things worth noting:
.PP
\fBGeneral\fP:
.PP
Specifying \fB--autoclose 0\fP means that no automatic close will be performed at all.
.PP
xt_pknock is capable of sending information about successful matches
via a netlink socket to userspace, should you need to implement your own
way of receiving and handling portknock notifications.
Be sure to read the documentation in the doc/pknock/ directory,
or visit the original site \(em http://portknocko.berlios.de/ .
.PP
\fBTCP mode\fP:
.PP
This mode is not immune against eavesdropping, spoofing and
replaying of the port knock sequence by someone else (but its use may still
be sufficient for scenarios where these factors are not necessarily
this important, such as bare shielding of the SSH port from brute-force attacks).
However, if you need these features, you should use UDP mode.
.PP
It is always wise to specify three or more ports that are not monotonically
increasing or decreasing with a small stepsize (e.g. 1024,1025,1026)
to avoid accidentally triggering
the rule by a portscan.
.PP
Specifying the inter-knock timeout with \fB--time\fP is mandatory in TCP mode,
to avoid permanent denial of services by clogging up the peer knock-state tracking table
that xt_pknock internally keeps, should there be a DDoS on the
first-in-row knock port from more hostile IP addresses than what the actual size
of this table is (defaults to 16, can be changed via the "peer_hasht_ents" module parameter).
It is also wise to use as short a time as possible (1 second) for \fB--time\fP
for this very reason. You may also consider increasing the size
of the peer knock-state tracking table. Using \fB--strict\fP also helps,
as it requires the knock sequence to be exact. This means that if the
hostile client sends more knocks to the same port, xt_pknock will
mark such attempt as failed knock sequence and will forget it immediately.
To completely thwart this kind of DDoS, knock-ports would need to have
an additional rate-limit protection. Or you may consider using UDP mode.
.PP
\fBUDP mode\fP:
.PP
This mode is immune against eavesdropping, replaying and spoofing attacks.
It is also immune against DDoS attack on the knockport.
.PP
For this mode to work, the clock difference on the client and on the server
must be below 1 minute. Synchronizing time on both ends by means
of NTP or rdate is strongly suggested.
.PP
There is a rate limiter built into xt_pknock which blocks any subsequent
open attempt in UDP mode should the request arrive within less than one
minute since the first successful open. This is intentional;
it thwarts eventual spoofing attacks.
.PP
Because the payload value of an UDP knock packet is influenced by client's IP address,
UDP mode cannot be used across NAT.
.PP
For sending UDP "SPA" packets, you may use either \fBknock.sh\fP or
\fBknock-orig.sh\fP. These may be found in doc/pknock/util.

158
extensions/libxt_psd.c Normal file
View File

@@ -0,0 +1,158 @@
/*
Shared library add-on to iptables to add PSD support
Copyright (C) 2000,2001 astaro AG
This file is distributed under the terms of the GNU General Public
License (GPL). Copies of the GPL can be obtained from:
ftp://prep.ai.mit.edu/pub/gnu/GPL
2000-05-04 Markus Hennig <hennig@astaro.de> : initial
2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
2003-03-02 Harald Welte <laforge@netfilter.org>: fix 'storage' bug
2008-04-03 Mohd Nawawi <nawawi@tracenetworkcorporation.com>: update to 2.6.24 / 1.4 code
2008-06-24 Mohd Nawawi <nawawi@tracenetworkcorporation.com>: update to 2.6.24 / 1.4.1 code
2009-08-07 Mohd Nawawi Mohamad Jamili <nawawi@tracenetworkcorporation.com> : ported to xtables-addons
*/
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <syslog.h>
#include <getopt.h>
#include <xtables.h>
#include <linux/netfilter/x_tables.h>
#include "xt_psd.h"
/* Function which prints out usage message. */
static void psd_mt_help(void) {
printf(
"psd match options:\n"
" --psd-weight-threshold threshhold Portscan detection weight threshold\n"
" --psd-delay-threshold delay Portscan detection delay threshold\n"
" --psd-lo-ports-weight lo Privileged ports weight\n"
" --psd-hi-ports-weight hi High ports weight\n\n");
}
static const struct option psd_mt_opts[] = {
{.name = "psd-weight-threshold", .has_arg = true, .val = '1'},
{.name = "psd-delay-threshold", .has_arg = true, .val = '2'},
{.name = "psd-lo-ports-weight", .has_arg = true, .val = '3'},
{.name = "psd-hi-ports-weight", .has_arg = true, .val = '4'},
{NULL}
};
/* Initialize the target. */
static void psd_mt_init(struct xt_entry_match *match) {
struct xt_psd_info *psdinfo = (struct xt_psd_info *)match->data;
psdinfo->weight_threshold = SCAN_WEIGHT_THRESHOLD;
psdinfo->delay_threshold = SCAN_DELAY_THRESHOLD;
psdinfo->lo_ports_weight = PORT_WEIGHT_PRIV;
psdinfo->hi_ports_weight = PORT_WEIGHT_HIGH;
}
#define XT_PSD_OPT_CTRESH 0x01
#define XT_PSD_OPT_DTRESH 0x02
#define XT_PSD_OPT_LPWEIGHT 0x04
#define XT_PSD_OPT_HPWEIGHT 0x08
static int psd_mt_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_match **match)
{
struct xt_psd_info *psdinfo = (struct xt_psd_info *)(*match)->data;
unsigned int num;
switch (c) {
/* PSD-weight-threshold */
case '1':
if (*flags & XT_PSD_OPT_CTRESH)
xtables_error(PARAMETER_PROBLEM,"Can't specify --psd-weight-threshold twice");
if (!xtables_strtoui(optarg, NULL, &num, 0, PSD_MAX_RATE))
xtables_error(PARAMETER_PROBLEM, "bad --psd-weight-threshold '%s'", optarg);
psdinfo->weight_threshold = num;
*flags |= XT_PSD_OPT_CTRESH;
return true;
/* PSD-delay-threshold */
case '2':
if (*flags & XT_PSD_OPT_DTRESH)
xtables_error(PARAMETER_PROBLEM, "Can't specify --psd-delay-threshold twice");
if (!xtables_strtoui(optarg, NULL, &num, 0, PSD_MAX_RATE))
xtables_error(PARAMETER_PROBLEM, "bad --psd-delay-threshold '%s'", optarg);
psdinfo->delay_threshold = num;
*flags |= XT_PSD_OPT_DTRESH;
return true;
/* PSD-lo-ports-weight */
case '3':
if (*flags & XT_PSD_OPT_LPWEIGHT)
xtables_error(PARAMETER_PROBLEM, "Can't specify --psd-lo-ports-weight twice");
if (!xtables_strtoui(optarg, NULL, &num, 0, PSD_MAX_RATE))
xtables_error(PARAMETER_PROBLEM, "bad --psd-lo-ports-weight '%s'", optarg);
psdinfo->lo_ports_weight = num;
*flags |= XT_PSD_OPT_LPWEIGHT;
return true;
/* PSD-hi-ports-weight */
case '4':
if (*flags & XT_PSD_OPT_HPWEIGHT)
xtables_error(PARAMETER_PROBLEM, "Can't specify --psd-hi-ports-weight twice");
if (!xtables_strtoui(optarg, NULL, &num, 0, PSD_MAX_RATE))
xtables_error(PARAMETER_PROBLEM, "bad --psd-hi-ports-weight '%s'", optarg);
psdinfo->hi_ports_weight = num;
*flags |= XT_PSD_OPT_HPWEIGHT;
return true;
}
return false;
}
/* Final check; nothing. */
static void psd_mt_final_check(unsigned int flags) {}
/* Prints out the targinfo. */
static void psd_mt_print(const void *ip, const struct xt_entry_match *match, int numeric)
{
const struct xt_psd_info *psdinfo = (const struct xt_psd_info *)match->data;
printf("psd ");
printf("weight-threshold: %u ", psdinfo->weight_threshold);
printf("delay-threshold: %u ", psdinfo->delay_threshold);
printf("lo-ports-weight: %u ", psdinfo->lo_ports_weight);
printf("hi-ports-weight: %u ", psdinfo->hi_ports_weight);
}
/* Saves the union ipt_targinfo in parsable form to stdout. */
static void psd_mt_save(const void *ip, const struct xt_entry_match *match)
{
const struct xt_psd_info *psdinfo = (const struct xt_psd_info *)match->data;
printf("--psd-weight-threshold %u ", psdinfo->weight_threshold);
printf("--psd-delay-threshold %u ", psdinfo->delay_threshold);
printf("--psd-lo-ports-weight %u ", psdinfo->lo_ports_weight);
printf("--psd-hi-ports-weight %u ", psdinfo->hi_ports_weight);
}
static struct xtables_match psd_mt_reg = {
.name = "psd",
.version = XTABLES_VERSION,
.revision = 1,
.family = PF_INET,
.size = XT_ALIGN(sizeof(struct xt_psd_info)),
.userspacesize = XT_ALIGN(sizeof(struct xt_psd_info)),
.help = psd_mt_help,
.init = psd_mt_init,
.parse = psd_mt_parse,
.final_check = psd_mt_final_check,
.print = psd_mt_print,
.save = psd_mt_save,
.extra_opts = psd_mt_opts,
};
static __attribute__((constructor)) void psd_mt_ldr(void)
{
xtables_register_match(&psd_mt_reg);
}

18
extensions/libxt_psd.man Normal file
View File

@@ -0,0 +1,18 @@
Attempt to detect TCP and UDP port scans. This match was derived from
Solar Designer's scanlogd.
.TP
\fB\-\-psd\-weight\-threshold\fP \fIthreshold\fP
Total weight of the latest TCP/UDP packets with different
destination ports coming from the same host to be treated as port
scan sequence.
.TP
\fB\-\-psd\-delay\-threshold\fP \fIdelay\fP
Delay (in hundredths of second) for the packets with different
destination ports coming from the same host to be treated as
possible port scan subsequence.
.TP
\fB\-\-psd\-lo\-ports\-weight\fP \fIweight\fP
Weight of the packet with privileged (<=1024) destination port.
.TP
\fB\-\-psd\-hi\-ports\-weight\fP \fIweight\fP
Weight of the packet with non-priviliged destination port.

View File

@@ -121,7 +121,7 @@ static void quota_mt2_print(const void *ip, const struct xt_entry_match *match,
static struct xtables_match quota_mt2_reg = {
.family = AF_UNSPEC,
.revision = 2,
.revision = 3,
.name = "quota2",
.version = XTABLES_VERSION,
.size = XT_ALIGN(sizeof (struct xt_quota_mtinfo2)),

View File

@@ -7,25 +7,25 @@ When counting down from the initial quota, the counter will stop at 0 and
the match will return false, just like the original "quota" match. In growing
(upcounting) mode, it will always return true.
.TP
\fB--grow\fP
\fB\-\-grow\fP
Count upwards instead of downwards.
.TP
\fB--name\fP \fIname\fP
\fB\-\-name\fP \fIname\fP
Assign the counter a specific name. This option must be present, as an empty
name is not allowed. Names starting with a dot or names containing a slash are
prohibited.
.TP
[\fB!\fP] \fB--quota\fP \fIiq\fP
[\fB!\fP] \fB\-\-quota\fP \fIiq\fP
Specify the initial quota for this counter. If the counter already exists,
it is not reset. An "!" may be used to invert the result of the match. The
negation has no effect when \fB--grow\fP is used.
negation has no effect when \fB\-\-grow\fP is used.
.TP
\fB--packets\fP
\fB\-\-packets\fP
Count packets instead of bytes that passed the quota2 match.
.PP
Because counters in quota2 can be shared, you can combine them for various
purposes, for example, a bytebucket filter that only lets as much traffic go
out as has come in:
.PP
-A INPUT -p tcp --dport 6881 -m quota --name bt --grow
-A OUTPUT -p tcp --sport 6881 -m quota --name bt
\-A INPUT \-p tcp \-\-dport 6881 \-m quota \-\-name bt \-\-grow;
\-A OUTPUT \-p tcp \-\-sport 6881 \-m quota \-\-name bt;

1
extensions/pknock/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/pknlusr

5
extensions/pknock/Kbuild Normal file
View File

@@ -0,0 +1,5 @@
# -*- Makefile -*-
EXTRA_CFLAGS = -I${src}/..
obj-m += xt_pknock.o

View File

@@ -0,0 +1,5 @@
# -*- Makefile -*-
include ../../Makefile.extra
noinst_PROGRAMS = pknlusr

3
extensions/pknock/Mbuild Normal file
View File

@@ -0,0 +1,3 @@
# -*- Makefile -*-
obj-${build_pknock} += libxt_pknock.so

View File

@@ -0,0 +1,343 @@
/*
* Shared library add-on to iptables to add Port Knocking and SPA matching
* support.
*
* (C) 2006-2009 J. Federico Hernandez <fede.hernandez@gmail.com>
* (C) 2006 Luis Floreani <luis.floreani@gmail.com>
*
* This program is released under the terms of GNU GPL version 2.
*/
#include <getopt.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <xtables.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include "xt_pknock.h"
static const struct option pknock_mt_opts[] = {
/* .name, .has_arg, .flag, .val */
{.name = "knockports", .has_arg = true, .val = 'k'},
{.name = "time", .has_arg = true, .val = 't'},
{.name = "autoclose", .has_arg = true, .val = 'a'},
{.name = "name", .has_arg = true, .val = 'n'},
{.name = "opensecret", .has_arg = true, .val = 'o'},
{.name = "closesecret", .has_arg = true, .val = 'z'},
{.name = "strict", .has_arg = false, .val = 'x'},
{.name = "checkip", .has_arg = false, .val = 'c'},
{NULL},
};
static void pknock_mt_help(void)
{
printf("pknock match options:\n"
" --knockports port[,port,port,...] "
"Matches destination port(s).\n"
" --time seconds\n"
"Max allowed time between knocks.\n"
" --autoclose minutes\n"
"Time after which to automatically close opened\n"
"\t\t\t\t\tport(s).\n"
" --strict "
"Knocks sequence must be exact.\n"
" --name rule_name "
"Rule name.\n"
" --checkip "
"Matches if the source ip is in the list.\n"
);
}
static unsigned int
parse_ports(const char *portstring, uint16_t *ports, const char *proto)
{
char *buffer, *cp, *next;
unsigned int i;
buffer = strdup(portstring);
if (buffer == NULL)
xtables_error(OTHER_PROBLEM, "strdup failed");
for (cp = buffer, i = 0; cp != NULL && i < XT_PKNOCK_MAX_PORTS; cp = next, ++i)
{
next=strchr(cp, ',');
if (next != NULL)
*next++ = '\0';
ports[i] = xtables_parse_port(cp, proto);
}
if (cp != NULL)
xtables_error(PARAMETER_PROBLEM, "too many ports specified");
free(buffer);
return i;
}
static char *
proto_to_name(uint8_t proto)
{
switch (proto) {
case IPPROTO_TCP:
return "tcp";
case IPPROTO_UDP:
return "udp";
default:
return NULL;
}
}
static const char *
check_proto(uint16_t pnum, uint8_t invflags)
{
char *proto;
if (invflags & XT_INV_PROTO)
xtables_error(PARAMETER_PROBLEM, PKNOCK "only works with TCP and UDP.");
if ((proto = proto_to_name(pnum)) != NULL)
return proto;
else if (pnum == 0)
xtables_error(PARAMETER_PROBLEM, PKNOCK "needs `-p tcp' or `-p udp'");
else
xtables_error(PARAMETER_PROBLEM, PKNOCK "only works with TCP and UDP.");
}
static int
__pknock_parse(int c, char **argv, int invert, unsigned int *flags,
struct xt_entry_match **match, uint16_t pnum,
uint16_t invflags)
{
const char *proto;
struct xt_pknock_mtinfo *info = (void *)(*match)->data;
unsigned int tmp;
switch (c) {
case 'k': /* --knockports */
if (*flags & XT_PKNOCK_KNOCKPORT)
xtables_error(PARAMETER_PROBLEM, PKNOCK
"cannot use --knockports twice.\n");
proto = check_proto(pnum, invflags);
info->ports_count = parse_ports(optarg, info->port, proto);
info->option |= XT_PKNOCK_KNOCKPORT;
*flags |= XT_PKNOCK_KNOCKPORT;
#if DEBUG
printf("ports_count: %d\n", info->ports_count);
#endif
break;
case 't': /* --time */
if (*flags & XT_PKNOCK_TIME)
xtables_error(PARAMETER_PROBLEM, PKNOCK
"cannot use --time twice.\n");
info->max_time = atoi(optarg);
if (info->max_time == 0)
xtables_error(PARAMETER_PROBLEM, PKNOCK
"--time number must be > 0.\n");
info->option |= XT_PKNOCK_TIME;
*flags |= XT_PKNOCK_TIME;
break;
case 'a': /* --autoclose */
if (*flags & XT_PKNOCK_AUTOCLOSE)
xtables_error(PARAMETER_PROBLEM, PKNOCK
"cannot use --autoclose twice.\n");
if (!xtables_strtoui(optarg, NULL, &tmp, 0, ~0U))
xtables_param_act(XTF_BAD_VALUE, PKNOCK,
"--autoclose", optarg);
info->autoclose_time = tmp;
info->option |= XT_PKNOCK_AUTOCLOSE;
*flags |= XT_PKNOCK_AUTOCLOSE;
break;
case 'n': /* --name */
if (*flags & XT_PKNOCK_NAME)
xtables_error(PARAMETER_PROBLEM, PKNOCK
"cannot use --name twice.\n");
memset(info->rule_name, 0, sizeof(info->rule_name));
strncpy(info->rule_name, optarg, sizeof(info->rule_name) - 1);
info->rule_name_len = strlen(info->rule_name);
info->option |= XT_PKNOCK_NAME;
*flags |= XT_PKNOCK_NAME;
#if DEBUG
printf("info->rule_name: %s\n", info->rule_name);
#endif
break;
case 'o': /* --opensecret */
if (*flags & XT_PKNOCK_OPENSECRET)
xtables_error(PARAMETER_PROBLEM, PKNOCK
"cannot use --opensecret twice.\n");
memset(info->open_secret, 0, sizeof(info->open_secret));
strncpy(info->open_secret, optarg, sizeof(info->open_secret) - 1);
info->open_secret_len = strlen(info->open_secret);
info->option |= XT_PKNOCK_OPENSECRET;
*flags |= XT_PKNOCK_OPENSECRET;
break;
case 'z': /* --closesecret */
if (*flags & XT_PKNOCK_CLOSESECRET)
xtables_error(PARAMETER_PROBLEM, PKNOCK
"cannot use --closesecret twice.\n");
memset(info->close_secret, 0, sizeof(info->close_secret));
strncpy(info->close_secret, optarg, sizeof(info->close_secret) - 1);
info->close_secret_len = strlen(info->close_secret);
info->option |= XT_PKNOCK_CLOSESECRET;
*flags |= XT_PKNOCK_CLOSESECRET;
break;
case 'c': /* --checkip */
if (*flags & XT_PKNOCK_CHECKIP)
xtables_error(PARAMETER_PROBLEM, PKNOCK
"cannot use --checkip twice.\n");
info->option |= XT_PKNOCK_CHECKIP;
*flags |= XT_PKNOCK_CHECKIP;
break;
case 'x': /* --strict */
if (*flags & XT_PKNOCK_STRICT)
xtables_error(PARAMETER_PROBLEM, PKNOCK
"cannot use --strict twice.\n");
info->option |= XT_PKNOCK_STRICT;
*flags |= XT_PKNOCK_STRICT;
break;
default:
return 0;
}
if (invert)
xtables_error(PARAMETER_PROBLEM, PKNOCK "does not support invert.");
return 1;
}
static int pknock_mt_parse(int c, char **argv, int invert, unsigned int *flags,
const void *e, struct xt_entry_match **match)
{
const struct ipt_entry *entry = e;
return __pknock_parse(c, argv, invert, flags, match,
entry->ip.proto, entry->ip.invflags);
}
static void pknock_mt_check(unsigned int flags)
{
if (!(flags & XT_PKNOCK_NAME))
xtables_error(PARAMETER_PROBLEM, PKNOCK
"--name option is required.\n");
if (flags & XT_PKNOCK_KNOCKPORT) {
if (flags & XT_PKNOCK_CHECKIP)
xtables_error(PARAMETER_PROBLEM, PKNOCK
"cannot specify --knockports with --checkip.\n");
if ((flags & XT_PKNOCK_OPENSECRET)
&& !(flags & XT_PKNOCK_CLOSESECRET))
xtables_error(PARAMETER_PROBLEM, PKNOCK
"--opensecret must go with --closesecret.\n");
if ((flags & XT_PKNOCK_CLOSESECRET)
&& !(flags & XT_PKNOCK_OPENSECRET))
xtables_error(PARAMETER_PROBLEM, PKNOCK
"--closesecret must go with --opensecret.\n");
}
if (flags & XT_PKNOCK_CHECKIP) {
if (flags & XT_PKNOCK_KNOCKPORT)
xtables_error(PARAMETER_PROBLEM, PKNOCK
"cannot specify --checkip with --knockports.\n");
if ((flags & XT_PKNOCK_OPENSECRET)
|| (flags & XT_PKNOCK_CLOSESECRET))
xtables_error(PARAMETER_PROBLEM, PKNOCK
"cannot specify --opensecret and"
" --closesecret with --checkip.\n");
if (flags & XT_PKNOCK_TIME)
xtables_error(PARAMETER_PROBLEM, PKNOCK
"cannot specify --time with --checkip.\n");
if (flags & XT_PKNOCK_AUTOCLOSE)
xtables_error(PARAMETER_PROBLEM, PKNOCK
"cannot specify --autoclose with --checkip.\n");
} else if (!(flags & (XT_PKNOCK_OPENSECRET | XT_PKNOCK_TIME))) {
xtables_error(PARAMETER_PROBLEM, PKNOCK
"you must specify --time.\n");
}
}
static void pknock_mt_print(const void *ip,
const struct xt_entry_match *match, int numeric)
{
const struct xt_pknock_mtinfo *info = (void *)match->data;
int i;
printf("pknock ");
if (info->option & XT_PKNOCK_KNOCKPORT) {
printf("knockports ");
for (i = 0; i < info->ports_count; ++i)
printf("%s%d", i ? "," : "", info->port[i]);
printf(" ");
}
if (info->option & XT_PKNOCK_TIME)
printf("time %ld ", (long)info->max_time);
if (info->option & XT_PKNOCK_AUTOCLOSE)
printf("autoclose %lu ", (unsigned long)info->autoclose_time);
if (info->option & XT_PKNOCK_NAME)
printf("name %s ", info->rule_name);
if (info->option & XT_PKNOCK_OPENSECRET)
printf("opensecret ");
if (info->option & XT_PKNOCK_CLOSESECRET)
printf("closesecret ");
if (info->option & XT_PKNOCK_STRICT)
printf("strict ");
if (info->option & XT_PKNOCK_CHECKIP)
printf("checkip ");
}
static void pknock_mt_save(const void *ip, const struct xt_entry_match *match)
{
int i;
const struct xt_pknock_mtinfo *info = (void *)match->data;
if (info->option & XT_PKNOCK_KNOCKPORT) {
printf("--knockports ");
for (i = 0; i < info->ports_count; ++i)
printf("%s%d", i ? "," : "", info->port[i]);
printf(" ");
}
if (info->option & XT_PKNOCK_TIME)
printf("--time %ld ", (long)info->max_time);
if (info->option & XT_PKNOCK_AUTOCLOSE)
printf("--autoclose %lu ",
(unsigned long)info->autoclose_time);
if (info->option & XT_PKNOCK_NAME)
printf("--name %s ", info->rule_name);
if (info->option & XT_PKNOCK_OPENSECRET)
printf("--opensecret ");
if (info->option & XT_PKNOCK_CLOSESECRET)
printf("--closesecret ");
if (info->option & XT_PKNOCK_STRICT)
printf("--strict ");
if (info->option & XT_PKNOCK_CHECKIP)
printf("--checkip ");
}
static struct xtables_match pknock_mt_reg = {
.name = "pknock",
.version = XTABLES_VERSION,
.revision = 1,
.family = AF_INET,
.size = XT_ALIGN(sizeof(struct xt_pknock_mtinfo)),
.userspacesize = XT_ALIGN(sizeof(struct xt_pknock_mtinfo)),
.help = pknock_mt_help,
.parse = pknock_mt_parse,
.final_check = pknock_mt_check,
.print = pknock_mt_print,
.save = pknock_mt_save,
.extra_opts = pknock_mt_opts,
};
static __attribute__((constructor)) void pknock_mt_ldr(void)
{
xtables_register_match(&pknock_mt_reg);
}

View File

@@ -0,0 +1,93 @@
#include <sys/socket.h>
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <linux/netlink.h>
#include <linux/connector.h>
#include "xt_pknock.h"
#define GROUP 1
static struct sockaddr_nl src_addr, dest_addr;
static struct msghdr msg;
static int sock_fd;
static unsigned char *buf;
static struct xt_pknock_nl_msg *nlmsg;
int main(void)
{
socklen_t addrlen;
int status;
int group = GROUP;
struct cn_msg *cnmsg;
int i, buf_size;
const char *ip;
char ipbuf[48];
sock_fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
if (sock_fd == -1) {
perror("socket()");
return 1;
}
memset(&src_addr, 0, sizeof(src_addr));
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pid = getpid();
src_addr.nl_groups = group;
status = bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr));
if (status == -1) {
close(sock_fd);
perror("bind()");
return 1;
}
memset(&dest_addr, 0, sizeof(dest_addr));
dest_addr.nl_family = AF_NETLINK;
dest_addr.nl_pid = 0;
dest_addr.nl_groups = group;
buf_size = sizeof(struct xt_pknock_nl_msg) + sizeof(struct cn_msg) + sizeof(struct nlmsghdr);
buf = malloc(buf_size);
if (!buf) {
perror("malloc()");
return 1;
}
addrlen = sizeof(dest_addr);
while(1) {
memset(buf, 0, buf_size);
status = recvfrom(sock_fd, buf, buf_size, 0, (struct sockaddr *)&dest_addr, &addrlen);
if (status <= 0) {
perror("recvfrom()");
return 1;
}
nlmsg = (struct xt_pknock_nl_msg *) (buf + sizeof(struct cn_msg) + sizeof(struct nlmsghdr));
ip = inet_ntop(AF_INET, &nlmsg->peer_ip, ipbuf, sizeof(ipbuf));
printf("rule_name: %s - ip %s\n", nlmsg->rule_name, ip);
}
close(sock_fd);
free(buf);
return 0;
}

View File

@@ -0,0 +1,13 @@
config NETFILTER_XT_MATCH_PKNOCK
tristate "Port knocking match support"
depends on NETFILTER_XTABLES && CONNECTOR
---help---
pknock match implements so-called Port Knocking, a stealthy system
for network authentication: client sends packets to selected, closed
ports on target machine in a specific sequence. The target machine
(which has pknock match rule set up) then decides whether to
unblock or block (again) its protected port with listening
service. This can be, for instance, used to avoid brute force attacks
on ssh or ftp services.
For more informations go to: http://portknocko.berlios.de/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,53 @@
/*
* Kernel module to implement Port Knocking and SPA matching support.
*
* (C) 2006-2008 J. Federico Hernandez <fede.hernandez@gmail.com>
* (C) 2006 Luis Floreani <luis.floreani@gmail.com>
*
* $Id$
*
* This program is released under the terms of GNU GPL version 2.
*/
#ifndef _XT_PKNOCK_H
#define _XT_PKNOCK_H
#define PKNOCK "xt_pknock: "
enum {
XT_PKNOCK_KNOCKPORT = 1 << 0,
XT_PKNOCK_TIME = 1 << 1,
XT_PKNOCK_NAME = 1 << 2,
XT_PKNOCK_STRICT = 1 << 3,
XT_PKNOCK_CHECKIP = 1 << 4,
XT_PKNOCK_OPENSECRET = 1 << 5,
XT_PKNOCK_CLOSESECRET = 1 << 6,
XT_PKNOCK_AUTOCLOSE = 1 << 7,
/* Can never change these, as they are make up the user protocol. */
XT_PKNOCK_MAX_PORTS = 15,
XT_PKNOCK_MAX_BUF_LEN = 31,
XT_PKNOCK_MAX_PASSWD_LEN = 31,
};
#define DEBUG 1
struct xt_pknock_mtinfo {
char rule_name[XT_PKNOCK_MAX_BUF_LEN+1];
uint32_t rule_name_len;
char open_secret[XT_PKNOCK_MAX_PASSWD_LEN+1];
uint32_t open_secret_len;
char close_secret[XT_PKNOCK_MAX_PASSWD_LEN+1];
uint32_t close_secret_len;
uint8_t option; /* --time, --knock-port, ... */
uint8_t ports_count; /* number of ports */
uint16_t port[XT_PKNOCK_MAX_PORTS]; /* port[,port,port,...] */
uint32_t max_time; /* max matching time between ports */
uint32_t autoclose_time;
};
struct xt_pknock_nl_msg {
char rule_name[XT_PKNOCK_MAX_BUF_LEN+1];
__be32 peer_ip;
};
#endif /* _XT_PKNOCK_H */

View File

@@ -119,19 +119,18 @@ static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
addr_type = RTN_LOCAL;
/* ip_route_me_harder expects skb->dst to be set */
dst_hold(oldskb->dst);
nskb->dst = oldskb->dst;
skb_dst_set(nskb, dst_clone(skb_dst(oldskb)));
if (ip_route_me_harder(&nskb, addr_type))
goto free_nskb;
else
niph = ip_hdr(nskb);
niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
niph->ttl = dst_metric(skb_dst(nskb), RTAX_HOPLIMIT);
nskb->ip_summed = CHECKSUM_NONE;
/* "Never happens" */
if (nskb->len > dst_mtu(nskb->dst))
if (nskb->len > dst_mtu(skb_dst(nskb)))
goto free_nskb;
nf_ct_attach(nskb, oldskb);

View File

@@ -167,20 +167,20 @@ static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
nskb->ip_summed = CHECKSUM_NONE;
/* Adjust IP TTL */
niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
niph->ttl = dst_metric(skb_dst(nskb), RTAX_HOPLIMIT);
/* Adjust IP checksum */
niph->check = 0;
niph->check = ip_fast_csum(skb_network_header(nskb), niph->ihl);
/* "Never happens" */
if (nskb->len > dst_mtu(nskb->dst))
if (nskb->len > dst_mtu(skb_dst(nskb)))
goto free_nskb;
nf_ct_attach(nskb, oldskb);
NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
dst_output);
NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, nskb, NULL,
skb_dst(nskb)->dev, dst_output);
return;
free_nskb:
@@ -192,7 +192,7 @@ tarpit_tg(struct sk_buff **pskb, const struct xt_target_param *par)
{
const struct sk_buff *skb = *pskb;
const struct iphdr *iph = ip_hdr(skb);
const struct rtable *rt = (const void *)skb->dst;
const struct rtable *rt = skb_rtable(skb);
/* Do we have an input route cache entry? (Not in PREROUTING.) */
if (rt == NULL)

View File

@@ -79,9 +79,9 @@ tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info)
return false;
}
dst_release(skb->dst);
skb->dst = &rt->u.dst;
skb->dev = skb->dst->dev;
dst_release(skb_dst(skb));
skb_dst_set(skb, &rt->u.dst);
skb->dev = rt->u.dst.dev;
skb->protocol = htons(ETH_P_IP);
return true;
}
@@ -104,7 +104,7 @@ static inline bool dev_hh_avail(const struct net_device *dev)
*/
static void tee_tg_send(struct sk_buff *skb)
{
const struct dst_entry *dst = skb->dst;
const struct dst_entry *dst = skb_dst(skb);
const struct net_device *dev = dst->dev;
unsigned int hh_len = LL_RESERVED_SPACE(dev);
@@ -175,7 +175,7 @@ tee_tg4(struct sk_buff **pskb, const struct xt_target_param *par)
/*
* Copy the skb, and route the copy. Will later return %XT_CONTINUE for
* the original skb, which should continue on its way as if nothing has
* happened. The copy should be independantly delivered to the TEE --gw.
* happened. The copy should be independently delivered to the TEE --gw.
*/
skb = skb_copy(skb, GFP_ATOMIC);
if (skb == NULL) {
@@ -251,9 +251,9 @@ tee_tg_route6(struct sk_buff *skb, const struct xt_tee_tginfo *info)
return false;
}
dst_release(skb->dst);
skb->dst = dst;
skb->dev = skb->dst->dev;
dst_release(skb_dst(skb));
skb_dst_set(skb, dst);
skb->dev = dst->dev;
skb->protocol = htons(ETH_P_IPV6);
return true;
}

View File

@@ -55,7 +55,7 @@ struct condition_variable {
/* proc_lock is a user context only semaphore used for write access */
/* to the conditions' list. */
static DECLARE_MUTEX(proc_lock);
static struct semaphore proc_lock;
static LIST_HEAD(conditions_list);
static struct proc_dir_entry *proc_net_condition;
@@ -232,6 +232,7 @@ static int __init condition_mt_init(void)
{
int ret;
sema_init(&proc_lock, 1);
proc_net_condition = proc_mkdir(dir_name, init_net__proc_net);
if (proc_net_condition == NULL)
return -EACCES;

View File

@@ -844,7 +844,13 @@ ipp2p_mt(const struct sk_buff *skb, const struct xt_match_param *par)
if (tcph->rst) return 0; /* if RST bit is set bail out */
haystack += tcph->doff * 4; /* get TCP-Header-Size */
if (tcph->doff * 4 > hlen) {
if (info->debug)
pr_info("TCP header indicated packet larger than it is\n");
hlen = 0;
} else {
hlen -= tcph->doff * 4;
}
while (matchlist[i].command) {
if ((info->cmd & matchlist[i].command) == matchlist[i].command &&
hlen > matchlist[i].packet_len)

View File

@@ -0,0 +1,6 @@
config NETFILTER_XT_MATCH_PSD
tristate 'psd match support'
depends on NETFILTER_XTABLES && NETFILTER_ADVANCED
---help---
This option adds a `psd' match, which allows you to create rules in
any iptables table wich will detect TCP and UDP port scans.

335
extensions/xt_psd.c Normal file
View File

@@ -0,0 +1,335 @@
/*
This is a module which is used for PSD (portscan detection)
Derived from scanlogd v2.1 written by Solar Designer <solar@false.com>
and LOG target module.
Copyright (C) 2000,2001 astaro AG
This file is distributed under the terms of the GNU General Public
License (GPL). Copies of the GPL can be obtained from:
ftp://prep.ai.mit.edu/pub/gnu/GPL
2000-05-04 Markus Hennig <hennig@astaro.de> : initial
2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
2001-01-02 Dennis Koslowski <koslowski@astaro.de> : output modified
2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
2004-05-05 Martijn Lievaart <m@rtij.nl> : ported to 2.6
2007-04-05 Mohd Nawawi Mohamad Jamili <nawawi@tracenetworkcorporation.com> : ported to 2.6.18
2008-03-21 Mohd Nawawi Mohamad Jamili <nawawi@tracenetworkcorporation.com> : ported to 2.6.24
2009-08-07 Mohd Nawawi Mohamad Jamili <nawawi@tracenetworkcorporation.com> : ported to xtables-addons
*/
#define pr_fmt(x) KBUILD_MODNAME ": " x
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <net/tcp.h>
#include <linux/spinlock.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter/x_tables.h>
#include "xt_psd.h"
#include "compat_xtables.h"
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Dennis Koslowski <koslowski@astaro.com>");
MODULE_AUTHOR("Martijn Lievaart <m@rtij.nl>");
MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
MODULE_AUTHOR(" Mohd Nawawi Mohamad Jamili <nawawi@tracenetworkcorporation.com>");
MODULE_DESCRIPTION("Xtables: PSD - portscan detection");
MODULE_ALIAS("ipt_psd");
#define HF_DADDR_CHANGING 0x01
#define HF_SPORT_CHANGING 0x02
#define HF_TOS_CHANGING 0x04
#define HF_TTL_CHANGING 0x08
/*
* Information we keep per each target port
*/
struct port {
u_int16_t number; /* port number */
u_int8_t proto; /* protocol number */
u_int8_t and_flags; /* tcp ANDed flags */
u_int8_t or_flags; /* tcp ORed flags */
};
/*
* Information we keep per each source address.
*/
struct host {
struct host *next; /* Next entry with the same hash */
unsigned long timestamp; /* Last update time */
struct in_addr src_addr; /* Source address */
struct in_addr dest_addr; /* Destination address */
unsigned short src_port; /* Source port */
int count; /* Number of ports in the list */
int weight; /* Total weight of ports in the list */
struct port ports[SCAN_MAX_COUNT - 1]; /* List of ports */
unsigned char tos; /* TOS */
unsigned char ttl; /* TTL */
unsigned char flags; /* HF_ flags bitmask */
};
/*
* State information.
*/
static struct {
spinlock_t lock;
struct host list[LIST_SIZE]; /* List of source addresses */
struct host *hash[HASH_SIZE]; /* Hash: pointers into the list */
int index; /* Oldest entry to be replaced */
} state;
/*
* Convert an IP address into a hash table index.
*/
static inline int hashfunc(struct in_addr addr)
{
unsigned int value;
int hash;
value = addr.s_addr;
hash = 0;
do {
hash ^= value;
} while ((value >>= HASH_LOG) != 0);
return hash & (HASH_SIZE - 1);
}
static bool
xt_psd_match(const struct sk_buff *pskb, const struct xt_match_param *match)
{
const struct iphdr *iph;
const struct tcphdr *tcph;
struct tcphdr _tcph;
struct in_addr addr;
u_int16_t src_port,dest_port;
u_int8_t tcp_flags, proto;
unsigned long now;
struct host *curr, *last, **head;
int hash, index, count;
/* Parameters from userspace */
const struct xt_psd_info *psdinfo = match->matchinfo;
/* IP header */
iph = ip_hdr(pskb);
/* Sanity check */
if (iph->frag_off & htons(IP_OFFSET)) {
pr_debug("sanity check failed\n");
return false;
}
/* TCP or UDP ? */
proto = iph->protocol;
if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
pr_debug("protocol not supported\n");
return false;
}
/* Get the source address, source & destination ports, and TCP flags */
addr.s_addr = iph->saddr;
tcph = skb_header_pointer(pskb, match->thoff, sizeof(_tcph), &_tcph);
if (tcph == NULL)
return false;
/* Yep, it's dirty */
src_port = tcph->source;
dest_port = tcph->dest;
if (proto == IPPROTO_TCP)
tcp_flags = *((u_int8_t*)tcph + 13);
else
tcp_flags = 0x00;
/* We're using IP address 0.0.0.0 for a special purpose here, so don't let
* them spoof us. [DHCP needs this feature - HW] */
if (addr.s_addr == 0) {
pr_debug("spoofed source address (0.0.0.0)\n");
return false;
}
/* Use jiffies here not to depend on someone setting the time while we're
* running; we need to be careful with possible return value overflows. */
now = jiffies;
spin_lock(&state.lock);
/* Do we know this source address already? */
count = 0;
last = NULL;
if ((curr = *(head = &state.hash[hash = hashfunc(addr)])) != NULL)
do {
if (curr->src_addr.s_addr == addr.s_addr)
break;
count++;
if (curr->next != NULL)
last = curr;
} while ((curr = curr->next) != NULL);
if (curr != NULL) {
/* We know this address, and the entry isn't too old. Update it. */
if (now - curr->timestamp <= (psdinfo->delay_threshold*HZ)/100 &&
time_after_eq(now, curr->timestamp)) {
/* Just update the appropriate list entry if we've seen this port already */
for (index = 0; index < curr->count; index++) {
if (curr->ports[index].number == dest_port) {
curr->ports[index].proto = proto;
curr->ports[index].and_flags &= tcp_flags;
curr->ports[index].or_flags |= tcp_flags;
goto out_no_match;
}
}
/* TCP/ACK and/or TCP/RST to a new port? This could be an outgoing connection. */
if (proto == IPPROTO_TCP && (tcph->ack || tcph->rst))
goto out_no_match;
/* Packet to a new port, and not TCP/ACK: update the timestamp */
curr->timestamp = now;
/* Logged this scan already? Then drop the packet. */
if (curr->weight >= psdinfo->weight_threshold)
goto out_match;
/* Specify if destination address, source port, TOS or TTL are not fixed */
if (curr->dest_addr.s_addr != iph->daddr)
curr->flags |= HF_DADDR_CHANGING;
if (curr->src_port != src_port)
curr->flags |= HF_SPORT_CHANGING;
if (curr->tos != iph->tos)
curr->flags |= HF_TOS_CHANGING;
if (curr->ttl != iph->ttl)
curr->flags |= HF_TTL_CHANGING;
/* Update the total weight */
curr->weight += (ntohs(dest_port) < 1024) ?
psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
/* Got enough destination ports to decide that this is a scan? */
/* Then log it and drop the packet. */
if (curr->weight >= psdinfo->weight_threshold)
goto out_match;
/* Remember the new port */
if (curr->count < SCAN_MAX_COUNT) {
curr->ports[curr->count].number = dest_port;
curr->ports[curr->count].proto = proto;
curr->ports[curr->count].and_flags = tcp_flags;
curr->ports[curr->count].or_flags = tcp_flags;
curr->count++;
}
goto out_no_match;
}
/* We know this address, but the entry is outdated. Mark it unused, and
* remove from the hash table. We'll allocate a new entry instead since
* this one might get re-used too soon. */
curr->src_addr.s_addr = 0;
if (last != NULL)
last->next = last->next->next;
else if (*head != NULL)
*head = (*head)->next;
last = NULL;
}
/* We don't need an ACK from a new source address */
if (proto == IPPROTO_TCP && tcph->ack)
goto out_no_match;
/* Got too many source addresses with the same hash value? Then remove the
* oldest one from the hash table, so that they can't take too much of our
* CPU time even with carefully chosen spoofed IP addresses. */
if (count >= HASH_MAX && last != NULL)
last->next = NULL;
/* We're going to re-use the oldest list entry, so remove it from the hash
* table first (if it is really already in use, and isn't removed from the
* hash table already because of the HASH_MAX check above). */
/* First, find it */
if (state.list[state.index].src_addr.s_addr != 0)
head = &state.hash[hashfunc(state.list[state.index].src_addr)];
else
head = &last;
last = NULL;
if ((curr = *head) != NULL)
do {
if (curr == &state.list[state.index])
break;
last = curr;
} while ((curr = curr->next) != NULL);
/* Then, remove it */
if (curr != NULL) {
if (last != NULL)
last->next = last->next->next;
else if (*head != NULL)
*head = (*head)->next;
}
/* Get our list entry */
curr = &state.list[state.index++];
if (state.index >= LIST_SIZE)
state.index = 0;
/* Link it into the hash table */
head = &state.hash[hash];
curr->next = *head;
*head = curr;
/* And fill in the fields */
curr->timestamp = now;
curr->src_addr = addr;
curr->dest_addr.s_addr = iph->daddr;
curr->src_port = src_port;
curr->count = 1;
curr->weight = (ntohs(dest_port) < 1024) ? psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
curr->ports[0].number = dest_port;
curr->ports[0].proto = proto;
curr->ports[0].and_flags = tcp_flags;
curr->ports[0].or_flags = tcp_flags;
curr->tos = iph->tos;
curr->ttl = iph->ttl;
out_no_match:
spin_unlock(&state.lock);
return false;
out_match:
spin_unlock(&state.lock);
return true;
}
static struct xt_match xt_psd_reg __read_mostly = {
.name = "psd",
.family = AF_INET,
.revision = 1,
.match = xt_psd_match,
.matchsize = sizeof(struct xt_psd_info),
.me = THIS_MODULE,
};
static int __init xt_psd_init(void)
{
spin_lock_init(&(state.lock));
return xt_register_match(&xt_psd_reg);
}
static void __exit xt_psd_exit(void)
{
xt_unregister_match(&xt_psd_reg);
}
module_init(xt_psd_init);
module_exit(xt_psd_exit);

41
extensions/xt_psd.h Normal file
View File

@@ -0,0 +1,41 @@
#ifndef _LINUX_NETFILTER_XT_PSD_H
#define _LINUX_NETFILTER_XT_PSD_H 1
#include <linux/param.h>
#include <linux/types.h>
/*
* High port numbers have a lower weight to reduce the frequency of false
* positives, such as from passive mode FTP transfers.
*/
#define PORT_WEIGHT_PRIV 3
#define PORT_WEIGHT_HIGH 1
#define PSD_MAX_RATE 10000
/*
* Port scan detection thresholds: at least COUNT ports need to be scanned
* from the same source, with no longer than DELAY ticks between ports.
*/
#define SCAN_MIN_COUNT 7
#define SCAN_MAX_COUNT (SCAN_MIN_COUNT * PORT_WEIGHT_PRIV)
#define SCAN_WEIGHT_THRESHOLD SCAN_MAX_COUNT
#define SCAN_DELAY_THRESHOLD (300) /* old usage of HZ here was erroneously and broke under uml */
/*
* Keep track of up to LIST_SIZE source addresses, using a hash table of
* HASH_SIZE entries for faster lookups, but limiting hash collisions to
* HASH_MAX source addresses per the same hash value.
*/
#define LIST_SIZE 0x100
#define HASH_LOG 9
#define HASH_SIZE (1 << HASH_LOG)
#define HASH_MAX 0x10
struct xt_psd_info {
__u32 weight_threshold;
__u32 delay_threshold;
__u16 lo_ports_weight;
__u16 hi_ports_weight;
};
#endif /*_LINUX_NETFILTER_XT_PSD_H*/

View File

@@ -21,12 +21,15 @@
#include "xt_quota2.h"
#include "compat_xtables.h"
struct quota_counter {
/**
* @lock: lock to protect quota writers from each other
*/
struct xt_quota_counter {
u_int64_t quota;
spinlock_t lock;
struct list_head list;
atomic_t ref;
char name[XT_QUOTA_COUNTER_NAME_LENGTH];
char name[sizeof(((struct xt_quota_mtinfo2 *)NULL)->name)];
struct proc_dir_entry *procfs_entry;
};
@@ -44,7 +47,7 @@ module_param_named(gid, quota_list_gid, uint, S_IRUGO | S_IWUSR);
static int quota_proc_read(char *page, char **start, off_t offset,
int count, int *eof, void *data)
{
struct quota_counter *e = data;
struct xt_quota_counter *e = data;
int ret;
spin_lock_bh(&e->lock);
@@ -56,7 +59,7 @@ static int quota_proc_read(char *page, char **start, off_t offset,
static int quota_proc_write(struct file *file, const char __user *input,
unsigned long size, void *data)
{
struct quota_counter *e = data;
struct xt_quota_counter *e = data;
char buf[sizeof("18446744073709551616")];
if (size > sizeof(buf))
@@ -66,39 +69,58 @@ static int quota_proc_write(struct file *file, const char __user *input,
buf[sizeof(buf)-1] = '\0';
spin_lock_bh(&e->lock);
e->quota = simple_strtoul(buf, NULL, 0);
e->quota = simple_strtoull(buf, NULL, 0);
spin_unlock_bh(&e->lock);
return size;
}
static struct xt_quota_counter *
q2_new_counter(const struct xt_quota_mtinfo2 *q, bool anon)
{
struct xt_quota_counter *e;
unsigned int size;
/* Do not need all the procfs things for anonymous counters. */
size = anon ? offsetof(typeof(*e), list) : sizeof(*e);
e = kmalloc(size, GFP_KERNEL);
if (e == NULL)
return NULL;
e->quota = q->quota;
spin_lock_init(&e->lock);
if (!anon) {
INIT_LIST_HEAD(&e->list);
atomic_set(&e->ref, 1);
strncpy(e->name, q->name, sizeof(e->name));
}
return e;
}
/**
* q2_get_counter - get ref to counter or create new
* @name: name of counter
*/
static struct quota_counter *q2_get_counter(const struct xt_quota_mtinfo2 *q)
static struct xt_quota_counter *
q2_get_counter(const struct xt_quota_mtinfo2 *q)
{
struct proc_dir_entry *p;
struct quota_counter *e;
struct xt_quota_counter *e;
if (*q->name == '\0')
return q2_new_counter(q, true);
spin_lock_bh(&counter_list_lock);
list_for_each_entry(e, &counter_list, list) {
list_for_each_entry(e, &counter_list, list)
if (strcmp(e->name, q->name) == 0) {
atomic_inc(&e->ref);
spin_unlock_bh(&counter_list_lock);
return e;
}
}
e = kmalloc(sizeof(struct quota_counter), GFP_KERNEL);
e = q2_new_counter(q, false);
if (e == NULL)
goto out;
e->quota = q->quota;
spin_lock_init(&e->lock);
INIT_LIST_HEAD(&e->list);
atomic_set(&e->ref, 1);
strncpy(e->name, q->name, sizeof(e->name));
p = e->procfs_entry = create_proc_entry(e->name, quota_list_perms,
proc_xt_quota);
if (p == NULL || IS_ERR(p))
@@ -130,15 +152,16 @@ static bool quota_mt2_check(const struct xt_mtchk_param *par)
return false;
q->name[sizeof(q->name)-1] = '\0';
if (*q->name == '\0' || *q->name == '.' ||
strchr(q->name, '/') != NULL) {
printk(KERN_ERR "xt_quota.2: illegal name\n");
if (*q->name == '.' || strchr(q->name, '/') != NULL) {
printk(KERN_ERR "xt_quota<%u>: illegal name\n",
par->match->revision);
return false;
}
q->master = q2_get_counter(q);
if (q->master == NULL) {
printk(KERN_ERR "xt_quota.2: memory alloc failure\n");
printk(KERN_ERR "xt_quota<%u>: memory alloc failure\n",
par->match->revision);
return false;
}
@@ -148,7 +171,12 @@ static bool quota_mt2_check(const struct xt_mtchk_param *par)
static void quota_mt2_destroy(const struct xt_mtdtor_param *par)
{
struct xt_quota_mtinfo2 *q = par->matchinfo;
struct quota_counter *e = q->master;
struct xt_quota_counter *e = q->master;
if (*q->name == '\0') {
kfree(e);
return;
}
spin_lock_bh(&counter_list_lock);
if (!atomic_dec_and_test(&e->ref)) {
@@ -157,8 +185,8 @@ static void quota_mt2_destroy(const struct xt_mtdtor_param *par)
}
list_del(&e->list);
spin_unlock_bh(&counter_list_lock);
remove_proc_entry(e->name, proc_xt_quota);
spin_unlock_bh(&counter_list_lock);
kfree(e);
}
@@ -166,17 +194,15 @@ static bool
quota_mt2(const struct sk_buff *skb, const struct xt_match_param *par)
{
struct xt_quota_mtinfo2 *q = (void *)par->matchinfo;
struct quota_counter *e = q->master;
struct xt_quota_counter *e = q->master;
bool ret = q->flags & XT_QUOTA_INVERT;
if (q->flags & XT_QUOTA_GROW) {
spin_lock_bh(&e->lock);
if (q->flags & XT_QUOTA_GROW) {
e->quota += (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len;
q->quota = e->quota;
spin_unlock_bh(&e->lock);
ret = true;
} else {
spin_lock_bh(&e->lock);
if (e->quota >= skb->len) {
e->quota -= (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len;
ret = !ret;
@@ -185,16 +211,15 @@ quota_mt2(const struct sk_buff *skb, const struct xt_match_param *par)
e->quota = 0;
}
q->quota = e->quota;
spin_unlock_bh(&e->lock);
}
spin_unlock_bh(&e->lock);
return ret;
}
static struct xt_match quota_mt2_reg[] __read_mostly = {
{
.name = "quota2",
.revision = 2,
.revision = 3,
.family = NFPROTO_IPV4,
.checkentry = quota_mt2_check,
.match = quota_mt2,
@@ -204,7 +229,7 @@ static struct xt_match quota_mt2_reg[] __read_mostly = {
},
{
.name = "quota2",
.revision = 2,
.revision = 3,
.family = NFPROTO_IPV6,
.checkentry = quota_mt2_check,
.match = quota_mt2,

View File

@@ -6,21 +6,19 @@ enum xt_quota_flags {
XT_QUOTA_GROW = 1 << 1,
XT_QUOTA_PACKET = 1 << 2,
XT_QUOTA_MASK = 0x7,
XT_QUOTA_COUNTER_NAME_LENGTH = 31,
};
struct quota_counter;
struct xt_quota_counter;
struct xt_quota_mtinfo2 {
char name[XT_QUOTA_COUNTER_NAME_LENGTH];
char name[15];
u_int8_t flags;
/* Comparison-invariant */
aligned_u64 quota;
/* Used internally by the kernel */
struct quota_counter *master __attribute__((aligned(8)));
struct xt_quota_counter *master __attribute__((aligned(8)));
};
#endif /* _XT_QUOTA_H */

View File

@@ -1,5 +1,6 @@
# -*- Makefile -*-
#
build_ACCOUNT=m
build_CHAOS=m
build_DELUDE=m
build_DHCPMAC=m
@@ -20,4 +21,6 @@ build_ipset=m
build_ipv4options=m
build_length2=m
build_lscan=m
build_pknock=m
build_psd=m
build_quota2=m

View File

@@ -1,6 +1,6 @@
.TH xtables\-addons 8 "v1.17 (2009\-06\-16)" "" "v1.17 (2009\-06\-16)"
.TH xtables-addons 8 "v1.19 (2009-10-12)" "" "v1.19 (2009-10-12)"
.SH Name
Xtables\-addons - additional extensions for iptables, ip6tables, etc.
Xtables-addons \(em additional extensions for iptables, ip6tables, etc.
.SH Targets
.\" @TARGET@
.SH Matches