Compare commits

..

23 Commits
v1.7 ... v1.9

Author SHA1 Message Date
Jan Engelhardt
c168a2f142 Xtables-addons 1.9 2009-01-30 06:34:07 +01:00
Jan Engelhardt
68af6989b1 ipset: bump version to 2.4.7
Moving from ipset 2.4.5 to 2.4.7. Upstream changed, but
the Xtables-addons copy did not (issues were not present):

>2.4.7
>  - Typo which broke compilation with kernels < 2.6.28
>    fixed (reported by Richard Lucassen, Danny Rawlins)
>
>2.4.6
>   - Compatibility fix for kernels >= 2.6.28
2009-01-30 06:33:21 +01:00
Jan Engelhardt
446c67018a TEE: remove calls to check_inverse 2009-01-30 06:19:22 +01:00
Jan Engelhardt
0fe8e180c4 ipp2p: version bump
For cosmetics, or so. The recent bugfix warrants this I'd say.
2009-01-30 06:02:10 +01:00
Jan Engelhardt
7cdfc0ac3d Add xt_length2
xt_length2 provides exact layer-4,-5 and -7 length matching
besides the preexisting layer-3 length match.
2009-01-30 06:01:12 +01:00
Jan Engelhardt
85cab10371 Xtables-addons 1.8 2009-01-10 14:05:46 +01:00
Jan Engelhardt
61d8425cb6 Merge branch 'TEE6' 2009-01-10 14:03:04 +01:00
Jan Engelhardt
d49b6244c1 Merge branch 'TEE' 2009-01-10 14:03:03 +01:00
Jan Engelhardt
10c2b97786 Merge branch 'ipp2p' 2009-01-10 13:59:43 +01:00
Jan Engelhardt
9ed364ed36 TEE: collapse tee_tg_send{4,6} 2009-01-10 13:58:19 +01:00
Jan Engelhardt
b95e5f6417 TEE: IPv6 support for iptables module 2009-01-10 10:19:21 +01:00
Jan Engelhardt
4afebf88eb Merge branch 'TEE' into TEE6 2009-01-10 10:01:31 +01:00
Jan Engelhardt
d523158e92 TEE: iptables -nL and -L produced conversely output 2009-01-10 10:01:27 +01:00
Jan Engelhardt
1fd1787a1c TEE: limit iptables module to NFPROTO_IPV4
The code here is only usable with IPv4.
2009-01-10 09:57:44 +01:00
Jan Engelhardt
fbbca68790 ipp2p: partial revert of 3c8131b9
Revert part of 3c8131b976.

The transport header offset is not (yet) set by the time Netfilter
is invoked so using tcp_hdr/udp_hdr has undefined behavior.
2009-01-10 08:25:42 +01:00
Jan Engelhardt
4cdfd49637 ipp2p: add boundary check in search_all_kazaa
To avoid underflow on "end - 18", we must check for plen >= 18.
2009-01-10 06:11:13 +01:00
Jan Engelhardt
31c01cf107 portscan: update manpage about --grscan caveats 2009-01-10 05:23:43 +01:00
Jan Engelhardt
879e964f60 ipp2p: remove log flooding
Syslog was flooded by lots of messages due to if (plen >= 5) firing
on any packet, when it should have been plen < 5. Incidentally, this
turned up that plen also takes on huge nonsense values, assuming
underflow - yet to be investigated.
2009-01-10 04:47:14 +01:00
Jan Engelhardt
019c9de291 ipp2p: update help text
More suggestions from Stanley Pinchak.
2009-01-10 04:42:27 +01:00
Jan Engelhardt
af370f81f0 ipp2p: update manpage
(With suggestions from Stanley Pinchak.)
2009-01-09 20:24:41 +01:00
Jan Engelhardt
4aad07bdc4 TEE: IPv6 support 2008-11-21 01:15:21 +01:00
Jan Engelhardt
7a3f874753 TEE: various cleanups, add comments
Normalize function names in light of upcoming IPv6 support.
Reformat other lines.
Add comment note about tee_send4.
2008-11-21 01:15:03 +01:00
Jan Engelhardt
f77a8e2eda TEE: do not use TOS for routing
Otherwise the cloned packet may be subject to more policy routing
rules than expected.
2008-11-21 01:15:02 +01:00
17 changed files with 695 additions and 76 deletions

View File

@@ -1,5 +1,5 @@
AC_INIT([xtables-addons], [1.7])
AC_INIT([xtables-addons], [1.9])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AC_PROG_INSTALL

View File

@@ -19,6 +19,7 @@ obj-${build_fuzzy} += xt_fuzzy.o
obj-${build_geoip} += xt_geoip.o
obj-${build_ipp2p} += xt_ipp2p.o
obj-${build_ipset} += ipset/
obj-${build_length2} += xt_length2.o
obj-${build_portscan} += xt_portscan.o
obj-${build_quota2} += xt_quota2.o

View File

