mirror of
git://git.code.sf.net/p/xtables-addons/xtables-addons
synced 2025-09-20 19:44:56 +02:00
Compare commits
46 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
03e10ff544 | ||
![]() |
37986fd785 | ||
![]() |
8ff64f4ef4 | ||
![]() |
93f6c1a312 | ||
![]() |
b535abce2e | ||
![]() |
5db988626f | ||
![]() |
c6f8f72bf1 | ||
![]() |
47cbb07162 | ||
![]() |
79c55ab325 | ||
![]() |
11ab4d0acc | ||
![]() |
8ae9ac5433 | ||
![]() |
2060a58912 | ||
![]() |
e1eed2b05e | ||
![]() |
7b077c7459 | ||
![]() |
ad146dbeef | ||
![]() |
fb4c49d794 | ||
![]() |
a17203e036 | ||
![]() |
987402dc61 | ||
![]() |
295b6b6d73 | ||
![]() |
7338a2a400 | ||
![]() |
ba35636718 | ||
![]() |
fd19a40dbe | ||
![]() |
937571bb9d | ||
![]() |
346fc1a376 | ||
![]() |
56535551b3 | ||
![]() |
dd8fdd09c8 | ||
![]() |
beb3358297 | ||
![]() |
02d8bdc3d9 | ||
![]() |
42b77a386a | ||
![]() |
6340363394 | ||
![]() |
c9b4e9c518 | ||
![]() |
8dd316ed56 | ||
![]() |
48327605c6 | ||
![]() |
414e95ffb1 | ||
![]() |
749e0b788a | ||
![]() |
7512101bca | ||
![]() |
1a17ed6a45 | ||
![]() |
1aeaadd740 | ||
![]() |
0acbe528ac | ||
![]() |
f5fe2dc801 | ||
![]() |
524201adcc | ||
![]() |
7cfd3b1dbb | ||
![]() |
ab13e58f96 | ||
![]() |
548922388c | ||
![]() |
43864ac6f1 | ||
![]() |
2ef714cc93 |
7
INSTALL
7
INSTALL
@@ -4,7 +4,7 @@ Installation instructions for Xtables-addons
|
||||
Xtables-addons uses the well-known configure(autotools) infrastructure
|
||||
in combination with the kernel's Kbuild system.
|
||||
|
||||
$ ./configure
|
||||
$ ./configure --with-xtlibdir=SEE_BELOW
|
||||
$ make
|
||||
# make install
|
||||
|
||||
@@ -55,7 +55,10 @@ Configuring and compiling
|
||||
|
||||
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/iptables package, ${libexecdir}/xtables.
|
||||
default as the Xtables/iptables package, ${libexecdir}/xtables,
|
||||
but you may need to specify this nevertheless, as autotools
|
||||
defaults to using /usr/local as prefix, and distributions put
|
||||
the files in differing locations.
|
||||
|
||||
If you want to enable debugging, use
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
|
||||
AC_INIT([xtables-addons], [1.23])
|
||||
AC_INIT([xtables-addons], [1.25])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_PROG_INSTALL
|
||||
@@ -34,7 +34,8 @@ AC_CHECK_HEADERS([linux/netfilter/x_tables.h], [],
|
||||
regular_CFLAGS="-D_LARGEFILE_SOURCE=1 -D_LARGE_FILES -D_FILE_OFFSET_BITS=64 \
|
||||
-D_REENTRANT -Wall -Waggregate-return -Wmissing-declarations \
|
||||
-Wmissing-prototypes -Wredundant-decls -Wshadow -Wstrict-prototypes \
|
||||
-Winline -pipe -DXTABLES_LIBDIR=\\\"\${xtlibdir}\\\"";
|
||||
-Winline -pipe -DXTABLES_LIBDIR=\\\"\${xtlibdir}\\\" \
|
||||
-I\${XA_TOPSRCDIR}/include";
|
||||
|
||||
#
|
||||
# check kernel version
|
||||
|
@@ -3,6 +3,28 @@ HEAD
|
||||
====
|
||||
|
||||
|
||||
Xtables-addons 1.25 (April 26 2010)
|
||||
===================================
|
||||
- TEE: do rechecksumming in PREROUTING too
|
||||
- TEE: decrease TTL on cloned packet
|
||||
- TEE: set dont-fragment on cloned packets
|
||||
- TEE: free skb when route lookup failed
|
||||
- TEE: do not limit use to mangle table
|
||||
- TEE: do not retain iif and mark on cloned packet
|
||||
- TEE: new loop detection logic
|
||||
- TEE: use less expensive pskb_copy
|
||||
- condition: remove unnecessary RCU protection
|
||||
|
||||
|
||||
Xtables-addons 1.24 (March 17 2010)
|
||||
===================================
|
||||
- build: fix build of userspace modules against old (pre-2.6.25)
|
||||
headers from linux-glibc-devel (/usr/include/linux)
|
||||
- ipp2p: updated bittorent command recognition
|
||||
- SYSRQ: let module load when crypto is unavailable
|
||||
- SYSRQ: allow processing of UDP-Lite
|
||||
|
||||
|
||||
Xtables-addons 1.23 (February 24 2010)
|
||||
======================================
|
||||
- build: support for Linux 2.6.34
|
||||
|
@@ -142,7 +142,7 @@ account_tg_save(const void *ip, const struct xt_entry_target *target)
|
||||
static struct xtables_target account_tg_reg = {
|
||||
.name = "ACCOUNT",
|
||||
.revision = 1,
|
||||
.family = AF_INET,
|
||||
.family = NFPROTO_IPV4,
|
||||
.version = XTABLES_VERSION,
|
||||
.size = XT_ALIGN(sizeof(struct ipt_acc_info)),
|
||||
.userspacesize = offsetof(struct ipt_acc_info, table_nr),
|
||||
|
@@ -264,7 +264,7 @@ static int ipt_acc_table_insert(const char *name, __be32 ip, __be32 netmask)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool ipt_acc_checkentry(const struct xt_tgchk_param *par)
|
||||
static int ipt_acc_checkentry(const struct xt_tgchk_param *par)
|
||||
{
|
||||
struct ipt_acc_info *info = par->targinfo;
|
||||
int table_nr;
|
||||
@@ -276,13 +276,13 @@ static bool ipt_acc_checkentry(const struct xt_tgchk_param *par)
|
||||
|
||||
if (table_nr == -1) {
|
||||
printk("ACCOUNT: Table insert problem. Aborting\n");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Table nr caching so we don't have to do an extra string compare
|
||||
for every packet */
|
||||
info->table_nr = table_nr;
|
||||
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ipt_acc_destroy(const struct xt_tgdtor_param *par)
|
||||
@@ -1082,7 +1082,7 @@ static int ipt_acc_get_ctl(struct sock *sk, int cmd, void *user, int *len)
|
||||
static struct xt_target xt_acc_reg __read_mostly = {
|
||||
.name = "ACCOUNT",
|
||||
.revision = 1,
|
||||
.family = AF_INET,
|
||||
.family = NFPROTO_IPV4,
|
||||
.target = ipt_acc_target,
|
||||
.targetsize = sizeof(struct ipt_acc_info),
|
||||
.checkentry = ipt_acc_checkentry,
|
||||
|
@@ -7,6 +7,8 @@
|
||||
_kcall = -C ${kbuilddir} M=${abs_srcdir}
|
||||
|
||||
modules:
|
||||
@echo -n "Xtables-addons ${PACKAGE_VERSION} - Linux "
|
||||
@if [ -n "${kbuilddir}" ]; then ${MAKE} ${_kcall} --no-print-directory -s kernelrelease; fi;
|
||||
${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} ${_kcall} modules; fi;
|
||||
|
||||
modules_install:
|
||||
|
@@ -84,6 +84,19 @@ static bool xtnu_match_check(const char *table, const void *entry,
|
||||
return nm->checkentry(&local_par);
|
||||
}
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) && \
|
||||
LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
|
||||
static bool xtnu_match_check(const struct xt_mtchk_param *par)
|
||||
{
|
||||
struct xtnu_match *nm = xtcompat_numatch(par->match);
|
||||
|
||||
if (nm == NULL)
|
||||
return false;
|
||||
if (nm->checkentry == NULL)
|
||||
return true;
|
||||
return nm->checkentry(par) == 0 ? true : false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
||||
static void xtnu_match_destroy(const struct xt_match *cm, void *matchinfo,
|
||||
@@ -105,7 +118,7 @@ static void xtnu_match_destroy(const struct xt_match *cm, void *matchinfo)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
|
||||
int xtnu_register_match(struct xtnu_match *nt)
|
||||
{
|
||||
struct xt_match *ct;
|
||||
@@ -127,9 +140,15 @@ int xtnu_register_match(struct xtnu_match *nt)
|
||||
ct->table = (char *)nt->table;
|
||||
ct->hooks = nt->hooks;
|
||||
ct->proto = nt->proto;
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
||||
ct->match = xtnu_match_run;
|
||||
ct->checkentry = xtnu_match_check;
|
||||
ct->destroy = xtnu_match_destroy;
|
||||
#else
|
||||
ct->match = nt->match;
|
||||
ct->checkentry = xtnu_match_check;
|
||||
ct->destroy = nt->destroy;
|
||||
#endif
|
||||
ct->matchsize = nt->matchsize;
|
||||
ct->me = nt->me;
|
||||
|
||||
@@ -250,6 +269,20 @@ static bool xtnu_target_check(const char *table, const void *entry,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) && \
|
||||
LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34)
|
||||
static bool xtnu_target_check(const struct xt_tgchk_param *par)
|
||||
{
|
||||
struct xtnu_target *nt = xtcompat_nutarget(par->target);
|
||||
|
||||
if (nt == NULL)
|
||||
return false;
|
||||
if (nt->checkentry == NULL)
|
||||
return true;
|
||||
return nt->checkentry(par) == 0 ? true : false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
||||
static void xtnu_target_destroy(const struct xt_target *ct, void *targinfo,
|
||||
unsigned int targinfosize)
|
||||
@@ -295,6 +328,9 @@ int xtnu_register_target(struct xtnu_target *nt)
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
||||
ct->checkentry = xtnu_target_check;
|
||||
ct->destroy = xtnu_target_destroy;
|
||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
|
||||
ct->checkentry = xtnu_target_check;
|
||||
ct->destroy = nt->destroy;
|
||||
#else
|
||||
ct->checkentry = nt->checkentry;
|
||||
ct->destroy = nt->destroy;
|
||||
@@ -509,4 +545,18 @@ int xtnu_skb_linearize(struct sk_buff *skb)
|
||||
EXPORT_SYMBOL_GPL(xtnu_skb_linearize);
|
||||
#endif
|
||||
|
||||
void *HX_memmem(const void *space, size_t spacesize,
|
||||
const void *point, size_t pointsize)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (pointsize > spacesize)
|
||||
return NULL;
|
||||
for (i = 0; i <= spacesize - pointsize; ++i)
|
||||
if (memcmp(space + i, point, pointsize) == 0)
|
||||
return (void *)space + i;
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(HX_memmem);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@@ -60,7 +60,7 @@
|
||||
# define init_net__proc_net init_net.proc_net
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
|
||||
# define xt_match xtnu_match
|
||||
# define xt_register_match xtnu_register_match
|
||||
# define xt_unregister_match xtnu_unregister_match
|
||||
|
@@ -85,7 +85,7 @@ struct xtnu_match {
|
||||
struct list_head list;
|
||||
char name[XT_FUNCTION_MAXNAMELEN - 1 - sizeof(void *)];
|
||||
bool (*match)(const struct sk_buff *, const struct xt_match_param *);
|
||||
bool (*checkentry)(const struct xt_mtchk_param *);
|
||||
int (*checkentry)(const struct xt_mtchk_param *);
|
||||
void (*destroy)(const struct xt_mtdtor_param *);
|
||||
struct module *me;
|
||||
const char *table;
|
||||
@@ -101,7 +101,7 @@ struct xtnu_target {
|
||||
char name[XT_FUNCTION_MAXNAMELEN - 1 - sizeof(void *)];
|
||||
unsigned int (*target)(struct sk_buff **,
|
||||
const struct xt_target_param *);
|
||||
bool (*checkentry)(const struct xt_tgchk_param *);
|
||||
int (*checkentry)(const struct xt_tgchk_param *);
|
||||
void (*destroy)(const struct xt_tgdtor_param *);
|
||||
struct module *me;
|
||||
const char *table;
|
||||
@@ -154,4 +154,6 @@ extern void xtnu_proto_csum_replace4(__u16 __bitwise *, struct sk_buff *,
|
||||
__be32, __be32, bool);
|
||||
extern int xtnu_skb_linearize(struct sk_buff *);
|
||||
|
||||
extern void *HX_memmem(const void *, size_t, const void *, size_t);
|
||||
|
||||
#endif /* _COMPAT_XTNU_H */
|
||||
|
@@ -45,7 +45,7 @@ target(struct sk_buff **pskb, const struct xt_target_param *par)
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
||||
static bool
|
||||
static int
|
||||
checkentry(const struct xt_tgchk_param *par)
|
||||
{
|
||||
struct ipt_set_info_target *info = par->targinfo;
|
||||
@@ -54,7 +54,7 @@ checkentry(const struct xt_tgchk_param *par)
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
|
||||
if (targinfosize != IPT_ALIGN(sizeof(*info))) {
|
||||
DP("bad target info size %u", targinfosize);
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -63,7 +63,7 @@ checkentry(const struct xt_tgchk_param *par)
|
||||
if (index == IP_SET_INVALID_ID) {
|
||||
ip_set_printk("cannot find add_set index %u as target",
|
||||
info->add_set.index);
|
||||
return 0; /* error */
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,16 +72,16 @@ checkentry(const struct xt_tgchk_param *par)
|
||||
if (index == IP_SET_INVALID_ID) {
|
||||
ip_set_printk("cannot find del_set index %u as target",
|
||||
info->del_set.index);
|
||||
return 0; /* error */
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
if (info->add_set.flags[IP_SET_MAX_BINDINGS] != 0
|
||||
|| info->del_set.flags[IP_SET_MAX_BINDINGS] != 0) {
|
||||
ip_set_printk("That's nasty!");
|
||||
return 0; /* error */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void destroy(const struct xt_tgdtor_param *par)
|
||||
|
@@ -47,7 +47,7 @@ match(const struct sk_buff *skb, const struct xt_match_param *par)
|
||||
info->match_set.flags[0] & IPSET_MATCH_INV);
|
||||
}
|
||||
|
||||
static bool
|
||||
static int
|
||||
checkentry(const struct xt_mtchk_param *par)
|
||||
{
|
||||
struct ipt_set_info_match *info = par->matchinfo;
|
||||
@@ -56,7 +56,7 @@ checkentry(const struct xt_mtchk_param *par)
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
|
||||
if (matchsize != IPT_ALIGN(sizeof(struct ipt_set_info_match))) {
|
||||
ip_set_printk("invalid matchsize %d", matchsize);
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -65,14 +65,14 @@ checkentry(const struct xt_mtchk_param *par)
|
||||
if (index == IP_SET_INVALID_ID) {
|
||||
ip_set_printk("Cannot find set indentified by id %u to match",
|
||||
info->match_set.index);
|
||||
return 0; /* error */
|
||||
return -ENOENT;
|
||||
}
|
||||
if (info->match_set.flags[IP_SET_MAX_BINDINGS] != 0) {
|
||||
ip_set_printk("That's nasty!");
|
||||
return 0; /* error */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void destroy(const struct xt_mtdtor_param *par)
|
||||
|
@@ -95,7 +95,7 @@ static void chaos_tg_save(const void *ip, const struct xt_entry_target *target)
|
||||
static struct xtables_target chaos_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "CHAOS",
|
||||
.family = AF_INET,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct xt_chaos_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_chaos_tginfo)),
|
||||
.help = chaos_tg_help,
|
||||
|
@@ -33,9 +33,7 @@ static struct xtables_target delude_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "DELUDE",
|
||||
.revision = 0,
|
||||
.family = AF_INET,
|
||||
.size = XT_ALIGN(0),
|
||||
.userspacesize = XT_ALIGN(0),
|
||||
.family = NFPROTO_IPV4,
|
||||
.help = delude_tg_help,
|
||||
.parse = delude_tg_parse,
|
||||
.final_check = delude_tg_check,
|
||||
|
@@ -84,7 +84,7 @@ static struct xtables_target dhcpmac_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "DHCPMAC",
|
||||
.revision = 0,
|
||||
.family = PF_INET,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct dhcpmac_info)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct dhcpmac_info)),
|
||||
.help = dhcpmac_tg_help,
|
||||
|
@@ -29,9 +29,7 @@ static void echo_tg_check(unsigned int flags)
|
||||
static struct xtables_target echo_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "ECHO",
|
||||
.family = AF_UNSPEC,
|
||||
.size = XT_ALIGN(0),
|
||||
.userspacesize = XT_ALIGN(0),
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.help = echo_tg_help,
|
||||
.parse = echo_tg_parse,
|
||||
.final_check = echo_tg_check,
|
||||
|
@@ -151,7 +151,7 @@ ipmark_tg_save(const void *entry, const struct xt_entry_target *target)
|
||||
static struct xtables_target ipmark_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "IPMARK",
|
||||
.family = PF_UNSPEC,
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.revision = 1,
|
||||
.size = XT_ALIGN(sizeof(struct xt_ipmark_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_ipmark_tginfo)),
|
||||
|
@@ -100,7 +100,7 @@ static struct xtables_target logmark_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "LOGMARK",
|
||||
.revision = 0,
|
||||
.family = AF_UNSPEC,
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.size = XT_ALIGN(sizeof(struct xt_logmark_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_logmark_tginfo)),
|
||||
.help = logmark_tg_help,
|
||||
|
@@ -154,7 +154,7 @@ static struct xtables_target rawdnat_tg4_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "RAWDNAT",
|
||||
.revision = 0,
|
||||
.family = PF_INET,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.help = rawdnat_tg_help,
|
||||
@@ -169,7 +169,7 @@ static struct xtables_target rawdnat_tg6_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "RAWDNAT",
|
||||
.revision = 0,
|
||||
.family = PF_INET6,
|
||||
.family = NFPROTO_IPV6,
|
||||
.size = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.help = rawdnat_tg_help,
|
||||
|
@@ -154,7 +154,7 @@ static struct xtables_target rawsnat_tg4_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "RAWSNAT",
|
||||
.revision = 0,
|
||||
.family = PF_INET,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.help = rawsnat_tg_help,
|
||||
@@ -169,7 +169,7 @@ static struct xtables_target rawsnat_tg6_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "RAWSNAT",
|
||||
.revision = 0,
|
||||
.family = PF_INET6,
|
||||
.family = NFPROTO_IPV6,
|
||||
.size = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.help = rawsnat_tg_help,
|
||||
|
@@ -19,9 +19,7 @@ static void steal_tg_check(unsigned int flags)
|
||||
static struct xtables_target steal_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "STEAL",
|
||||
.family = AF_UNSPEC,
|
||||
.size = XT_ALIGN(0),
|
||||
.userspacesize = XT_ALIGN(0),
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.help = steal_tg_help,
|
||||
.parse = steal_tg_parse,
|
||||
.final_check = steal_tg_check,
|
||||
|
@@ -25,9 +25,7 @@ static struct xtables_target sysrq_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "SYSRQ",
|
||||
.revision = 1,
|
||||
.family = PF_UNSPEC,
|
||||
.size = XT_ALIGN(0),
|
||||
.userspacesize = XT_ALIGN(0),
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.help = sysrq_tg_help,
|
||||
.parse = sysrq_tg_parse,
|
||||
.final_check = sysrq_tg_check,
|
||||
|
@@ -24,9 +24,7 @@ static void tarpit_tg_check(unsigned int flags)
|
||||
static struct xtables_target tarpit_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "TARPIT",
|
||||
.family = AF_INET,
|
||||
.size = XT_ALIGN(0),
|
||||
.userspacesize = XT_ALIGN(0),
|
||||
.family = NFPROTO_IPV4,
|
||||
.help = tarpit_tg_help,
|
||||
.parse = tarpit_tg_parse,
|
||||
.final_check = tarpit_tg_check,
|
||||
|
@@ -138,7 +138,7 @@ static struct xtables_target tee_tg_reg = {
|
||||
.name = "TEE",
|
||||
.version = XTABLES_VERSION,
|
||||
.revision = 0,
|
||||
.family = PF_INET,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
|
||||
.help = tee_tg_help,
|
||||
@@ -153,7 +153,7 @@ static struct xtables_target tee_tg6_reg = {
|
||||
.name = "TEE",
|
||||
.version = XTABLES_VERSION,
|
||||
.revision = 0,
|
||||
.family = PF_INET6,
|
||||
.family = NFPROTO_IPV6,
|
||||
.size = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
|
||||
.help = tee_tg_help,
|
||||
|
@@ -80,7 +80,7 @@ static void condition_save(const void *ip, const struct xt_entry_match *match)
|
||||
static struct xtables_match condition_mt_reg = {
|
||||
.name = "condition",
|
||||
.revision = 1,
|
||||
.family = PF_UNSPEC,
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.version = XTABLES_VERSION,
|
||||
.size = XT_ALIGN(sizeof(struct xt_condition_mtinfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_condition_mtinfo)),
|
||||
|
@@ -85,7 +85,7 @@ static struct xtables_match dhcpmac_mt_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "dhcpmac",
|
||||
.revision = 0,
|
||||
.family = PF_INET,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct dhcpmac_info)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct dhcpmac_info)),
|
||||
.help = dhcpmac_mt_help,
|
||||
|
@@ -103,6 +103,7 @@ static struct xtables_match fuzzy_mt_reg = {
|
||||
.name = "fuzzy",
|
||||
.revision = 1,
|
||||
.version = XTABLES_VERSION,
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.size = XT_ALIGN(sizeof(struct xt_fuzzy_mtinfo)),
|
||||
.userspacesize = offsetof(struct xt_fuzzy_mtinfo, packets_total),
|
||||
.help = fuzzy_mt_help,
|
||||
|
@@ -259,7 +259,7 @@ geoip_save(const void *ip, const struct xt_entry_match *match)
|
||||
}
|
||||
|
||||
static struct xtables_match geoip_match = {
|
||||
.family = AF_INET,
|
||||
.family = NFPROTO_IPV4,
|
||||
.name = "geoip",
|
||||
.revision = 1,
|
||||
.version = XTABLES_VERSION,
|
||||
|
@@ -200,7 +200,7 @@ static struct xtables_match iface_mt_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "iface",
|
||||
.revision = 0,
|
||||
.family = AF_UNSPEC,
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.size = XT_ALIGN(sizeof(struct xt_iface_mtinfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_iface_mtinfo)),
|
||||
.help = iface_mt_help,
|
||||
|
@@ -229,7 +229,7 @@ static struct xtables_match ipp2p_mt_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "ipp2p",
|
||||
.revision = 1,
|
||||
.family = AF_INET,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct ipt_p2p_info)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct ipt_p2p_info)),
|
||||
.help = ipp2p_mt_help,
|
||||
|
@@ -161,7 +161,7 @@ static struct xtables_match ipv4options_mt_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "ipv4options",
|
||||
.revision = 1,
|
||||
.family = PF_INET,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct xt_ipv4options_mtinfo1)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_ipv4options_mtinfo1)),
|
||||
.help = ipv4options_mt_help,
|
||||
|
@@ -155,7 +155,7 @@ static struct xtables_match length2_mt_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "length2",
|
||||
.revision = 2,
|
||||
.family = PF_UNSPEC,
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.size = XT_ALIGN(sizeof(struct xt_length_mtinfo2)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_length_mtinfo2)),
|
||||
.init = length_mt_init,
|
||||
|
@@ -105,7 +105,7 @@ static struct xtables_match lscan_mt_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "lscan",
|
||||
.revision = 0,
|
||||
.family = AF_INET,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct xt_lscan_mtinfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_lscan_mtinfo)),
|
||||
.help = lscan_mt_help,
|
||||
|
@@ -139,7 +139,7 @@ static struct xtables_match psd_mt_reg = {
|
||||
.name = "psd",
|
||||
.version = XTABLES_VERSION,
|
||||
.revision = 1,
|
||||
.family = PF_INET,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct xt_psd_info)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_psd_info)),
|
||||
.help = psd_mt_help,
|
||||
|
@@ -133,7 +133,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,
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.revision = 3,
|
||||
.name = "quota2",
|
||||
.version = XTABLES_VERSION,
|
||||
|
@@ -326,7 +326,7 @@ static struct xtables_match pknock_mt_reg = {
|
||||
.name = "pknock",
|
||||
.version = XTABLES_VERSION,
|
||||
.revision = 1,
|
||||
.family = AF_INET,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct xt_pknock_mtinfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_pknock_mtinfo)),
|
||||
.help = pknock_mt_help,
|
||||
|
@@ -1064,9 +1064,9 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define RETURN_ERR(err) do { printk(KERN_ERR PKNOCK err); return false; } while (false)
|
||||
#define RETURN_ERR(err) do { printk(KERN_ERR PKNOCK err); return -EINVAL; } while (false)
|
||||
|
||||
static bool pknock_mt_check(const struct xt_mtchk_param *par)
|
||||
static int pknock_mt_check(const struct xt_mtchk_param *par)
|
||||
{
|
||||
struct xt_pknock_mtinfo *info = par->matchinfo;
|
||||
|
||||
@@ -1124,9 +1124,10 @@ static bool pknock_mt_check(const struct xt_mtchk_param *par)
|
||||
}
|
||||
|
||||
if (!add_rule(info))
|
||||
/* should ENOMEM here */
|
||||
RETURN_ERR("add_rule() error in checkentry() function.\n");
|
||||
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pknock_mt_destroy(const struct xt_mtdtor_param *par)
|
||||
|
@@ -141,22 +141,22 @@ chaos_tg(struct sk_buff **pskb, const struct xt_target_param *par)
|
||||
return NF_DROP;
|
||||
}
|
||||
|
||||
static bool chaos_tg_check(const struct xt_tgchk_param *par)
|
||||
static int chaos_tg_check(const struct xt_tgchk_param *par)
|
||||
{
|
||||
const struct xt_chaos_tginfo *info = par->targinfo;
|
||||
|
||||
if (info->variant == XTCHAOS_DELUDE && !have_delude) {
|
||||
printk(KERN_WARNING PFX "Error: Cannot use --delude when "
|
||||
"DELUDE module not available\n");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
if (info->variant == XTCHAOS_TARPIT && !have_tarpit) {
|
||||
printk(KERN_WARNING PFX "Error: Cannot use --tarpit when "
|
||||
"TARPIT module not available\n");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xt_target chaos_tg_reg = {
|
||||
|
@@ -139,7 +139,7 @@ static struct xt_match dhcpmac_mt_reg __read_mostly = {
|
||||
.family = NFPROTO_IPV4,
|
||||
.proto = IPPROTO_UDP,
|
||||
.match = dhcpmac_mt,
|
||||
.matchsize = XT_ALIGN(sizeof(struct dhcpmac_info)),
|
||||
.matchsize = sizeof(struct dhcpmac_info),
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
@@ -113,7 +113,6 @@ static struct xt_target echo_tg_reg __read_mostly = {
|
||||
.proto = IPPROTO_UDP,
|
||||
.table = "filter",
|
||||
.target = echo_tg4,
|
||||
.targetsize = XT_ALIGN(0),
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
@@ -86,7 +86,7 @@ static struct xt_target ipmark_tg_reg[] __read_mostly = {
|
||||
.family = NFPROTO_IPV4,
|
||||
.table = "mangle",
|
||||
.target = ipmark_tg4,
|
||||
.targetsize = XT_ALIGN(sizeof(struct xt_ipmark_tginfo)),
|
||||
.targetsize = sizeof(struct xt_ipmark_tginfo),
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
{
|
||||
@@ -95,7 +95,7 @@ static struct xt_target ipmark_tg_reg[] __read_mostly = {
|
||||
.family = NFPROTO_IPV6,
|
||||
.table = "mangle",
|
||||
.target = ipmark_tg6,
|
||||
.targetsize = XT_ALIGN(sizeof(struct xt_ipmark_tginfo)),
|
||||
.targetsize = sizeof(struct xt_ipmark_tginfo),
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
@@ -81,17 +81,17 @@ logmark_tg(struct sk_buff **pskb, const struct xt_target_param *par)
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
||||
static bool
|
||||
static int
|
||||
logmark_tg_check(const struct xt_tgchk_param *par)
|
||||
{
|
||||
const struct xt_logmark_tginfo *info = par->targinfo;
|
||||
|
||||
if (info->level >= 8) {
|
||||
pr_debug("LOGMARK: level %u >= 8\n", info->level);
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xt_target logmark_tg_reg[] __read_mostly = {
|
||||
|
@@ -283,15 +283,15 @@ rawdnat_tg6(struct sk_buff **pskb, const struct xt_target_param *par)
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool rawnat_tg_check(const struct xt_tgchk_param *par)
|
||||
static int rawnat_tg_check(const struct xt_tgchk_param *par)
|
||||
{
|
||||
if (strcmp(par->table, "raw") == 0 ||
|
||||
strcmp(par->table, "rawpost") == 0)
|
||||
return true;
|
||||
return 0;
|
||||
|
||||
printk(KERN_ERR KBUILD_MODNAME " may only be used in the \"raw\" or "
|
||||
"\"rawpost\" table.\n");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct xt_target rawnat_tg_reg[] __read_mostly = {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* "SYSRQ" target extension for Netfilter
|
||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008
|
||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008 - 2010
|
||||
*
|
||||
* Based upon the ipt_SYSRQ idea by Marek Zalem <marek [at] terminus sk>
|
||||
*
|
||||
@@ -23,6 +23,10 @@
|
||||
#include <net/ip.h>
|
||||
#include "compat_xtables.h"
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) && \
|
||||
(defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE))
|
||||
# define WITH_CRYPTO 1
|
||||
#endif
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
# define WITH_IPV6 1
|
||||
#endif
|
||||
@@ -42,7 +46,7 @@ MODULE_PARM_DESC(hash, "hash algorithm, default sha1");
|
||||
MODULE_PARM_DESC(seqno, "sequence number for remote sysrq");
|
||||
MODULE_PARM_DESC(debug, "debugging: 0=off, 1=on");
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
|
||||
#ifdef WITH_CRYPTO
|
||||
static struct crypto_hash *sysrq_tfm;
|
||||
static int sysrq_digest_size;
|
||||
static unsigned char *sysrq_digest_password;
|
||||
@@ -204,8 +208,8 @@ sysrq_tg4(struct sk_buff **pskb, const struct xt_target_param *par)
|
||||
return NF_DROP;
|
||||
|
||||
iph = ip_hdr(skb);
|
||||
if (iph->protocol != IPPROTO_UDP)
|
||||
return NF_ACCEPT; /* sink it */
|
||||
if (iph->protocol != IPPROTO_UDP && iph->protocol != IPPROTO_UDPLITE)
|
||||
return NF_DROP;
|
||||
|
||||
udph = (const void *)iph + ip_hdrlen(skb);
|
||||
len = ntohs(udph->len) - sizeof(struct udphdr);
|
||||
@@ -235,7 +239,7 @@ sysrq_tg6(struct sk_buff **pskb, const struct xt_target_param *par)
|
||||
iph = ipv6_hdr(skb);
|
||||
if (ipv6_find_hdr(skb, &th_off, IPPROTO_UDP, &frag_off) < 0 ||
|
||||
frag_off > 0)
|
||||
return NF_ACCEPT; /* sink it */
|
||||
return NF_DROP;
|
||||
|
||||
udph = (const void *)iph + th_off;
|
||||
len = ntohs(udph->len) - sizeof(struct udphdr);
|
||||
@@ -249,9 +253,8 @@ sysrq_tg6(struct sk_buff **pskb, const struct xt_target_param *par)
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool sysrq_tg_check(const struct xt_tgchk_param *par)
|
||||
static int sysrq_tg_check(const struct xt_tgchk_param *par)
|
||||
{
|
||||
|
||||
if (par->target->family == NFPROTO_IPV4) {
|
||||
const struct ipt_entry *entry = par->entryinfo;
|
||||
|
||||
@@ -268,11 +271,11 @@ static bool sysrq_tg_check(const struct xt_tgchk_param *par)
|
||||
goto out;
|
||||
}
|
||||
|
||||
return true;
|
||||
return 0;
|
||||
|
||||
out:
|
||||
printk(KERN_ERR KBUILD_MODNAME ": only available for UDP and UDP-Lite");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct xt_target sysrq_tg_reg[] __read_mostly = {
|
||||
@@ -296,43 +299,9 @@ static struct xt_target sysrq_tg_reg[] __read_mostly = {
|
||||
#endif
|
||||
};
|
||||
|
||||
static int __init sysrq_tg_init(void)
|
||||
static void sysrq_crypto_exit(void)
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
|
||||
struct timeval now;
|
||||
|
||||
sysrq_tfm = crypto_alloc_hash(sysrq_hash, 0, CRYPTO_ALG_ASYNC);
|
||||
if (IS_ERR(sysrq_tfm)) {
|
||||
printk(KERN_WARNING KBUILD_MODNAME
|
||||
": Error: Could not find or load %s hash\n",
|
||||
sysrq_hash);
|
||||
sysrq_tfm = NULL;
|
||||
goto fail;
|
||||
}
|
||||
sysrq_digest_size = crypto_hash_digestsize(sysrq_tfm);
|
||||
sysrq_digest = kmalloc(sysrq_digest_size, GFP_KERNEL);
|
||||
if (sysrq_digest == NULL) {
|
||||
printk(KERN_WARNING KBUILD_MODNAME
|
||||
": Cannot allocate digest\n");
|
||||
goto fail;
|
||||
}
|
||||
sysrq_hexdigest = kmalloc(2 * sysrq_digest_size + 1, GFP_KERNEL);
|
||||
if (sysrq_hexdigest == NULL) {
|
||||
printk(KERN_WARNING KBUILD_MODNAME
|
||||
": Cannot allocate hexdigest\n");
|
||||
goto fail;
|
||||
}
|
||||
sysrq_digest_password = kmalloc(sizeof(sysrq_password), GFP_KERNEL);
|
||||
if (sysrq_digest_password == NULL) {
|
||||
printk(KERN_WARNING KBUILD_MODNAME
|
||||
": Cannot allocate password digest space\n");
|
||||
goto fail;
|
||||
}
|
||||
do_gettimeofday(&now);
|
||||
sysrq_seqno = now.tv_sec;
|
||||
return xt_register_targets(sysrq_tg_reg, ARRAY_SIZE(sysrq_tg_reg));
|
||||
|
||||
fail:
|
||||
#ifdef WITH_CRYPTO
|
||||
if (sysrq_tfm)
|
||||
crypto_free_hash(sysrq_tfm);
|
||||
if (sysrq_digest)
|
||||
@@ -341,22 +310,62 @@ static int __init sysrq_tg_init(void)
|
||||
kfree(sysrq_hexdigest);
|
||||
if (sysrq_digest_password)
|
||||
kfree(sysrq_digest_password);
|
||||
return -EINVAL;
|
||||
#else
|
||||
printk(KERN_WARNING "xt_SYSRQ does not provide crypto for <= 2.6.18\n");
|
||||
return xt_register_targets(sysrq_tg_reg, ARRAY_SIZE(sysrq_tg_reg));
|
||||
#endif
|
||||
}
|
||||
|
||||
static int __init sysrq_crypto_init(void)
|
||||
{
|
||||
#if defined(WITH_CRYPTO)
|
||||
struct timeval now;
|
||||
int ret;
|
||||
|
||||
sysrq_tfm = crypto_alloc_hash(sysrq_hash, 0, CRYPTO_ALG_ASYNC);
|
||||
if (IS_ERR(sysrq_tfm)) {
|
||||
printk(KERN_WARNING KBUILD_MODNAME
|
||||
": Error: Could not find or load %s hash\n",
|
||||
sysrq_hash);
|
||||
sysrq_tfm = NULL;
|
||||
ret = PTR_ERR(sysrq_tfm);
|
||||
goto fail;
|
||||
}
|
||||
sysrq_digest_size = crypto_hash_digestsize(sysrq_tfm);
|
||||
sysrq_digest = kmalloc(sysrq_digest_size, GFP_KERNEL);
|
||||
ret = -ENOMEM;
|
||||
if (sysrq_digest == NULL)
|
||||
goto fail;
|
||||
sysrq_hexdigest = kmalloc(2 * sysrq_digest_size + 1, GFP_KERNEL);
|
||||
if (sysrq_hexdigest == NULL)
|
||||
goto fail;
|
||||
sysrq_digest_password = kmalloc(sizeof(sysrq_password), GFP_KERNEL);
|
||||
if (sysrq_digest_password == NULL)
|
||||
goto fail;
|
||||
do_gettimeofday(&now);
|
||||
sysrq_seqno = now.tv_sec;
|
||||
ret = xt_register_targets(sysrq_tg_reg, ARRAY_SIZE(sysrq_tg_reg));
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
return ret;
|
||||
|
||||
fail:
|
||||
sysrq_crypto_exit();
|
||||
return ret;
|
||||
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
|
||||
printk(KERN_WARNING "xt_SYSRQ does not provide crypto for < 2.6.19\n");
|
||||
#endif
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int __init sysrq_tg_init(void)
|
||||
{
|
||||
if (sysrq_crypto_init() < 0)
|
||||
printk(KERN_WARNING "xt_SYSRQ starting without crypto\n");
|
||||
return xt_register_targets(sysrq_tg_reg, ARRAY_SIZE(sysrq_tg_reg));
|
||||
}
|
||||
|
||||
static void __exit sysrq_tg_exit(void)
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
|
||||
crypto_free_hash(sysrq_tfm);
|
||||
kfree(sysrq_digest);
|
||||
kfree(sysrq_hexdigest);
|
||||
kfree(sysrq_digest_password);
|
||||
#endif
|
||||
return xt_unregister_targets(sysrq_tg_reg, ARRAY_SIZE(sysrq_tg_reg));
|
||||
sysrq_crypto_exit();
|
||||
xt_unregister_targets(sysrq_tg_reg, ARRAY_SIZE(sysrq_tg_reg));
|
||||
}
|
||||
|
||||
module_init(sysrq_tg_init);
|
||||
|
@@ -24,7 +24,6 @@
|
||||
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
|
||||
# define WITH_CONNTRACK 1
|
||||
# include <net/netfilter/nf_conntrack.h>
|
||||
static struct nf_conn tee_track;
|
||||
#endif
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
# define WITH_IPV6 1
|
||||
@@ -33,51 +32,23 @@ static struct nf_conn tee_track;
|
||||
#include "compat_xtables.h"
|
||||
#include "xt_TEE.h"
|
||||
|
||||
static bool tee_active[NR_CPUS];
|
||||
static const union nf_inet_addr tee_zero_address;
|
||||
|
||||
/*
|
||||
* Try to route the packet according to the routing keys specified in
|
||||
* route_info. Keys are :
|
||||
* - ifindex :
|
||||
* 0 if no oif preferred,
|
||||
* otherwise set to the index of the desired oif
|
||||
* - route_info->gateway :
|
||||
* 0 if no gateway specified,
|
||||
* otherwise set to the next host to which the pkt must be routed
|
||||
* If success, skb->dev is the output device to which the packet must
|
||||
* be sent and skb->dst is not NULL
|
||||
*
|
||||
* RETURN: false - if an error occured
|
||||
* true - if the packet was succesfully routed to the
|
||||
* destination desired
|
||||
*/
|
||||
static bool
|
||||
tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info)
|
||||
{
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
int err;
|
||||
struct rtable *rt;
|
||||
struct flowi fl;
|
||||
|
||||
memset(&fl, 0, sizeof(fl));
|
||||
fl.iif = skb_ifindex(skb);
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
||||
fl.nl_u.ip4_u.fwmark = skb_nfmark(skb);
|
||||
#else
|
||||
fl.mark = skb_nfmark(skb);
|
||||
#endif
|
||||
fl.nl_u.ip4_u.daddr = info->gw.ip;
|
||||
fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
|
||||
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);
|
||||
if (err != 0) {
|
||||
if (net_ratelimit())
|
||||
pr_debug(KBUILD_MODNAME
|
||||
": could not route packet (%d)", err);
|
||||
if (ip_route_output_key(&init_net, &rt, &fl) != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
dst_release(skb_dst(skb));
|
||||
skb_dst_set(skb, &rt->u.dst);
|
||||
@@ -123,79 +94,58 @@ static void tee_tg_send(struct sk_buff *skb)
|
||||
skb = skb2;
|
||||
}
|
||||
|
||||
if (dst->hh != NULL) {
|
||||
if (dst->hh != NULL)
|
||||
neigh_hh_output(dst->hh, skb);
|
||||
} else if (dst->neighbour != NULL) {
|
||||
else if (dst->neighbour != NULL)
|
||||
dst->neighbour->output(skb);
|
||||
} else {
|
||||
if (net_ratelimit())
|
||||
pr_debug(KBUILD_MODNAME "no hdr & no neighbour cache!\n");
|
||||
else
|
||||
kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* To detect and deter routed packet loopback when using the --tee option, we
|
||||
* take a page out of the raw.patch book: on the copied skb, we set up a fake
|
||||
* ->nfct entry, pointing to the local &route_tee_track. We skip routing
|
||||
* packets when we see they already have that ->nfct.
|
||||
*/
|
||||
static unsigned int
|
||||
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;
|
||||
struct iphdr *iph;
|
||||
unsigned int cpu = smp_processor_id();
|
||||
|
||||
#ifdef WITH_CONNTRACK
|
||||
if (skb->nfct == &tee_track.ct_general) {
|
||||
/*
|
||||
* Loopback - a packet we already routed, is to be
|
||||
* routed another time. Avoid that, now.
|
||||
*/
|
||||
if (net_ratelimit())
|
||||
pr_debug(KBUILD_MODNAME "loopback - DROP!\n");
|
||||
return NF_DROP;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!skb_make_writable(pskb, sizeof(struct iphdr)))
|
||||
return NF_DROP;
|
||||
skb = *pskb;
|
||||
|
||||
/*
|
||||
* If we are in INPUT, the checksum must be recalculated since
|
||||
* the length could have changed as a result of defragmentation.
|
||||
*/
|
||||
if (par->hooknum == NF_INET_LOCAL_IN) {
|
||||
struct iphdr *iph = ip_hdr(skb);
|
||||
iph->check = 0;
|
||||
iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
|
||||
}
|
||||
|
||||
if (tee_active[cpu])
|
||||
return XT_CONTINUE;
|
||||
/*
|
||||
* 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 independently delivered to the TEE
|
||||
* --gateway.
|
||||
*/
|
||||
skb = skb_copy(skb, GFP_ATOMIC);
|
||||
if (skb == NULL) {
|
||||
if (net_ratelimit())
|
||||
pr_debug(KBUILD_MODNAME "copy failed!\n");
|
||||
skb = pskb_copy(skb, GFP_ATOMIC);
|
||||
if (skb == NULL)
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
/*
|
||||
* If we are in PREROUTING/INPUT, the checksum must be recalculated
|
||||
* since the length could have changed as a result of defragmentation.
|
||||
*
|
||||
* We also decrease the TTL to mitigate potential TEE loops
|
||||
* between two hosts.
|
||||
*
|
||||
* Set %IP_DF so that the original source is notified of a potentially
|
||||
* decreased MTU on the clone route. IPv6 does this too.
|
||||
*/
|
||||
iph = ip_hdr(skb);
|
||||
iph->frag_off |= htons(IP_DF);
|
||||
if (par->hooknum == NF_INET_PRE_ROUTING ||
|
||||
par->hooknum == NF_INET_LOCAL_IN)
|
||||
--iph->ttl;
|
||||
ip_send_check(iph);
|
||||
|
||||
#ifdef WITH_CONNTRACK
|
||||
/*
|
||||
* Tell conntrack to forget this packet since it may get confused
|
||||
* when a packet is leaving with dst address == our address.
|
||||
* Good idea? Dunno. Need advice.
|
||||
*
|
||||
* NEW: mark the skb with our &tee_track, so we avoid looping
|
||||
* on any already routed packet.
|
||||
* Tell conntrack to forget this packet. It may have side effects to
|
||||
* see the same packet twice, as for example, accounting the original
|
||||
* connection for the cloned packet.
|
||||
*/
|
||||
nf_conntrack_put(skb->nfct);
|
||||
skb->nfct = &tee_track.ct_general;
|
||||
skb->nfct = &nf_conntrack_untracked.ct_general;
|
||||
skb->nfctinfo = IP_CT_NEW;
|
||||
nf_conntrack_get(skb->nfct);
|
||||
#endif
|
||||
@@ -216,9 +166,13 @@ tee_tg4(struct sk_buff **pskb, const struct xt_target_param *par)
|
||||
* Also on purpose, no fragmentation is done, to preserve the
|
||||
* packet as best as possible.
|
||||
*/
|
||||
if (tee_tg_route4(skb, info))
|
||||
if (tee_tg_route4(skb, info)) {
|
||||
tee_active[cpu] = true;
|
||||
tee_tg_send(skb);
|
||||
|
||||
tee_active[cpu] = false;
|
||||
} else {
|
||||
kfree_skb(skb);
|
||||
}
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
||||
@@ -231,12 +185,6 @@ tee_tg_route6(struct sk_buff *skb, const struct xt_tee_tginfo *info)
|
||||
struct flowi fl;
|
||||
|
||||
memset(&fl, 0, sizeof(fl));
|
||||
fl.iif = skb_ifindex(skb);
|
||||
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 19)
|
||||
fl.nl_u.ip6_u.fwmark = skb_nfmark(skb);
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
|
||||
fl.mark = skb_nfmark(skb);
|
||||
#endif
|
||||
fl.nl_u.ip6_u.daddr = info->gw.in6;
|
||||
fl.nl_u.ip6_u.flowlabel = ((iph->flow_lbl[0] & 0xF) << 16) |
|
||||
(iph->flow_lbl[1] << 8) | iph->flow_lbl[2];
|
||||
@@ -246,11 +194,8 @@ tee_tg_route6(struct sk_buff *skb, const struct xt_tee_tginfo *info)
|
||||
#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");
|
||||
if (dst == NULL)
|
||||
return false;
|
||||
}
|
||||
|
||||
dst_release(skb_dst(skb));
|
||||
skb_dst_set(skb, dst);
|
||||
@@ -264,36 +209,43 @@ 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;
|
||||
unsigned int cpu = smp_processor_id();
|
||||
|
||||
/* Try silence. */
|
||||
#ifdef WITH_CONNTRACK
|
||||
if (skb->nfct == &tee_track.ct_general)
|
||||
return NF_DROP;
|
||||
#endif
|
||||
|
||||
if ((skb = skb_copy(skb, GFP_ATOMIC)) == NULL)
|
||||
if (tee_active[cpu])
|
||||
return XT_CONTINUE;
|
||||
skb = pskb_copy(skb, GFP_ATOMIC);
|
||||
if (skb == NULL)
|
||||
return XT_CONTINUE;
|
||||
|
||||
#ifdef WITH_CONNTRACK
|
||||
nf_conntrack_put(skb->nfct);
|
||||
skb->nfct = &tee_track.ct_general;
|
||||
skb->nfct = &nf_conntrack_untracked.ct_general;
|
||||
skb->nfctinfo = IP_CT_NEW;
|
||||
nf_conntrack_get(skb->nfct);
|
||||
#endif
|
||||
if (tee_tg_route6(skb, info))
|
||||
if (par->hooknum == NF_INET_PRE_ROUTING ||
|
||||
par->hooknum == NF_INET_LOCAL_IN) {
|
||||
struct ipv6hdr *iph = ipv6_hdr(skb);
|
||||
--iph->hop_limit;
|
||||
}
|
||||
if (tee_tg_route6(skb, info)) {
|
||||
tee_active[cpu] = true;
|
||||
tee_tg_send(skb);
|
||||
|
||||
tee_active[cpu] = false;
|
||||
} else {
|
||||
kfree_skb(skb);
|
||||
}
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
#endif /* WITH_IPV6 */
|
||||
|
||||
static bool tee_tg_check(const struct xt_tgchk_param *par)
|
||||
static int 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, &tee_zero_address,
|
||||
sizeof(tee_zero_address)) != 0;
|
||||
return (memcmp(&info->gw, &tee_zero_address,
|
||||
sizeof(tee_zero_address)) == 0) ? -EINVAL : 0;
|
||||
}
|
||||
|
||||
static struct xt_target tee_tg_reg[] __read_mostly = {
|
||||
@@ -301,7 +253,6 @@ 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,
|
||||
@@ -312,7 +263,6 @@ static struct xt_target tee_tg_reg[] __read_mostly = {
|
||||
.name = "TEE",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV6,
|
||||
.table = "mangle",
|
||||
.target = tee_tg6,
|
||||
.targetsize = sizeof(struct xt_tee_tginfo),
|
||||
.checkentry = tee_tg_check,
|
||||
@@ -323,27 +273,12 @@ static struct xt_target tee_tg_reg[] __read_mostly = {
|
||||
|
||||
static int __init tee_tg_init(void)
|
||||
{
|
||||
#ifdef WITH_CONNTRACK
|
||||
/*
|
||||
* Set up fake conntrack (stolen from raw.patch):
|
||||
* - to never be deleted, not in any hashes
|
||||
*/
|
||||
atomic_set(&tee_track.ct_general.use, 1);
|
||||
|
||||
/* - and look it like as a confirmed connection */
|
||||
set_bit(IPS_CONFIRMED_BIT, &tee_track.status);
|
||||
|
||||
/* Initialize fake conntrack so that NAT will skip it */
|
||||
tee_track.status |= IPS_NAT_DONE_MASK;
|
||||
#endif
|
||||
|
||||
return xt_register_targets(tee_tg_reg, ARRAY_SIZE(tee_tg_reg));
|
||||
}
|
||||
|
||||
static void __exit tee_tg_exit(void)
|
||||
{
|
||||
xt_unregister_targets(tee_tg_reg, ARRAY_SIZE(tee_tg_reg));
|
||||
/* [SC]: shoud not we cleanup tee_track here? */
|
||||
}
|
||||
|
||||
module_init(tee_tg_init);
|
||||
|
@@ -35,6 +35,7 @@ static unsigned int condition_gid_perms = 0;
|
||||
|
||||
MODULE_AUTHOR("Stephane Ouellette <ouellettes@videotron.ca>");
|
||||
MODULE_AUTHOR("Massimiliano Hofer <max@nucleus.it>");
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_DESCRIPTION("Allows rules to match against condition variables");
|
||||
MODULE_LICENSE("GPL");
|
||||
module_param(condition_list_perms, uint, S_IRUSR | S_IWUSR);
|
||||
@@ -55,7 +56,7 @@ struct condition_variable {
|
||||
|
||||
/* proc_lock is a user context only semaphore used for write access */
|
||||
/* to the conditions' list. */
|
||||
static struct semaphore proc_lock;
|
||||
static DEFINE_MUTEX(proc_lock);
|
||||
|
||||
static LIST_HEAD(conditions_list);
|
||||
static struct proc_dir_entry *proc_net_condition;
|
||||
@@ -69,7 +70,6 @@ static int condition_proc_read(char __user *buffer, char **start, off_t offset,
|
||||
buffer[1] = '\n';
|
||||
if (length >= 2)
|
||||
*eof = true;
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,6 @@ static int condition_proc_write(struct file *file, const char __user *buffer,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
@@ -101,16 +100,11 @@ condition_mt(const struct sk_buff *skb, const struct xt_match_param *par)
|
||||
{
|
||||
const struct xt_condition_mtinfo *info = par->matchinfo;
|
||||
const struct condition_variable *var = info->condvar;
|
||||
bool x;
|
||||
|
||||
rcu_read_lock();
|
||||
x = rcu_dereference(var->enabled);
|
||||
rcu_read_unlock();
|
||||
|
||||
return x ^ info->invert;
|
||||
return var->enabled ^ info->invert;
|
||||
}
|
||||
|
||||
static bool condition_mt_check(const struct xt_mtchk_param *par)
|
||||
static int condition_mt_check(const struct xt_mtchk_param *par)
|
||||
{
|
||||
struct xt_condition_mtinfo *info = par->matchinfo;
|
||||
struct condition_variable *var;
|
||||
@@ -122,41 +116,36 @@ static bool condition_mt_check(const struct xt_mtchk_param *par)
|
||||
printk(KERN_INFO KBUILD_MODNAME ": name not allowed or too "
|
||||
"long: \"%.*s\"\n", (unsigned int)sizeof(info->name),
|
||||
info->name);
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Let's acquire the lock, check for the condition and add it
|
||||
* or increase the reference counter.
|
||||
*/
|
||||
if (down_interruptible(&proc_lock))
|
||||
return false;
|
||||
|
||||
mutex_lock(&proc_lock);
|
||||
list_for_each_entry(var, &conditions_list, list) {
|
||||
if (strcmp(info->name, var->status_proc->name) == 0) {
|
||||
var->refcount++;
|
||||
up(&proc_lock);
|
||||
mutex_unlock(&proc_lock);
|
||||
info->condvar = var;
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* At this point, we need to allocate a new condition variable. */
|
||||
var = kmalloc(sizeof(struct condition_variable), GFP_KERNEL);
|
||||
|
||||
if (var == NULL) {
|
||||
up(&proc_lock);
|
||||
return false;
|
||||
mutex_unlock(&proc_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Create the condition variable's proc file entry. */
|
||||
var->status_proc = create_proc_entry(info->name, condition_list_perms,
|
||||
proc_net_condition);
|
||||
|
||||
if (var->status_proc == NULL) {
|
||||
kfree(var);
|
||||
up(&proc_lock);
|
||||
return false;
|
||||
mutex_unlock(&proc_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
var->refcount = 1;
|
||||
@@ -168,16 +157,12 @@ static bool condition_mt_check(const struct xt_mtchk_param *par)
|
||||
wmb();
|
||||
var->status_proc->read_proc = condition_proc_read;
|
||||
var->status_proc->write_proc = condition_proc_write;
|
||||
|
||||
list_add_rcu(&var->list, &conditions_list);
|
||||
|
||||
list_add(&var->list, &conditions_list);
|
||||
var->status_proc->uid = condition_uid_perms;
|
||||
var->status_proc->gid = condition_gid_perms;
|
||||
|
||||
up(&proc_lock);
|
||||
|
||||
mutex_unlock(&proc_lock);
|
||||
info->condvar = var;
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void condition_mt_destroy(const struct xt_mtdtor_param *par)
|
||||
@@ -185,22 +170,15 @@ static void condition_mt_destroy(const struct xt_mtdtor_param *par)
|
||||
const struct xt_condition_mtinfo *info = par->matchinfo;
|
||||
struct condition_variable *var = info->condvar;
|
||||
|
||||
down(&proc_lock);
|
||||
mutex_lock(&proc_lock);
|
||||
if (--var->refcount == 0) {
|
||||
list_del_rcu(&var->list);
|
||||
list_del(&var->list);
|
||||
remove_proc_entry(var->status_proc->name, proc_net_condition);
|
||||
up(&proc_lock);
|
||||
/*
|
||||
* synchronize_rcu() would be good enough, but
|
||||
* synchronize_net() guarantees that no packet
|
||||
* will go out with the old rule after
|
||||
* succesful removal.
|
||||
*/
|
||||
synchronize_net();
|
||||
mutex_unlock(&proc_lock);
|
||||
kfree(var);
|
||||
return;
|
||||
}
|
||||
up(&proc_lock);
|
||||
mutex_unlock(&proc_lock);
|
||||
}
|
||||
|
||||
static struct xt_match condition_mt_reg[] __read_mostly = {
|
||||
@@ -208,7 +186,7 @@ static struct xt_match condition_mt_reg[] __read_mostly = {
|
||||
.name = "condition",
|
||||
.revision = 1,
|
||||
.family = NFPROTO_IPV4,
|
||||
.matchsize = XT_ALIGN(sizeof(struct xt_condition_mtinfo)),
|
||||
.matchsize = sizeof(struct xt_condition_mtinfo),
|
||||
.match = condition_mt,
|
||||
.checkentry = condition_mt_check,
|
||||
.destroy = condition_mt_destroy,
|
||||
@@ -218,7 +196,7 @@ static struct xt_match condition_mt_reg[] __read_mostly = {
|
||||
.name = "condition",
|
||||
.revision = 1,
|
||||
.family = NFPROTO_IPV6,
|
||||
.matchsize = XT_ALIGN(sizeof(struct xt_condition_mtinfo)),
|
||||
.matchsize = sizeof(struct xt_condition_mtinfo),
|
||||
.match = condition_mt,
|
||||
.checkentry = condition_mt_check,
|
||||
.destroy = condition_mt_destroy,
|
||||
@@ -232,7 +210,7 @@ static int __init condition_mt_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
sema_init(&proc_lock, 1);
|
||||
mutex_init(&proc_lock);
|
||||
proc_net_condition = proc_mkdir(dir_name, init_net__proc_net);
|
||||
if (proc_net_condition == NULL)
|
||||
return -EACCES;
|
||||
|
@@ -125,7 +125,7 @@ fuzzy_mt(const struct sk_buff *skb, const struct xt_match_param *par)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool fuzzy_mt_check(const struct xt_mtchk_param *par)
|
||||
static int fuzzy_mt_check(const struct xt_mtchk_param *par)
|
||||
{
|
||||
const struct xt_fuzzy_mtinfo *info = par->matchinfo;
|
||||
|
||||
@@ -133,10 +133,10 @@ static bool fuzzy_mt_check(const struct xt_mtchk_param *par)
|
||||
info->maximum_rate > FUZZY_MAX_RATE ||
|
||||
info->minimum_rate >= info->maximum_rate) {
|
||||
printk(KERN_INFO KBUILD_MODNAME ": bad values, please check.\n");
|
||||
return false;
|
||||
return -EDOM;
|
||||
}
|
||||
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xt_match fuzzy_mt_reg[] __read_mostly = {
|
||||
@@ -146,7 +146,7 @@ static struct xt_match fuzzy_mt_reg[] __read_mostly = {
|
||||
.family = NFPROTO_IPV4,
|
||||
.match = fuzzy_mt,
|
||||
.checkentry = fuzzy_mt_check,
|
||||
.matchsize = XT_ALIGN(sizeof(struct xt_fuzzy_mtinfo)),
|
||||
.matchsize = sizeof(struct xt_fuzzy_mtinfo),
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
{
|
||||
@@ -155,7 +155,7 @@ static struct xt_match fuzzy_mt_reg[] __read_mostly = {
|
||||
.family = NFPROTO_IPV6,
|
||||
.match = fuzzy_mt,
|
||||
.checkentry = fuzzy_mt_check,
|
||||
.matchsize = XT_ALIGN(sizeof(struct xt_fuzzy_mtinfo)),
|
||||
.matchsize = sizeof(struct xt_fuzzy_mtinfo),
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
@@ -46,23 +46,28 @@ geoip_add_node(const struct geoip_country_user __user *umem_ptr)
|
||||
struct geoip_country_user umem;
|
||||
struct geoip_country_kernel *p;
|
||||
struct geoip_subnet *s;
|
||||
int ret;
|
||||
|
||||
if (copy_from_user(&umem, umem_ptr, sizeof(umem)) != 0)
|
||||
return NULL;
|
||||
return ERR_PTR(-EFAULT);
|
||||
|
||||
p = kmalloc(sizeof(struct geoip_country_kernel), GFP_KERNEL);
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
p->count = umem.count;
|
||||
p->cc = umem.cc;
|
||||
|
||||
s = vmalloc(p->count * sizeof(struct geoip_subnet));
|
||||
if (s == NULL)
|
||||
if (s == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto free_p;
|
||||
}
|
||||
if (copy_from_user(s, (const void __user *)(unsigned long)umem.subnets,
|
||||
p->count * sizeof(struct geoip_subnet)) != 0)
|
||||
p->count * sizeof(struct geoip_subnet)) != 0) {
|
||||
ret = -EFAULT;
|
||||
goto free_s;
|
||||
}
|
||||
|
||||
p->subnets = s;
|
||||
atomic_set(&p->ref, 1);
|
||||
@@ -78,7 +83,7 @@ geoip_add_node(const struct geoip_country_user __user *umem_ptr)
|
||||
vfree(s);
|
||||
free_p:
|
||||
kfree(p);
|
||||
return NULL;
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static void geoip_try_remove_node(struct geoip_country_kernel *p)
|
||||
@@ -168,7 +173,7 @@ xt_geoip_mt(const struct sk_buff *skb, const struct xt_match_param *par)
|
||||
return info->flags & XT_GEOIP_INV;
|
||||
}
|
||||
|
||||
static bool xt_geoip_mt_checkentry(const struct xt_mtchk_param *par)
|
||||
static int xt_geoip_mt_checkentry(const struct xt_mtchk_param *par)
|
||||
{
|
||||
struct xt_geoip_match_info *info = par->matchinfo;
|
||||
struct geoip_country_kernel *node;
|
||||
@@ -176,13 +181,15 @@ static bool xt_geoip_mt_checkentry(const struct xt_mtchk_param *par)
|
||||
|
||||
for (i = 0; i < info->count; i++) {
|
||||
node = find_node(info->cc[i]);
|
||||
if (node == NULL)
|
||||
if ((node = geoip_add_node((const void __user *)(unsigned long)info->mem[i].user)) == NULL) {
|
||||
if (node == NULL) {
|
||||
node = geoip_add_node((const void __user *)(unsigned long)info->mem[i].user);
|
||||
if (IS_ERR(node)) {
|
||||
printk(KERN_ERR
|
||||
"xt_geoip: unable to load '%c%c' into memory\n",
|
||||
COUNTRY(info->cc[i]));
|
||||
return false;
|
||||
"xt_geoip: unable to load '%c%c' into memory: %ld\n",
|
||||
COUNTRY(info->cc[i]), PTR_ERR(node));
|
||||
return PTR_ERR(node);
|
||||
}
|
||||
}
|
||||
|
||||
/* Overwrite the now-useless pointer info->mem[i] with
|
||||
* a pointer to the node's kernelspace structure.
|
||||
@@ -192,7 +199,7 @@ static bool xt_geoip_mt_checkentry(const struct xt_mtchk_param *par)
|
||||
info->mem[i].kernel = node;
|
||||
}
|
||||
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xt_geoip_mt_destroy(const struct xt_mtdtor_param *par)
|
||||
|
@@ -71,7 +71,7 @@ static struct xt_match xt_iface_mt_reg[] __read_mostly = {
|
||||
.name = "iface",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV4,
|
||||
.matchsize = XT_ALIGN(sizeof(struct xt_iface_mtinfo)),
|
||||
.matchsize = sizeof(struct xt_iface_mtinfo),
|
||||
.match = xt_iface_mt,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
@@ -79,7 +79,7 @@ static struct xt_match xt_iface_mt_reg[] __read_mostly = {
|
||||
.name = "iface",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV6,
|
||||
.matchsize = XT_ALIGN(sizeof(struct xt_iface_mtinfo)),
|
||||
.matchsize = sizeof(struct xt_iface_mtinfo),
|
||||
.match = xt_iface_mt,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
|
@@ -505,19 +505,18 @@ search_bittorrent(const unsigned char *payload, const unsigned int plen)
|
||||
if (payload[0] == 0x13)
|
||||
if (memcmp(payload + 1, "BitTorrent protocol", 19) == 0)
|
||||
return IPP2P_BIT * 100;
|
||||
|
||||
/*
|
||||
* get tracker commandos, all starts with GET /
|
||||
* then it can follow: scrape| announce
|
||||
* and then ?hash_info=
|
||||
* Any tracker command starts with GET / then *may be* some file on web server
|
||||
* (e.g. announce.php or dupa.pl or whatever.cgi or NOTHING for tracker on root dir)
|
||||
* but *must have* one (or more) of strings listed below (true for scrape and announce)
|
||||
*/
|
||||
if (memcmp(payload, "GET /", 5) == 0) {
|
||||
/* message scrape */
|
||||
if (memcmp(payload + 5, "scrape?info_hash=", 17) == 0)
|
||||
if (HX_memmem(payload, plen, "info_hash=", 9) != NULL)
|
||||
return IPP2P_BIT * 100 + 1;
|
||||
/* message announce */
|
||||
if (memcmp(payload + 5, "announce?info_hash=", 19) == 0)
|
||||
if (HX_memmem(payload, plen, "peer_id=", 8) != NULL)
|
||||
return IPP2P_BIT * 100 + 2;
|
||||
if (HX_memmem(payload, plen, "passkey=", 8) != NULL)
|
||||
return IPP2P_BIT * 100 + 4;
|
||||
}
|
||||
} else {
|
||||
/* bitcomet encryptes the first packet, so we have to detect another
|
||||
|
@@ -50,7 +50,7 @@ static struct xt_match ipv4options_mt_reg __read_mostly = {
|
||||
.revision = 1,
|
||||
.family = NFPROTO_IPV4,
|
||||
.match = ipv4options_mt,
|
||||
.matchsize = XT_ALIGN(sizeof(struct xt_ipv4options_mtinfo1)),
|
||||
.matchsize = sizeof(struct xt_ipv4options_mtinfo1),
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
@@ -216,16 +216,16 @@ lscan_mt(const struct sk_buff *skb, const struct xt_match_param *par)
|
||||
(info->match_gr && ctdata->mark == mark_grscan);
|
||||
}
|
||||
|
||||
static bool lscan_mt_check(const struct xt_mtchk_param *par)
|
||||
static int lscan_mt_check(const struct xt_mtchk_param *par)
|
||||
{
|
||||
const struct xt_lscan_mtinfo *info = par->matchinfo;
|
||||
|
||||
if ((info->match_stealth & ~1) || (info->match_syn & ~1) ||
|
||||
(info->match_cn & ~1) || (info->match_gr & ~1)) {
|
||||
printk(KERN_WARNING PFX "Invalid flags\n");
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xt_match lscan_mt_reg[] __read_mostly = {
|
||||
|
@@ -312,7 +312,7 @@ out_match:
|
||||
|
||||
static struct xt_match xt_psd_reg __read_mostly = {
|
||||
.name = "psd",
|
||||
.family = AF_INET,
|
||||
.family = NFPROTO_IPV4,
|
||||
.revision = 1,
|
||||
.match = xt_psd_match,
|
||||
.matchsize = sizeof(struct xt_psd_info),
|
||||
|
@@ -144,28 +144,28 @@ q2_get_counter(const struct xt_quota_mtinfo2 *q)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool quota_mt2_check(const struct xt_mtchk_param *par)
|
||||
static int quota_mt2_check(const struct xt_mtchk_param *par)
|
||||
{
|
||||
struct xt_quota_mtinfo2 *q = par->matchinfo;
|
||||
|
||||
if (q->flags & ~XT_QUOTA_MASK)
|
||||
return false;
|
||||
return -EINVAL;
|
||||
|
||||
q->name[sizeof(q->name)-1] = '\0';
|
||||
if (*q->name == '.' || strchr(q->name, '/') != NULL) {
|
||||
printk(KERN_ERR "xt_quota<%u>: illegal name\n",
|
||||
par->match->revision);
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
q->master = q2_get_counter(q);
|
||||
if (q->master == NULL) {
|
||||
printk(KERN_ERR "xt_quota<%u>: memory alloc failure\n",
|
||||
par->match->revision);
|
||||
return false;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void quota_mt2_destroy(const struct xt_mtdtor_param *par)
|
||||
|
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
|
||||
/* Responses from hook functions. */
|
||||
#define NF_DROP 0
|
||||
#define NF_ACCEPT 1
|
||||
@@ -37,6 +38,16 @@ enum nf_inet_hooks {
|
||||
NF_INET_NUMHOOKS
|
||||
};
|
||||
|
||||
enum {
|
||||
NFPROTO_UNSPEC = 0,
|
||||
NFPROTO_IPV4 = 2,
|
||||
NFPROTO_ARP = 3,
|
||||
NFPROTO_BRIDGE = 7,
|
||||
NFPROTO_IPV6 = 10,
|
||||
NFPROTO_DECNET = 12,
|
||||
NFPROTO_NUMPROTO,
|
||||
};
|
||||
|
||||
union nf_inet_addr {
|
||||
__u32 all[4];
|
||||
__be32 ip;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
.TH xtables-addons 8 "v1.23 (2010-02-24)" "" "v1.23 (2010-02-24)"
|
||||
.TH xtables-addons 8 "v1.25 (2010-04-26)" "" "v1.25 (2010-04-26)"
|
||||
.SH Name
|
||||
Xtables-addons \(em additional extensions for iptables, ip6tables, etc.
|
||||
.SH Targets
|
||||
|
Reference in New Issue
Block a user