@@ -12,5 +12,6 @@ obj-${build_fuzzy} += libxt_fuzzy.so
obj-${build_geoip} += libxt_geoip.so
obj-${build_ipp2p} += libxt_ipp2p.so
obj-${build_ipset} += ipset/
obj-${build_length2} += libxt_length2.so
obj-${build_portscan} += libxt_portscan.so
obj-${build_quota2} += libxt_quota2.so

View File

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

View File

@@ -1,7 +1,7 @@
/*
* "TEE" target extension for iptables
* Copyright © Sebastian Claßen <sebastian.classen [at] freenet.ag>, 2007
* Jan Engelhardt <jengelh [at] medozas de>, 2007 - 2008
* Jan Engelhardt <jengelh [at] medozas de>, 2007 - 2009
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License; either
@@ -53,10 +53,6 @@ static int tee_tg_parse(int c, char **argv, int invert, unsigned int *flags,
exit_error(PARAMETER_PROBLEM,
"Cannot specify --gw more than once");
if (check_inverse(optarg, &invert, NULL, 0))
exit_error(PARAMETER_PROBLEM,
"Unexpected \"!\" after --gateway");
ia = numeric_to_ipaddr(optarg);
if (ia == NULL)
exit_error(PARAMETER_PROBLEM,
@@ -70,6 +66,31 @@ static int tee_tg_parse(int c, char **argv, int invert, unsigned int *flags,
return false;
}
static int tee_tg6_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_target **target)
{
struct xt_tee_tginfo *info = (void *)(*target)->data;
const struct in6_addr *ia;
switch (c) {
case 'g':
if (*flags & FLAG_GATEWAY)
exit_error(PARAMETER_PROBLEM,
"Cannot specify --gw more than once");
ia = numeric_to_ip6addr(optarg);
if (ia == NULL)
exit_error(PARAMETER_PROBLEM,
"Invalid IP address %s", optarg);
memcpy(&info->gw, ia, sizeof(*ia));
*flags |= FLAG_GATEWAY;
return true;
}
return false;
}
static void tee_tg_check(unsigned int flags)
{
if (flags == 0)
@@ -83,9 +104,20 @@ static void tee_tg_print(const void *ip, const struct xt_entry_target *target,
const struct xt_tee_tginfo *info = (const void *)target->data;
if (numeric)
printf("TEE gw:%s ", ipaddr_to_anyname(&info->gw.in));
else
printf("TEE gw:%s ", ipaddr_to_numeric(&info->gw.in));
else
printf("TEE gw:%s ", ipaddr_to_anyname(&info->gw.in));
}
static void tee_tg6_print(const void *ip, const struct xt_entry_target *target,
int numeric)
{
const struct xt_tee_tginfo *info = (const void *)target->data;
if (numeric)
printf("TEE gw:%s ", ip6addr_to_numeric(&info->gw.in6));
else
printf("TEE gw:%s ", ip6addr_to_anyname(&info->gw.in6));
}
static void tee_tg_save(const void *ip, const struct xt_entry_target *target)
@@ -95,9 +127,18 @@ static void tee_tg_save(const void *ip, const struct xt_entry_target *target)
printf("--gateway %s ", ipaddr_to_numeric(&info->gw.in));
}
static void tee_tg6_save(const void *ip, const struct xt_entry_target *target)
{
const struct xt_tee_tginfo *info = (const void *)target->data;
printf("--gateway %s ", ip6addr_to_numeric(&info->gw.in6));
}
static struct xtables_target tee_tg_reg = {
.name = "TEE",
.version = XTABLES_VERSION,
.revision = 0,
.family = PF_INET,
.size = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
.userspacesize = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
.help = tee_tg_help,
@@ -108,7 +149,23 @@ static struct xtables_target tee_tg_reg = {
.extra_opts = tee_tg_opts,
};
static struct xtables_target tee_tg6_reg = {
.name = "TEE",
.version = XTABLES_VERSION,
.revision = 0,
.family = PF_INET6,
.size = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
.userspacesize = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
.help = tee_tg_help,
.parse = tee_tg6_parse,
.final_check = tee_tg_check,
.print = tee_tg6_print,
.save = tee_tg6_save,
.extra_opts = tee_tg_opts,
};
static __attribute__((constructor)) void tee_tg_ldr(void)
{
xtables_register_target(&tee_tg_reg);
xtables_register_target(&tee_tg6_reg);
}

View File

@@ -22,7 +22,7 @@
static void ipp2p_mt_help(void)
{
printf(
"IPP2P v%s options:\n"
"ipp2p v%s match options:\n"
" --edk [tcp,udp] All known eDonkey/eMule/Overnet packets\n"
" --dc [tcp] All known Direct Connect packets\n"
" --kazaa [tcp,udp] All known KaZaA packets\n"
@@ -32,19 +32,10 @@ static void ipp2p_mt_help(void)
" --winmx [tcp] All known WinMX\n"
" --soul [tcp] All known SoulSeek\n"
" --ares [tcp] All known Ares\n\n"
"EXPERIMENTAL protocols (please send feedback to: ipp2p@ipp2p.org) :\n"
"EXPERIMENTAL protocols:\n"
" --mute [tcp] All known Mute packets\n"
" --waste [tcp] All known Waste packets\n"
" --xdcc [tcp] All known XDCC packets (only xdcc login)\n\n"
"DEBUG SUPPPORT, use only if you know why\n"
" --debug Generate kernel debug output, THIS WILL SLOW DOWN THE FILTER\n"
"\nIPP2P was intended for TCP only. Due to increasing usage of UDP we needed to change this.\n"
"You can now use -p udp to search UDP packets only or without -p switch to search UDP and TCP packets.\n"
"\nSee README included with this package for more details or visit http://www.ipp2p.org\n"
"\nExamples:\n"
" iptables -A FORWARD -m ipp2p --ipp2p -j MARK --set-mark 0x01\n"
" iptables -A FORWARD -p udp -m ipp2p --kazaa --bit -j DROP\n"
" iptables -A FORWARD -p tcp -m ipp2p --edk --soul -j DROP\n\n"
, IPP2P_VERSION);
}

View File

@@ -1,12 +1,12 @@
This module matches certain packets in P2P flows. It is not
designed to match all packets belonging to a P2P connection -
use IPP2P together with CONNMARK for this purpose. Also visit
http://www.ipp2p.org for detailed information.
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.
IPP2P provides the following options:
.PP
IPP2P provides the following options, of which one or more may be specified
on the command line:
.TP
.B "--edk "
Matches as many eDonkey/eMule packets as possible.
@@ -38,3 +38,11 @@ Matches Ares and AresLite packets. Use together with -j DROP only.
.B "--debug "
Prints some information about each hit into kernel logfile. May
produce huge logfiles so beware!
.PP
Note that ipp2p may not (and often, does not) identify all packets that are
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.

View File

@@ -0,0 +1,18 @@
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]
Match exact length or length range.
.TP
\fB--layer3\fR
Match the layer3 frame size (e.g. IPv4/v6 header plus payload).
.TP
\fB--layer4\fR
Match the layer4 frame size (e.g. TCP/UDP header plus payload).
.TP
\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.

173
extensions/libxt_length2.c Normal file
View File

@@ -0,0 +1,173 @@
#include <getopt.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <xtables.h>
#include "xt_length2.h"
enum {
F_LAYER = 1 << 0,
F_LENGTH = 1 << 1,
XT_LENGTH_LAYER_MASK = XT_LENGTH_LAYER3 | XT_LENGTH_LAYER4 |
XT_LENGTH_LAYER5 | XT_LENGTH_LAYER7,
};
static void length_mt_help(void)
{
printf(
"length match options:\n"
" --layer3 Match against layer3 size (e.g. L4 + IPv6 header)\n"
" --layer4 Match against layer4 size (e.g. L5 + SCTP header)\n"
" --layer5 Match against layer5 size (e.g. L7 + chunk headers)\n"
" --layer7 Match against layer7 payload (e.g. SCTP payload)\n"
"[!] --length n[:n] Match packet length against value or range\n"
" of values (inclusive)\n"
);
}
static const struct option length_mt_opts[] = {
{.name = "layer3", .has_arg = false, .val = '3'},
{.name = "layer4", .has_arg = false, .val = '4'},
{.name = "layer5", .has_arg = false, .val = '5'},
{.name = "layer7", .has_arg = false, .val = '7'},
{.name = "length", .has_arg = true, .val = '='},
{NULL},
};
static void length_mt_init(struct xt_entry_match *match)
{
struct xt_length_mtinfo2 *info = (void *)match->data;
info->flags = XT_LENGTH_LAYER3;
}
static int length_mt_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_match **match)
{
struct xt_length_mtinfo2 *info = (void *)(*match)->data;
unsigned int from, to;
char *end;
switch (c) {
case '3': /* --layer3 */
param_act(P_ONLY_ONCE, "length", "--layer*", *flags & F_LAYER);
info->flags &= ~XT_LENGTH_LAYER_MASK;
info->flags |= XT_LENGTH_LAYER3;
*flags |= F_LAYER;
return true;
case '4': /* --layer4 */
param_act(P_ONLY_ONCE, "length", "--layer*", *flags & F_LAYER);
info->flags &= ~XT_LENGTH_LAYER_MASK;
info->flags |= XT_LENGTH_LAYER4;
*flags |= F_LAYER;
return true;
case '5': /* --layer5 */
param_act(P_ONLY_ONCE, "length", "--layer*", *flags & F_LAYER);
info->flags &= ~XT_LENGTH_LAYER_MASK;
info->flags |= XT_LENGTH_LAYER5;
*flags |= F_LAYER;
return true;
case '7': /* --layer7 */
param_act(P_ONLY_ONCE, "length", "--layer*", *flags & F_LAYER);
info->flags &= ~XT_LENGTH_LAYER_MASK;
info->flags |= XT_LENGTH_LAYER7;
*flags |= F_LAYER;
return true;
case '=': /* --length */
param_act(P_ONLY_ONCE, "length", "--length", *flags & F_LENGTH);
if (invert)
info->flags |= XT_LENGTH_INVERT;
if (!strtonum(optarg, &end, &from, 0, ~0U))
param_act(P_BAD_VALUE, "length", "--length", optarg);
to = from;
if (*end == ':')
if (!strtonum(end + 1, &end, &to, 0, ~0U))
param_act(P_BAD_VALUE, "length",
"--length", optarg);
if (*end != '\0')
param_act(P_BAD_VALUE, "length", "--length", optarg);
info->min = from;
info->max = to;
*flags |= F_LENGTH;
return true;
}
return false;
}
static void length_mt_check(unsigned int flags)
{
if (!(flags & F_LENGTH))
exit_error(PARAMETER_PROBLEM,
"length: You must specify \"--length\"");
if (!(flags & F_LAYER))
fprintf(stderr, "iptables: length match: Defaulting to "
"--layer3. Consider specifying it explicitly.\n");
}
static void length_mt_print(const void *ip, const struct xt_entry_match *match,
int numeric)
{
const struct xt_length_mtinfo2 *info = (const void *)match->data;
if (info->flags & XT_LENGTH_LAYER3)
printf("layer3 ");
else if (info->flags & XT_LENGTH_LAYER4)
printf("layer4 ");
else if (info->flags & XT_LENGTH_LAYER5)
printf("layer5 ");
else if (info->flags & XT_LENGTH_LAYER7)
printf("layer7 ");
printf("length ");
if (info->flags & XT_LENGTH_INVERT)
printf("! ");
if (info->min == info->max)
printf("%u ", (unsigned int)info->min);
else
printf("%u-%u ", (unsigned int)info->min,
(unsigned int)info->max);
}
static void length_mt_save(const void *ip, const struct xt_entry_match *match)
{
const struct xt_length_mtinfo2 *info = (const void *)match->data;
if (info->flags & XT_LENGTH_LAYER3)
printf("--layer3 ");
else if (info->flags & XT_LENGTH_LAYER4)
printf("--layer4 ");
else if (info->flags & XT_LENGTH_LAYER5)
printf("--layer5 ");
else if (info->flags & XT_LENGTH_LAYER7)
printf("--layer7 ");
if (info->flags & XT_LENGTH_INVERT)
printf("! ");
printf("--length ");
if (info->min == info->max)
printf("%u ", (unsigned int)info->min);
else
printf("%u:%u ", (unsigned int)info->min,
(unsigned int)info->max);
}
static struct xtables_match length2_mt_reg = {
.version = XTABLES_VERSION,
.name = "length2",
.revision = 2,
.family = PF_UNSPEC,
.size = XT_ALIGN(sizeof(struct xt_length_mtinfo2)),
.userspacesize = XT_ALIGN(sizeof(struct xt_length_mtinfo2)),
.init = length_mt_init,
.help = length_mt_help,
.parse = length_mt_parse,
.final_check = length_mt_check,
.print = length_mt_print,
.save = length_mt_save,
.extra_opts = length_mt_opts,
};
static void _init(void)
{
xtables_register_match(&length2_mt_reg);
}

View File

@@ -20,7 +20,11 @@ connection was torn down after completion of the 3-way handshake.
\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)
identification. (E.g. openssh, smtp, ftpd.) This may falsely trigger on
warranted single-direction data flows, usually bulk data transfers such as
FTP DATA connections or IRC DCC. Grab Scan Detection should only be used on
ports where a protocol runs that is guaranteed to do a bidirectional exchange
of bytes.
.PP
NOTE: Some clients (Windows XP for example) may do what looks like a SYN scan,
so be advised to carefully use xt_portscan in conjunction with blocking rules,

View File

@@ -1,7 +1,7 @@
/*
* "TEE" target extension for Xtables
* Copyright © Sebastian Claßen <sebastian.classen [at] freenet de>, 2007
* Jan Engelhardt <jengelh [at] medozas de>, 2007
* Jan Engelhardt <jengelh [at] medozas de>, 2007 - 2008
*
* based on ipt_ROUTE.c from Cédric de Launois
* <delaunois [at] info ucl ac be>
@@ -17,6 +17,7 @@
#include <net/checksum.h>
#include <net/icmp.h>
#include <net/ip.h>
#include <net/ip6_route.h>
#include <net/route.h>
#include <linux/netfilter/x_tables.h>
@@ -29,7 +30,7 @@ static struct nf_conn tee_track;
#include "compat_xtables.h"
#include "xt_TEE.h"
static const union nf_inet_addr zero_address;
static const union nf_inet_addr tee_zero_address;
/*
* Try to route the packet according to the routing keys specified in
@@ -47,21 +48,16 @@ static const union nf_inet_addr zero_address;
* true - if the packet was succesfully routed to the
* destination desired
*/
static bool tee_routing(struct sk_buff *skb,
const struct xt_tee_tginfo *info)
static bool
tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info)
{
int err;
struct rtable *rt;
struct iphdr *iph = ip_hdr(skb);
struct flowi fl = {
.nl_u = {
.ip4_u = {
.daddr = info->gw.ip,
.tos = RT_TOS(iph->tos),
.scope = RT_SCOPE_UNIVERSE,
}
}
};
struct flowi fl;
memset(&fl, 0, sizeof(fl));
fl.nl_u.ip4_u.daddr = info->gw.ip;
fl.nl_u.ip4_u.scope = RT_SCOPE_UNIVERSE;
/* Trying to route the packet using the standard routing table. */
err = ip_route_output_key(&init_net, &rt, &fl);
@@ -72,22 +68,14 @@ static bool tee_routing(struct sk_buff *skb,
return false;
}
/* Drop old route. */
dst_release(skb->dst);
skb->dst = NULL;
/*
* Success if no oif specified or if the oif correspond to the
* one desired.
* [SC]: always the case, because we have no oif.
*/
skb->dst = &rt->u.dst;
skb->dev = skb->dst->dev;
skb->protocol = htons(ETH_P_IP);
return true;
}
static bool dev_hh_avail(const struct net_device *dev)
static inline bool dev_hh_avail(const struct net_device *dev)
{
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
return dev->hard_header != NULL;
@@ -103,14 +91,14 @@ static bool dev_hh_avail(const struct net_device *dev)
* POST: the packet is sent with the link layer header pushed
* the packet is destroyed
*/
static void tee_ip_direct_send(struct sk_buff *skb)
static void tee_tg_send(struct sk_buff *skb)
{
const struct dst_entry *dst = skb->dst;
const struct net_device *dev = dst->dev;
unsigned int hh_len = LL_RESERVED_SPACE(dev);
/* Be paranoid, rather than too clever. */
if (unlikely(skb_headroom(skb) < hh_len) && dev_hh_avail(dev)) {
if (unlikely(skb_headroom(skb) < hh_len && dev_hh_avail(dev))) {
struct sk_buff *skb2;
skb2 = skb_realloc_headroom(skb, LL_RESERVED_SPACE(dev));
@@ -142,7 +130,7 @@ static void tee_ip_direct_send(struct sk_buff *skb)
* packets when we see they already have that ->nfct.
*/
static unsigned int
tee_tg(struct sk_buff **pskb, const struct xt_target_param *par)
tee_tg4(struct sk_buff **pskb, const struct xt_target_param *par)
{
const struct xt_tee_tginfo *info = par->targinfo;
struct sk_buff *skb = *pskb;
@@ -200,8 +188,78 @@ tee_tg(struct sk_buff **pskb, const struct xt_target_param *par)
nf_conntrack_get(skb->nfct);
#endif
if (tee_routing(skb, info))
tee_ip_direct_send(skb);
/*
* Normally, we would just use ip_local_out. Because iph->check is
* already correct, we could take a shortcut and call dst_output
* [forwards to ip_output] directly. ip_output however will invoke
* Netfilter hooks and cause reentrancy. So we skip that too and go
* directly to ip_finish_output. Since we should not do XFRM, control
* passes to ip_finish_output2. That function is not exported, so it is
* copied here as tee_ip_direct_send.
*
* We do no XFRM on the cloned packet on purpose! The choice of
* iptables match options will control whether the raw packet or the
* transformed version is cloned.
*
* Also on purpose, no fragmentation is done, to preserve the
* packet as best as possible.
*/
if (tee_tg_route4(skb, info))
tee_tg_send(skb);
return XT_CONTINUE;
}
static bool
tee_tg_route6(struct sk_buff *skb, const struct xt_tee_tginfo *info)
{
struct dst_entry *dst;
struct flowi fl;
memset(&fl, 0, sizeof(fl));
fl.nl_u.ip6_u.daddr = info->gw.in6;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 25)
dst = ip6_route_output(NULL, &fl);
#else
dst = ip6_route_output(dev_net(skb->dev), NULL, &fl);
#endif
if (dst == NULL) {
if (net_ratelimit())
printk(KERN_ERR "ip6_route_output failed for tee\n");
return false;
}
dst_release(skb->dst);
skb->dst = dst;
skb->dev = skb->dst->dev;
skb->protocol = htons(ETH_P_IPV6);
return true;
}
static unsigned int
tee_tg6(struct sk_buff **pskb, const struct xt_target_param *par)
{
const struct xt_tee_tginfo *info = par->targinfo;
struct sk_buff *skb = *pskb;
/* Try silence. */
#ifdef WITH_CONNTRACK
if (skb->nfct == &tee_track.ct_general)
return NF_DROP;
#endif
if ((skb = skb_copy(skb, GFP_ATOMIC)) == NULL)
return XT_CONTINUE;
#ifdef WITH_CONNTRACK
nf_conntrack_put(skb->nfct);
skb->nfct = &tee_track.ct_general;
skb->nfctinfo = IP_CT_NEW;
nf_conntrack_get(skb->nfct);
#endif
if (tee_tg_route6(skb, info))
tee_tg_send(skb);
return XT_CONTINUE;
}
@@ -211,18 +269,31 @@ static bool tee_tg_check(const struct xt_tgchk_param *par)
const struct xt_tee_tginfo *info = par->targinfo;
/* 0.0.0.0 and :: not allowed */
return memcmp(&info->gw, &zero_address, sizeof(zero_address)) != 0;
return memcmp(&info->gw, &tee_zero_address,
sizeof(tee_zero_address)) != 0;
}
static struct xt_target tee_tg_reg __read_mostly = {
.name = "TEE",
.revision = 0,
.family = NFPROTO_IPV4,
.table = "mangle",
.target = tee_tg,
.targetsize = sizeof(struct xt_tee_tginfo),
.checkentry = tee_tg_check,
.me = THIS_MODULE,
static struct xt_target tee_tg_reg[] __read_mostly = {
{
.name = "TEE",
.revision = 0,
.family = NFPROTO_IPV4,
.table = "mangle",
.target = tee_tg4,
.targetsize = sizeof(struct xt_tee_tginfo),
.checkentry = tee_tg_check,
.me = THIS_MODULE,
},
{
.name = "TEE",
.revision = 0,
.family = NFPROTO_IPV6,
.table = "mangle",
.target = tee_tg6,
.targetsize = sizeof(struct xt_tee_tginfo),
.checkentry = tee_tg_check,
.me = THIS_MODULE,
},
};
static int __init tee_tg_init(void)
@@ -241,19 +312,20 @@ static int __init tee_tg_init(void)
tee_track.status |= IPS_NAT_DONE_MASK;
#endif
return xt_register_target(&tee_tg_reg);
return xt_register_targets(tee_tg_reg, ARRAY_SIZE(tee_tg_reg));
}
static void __exit tee_tg_exit(void)
{
xt_unregister_target(&tee_tg_reg);
xt_unregister_targets(tee_tg_reg, ARRAY_SIZE(tee_tg_reg));
/* [SC]: shoud not we cleanup tee_track here? */
}
module_init(tee_tg_init);
module_exit(tee_tg_exit);
MODULE_AUTHOR("Sebastian Claßen <sebastian.classen@freenet.ag>");
MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
MODULE_DESCRIPTION("Xtables: Reroute packet copy");
MODULE_LICENSE("GPL");
MODULE_ALIAS("ipt_TEE");
MODULE_ALIAS("ip6t_TEE");

View File

@@ -603,8 +603,13 @@ search_all_kazaa(const unsigned char *payload, const unsigned int plen)
{
uint16_t c, end, rem;
if (plen >= 5) {
printk(KERN_WARNING KBUILD_MODNAME ": %s: plen (%u) < 5\n",
if (plen < 5)
/* too short for anything we test for - early bailout */
return 0;
if (plen >= 65535) {
/* Something seems _really_ fishy */
printk(KERN_WARNING KBUILD_MODNAME ": %s: plen (%u) >= 65535\n",
__func__, plen);
return 0;
}
@@ -618,6 +623,10 @@ search_all_kazaa(const unsigned char *payload, const unsigned int plen)
if (memcmp(payload, "GET /", 5) != 0)
return 0;
if (plen < 18)
/* The next tests would not succeed anyhow. */
return 0;
end = plen - 18;
rem = plen - 5;
for (c = 5; c < end; ++c, --rem) {
@@ -828,7 +837,7 @@ ipp2p_mt(const struct sk_buff *skb, const struct xt_match_param *par)
switch (ip->protocol) {
case IPPROTO_TCP: /* what to do with a TCP packet */
{
const struct tcphdr *tcph = tcp_hdr(skb);
const struct tcphdr *tcph = (const void *)ip + ip_hdrlen(skb);
if (tcph->fin) return 0; /* if FIN bit is set bail out */
if (tcph->syn) return 0; /* if SYN bit is set bail out */
@@ -855,7 +864,7 @@ ipp2p_mt(const struct sk_buff *skb, const struct xt_match_param *par)
case IPPROTO_UDP: /* what to do with an UDP packet */
{
const struct udphdr *udph = udp_hdr(skb);
const struct udphdr *udph = (const void *)ip + ip_hdrlen(skb);
while (udp_list[i].command) {
if ((info->cmd & udp_list[i].command) == udp_list[i].command &&

View File

@@ -1,6 +1,6 @@
#ifndef __IPT_IPP2P_H
#define __IPT_IPP2P_H
#define IPP2P_VERSION "0.9"
#define IPP2P_VERSION "0.10"
enum {
IPP2N_EDK,

262
extensions/xt_length2.c Normal file
View File

@@ -0,0 +1,262 @@
/*
* xt_length - Netfilter module to match packet length
* Copyright © Jan Engelhardt <jengelh@medozas.de>, 2007 - 2009
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License; either
* version 2 of the License, or any later version, as published by the
* Free Software Foundation.
*/
#include <linux/dccp.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/icmp.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/sctp.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <net/ip.h>
#include <net/ipv6.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#include "xt_length2.h"
#include "compat_xtables.h"
#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
# define WITH_IPV6 1
#endif
#ifndef NEXTHDR_IPV4
# define NEXTHDR_IPV4 4
#endif
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
MODULE_DESCRIPTION("Xtables: Packet length (Layer3,4,5) match");
MODULE_LICENSE("GPL");
MODULE_ALIAS("ipt_length2");
MODULE_ALIAS("ip6t_length2");
static bool
xtlength_layer5_tcp(unsigned int *length, const struct sk_buff *skb,
unsigned int offset)
{
const struct tcphdr *tcph;
struct tcphdr buf;
tcph = skb_header_pointer(skb, offset, sizeof(buf), &buf);
if (tcph == NULL)
return false;
*length = skb->len - offset;
if (*length >= 4 * tcph->doff)
*length -= 4 * tcph->doff;
return true;
}
static bool
xtlength_layer5_dccp(unsigned int *length, const struct sk_buff *skb,
unsigned int offset)
{
const struct dccp_hdr *dh;
struct dccp_hdr dhbuf;
dh = skb_header_pointer(skb, offset, sizeof(dhbuf), &dhbuf);
if (dh == NULL)
return false;
*length = skb->len - offset;
if (*length >= 4 * dh->dccph_doff)
*length -= 4 * dh->dccph_doff;
return true;
}
static inline bool
xtlength_layer5(unsigned int *length, const struct sk_buff *skb,
unsigned int prot, unsigned int offset)
{
switch (prot) {
case IPPROTO_TCP:
return xtlength_layer5_tcp(length, skb, offset);
case IPPROTO_UDP:
case IPPROTO_UDPLITE:
*length = skb->len - offset - sizeof(struct udphdr);
return true;
case IPPROTO_SCTP:
*length = skb->len - offset - sizeof(struct sctphdr);
return true;
case IPPROTO_DCCP:
return xtlength_layer5_dccp(length, skb, offset);
case IPPROTO_ICMP:
*length = skb->len - offset - sizeof(struct icmphdr);
return true;
case IPPROTO_ICMPV6:
*length = skb->len - offset -
offsetof(struct icmp6hdr, icmp6_dataun);
return true;
case IPPROTO_AH:
*length = skb->len - offset - sizeof(struct ip_auth_hdr);
return true;
case IPPROTO_ESP:
*length = skb->len - offset - sizeof(struct ip_esp_hdr);
return true;
}
return false;
}
static bool
xtlength_layer7_sctp(unsigned int *length, const struct sk_buff *skb,
unsigned int offset)
{
const struct sctp_chunkhdr *ch;
struct sctp_chunkhdr chbuf;
unsigned int pos;
*length = 0;
for (pos = sizeof(struct sctphdr); pos < skb->len;
pos += ntohs(ch->length))
{
ch = skb_header_pointer(skb, offset + pos,
sizeof(chbuf), &chbuf);
if (ch == NULL)
return false;
if (ch->type != SCTP_CID_DATA)
continue;
*length += ntohs(ch->length);
}
return true;
}
static bool xtlength_layer7(unsigned int *length, const struct sk_buff *skb,
unsigned int proto, unsigned int offset)
{
switch (proto) {
case IPPROTO_SCTP:
return xtlength_layer7_sctp(length, skb, offset);
default:
return xtlength_layer5(length, skb, proto, offset);
}
}
/**
* llayer4_proto - figure out the L4 protocol in an IPv6 packet
* @skb: skb pointer
* @offset: position at which L4 starts (equal to 'protoff' in IPv4 code)
* @hotdrop: hotdrop pointer
*
* Searches for a recognized L4 header. On success, fills in @offset and
* returns the protocol number. If not found, %NEXTHDR_MAX is returned.
* On error, @hotdrop is set.
*/
static unsigned int
llayer4_proto(const struct sk_buff *skb, unsigned int *offset, bool *hotdrop)
{
/*
* Do encapsulation first so that %NEXTHDR_TCP does not hit the TCP
* part in an IPv6-in-IPv6 encapsulation.
*/
static const unsigned int types[] =
{IPPROTO_IPV6, IPPROTO_IPIP, IPPROTO_ESP, IPPROTO_AH,
IPPROTO_ICMP, IPPROTO_TCP, IPPROTO_UDP, IPPROTO_UDPLITE,
IPPROTO_SCTP, IPPROTO_DCCP};
unsigned int i;
int err;
for (i = 0; i < ARRAY_SIZE(types); ++i) {
err = ipv6_find_hdr(skb, offset, types[i], NULL);
if (err >= 0)
return types[i];
if (err != -ENOENT) {
*hotdrop = true;
break;
}
}
return NEXTHDR_MAX;
}
static bool
length2_mt(const struct sk_buff *skb, const struct xt_match_param *par)
{
const struct xt_length_mtinfo2 *info = par->matchinfo;
const struct iphdr *iph = ip_hdr(skb);
unsigned int len = 0;
bool hit = true;
if (info->flags & XT_LENGTH_LAYER3)
len = ntohs(iph->tot_len);
else if (info->flags & XT_LENGTH_LAYER4)
len = ntohs(iph->tot_len) - par->thoff;
else if (info->flags & XT_LENGTH_LAYER5)
hit = xtlength_layer5(&len, skb, iph->protocol, par->thoff);
else if (info->flags & XT_LENGTH_LAYER7)
hit = xtlength_layer7(&len, skb, iph->protocol, par->thoff);
if (!hit)
return false;
return (len >= info->min && len <= info->max) ^
!!(info->flags & XT_LENGTH_INVERT);
}
#ifdef WITH_IPV6
static bool
length2_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
{
const struct xt_length_mtinfo2 *info = par->matchinfo;
const struct ipv6hdr *iph = ipv6_hdr(skb);
unsigned int len = 0, l4proto;
unsigned int thoff = par->thoff;
bool hit = true;
if (info->flags & XT_LENGTH_LAYER3) {
len = sizeof(struct ipv6hdr) + ntohs(iph->payload_len);
} else {
l4proto = llayer4_proto(skb, &thoff, par->hotdrop);
if (l4proto == NEXTHDR_MAX)
return false;
if (info->flags & XT_LENGTH_LAYER4)
len = skb->len - thoff;
else if (info->flags & XT_LENGTH_LAYER5)
hit = xtlength_layer5(&len, skb, l4proto, thoff);
else if (info->flags & XT_LENGTH_LAYER7)
hit = xtlength_layer7(&len, skb, l4proto, thoff);
}
if (!hit)
return false;
return (len >= info->min && len <= info->max) ^
!!(info->flags & XT_LENGTH_INVERT);
}
#endif
static struct xt_match length2_mt_reg[] __read_mostly = {
{
.name = "length2",
.revision = 2,
.family = NFPROTO_IPV4,
.match = length2_mt,
.matchsize = sizeof(struct xt_length_mtinfo2),
.me = THIS_MODULE,
},
#ifdef WITH_IPV6
{
.name = "length2",
.revision = 2,
.family = NFPROTO_IPV6,
.match = length2_mt6,
.matchsize = sizeof(struct xt_length_mtinfo2),
.me = THIS_MODULE,
},
#endif
};
static int __init length2_mt_init(void)
{
return xt_register_matches(length2_mt_reg, ARRAY_SIZE(length2_mt_reg));
}
static void __exit length2_mt_exit(void)
{
xt_unregister_matches(length2_mt_reg, ARRAY_SIZE(length2_mt_reg));
}
module_init(length2_mt_init);
module_exit(length2_mt_exit);

22
extensions/xt_length2.h Normal file
View File

@@ -0,0 +1,22 @@
#ifndef _LINUX_NETFILTER_XT_LENGTH2_H
#define _LINUX_NETFILTER_XT_LENGTH2_H
enum {
XT_LENGTH_INVERT = 1 << 0,
/* IP header plus payload */
XT_LENGTH_LAYER3 = 1 << 1,
/* Strip IP header: */
XT_LENGTH_LAYER4 = 1 << 2,
/* Strip TCP/UDP/etc. header */
XT_LENGTH_LAYER5 = 1 << 3,
/* TCP/UDP/SCTP payload */
XT_LENGTH_LAYER7 = 1 << 4,
};
struct xt_length_mtinfo2 {
u_int32_t min, max;
u_int16_t flags;
};
#endif /* _LINUX_NETFILTER_XT_LENGTH2_H */

View File

@@ -14,5 +14,6 @@ build_fuzzy=m
build_geoip=m
build_ipp2p=m
build_ipset=m
build_length2=m
build_portscan=m
build_quota2=m

View File

@@ -1,9 +1,9 @@
.TH xtables\-addons 8 "v1.7 (2008\-12\-25)" "" "v1.7 (2008\-12\-25)"
.SH NAME
.TH xtables\-addons 8 "v1.9 (2009\-01\-30)" "" "v1.9 (2009\-01\-30)"
.SH Name
Xtables\-addons - additional extensions for iptables, ip6tables, etc.
.SH TARGETS
.SH Targets
.\" @TARGET@
.SH MATCHES
.SH Matches
.\" @MATCHES@
.SH "SEE ALSO"
\fBiptables\fP(8), \fBip6tables\fP(8)