mirror of
git://git.code.sf.net/p/xtables-addons/xtables-addons
synced 2025-09-21 03:54:59 +02:00
Compare commits
28 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
65b75fc19c | ||
![]() |
bac406bff5 | ||
![]() |
aa53733851 | ||
![]() |
9ccd32d840 | ||
![]() |
939d3c8b27 | ||
![]() |
c2d93e16fd | ||
![]() |
04aed87cb6 | ||
![]() |
5ef3a7c436 | ||
![]() |
27a77b62f5 | ||
![]() |
c10e974bd6 | ||
![]() |
01d864f4fc | ||
![]() |
071c95b750 | ||
![]() |
a141cc311c | ||
![]() |
7e92ce7ce6 | ||
![]() |
21da1dfea5 | ||
![]() |
6c17eb46b5 | ||
![]() |
74ea647303 | ||
![]() |
e0154bfa4c | ||
![]() |
cd18e2479c | ||
![]() |
d2f3541cda | ||
![]() |
1fed8bbf09 | ||
![]() |
6e8fb7f231 | ||
![]() |
eceaee3431 | ||
![]() |
77b29a62ee | ||
![]() |
33db992c39 | ||
![]() |
85d8f98dd7 | ||
![]() |
e84391ce66 | ||
![]() |
ef7fb0db7f |
6
INSTALL
6
INSTALL
@@ -22,12 +22,14 @@ Supported configurations for this release
|
|||||||
- CONFIG_CONNECTOR y/m if you wish to receive userspace
|
- CONFIG_CONNECTOR y/m if you wish to receive userspace
|
||||||
notifications from pknock through netlink/connector
|
notifications from pknock through netlink/connector
|
||||||
|
|
||||||
For ipset-6 you need:
|
Compilation of ipset-genl-6.x is enabled by default. This additionally
|
||||||
|
requires
|
||||||
|
|
||||||
* libmnl
|
* libmnl
|
||||||
|
|
||||||
* Linux kernel >= 2.6.35
|
* Linux kernel >= 2.6.35
|
||||||
|
|
||||||
|
so if you do not have these, turn it off in mconfig before compilation.
|
||||||
|
|
||||||
|
|
||||||
Selecting extensions
|
Selecting extensions
|
||||||
====================
|
====================
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
|
AC_INIT([xtables-addons], [1.38])
|
||||||
AC_INIT([xtables-addons], [1.36])
|
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
@@ -42,7 +41,7 @@ regular_CFLAGS="-Wall -Waggregate-return -Wmissing-declarations \
|
|||||||
|
|
||||||
if test -n "$kbuilddir"; then
|
if test -n "$kbuilddir"; then
|
||||||
AC_MSG_CHECKING([kernel version that we will build against])
|
AC_MSG_CHECKING([kernel version that we will build against])
|
||||||
krel="$(make -sC "$kbuilddir" M=. kernelrelease)";
|
krel="$(make -sC "$kbuilddir" M=$PWD kernelrelease)";
|
||||||
kmajor="${krel%%[[^0-9]]*}";
|
kmajor="${krel%%[[^0-9]]*}";
|
||||||
kmajor="$(($kmajor+0))";
|
kmajor="$(($kmajor+0))";
|
||||||
krel="${krel:${#kmajor}}";
|
krel="${krel:${#kmajor}}";
|
||||||
@@ -65,7 +64,7 @@ if test -n "$kbuilddir"; then
|
|||||||
echo "WARNING: You are trying a newer kernel. Results may vary. :-)";
|
echo "WARNING: You are trying a newer kernel. Results may vary. :-)";
|
||||||
elif test "$kmajor" -eq 3; then
|
elif test "$kmajor" -eq 3; then
|
||||||
:;
|
:;
|
||||||
elif test "$kmajor" -eq 2 -a "$kminor" -ge 29; then
|
elif test "$kmajor" -eq 2 -a "$kminor" -eq 6 -a "$kmicro" -ge 29; then
|
||||||
:;
|
:;
|
||||||
else
|
else
|
||||||
echo "WARNING: That kernel version is not supported.";
|
echo "WARNING: That kernel version is not supported.";
|
||||||
|
@@ -3,6 +3,28 @@ HEAD
|
|||||||
====
|
====
|
||||||
|
|
||||||
|
|
||||||
|
v1.38 (2011-08-20)
|
||||||
|
==================
|
||||||
|
- xt_CHECKSUM: abort build when the feature is already provided by mainline
|
||||||
|
- xt_SYSRQ: fix UDPLITE header lookup in IPv6
|
||||||
|
- xt_TARPIT: fix kernel warning about RTAX_HOPLIMIT being used
|
||||||
|
- xt_TEE: abort build when the feature is already provided by mainline
|
||||||
|
- xt_ipp2p: support UDPLITE
|
||||||
|
- xt_pknock: support UDPLITE
|
||||||
|
- xt_psd: restore functionality with UDP
|
||||||
|
- xt_psd: support UDPLITE
|
||||||
|
- update to ipset 6.8
|
||||||
|
- support for Linux 3.1
|
||||||
|
|
||||||
|
|
||||||
|
v1.37 (2011-06-25)
|
||||||
|
==================
|
||||||
|
Fixes:
|
||||||
|
- xt_SYSRQ: make IPv6 trigger work again
|
||||||
|
- xt_SYSRQ: improve security: include host address in digest
|
||||||
|
- xt_TARPIT: fix a kernel oops in --reset mode
|
||||||
|
|
||||||
|
|
||||||
v1.36 (2011-06-03)
|
v1.36 (2011-06-03)
|
||||||
==================
|
==================
|
||||||
Changes:
|
Changes:
|
||||||
|
@@ -28,7 +28,32 @@
|
|||||||
/* Number of elements to store in an initial array block */
|
/* Number of elements to store in an initial array block */
|
||||||
#define AHASH_INIT_SIZE 4
|
#define AHASH_INIT_SIZE 4
|
||||||
/* Max number of elements to store in an array block */
|
/* Max number of elements to store in an array block */
|
||||||
#define AHASH_MAX_SIZE (3*4)
|
#define AHASH_MAX_SIZE (3*AHASH_INIT_SIZE)
|
||||||
|
|
||||||
|
/* Max number of elements can be tuned */
|
||||||
|
#ifdef IP_SET_HASH_WITH_MULTI
|
||||||
|
#define AHASH_MAX(h) ((h)->ahash_max)
|
||||||
|
|
||||||
|
static inline u8
|
||||||
|
tune_ahash_max(u8 curr, u32 multi)
|
||||||
|
{
|
||||||
|
u32 n;
|
||||||
|
|
||||||
|
if (multi < curr)
|
||||||
|
return curr;
|
||||||
|
|
||||||
|
n = curr + AHASH_INIT_SIZE;
|
||||||
|
/* Currently, at listing one hash bucket must fit into a message.
|
||||||
|
* Therefore we have a hard limit here.
|
||||||
|
*/
|
||||||
|
return n > curr && n <= 64 ? n : curr;
|
||||||
|
}
|
||||||
|
#define TUNE_AHASH_MAX(h, multi) \
|
||||||
|
((h)->ahash_max = tune_ahash_max((h)->ahash_max, multi))
|
||||||
|
#else
|
||||||
|
#define AHASH_MAX(h) AHASH_MAX_SIZE
|
||||||
|
#define TUNE_AHASH_MAX(h, multi)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* A hash bucket */
|
/* A hash bucket */
|
||||||
struct hbucket {
|
struct hbucket {
|
||||||
@@ -60,6 +85,9 @@ struct ip_set_hash {
|
|||||||
u32 timeout; /* timeout value, if enabled */
|
u32 timeout; /* timeout value, if enabled */
|
||||||
struct timer_list gc; /* garbage collection when timeout enabled */
|
struct timer_list gc; /* garbage collection when timeout enabled */
|
||||||
struct type_pf_next next; /* temporary storage for uadd */
|
struct type_pf_next next; /* temporary storage for uadd */
|
||||||
|
#ifdef IP_SET_HASH_WITH_MULTI
|
||||||
|
u8 ahash_max; /* max elements in an array block */
|
||||||
|
#endif
|
||||||
#ifdef IP_SET_HASH_WITH_NETMASK
|
#ifdef IP_SET_HASH_WITH_NETMASK
|
||||||
u8 netmask; /* netmask value for subnets to store */
|
u8 netmask; /* netmask value for subnets to store */
|
||||||
#endif
|
#endif
|
||||||
@@ -211,12 +239,16 @@ ip_set_hash_destroy(struct ip_set *set)
|
|||||||
set->data = NULL;
|
set->data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HKEY(data, initval, htable_bits) \
|
|
||||||
(jhash2((u32 *)(data), sizeof(struct type_pf_elem)/sizeof(u32), initval) \
|
|
||||||
& jhash_mask(htable_bits))
|
|
||||||
|
|
||||||
#endif /* _IP_SET_AHASH_H */
|
#endif /* _IP_SET_AHASH_H */
|
||||||
|
|
||||||
|
#ifndef HKEY_DATALEN
|
||||||
|
#define HKEY_DATALEN sizeof(struct type_pf_elem)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define HKEY(data, initval, htable_bits) \
|
||||||
|
(jhash2((u32 *)(data), HKEY_DATALEN/sizeof(u32), initval) \
|
||||||
|
& jhash_mask(htable_bits))
|
||||||
|
|
||||||
#define CONCAT(a, b, c) a##b##c
|
#define CONCAT(a, b, c) a##b##c
|
||||||
#define TOKEN(a, b, c) CONCAT(a, b, c)
|
#define TOKEN(a, b, c) CONCAT(a, b, c)
|
||||||
|
|
||||||
@@ -275,12 +307,13 @@ ip_set_hash_destroy(struct ip_set *set)
|
|||||||
/* Add an element to the hash table when resizing the set:
|
/* Add an element to the hash table when resizing the set:
|
||||||
* we spare the maintenance of the internal counters. */
|
* we spare the maintenance of the internal counters. */
|
||||||
static int
|
static int
|
||||||
type_pf_elem_add(struct hbucket *n, const struct type_pf_elem *value)
|
type_pf_elem_add(struct hbucket *n, const struct type_pf_elem *value,
|
||||||
|
u8 ahash_max)
|
||||||
{
|
{
|
||||||
if (n->pos >= n->size) {
|
if (n->pos >= n->size) {
|
||||||
void *tmp;
|
void *tmp;
|
||||||
|
|
||||||
if (n->size >= AHASH_MAX_SIZE)
|
if (n->size >= ahash_max)
|
||||||
/* Trigger rehashing */
|
/* Trigger rehashing */
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
@@ -335,7 +368,7 @@ retry:
|
|||||||
for (j = 0; j < n->pos; j++) {
|
for (j = 0; j < n->pos; j++) {
|
||||||
data = ahash_data(n, j);
|
data = ahash_data(n, j);
|
||||||
m = hbucket(t, HKEY(data, h->initval, htable_bits));
|
m = hbucket(t, HKEY(data, h->initval, htable_bits));
|
||||||
ret = type_pf_elem_add(m, data);
|
ret = type_pf_elem_add(m, data, AHASH_MAX(h));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
read_unlock_bh(&set->lock);
|
read_unlock_bh(&set->lock);
|
||||||
ahash_destroy(t);
|
ahash_destroy(t);
|
||||||
@@ -359,7 +392,7 @@ retry:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static inline void
|
||||||
type_pf_data_next(struct ip_set_hash *h, const struct type_pf_elem *d);
|
type_pf_data_next(struct ip_set_hash *h, const struct type_pf_elem *d);
|
||||||
|
|
||||||
/* Add an element to a hash and update the internal counters when succeeded,
|
/* Add an element to a hash and update the internal counters when succeeded,
|
||||||
@@ -372,7 +405,7 @@ type_pf_add(struct ip_set *set, void *value, u32 timeout, u32 flags)
|
|||||||
const struct type_pf_elem *d = value;
|
const struct type_pf_elem *d = value;
|
||||||
struct hbucket *n;
|
struct hbucket *n;
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
u32 key;
|
u32 key, multi = 0;
|
||||||
|
|
||||||
if (h->elements >= h->maxelem)
|
if (h->elements >= h->maxelem)
|
||||||
return -IPSET_ERR_HASH_FULL;
|
return -IPSET_ERR_HASH_FULL;
|
||||||
@@ -382,12 +415,12 @@ type_pf_add(struct ip_set *set, void *value, u32 timeout, u32 flags)
|
|||||||
key = HKEY(value, h->initval, t->htable_bits);
|
key = HKEY(value, h->initval, t->htable_bits);
|
||||||
n = hbucket(t, key);
|
n = hbucket(t, key);
|
||||||
for (i = 0; i < n->pos; i++)
|
for (i = 0; i < n->pos; i++)
|
||||||
if (type_pf_data_equal(ahash_data(n, i), d)) {
|
if (type_pf_data_equal(ahash_data(n, i), d, &multi)) {
|
||||||
ret = -IPSET_ERR_EXIST;
|
ret = -IPSET_ERR_EXIST;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
TUNE_AHASH_MAX(h, multi);
|
||||||
ret = type_pf_elem_add(n, value);
|
ret = type_pf_elem_add(n, value, AHASH_MAX(h));
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
if (ret == -EAGAIN)
|
if (ret == -EAGAIN)
|
||||||
type_pf_data_next(h, d);
|
type_pf_data_next(h, d);
|
||||||
@@ -415,13 +448,13 @@ type_pf_del(struct ip_set *set, void *value, u32 timeout, u32 flags)
|
|||||||
struct hbucket *n;
|
struct hbucket *n;
|
||||||
int i;
|
int i;
|
||||||
struct type_pf_elem *data;
|
struct type_pf_elem *data;
|
||||||
u32 key;
|
u32 key, multi = 0;
|
||||||
|
|
||||||
key = HKEY(value, h->initval, t->htable_bits);
|
key = HKEY(value, h->initval, t->htable_bits);
|
||||||
n = hbucket(t, key);
|
n = hbucket(t, key);
|
||||||
for (i = 0; i < n->pos; i++) {
|
for (i = 0; i < n->pos; i++) {
|
||||||
data = ahash_data(n, i);
|
data = ahash_data(n, i);
|
||||||
if (!type_pf_data_equal(data, d))
|
if (!type_pf_data_equal(data, d, &multi))
|
||||||
continue;
|
continue;
|
||||||
if (i != n->pos - 1)
|
if (i != n->pos - 1)
|
||||||
/* Not last one */
|
/* Not last one */
|
||||||
@@ -462,17 +495,17 @@ type_pf_test_cidrs(struct ip_set *set, struct type_pf_elem *d, u32 timeout)
|
|||||||
struct hbucket *n;
|
struct hbucket *n;
|
||||||
const struct type_pf_elem *data;
|
const struct type_pf_elem *data;
|
||||||
int i, j = 0;
|
int i, j = 0;
|
||||||
u32 key;
|
u32 key, multi = 0;
|
||||||
u8 host_mask = SET_HOST_MASK(set->family);
|
u8 host_mask = SET_HOST_MASK(set->family);
|
||||||
|
|
||||||
pr_debug("test by nets\n");
|
pr_debug("test by nets\n");
|
||||||
for (; j < host_mask && h->nets[j].cidr; j++) {
|
for (; j < host_mask && h->nets[j].cidr && !multi; j++) {
|
||||||
type_pf_data_netmask(d, h->nets[j].cidr);
|
type_pf_data_netmask(d, h->nets[j].cidr);
|
||||||
key = HKEY(d, h->initval, t->htable_bits);
|
key = HKEY(d, h->initval, t->htable_bits);
|
||||||
n = hbucket(t, key);
|
n = hbucket(t, key);
|
||||||
for (i = 0; i < n->pos; i++) {
|
for (i = 0; i < n->pos; i++) {
|
||||||
data = ahash_data(n, i);
|
data = ahash_data(n, i);
|
||||||
if (type_pf_data_equal(data, d))
|
if (type_pf_data_equal(data, d, &multi))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -490,7 +523,7 @@ type_pf_test(struct ip_set *set, void *value, u32 timeout, u32 flags)
|
|||||||
struct hbucket *n;
|
struct hbucket *n;
|
||||||
const struct type_pf_elem *data;
|
const struct type_pf_elem *data;
|
||||||
int i;
|
int i;
|
||||||
u32 key;
|
u32 key, multi = 0;
|
||||||
|
|
||||||
#ifdef IP_SET_HASH_WITH_NETS
|
#ifdef IP_SET_HASH_WITH_NETS
|
||||||
/* If we test an IP address and not a network address,
|
/* If we test an IP address and not a network address,
|
||||||
@@ -503,7 +536,7 @@ type_pf_test(struct ip_set *set, void *value, u32 timeout, u32 flags)
|
|||||||
n = hbucket(t, key);
|
n = hbucket(t, key);
|
||||||
for (i = 0; i < n->pos; i++) {
|
for (i = 0; i < n->pos; i++) {
|
||||||
data = ahash_data(n, i);
|
data = ahash_data(n, i);
|
||||||
if (type_pf_data_equal(data, d))
|
if (type_pf_data_equal(data, d, &multi))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -660,14 +693,14 @@ type_pf_data_timeout_set(struct type_pf_elem *data, u32 timeout)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
type_pf_elem_tadd(struct hbucket *n, const struct type_pf_elem *value,
|
type_pf_elem_tadd(struct hbucket *n, const struct type_pf_elem *value,
|
||||||
u32 timeout)
|
u8 ahash_max, u32 timeout)
|
||||||
{
|
{
|
||||||
struct type_pf_elem *data;
|
struct type_pf_elem *data;
|
||||||
|
|
||||||
if (n->pos >= n->size) {
|
if (n->pos >= n->size) {
|
||||||
void *tmp;
|
void *tmp;
|
||||||
|
|
||||||
if (n->size >= AHASH_MAX_SIZE)
|
if (n->size >= ahash_max)
|
||||||
/* Trigger rehashing */
|
/* Trigger rehashing */
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
@@ -772,7 +805,7 @@ retry:
|
|||||||
for (j = 0; j < n->pos; j++) {
|
for (j = 0; j < n->pos; j++) {
|
||||||
data = ahash_tdata(n, j);
|
data = ahash_tdata(n, j);
|
||||||
m = hbucket(t, HKEY(data, h->initval, htable_bits));
|
m = hbucket(t, HKEY(data, h->initval, htable_bits));
|
||||||
ret = type_pf_elem_tadd(m, data,
|
ret = type_pf_elem_tadd(m, data, AHASH_MAX(h),
|
||||||
type_pf_data_timeout(data));
|
type_pf_data_timeout(data));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
read_unlock_bh(&set->lock);
|
read_unlock_bh(&set->lock);
|
||||||
@@ -803,9 +836,9 @@ type_pf_tadd(struct ip_set *set, void *value, u32 timeout, u32 flags)
|
|||||||
const struct type_pf_elem *d = value;
|
const struct type_pf_elem *d = value;
|
||||||
struct hbucket *n;
|
struct hbucket *n;
|
||||||
struct type_pf_elem *data;
|
struct type_pf_elem *data;
|
||||||
int ret = 0, i, j = AHASH_MAX_SIZE + 1;
|
int ret = 0, i, j = AHASH_MAX(h) + 1;
|
||||||
bool flag_exist = flags & IPSET_FLAG_EXIST;
|
bool flag_exist = flags & IPSET_FLAG_EXIST;
|
||||||
u32 key;
|
u32 key, multi = 0;
|
||||||
|
|
||||||
if (h->elements >= h->maxelem)
|
if (h->elements >= h->maxelem)
|
||||||
/* FIXME: when set is full, we slow down here */
|
/* FIXME: when set is full, we slow down here */
|
||||||
@@ -819,18 +852,18 @@ type_pf_tadd(struct ip_set *set, void *value, u32 timeout, u32 flags)
|
|||||||
n = hbucket(t, key);
|
n = hbucket(t, key);
|
||||||
for (i = 0; i < n->pos; i++) {
|
for (i = 0; i < n->pos; i++) {
|
||||||
data = ahash_tdata(n, i);
|
data = ahash_tdata(n, i);
|
||||||
if (type_pf_data_equal(data, d)) {
|
if (type_pf_data_equal(data, d, &multi)) {
|
||||||
if (type_pf_data_expired(data) || flag_exist)
|
if (type_pf_data_expired(data) || flag_exist)
|
||||||
j = i;
|
j = i;
|
||||||
else {
|
else {
|
||||||
ret = -IPSET_ERR_EXIST;
|
ret = -IPSET_ERR_EXIST;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else if (j == AHASH_MAX_SIZE + 1 &&
|
} else if (j == AHASH_MAX(h) + 1 &&
|
||||||
type_pf_data_expired(data))
|
type_pf_data_expired(data))
|
||||||
j = i;
|
j = i;
|
||||||
}
|
}
|
||||||
if (j != AHASH_MAX_SIZE + 1) {
|
if (j != AHASH_MAX(h) + 1) {
|
||||||
data = ahash_tdata(n, j);
|
data = ahash_tdata(n, j);
|
||||||
#ifdef IP_SET_HASH_WITH_NETS
|
#ifdef IP_SET_HASH_WITH_NETS
|
||||||
del_cidr(h, data->cidr, HOST_MASK);
|
del_cidr(h, data->cidr, HOST_MASK);
|
||||||
@@ -840,7 +873,8 @@ type_pf_tadd(struct ip_set *set, void *value, u32 timeout, u32 flags)
|
|||||||
type_pf_data_timeout_set(data, timeout);
|
type_pf_data_timeout_set(data, timeout);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
ret = type_pf_elem_tadd(n, d, timeout);
|
TUNE_AHASH_MAX(h, multi);
|
||||||
|
ret = type_pf_elem_tadd(n, d, AHASH_MAX(h), timeout);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
if (ret == -EAGAIN)
|
if (ret == -EAGAIN)
|
||||||
type_pf_data_next(h, d);
|
type_pf_data_next(h, d);
|
||||||
@@ -865,13 +899,13 @@ type_pf_tdel(struct ip_set *set, void *value, u32 timeout, u32 flags)
|
|||||||
struct hbucket *n;
|
struct hbucket *n;
|
||||||
int i;
|
int i;
|
||||||
struct type_pf_elem *data;
|
struct type_pf_elem *data;
|
||||||
u32 key;
|
u32 key, multi = 0;
|
||||||
|
|
||||||
key = HKEY(value, h->initval, t->htable_bits);
|
key = HKEY(value, h->initval, t->htable_bits);
|
||||||
n = hbucket(t, key);
|
n = hbucket(t, key);
|
||||||
for (i = 0; i < n->pos; i++) {
|
for (i = 0; i < n->pos; i++) {
|
||||||
data = ahash_tdata(n, i);
|
data = ahash_tdata(n, i);
|
||||||
if (!type_pf_data_equal(data, d))
|
if (!type_pf_data_equal(data, d, &multi))
|
||||||
continue;
|
continue;
|
||||||
if (type_pf_data_expired(data))
|
if (type_pf_data_expired(data))
|
||||||
return -IPSET_ERR_EXIST;
|
return -IPSET_ERR_EXIST;
|
||||||
@@ -911,16 +945,16 @@ type_pf_ttest_cidrs(struct ip_set *set, struct type_pf_elem *d, u32 timeout)
|
|||||||
struct type_pf_elem *data;
|
struct type_pf_elem *data;
|
||||||
struct hbucket *n;
|
struct hbucket *n;
|
||||||
int i, j = 0;
|
int i, j = 0;
|
||||||
u32 key;
|
u32 key, multi = 0;
|
||||||
u8 host_mask = SET_HOST_MASK(set->family);
|
u8 host_mask = SET_HOST_MASK(set->family);
|
||||||
|
|
||||||
for (; j < host_mask && h->nets[j].cidr; j++) {
|
for (; j < host_mask && h->nets[j].cidr && !multi; j++) {
|
||||||
type_pf_data_netmask(d, h->nets[j].cidr);
|
type_pf_data_netmask(d, h->nets[j].cidr);
|
||||||
key = HKEY(d, h->initval, t->htable_bits);
|
key = HKEY(d, h->initval, t->htable_bits);
|
||||||
n = hbucket(t, key);
|
n = hbucket(t, key);
|
||||||
for (i = 0; i < n->pos; i++) {
|
for (i = 0; i < n->pos; i++) {
|
||||||
data = ahash_tdata(n, i);
|
data = ahash_tdata(n, i);
|
||||||
if (type_pf_data_equal(data, d))
|
if (type_pf_data_equal(data, d, &multi))
|
||||||
return !type_pf_data_expired(data);
|
return !type_pf_data_expired(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -936,7 +970,7 @@ type_pf_ttest(struct ip_set *set, void *value, u32 timeout, u32 flags)
|
|||||||
struct type_pf_elem *data, *d = value;
|
struct type_pf_elem *data, *d = value;
|
||||||
struct hbucket *n;
|
struct hbucket *n;
|
||||||
int i;
|
int i;
|
||||||
u32 key;
|
u32 key, multi = 0;
|
||||||
|
|
||||||
#ifdef IP_SET_HASH_WITH_NETS
|
#ifdef IP_SET_HASH_WITH_NETS
|
||||||
if (d->cidr == SET_HOST_MASK(set->family))
|
if (d->cidr == SET_HOST_MASK(set->family))
|
||||||
@@ -946,7 +980,7 @@ type_pf_ttest(struct ip_set *set, void *value, u32 timeout, u32 flags)
|
|||||||
n = hbucket(t, key);
|
n = hbucket(t, key);
|
||||||
for (i = 0; i < n->pos; i++) {
|
for (i = 0; i < n->pos; i++) {
|
||||||
data = ahash_tdata(n, i);
|
data = ahash_tdata(n, i);
|
||||||
if (type_pf_data_equal(data, d))
|
if (type_pf_data_equal(data, d, &multi))
|
||||||
return !type_pf_data_expired(data);
|
return !type_pf_data_expired(data);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1054,6 +1088,8 @@ type_pf_gc_init(struct ip_set *set)
|
|||||||
IPSET_GC_PERIOD(h->timeout));
|
IPSET_GC_PERIOD(h->timeout));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef HKEY_DATALEN
|
||||||
|
#undef HKEY
|
||||||
#undef type_pf_data_equal
|
#undef type_pf_data_equal
|
||||||
#undef type_pf_data_isnull
|
#undef type_pf_data_isnull
|
||||||
#undef type_pf_data_copy
|
#undef type_pf_data_copy
|
||||||
|
@@ -1160,9 +1160,13 @@ ip_set_dump(struct sk_buff *skb, struct genl_info *info)
|
|||||||
return -IPSET_ERR_PROTOCOL;
|
return -IPSET_ERR_PROTOCOL;
|
||||||
|
|
||||||
genl_unlock();
|
genl_unlock();
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0)
|
||||||
|
ret = netlink_dump_start(ctnl, skb, nlh, ip_set_dump_start, ip_set_dump_done, 0);
|
||||||
|
#else
|
||||||
ret = netlink_dump_start(ctnl, skb, nlh,
|
ret = netlink_dump_start(ctnl, skb, nlh,
|
||||||
ip_set_dump_start,
|
ip_set_dump_start,
|
||||||
ip_set_dump_done);
|
ip_set_dump_done);
|
||||||
|
#endif
|
||||||
genl_lock();
|
genl_lock();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@@ -53,7 +53,8 @@ struct hash_ip4_telem {
|
|||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
hash_ip4_data_equal(const struct hash_ip4_elem *ip1,
|
hash_ip4_data_equal(const struct hash_ip4_elem *ip1,
|
||||||
const struct hash_ip4_elem *ip2)
|
const struct hash_ip4_elem *ip2,
|
||||||
|
u32 *multi)
|
||||||
{
|
{
|
||||||
return ip1->ip == ip2->ip;
|
return ip1->ip == ip2->ip;
|
||||||
}
|
}
|
||||||
@@ -225,7 +226,8 @@ struct hash_ip6_telem {
|
|||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
hash_ip6_data_equal(const struct hash_ip6_elem *ip1,
|
hash_ip6_data_equal(const struct hash_ip6_elem *ip1,
|
||||||
const struct hash_ip6_elem *ip2)
|
const struct hash_ip6_elem *ip2,
|
||||||
|
u32 *multi)
|
||||||
{
|
{
|
||||||
return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0;
|
return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0;
|
||||||
}
|
}
|
||||||
|
@@ -60,7 +60,8 @@ struct hash_ipport4_telem {
|
|||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
hash_ipport4_data_equal(const struct hash_ipport4_elem *ip1,
|
hash_ipport4_data_equal(const struct hash_ipport4_elem *ip1,
|
||||||
const struct hash_ipport4_elem *ip2)
|
const struct hash_ipport4_elem *ip2,
|
||||||
|
u32 *multi)
|
||||||
{
|
{
|
||||||
return ip1->ip == ip2->ip &&
|
return ip1->ip == ip2->ip &&
|
||||||
ip1->port == ip2->port &&
|
ip1->port == ip2->port &&
|
||||||
@@ -276,7 +277,8 @@ struct hash_ipport6_telem {
|
|||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
hash_ipport6_data_equal(const struct hash_ipport6_elem *ip1,
|
hash_ipport6_data_equal(const struct hash_ipport6_elem *ip1,
|
||||||
const struct hash_ipport6_elem *ip2)
|
const struct hash_ipport6_elem *ip2,
|
||||||
|
u32 *multi)
|
||||||
{
|
{
|
||||||
return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 &&
|
return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 &&
|
||||||
ip1->port == ip2->port &&
|
ip1->port == ip2->port &&
|
||||||
|
@@ -62,7 +62,8 @@ struct hash_ipportip4_telem {
|
|||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
hash_ipportip4_data_equal(const struct hash_ipportip4_elem *ip1,
|
hash_ipportip4_data_equal(const struct hash_ipportip4_elem *ip1,
|
||||||
const struct hash_ipportip4_elem *ip2)
|
const struct hash_ipportip4_elem *ip2,
|
||||||
|
u32 *multi)
|
||||||
{
|
{
|
||||||
return ip1->ip == ip2->ip &&
|
return ip1->ip == ip2->ip &&
|
||||||
ip1->ip2 == ip2->ip2 &&
|
ip1->ip2 == ip2->ip2 &&
|
||||||
@@ -286,7 +287,8 @@ struct hash_ipportip6_telem {
|
|||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
hash_ipportip6_data_equal(const struct hash_ipportip6_elem *ip1,
|
hash_ipportip6_data_equal(const struct hash_ipportip6_elem *ip1,
|
||||||
const struct hash_ipportip6_elem *ip2)
|
const struct hash_ipportip6_elem *ip2,
|
||||||
|
u32 *multi)
|
||||||
{
|
{
|
||||||
return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 &&
|
return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 &&
|
||||||
ipv6_addr_cmp(&ip1->ip2.in6, &ip2->ip2.in6) == 0 &&
|
ipv6_addr_cmp(&ip1->ip2.in6, &ip2->ip2.in6) == 0 &&
|
||||||
|
@@ -62,7 +62,8 @@ struct hash_ipportnet4_telem {
|
|||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
hash_ipportnet4_data_equal(const struct hash_ipportnet4_elem *ip1,
|
hash_ipportnet4_data_equal(const struct hash_ipportnet4_elem *ip1,
|
||||||
const struct hash_ipportnet4_elem *ip2)
|
const struct hash_ipportnet4_elem *ip2,
|
||||||
|
u32 *multi)
|
||||||
{
|
{
|
||||||
return ip1->ip == ip2->ip &&
|
return ip1->ip == ip2->ip &&
|
||||||
ip1->ip2 == ip2->ip2 &&
|
ip1->ip2 == ip2->ip2 &&
|
||||||
@@ -335,7 +336,8 @@ struct hash_ipportnet6_telem {
|
|||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
hash_ipportnet6_data_equal(const struct hash_ipportnet6_elem *ip1,
|
hash_ipportnet6_data_equal(const struct hash_ipportnet6_elem *ip1,
|
||||||
const struct hash_ipportnet6_elem *ip2)
|
const struct hash_ipportnet6_elem *ip2,
|
||||||
|
u32 *multi)
|
||||||
{
|
{
|
||||||
return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 &&
|
return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 &&
|
||||||
ipv6_addr_cmp(&ip1->ip2.in6, &ip2->ip2.in6) == 0 &&
|
ipv6_addr_cmp(&ip1->ip2.in6, &ip2->ip2.in6) == 0 &&
|
||||||
|
@@ -58,7 +58,8 @@ struct hash_net4_telem {
|
|||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
hash_net4_data_equal(const struct hash_net4_elem *ip1,
|
hash_net4_data_equal(const struct hash_net4_elem *ip1,
|
||||||
const struct hash_net4_elem *ip2)
|
const struct hash_net4_elem *ip2,
|
||||||
|
u32 *multi)
|
||||||
{
|
{
|
||||||
return ip1->ip == ip2->ip && ip1->cidr == ip2->cidr;
|
return ip1->ip == ip2->ip && ip1->cidr == ip2->cidr;
|
||||||
}
|
}
|
||||||
@@ -249,7 +250,8 @@ struct hash_net6_telem {
|
|||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
hash_net6_data_equal(const struct hash_net6_elem *ip1,
|
hash_net6_data_equal(const struct hash_net6_elem *ip1,
|
||||||
const struct hash_net6_elem *ip2)
|
const struct hash_net6_elem *ip2,
|
||||||
|
u32 *multi)
|
||||||
{
|
{
|
||||||
return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 &&
|
return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 &&
|
||||||
ip1->cidr == ip2->cidr;
|
ip1->cidr == ip2->cidr;
|
||||||
|
@@ -99,7 +99,7 @@ iface_test(struct rb_root *root, const char **iface)
|
|||||||
|
|
||||||
while (n) {
|
while (n) {
|
||||||
const char *d = iface_data(n);
|
const char *d = iface_data(n);
|
||||||
int res = ifname_compare(*iface, d);
|
long res = ifname_compare(*iface, d);
|
||||||
|
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
n = n->rb_left;
|
n = n->rb_left;
|
||||||
@@ -121,7 +121,7 @@ iface_add(struct rb_root *root, const char **iface)
|
|||||||
|
|
||||||
while (*n) {
|
while (*n) {
|
||||||
char *ifname = iface_data(*n);
|
char *ifname = iface_data(*n);
|
||||||
int res = ifname_compare(*iface, ifname);
|
long res = ifname_compare(*iface, ifname);
|
||||||
|
|
||||||
p = *n;
|
p = *n;
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
@@ -159,31 +159,42 @@ hash_netiface_same_set(const struct ip_set *a, const struct ip_set *b);
|
|||||||
|
|
||||||
/* The type variant functions: IPv4 */
|
/* The type variant functions: IPv4 */
|
||||||
|
|
||||||
/* Member elements without timeout */
|
struct hash_netiface4_elem_hashed {
|
||||||
struct hash_netiface4_elem {
|
|
||||||
__be32 ip;
|
__be32 ip;
|
||||||
const char *iface;
|
|
||||||
u8 physdev;
|
u8 physdev;
|
||||||
u8 cidr;
|
u8 cidr;
|
||||||
u16 padding;
|
u16 padding;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define HKEY_DATALEN sizeof(struct hash_netiface4_elem_hashed)
|
||||||
|
|
||||||
|
/* Member elements without timeout */
|
||||||
|
struct hash_netiface4_elem {
|
||||||
|
__be32 ip;
|
||||||
|
u8 physdev;
|
||||||
|
u8 cidr;
|
||||||
|
u16 padding;
|
||||||
|
const char *iface;
|
||||||
|
};
|
||||||
|
|
||||||
/* Member elements with timeout support */
|
/* Member elements with timeout support */
|
||||||
struct hash_netiface4_telem {
|
struct hash_netiface4_telem {
|
||||||
__be32 ip;
|
__be32 ip;
|
||||||
const char *iface;
|
|
||||||
u8 physdev;
|
u8 physdev;
|
||||||
u8 cidr;
|
u8 cidr;
|
||||||
u16 padding;
|
u16 padding;
|
||||||
|
const char *iface;
|
||||||
unsigned long timeout;
|
unsigned long timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
hash_netiface4_data_equal(const struct hash_netiface4_elem *ip1,
|
hash_netiface4_data_equal(const struct hash_netiface4_elem *ip1,
|
||||||
const struct hash_netiface4_elem *ip2)
|
const struct hash_netiface4_elem *ip2,
|
||||||
|
u32 *multi)
|
||||||
{
|
{
|
||||||
return ip1->ip == ip2->ip &&
|
return ip1->ip == ip2->ip &&
|
||||||
ip1->cidr == ip2->cidr &&
|
ip1->cidr == ip2->cidr &&
|
||||||
|
(++*multi) &&
|
||||||
ip1->physdev == ip2->physdev &&
|
ip1->physdev == ip2->physdev &&
|
||||||
ip1->iface == ip2->iface;
|
ip1->iface == ip2->iface;
|
||||||
}
|
}
|
||||||
@@ -257,6 +268,7 @@ nla_put_failure:
|
|||||||
|
|
||||||
#define IP_SET_HASH_WITH_NETS
|
#define IP_SET_HASH_WITH_NETS
|
||||||
#define IP_SET_HASH_WITH_RBTREE
|
#define IP_SET_HASH_WITH_RBTREE
|
||||||
|
#define IP_SET_HASH_WITH_MULTI
|
||||||
|
|
||||||
#define PF 4
|
#define PF 4
|
||||||
#define HOST_MASK 32
|
#define HOST_MASK 32
|
||||||
@@ -424,29 +436,40 @@ hash_netiface_same_set(const struct ip_set *a, const struct ip_set *b)
|
|||||||
|
|
||||||
/* The type variant functions: IPv6 */
|
/* The type variant functions: IPv6 */
|
||||||
|
|
||||||
struct hash_netiface6_elem {
|
struct hash_netiface6_elem_hashed {
|
||||||
union nf_inet_addr ip;
|
union nf_inet_addr ip;
|
||||||
const char *iface;
|
|
||||||
u8 physdev;
|
u8 physdev;
|
||||||
u8 cidr;
|
u8 cidr;
|
||||||
u16 padding;
|
u16 padding;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hash_netiface6_telem {
|
#define HKEY_DATALEN sizeof(struct hash_netiface6_elem_hashed)
|
||||||
|
|
||||||
|
struct hash_netiface6_elem {
|
||||||
union nf_inet_addr ip;
|
union nf_inet_addr ip;
|
||||||
const char *iface;
|
|
||||||
u8 physdev;
|
u8 physdev;
|
||||||
u8 cidr;
|
u8 cidr;
|
||||||
u16 padding;
|
u16 padding;
|
||||||
|
const char *iface;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hash_netiface6_telem {
|
||||||
|
union nf_inet_addr ip;
|
||||||
|
u8 physdev;
|
||||||
|
u8 cidr;
|
||||||
|
u16 padding;
|
||||||
|
const char *iface;
|
||||||
unsigned long timeout;
|
unsigned long timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
hash_netiface6_data_equal(const struct hash_netiface6_elem *ip1,
|
hash_netiface6_data_equal(const struct hash_netiface6_elem *ip1,
|
||||||
const struct hash_netiface6_elem *ip2)
|
const struct hash_netiface6_elem *ip2,
|
||||||
|
u32 *multi)
|
||||||
{
|
{
|
||||||
return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 &&
|
return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 &&
|
||||||
ip1->cidr == ip2->cidr &&
|
ip1->cidr == ip2->cidr &&
|
||||||
|
(++*multi) &&
|
||||||
ip1->physdev == ip2->physdev &&
|
ip1->physdev == ip2->physdev &&
|
||||||
ip1->iface == ip2->iface;
|
ip1->iface == ip2->iface;
|
||||||
}
|
}
|
||||||
@@ -681,6 +704,7 @@ hash_netiface_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
|
|||||||
h->maxelem = maxelem;
|
h->maxelem = maxelem;
|
||||||
get_random_bytes(&h->initval, sizeof(h->initval));
|
get_random_bytes(&h->initval, sizeof(h->initval));
|
||||||
h->timeout = IPSET_NO_TIMEOUT;
|
h->timeout = IPSET_NO_TIMEOUT;
|
||||||
|
h->ahash_max = AHASH_MAX_SIZE;
|
||||||
|
|
||||||
hbits = htable_bits(hashsize);
|
hbits = htable_bits(hashsize);
|
||||||
h->table = ip_set_alloc(
|
h->table = ip_set_alloc(
|
||||||
|
@@ -59,7 +59,8 @@ struct hash_netport4_telem {
|
|||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
hash_netport4_data_equal(const struct hash_netport4_elem *ip1,
|
hash_netport4_data_equal(const struct hash_netport4_elem *ip1,
|
||||||
const struct hash_netport4_elem *ip2)
|
const struct hash_netport4_elem *ip2,
|
||||||
|
u32 *multi)
|
||||||
{
|
{
|
||||||
return ip1->ip == ip2->ip &&
|
return ip1->ip == ip2->ip &&
|
||||||
ip1->port == ip2->port &&
|
ip1->port == ip2->port &&
|
||||||
@@ -300,7 +301,8 @@ struct hash_netport6_telem {
|
|||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
hash_netport6_data_equal(const struct hash_netport6_elem *ip1,
|
hash_netport6_data_equal(const struct hash_netport6_elem *ip1,
|
||||||
const struct hash_netport6_elem *ip2)
|
const struct hash_netport6_elem *ip2,
|
||||||
|
u32 *multi)
|
||||||
{
|
{
|
||||||
return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 &&
|
return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 &&
|
||||||
ip1->port == ip2->port &&
|
ip1->port == ip2->port &&
|
||||||
|
@@ -769,6 +769,10 @@ as the incoming/outgoing bridge port.
|
|||||||
The lookup time grows linearly with the number of the different prefix
|
The lookup time grows linearly with the number of the different prefix
|
||||||
values added to the set.
|
values added to the set.
|
||||||
.PP
|
.PP
|
||||||
|
The internal restriction of the \fBhash:net,iface\fR set type is that
|
||||||
|
the same network prefix cannot be stored with more than 64 different interfaces
|
||||||
|
in a single set.
|
||||||
|
.PP
|
||||||
Examples:
|
Examples:
|
||||||
.IP
|
.IP
|
||||||
ipset create foo hash:net,iface
|
ipset create foo hash:net,iface
|
||||||
|
@@ -23,8 +23,8 @@
|
|||||||
#include <libipset/ui.h> /* core options, commands */
|
#include <libipset/ui.h> /* core options, commands */
|
||||||
#include <libipset/utils.h> /* STREQ */
|
#include <libipset/utils.h> /* STREQ */
|
||||||
|
|
||||||
static char program_name[] = PACKAGE;
|
static char program_name[] = "ipset";
|
||||||
static char program_version[] = PACKAGE_VERSION;
|
static char program_version[] = "6.8-genl-xta";
|
||||||
|
|
||||||
static struct ipset_session *session;
|
static struct ipset_session *session;
|
||||||
static uint32_t restore_line;
|
static uint32_t restore_line;
|
||||||
|
@@ -36,6 +36,8 @@ The SYSRQ password can be changed through
|
|||||||
.IP
|
.IP
|
||||||
echo \-n "password" >/sys/module/xt_SYSRQ/parameters/password
|
echo \-n "password" >/sys/module/xt_SYSRQ/parameters/password
|
||||||
.PP
|
.PP
|
||||||
|
The module will not respond to sysrq requests until a password has been set.
|
||||||
|
.PP
|
||||||
Alternatively, the password may be specified at modprobe time, but this is
|
Alternatively, the password may be specified at modprobe time, but this is
|
||||||
insecure as people can possible see it through ps(1). You can use an option
|
insecure as people can possible see it through ps(1). You can use an option
|
||||||
line in e.g. /etc/modprobe.d/xt_sysrq if it is properly guarded, that is, only
|
line in e.g. /etc/modprobe.d/xt_sysrq if it is properly guarded, that is, only
|
||||||
@@ -52,7 +54,7 @@ The xt_SYSRQ module is normally silent unless a successful request is received,
|
|||||||
but the \fIdebug\fP module parameter can be used to find exactly why a
|
but the \fIdebug\fP module parameter can be used to find exactly why a
|
||||||
seemingly correct request is not being processed.
|
seemingly correct request is not being processed.
|
||||||
.PP
|
.PP
|
||||||
To trigger SYSRQ from a remote host, just use netcat or socat:
|
To trigger SYSRQ from a remote host, just use socat:
|
||||||
.PP
|
.PP
|
||||||
.nf
|
.nf
|
||||||
sysrq_key="s" # the SysRq key(s)
|
sysrq_key="s" # the SysRq key(s)
|
||||||
@@ -60,12 +62,11 @@ password="password"
|
|||||||
seqno="$(date +%s)"
|
seqno="$(date +%s)"
|
||||||
salt="$(dd bs=12 count=1 if=/dev/urandom 2>/dev/null |
|
salt="$(dd bs=12 count=1 if=/dev/urandom 2>/dev/null |
|
||||||
openssl enc \-base64)"
|
openssl enc \-base64)"
|
||||||
|
ipaddr=10.10.25.7
|
||||||
req="$sysrq_key,$seqno,$salt"
|
req="$sysrq_key,$seqno,$salt"
|
||||||
req="$req,$(echo \-n "$req,$password" | sha1sum | cut \-c1\-40)"
|
req="$req,$(echo \-n "$req,$ipaddr,$password" | sha1sum | cut \-c1\-40)"
|
||||||
|
|
||||||
echo "$req" | socat stdin udp\-sendto:10.10.25.7:9
|
echo "$req" | socat stdin udp\-sendto:$ipaddr:9
|
||||||
# or
|
|
||||||
echo "$req" | netcat \-uw1 10.10.25.7 9
|
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
See the Linux docs for possible sysrq keys. Important ones are: re(b)oot,
|
See the Linux docs for possible sysrq keys. Important ones are: re(b)oot,
|
||||||
@@ -73,8 +74,10 @@ power(o)ff, (s)ync filesystems, (u)mount and remount readonly. More than one
|
|||||||
sysrq key can be used at once, but bear in mind that, for example, a sync may
|
sysrq key can be used at once, but bear in mind that, for example, a sync may
|
||||||
not complete before a subsequent reboot or poweroff.
|
not complete before a subsequent reboot or poweroff.
|
||||||
.PP
|
.PP
|
||||||
|
An IPv4 address should have no leading zeros, an IPv6 address should
|
||||||
|
be in the form recommended by RFC 5952. The debug option will log the
|
||||||
|
correct form of the address.
|
||||||
|
.PP
|
||||||
The hashing scheme should be enough to prevent mis-use of SYSRQ in many
|
The hashing scheme should be enough to prevent mis-use of SYSRQ in many
|
||||||
environments, but it is not perfect: take reasonable precautions to
|
environments, but it is not perfect: take reasonable precautions to
|
||||||
protect your machines. Most importantly ensure that each machine has a
|
protect your machines.
|
||||||
different password; there is scant protection for a SYSRQ packet being
|
|
||||||
applied to a machine that happens to have the same password.
|
|
||||||
|
@@ -881,7 +881,7 @@ update_peer(struct peer *peer, const struct xt_pknock_mtinfo *info,
|
|||||||
|
|
||||||
/* If security is needed. */
|
/* If security is needed. */
|
||||||
if (info->option & XT_PKNOCK_OPENSECRET ) {
|
if (info->option & XT_PKNOCK_OPENSECRET ) {
|
||||||
if (hdr->proto != IPPROTO_UDP)
|
if (hdr->proto != IPPROTO_UDP && hdr->proto != IPPROTO_UDPLITE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!pass_security(peer, info, hdr->payload, hdr->payload_len))
|
if (!pass_security(peer, info, hdr->payload, hdr->payload_len))
|
||||||
@@ -982,6 +982,7 @@ static bool pknock_mt(const struct sk_buff *skb,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case IPPROTO_UDP:
|
case IPPROTO_UDP:
|
||||||
|
case IPPROTO_UDPLITE:
|
||||||
#ifdef PK_CRYPTO
|
#ifdef PK_CRYPTO
|
||||||
hdr_len = (iph->ihl * 4) + sizeof(struct udphdr);
|
hdr_len = (iph->ihl * 4) + sizeof(struct udphdr);
|
||||||
break;
|
break;
|
||||||
@@ -1013,7 +1014,7 @@ static bool pknock_mt(const struct sk_buff *skb,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iph->protocol == IPPROTO_UDP) {
|
if (iph->protocol == IPPROTO_UDP || iph->protocol == IPPROTO_UDPLITE) {
|
||||||
hdr.payload = (void *)iph + hdr_len;
|
hdr.payload = (void *)iph + hdr_len;
|
||||||
hdr.payload_len = skb->len - hdr_len;
|
hdr.payload_len = skb->len - hdr_len;
|
||||||
}
|
}
|
||||||
@@ -1022,7 +1023,8 @@ static bool pknock_mt(const struct sk_buff *skb,
|
|||||||
if (info->option & XT_PKNOCK_KNOCKPORT) {
|
if (info->option & XT_PKNOCK_KNOCKPORT) {
|
||||||
if ((ret = is_allowed(peer))) {
|
if ((ret = is_allowed(peer))) {
|
||||||
if (info->option & XT_PKNOCK_CLOSESECRET &&
|
if (info->option & XT_PKNOCK_CLOSESECRET &&
|
||||||
iph->protocol == IPPROTO_UDP)
|
(iph->protocol == IPPROTO_UDP ||
|
||||||
|
iph->protocol == IPPROTO_UDPLITE))
|
||||||
{
|
{
|
||||||
if (is_close_knock(peer, info, hdr.payload, hdr.payload_len))
|
if (is_close_knock(peer, info, hdr.payload, hdr.payload_len))
|
||||||
{
|
{
|
||||||
|
@@ -12,6 +12,13 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
|
||||||
|
# error ----------------------------------------------------------
|
||||||
|
# error This module has been merged into, and is available in the
|
||||||
|
# error mainline since Linux kernel v2.6.36. Please use that.
|
||||||
|
# error ----------------------------------------------------------
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <linux/netfilter/x_tables.h>
|
#include <linux/netfilter/x_tables.h>
|
||||||
#include "xt_CHECKSUM.h"
|
#include "xt_CHECKSUM.h"
|
||||||
#include "compat_xtables.h"
|
#include "compat_xtables.h"
|
||||||
|
@@ -29,6 +29,38 @@ static const char *const dir_names[] = {
|
|||||||
"ORIGINAL", "REPLY",
|
"ORIGINAL", "REPLY",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void logmark_ct(const struct nf_conn *ct, enum ip_conntrack_info ctinfo)
|
||||||
|
{
|
||||||
|
bool prev = false;
|
||||||
|
|
||||||
|
printk(" ct=0x%p ctmark=0x%x ctstate=", ct, ct->mark);
|
||||||
|
ctinfo %= IP_CT_IS_REPLY;
|
||||||
|
if (ctinfo == IP_CT_NEW)
|
||||||
|
printk("NEW");
|
||||||
|
else if (ctinfo == IP_CT_ESTABLISHED)
|
||||||
|
printk("ESTABLISHED");
|
||||||
|
else if (ctinfo == IP_CT_RELATED)
|
||||||
|
printk("RELATED");
|
||||||
|
if (test_bit(IPS_SRC_NAT_BIT, &ct->status))
|
||||||
|
printk(",SNAT");
|
||||||
|
if (test_bit(IPS_DST_NAT_BIT, &ct->status))
|
||||||
|
printk(",DNAT");
|
||||||
|
|
||||||
|
printk(" ctstatus=");
|
||||||
|
if (ct->status & IPS_EXPECTED) {
|
||||||
|
printk("EXPECTED");
|
||||||
|
prev = true;
|
||||||
|
}
|
||||||
|
if (ct->status & IPS_SEEN_REPLY)
|
||||||
|
printk("%s""SEEN_REPLY", prev++ ? "," : "");
|
||||||
|
if (ct->status & IPS_ASSURED)
|
||||||
|
printk("%s""ASSURED", prev++ ? "," : "");
|
||||||
|
if (ct->status & IPS_CONFIRMED)
|
||||||
|
printk("%s""CONFIRMED", prev++ ? "," : "");
|
||||||
|
printk(" lifetime=%lus",
|
||||||
|
(jiffies - ct->timeout.expires) / HZ);
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
logmark_tg(struct sk_buff **pskb, const struct xt_action_param *par)
|
logmark_tg(struct sk_buff **pskb, const struct xt_action_param *par)
|
||||||
{
|
{
|
||||||
@@ -36,7 +68,6 @@ logmark_tg(struct sk_buff **pskb, const struct xt_action_param *par)
|
|||||||
const struct xt_logmark_tginfo *info = par->targinfo;
|
const struct xt_logmark_tginfo *info = par->targinfo;
|
||||||
const struct nf_conn *ct;
|
const struct nf_conn *ct;
|
||||||
enum ip_conntrack_info ctinfo;
|
enum ip_conntrack_info ctinfo;
|
||||||
bool prev = false;
|
|
||||||
|
|
||||||
printk("<%u>%.*s""iif=%d hook=%s nfmark=0x%x "
|
printk("<%u>%.*s""iif=%d hook=%s nfmark=0x%x "
|
||||||
"secmark=0x%x classify=0x%x",
|
"secmark=0x%x classify=0x%x",
|
||||||
@@ -46,43 +77,17 @@ logmark_tg(struct sk_buff **pskb, const struct xt_action_param *par)
|
|||||||
|
|
||||||
ct = nf_ct_get(skb, &ctinfo);
|
ct = nf_ct_get(skb, &ctinfo);
|
||||||
printk(" ctdir=%s", dir_names[ctinfo >= IP_CT_IS_REPLY]);
|
printk(" ctdir=%s", dir_names[ctinfo >= IP_CT_IS_REPLY]);
|
||||||
if (ct == NULL) {
|
if (ct == NULL)
|
||||||
printk(" ct=NULL ctmark=NULL ctstate=INVALID ctstatus=NONE");
|
printk(" ct=NULL ctmark=NULL ctstate=INVALID ctstatus=NONE");
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
|
||||||
} else if (nf_ct_is_untracked(ct)) {
|
else if (nf_ct_is_untracked(ct))
|
||||||
printk(" ct=UNTRACKED ctmark=NULL ctstate=UNTRACKED ctstatus=NONE");
|
printk(" ct=UNTRACKED ctmark=NULL ctstate=UNTRACKED ctstatus=NONE");
|
||||||
#else
|
#else
|
||||||
} else if (ct == &nf_conntrack_untracked) {
|
else if (ct == &nf_conntrack_untracked)
|
||||||
printk(" ct=UNTRACKED ctmark=NULL ctstate=UNTRACKED ctstatus=NONE");
|
printk(" ct=UNTRACKED ctmark=NULL ctstate=UNTRACKED ctstatus=NONE");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
else
|
||||||
printk(" ct=0x%p ctmark=0x%x ctstate=", ct, ct->mark);
|
logmark_ct(ct, ctinfo);
|
||||||
ctinfo %= IP_CT_IS_REPLY;
|
|
||||||
if (ctinfo == IP_CT_NEW)
|
|
||||||
printk("NEW");
|
|
||||||
else if (ctinfo == IP_CT_ESTABLISHED)
|
|
||||||
printk("ESTABLISHED");
|
|
||||||
else if (ctinfo == IP_CT_RELATED)
|
|
||||||
printk("RELATED");
|
|
||||||
if (test_bit(IPS_SRC_NAT_BIT, &ct->status))
|
|
||||||
printk(",SNAT");
|
|
||||||
if (test_bit(IPS_DST_NAT_BIT, &ct->status))
|
|
||||||
printk(",DNAT");
|
|
||||||
|
|
||||||
printk(" ctstatus=");
|
|
||||||
if (ct->status & IPS_EXPECTED) {
|
|
||||||
printk("EXPECTED");
|
|
||||||
prev = true;
|
|
||||||
}
|
|
||||||
if (ct->status & IPS_SEEN_REPLY)
|
|
||||||
printk("%s""SEEN_REPLY", prev++ ? "," : "");
|
|
||||||
if (ct->status & IPS_ASSURED)
|
|
||||||
printk("%s""ASSURED", prev++ ? "," : "");
|
|
||||||
if (ct->status & IPS_CONFIRMED)
|
|
||||||
printk("%s""CONFIRMED", prev++ ? "," : "");
|
|
||||||
printk(" lifetime=%lus",
|
|
||||||
(jiffies - ct->timeout.expires) / HZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
printk("\n");
|
printk("\n");
|
||||||
return XT_CONTINUE;
|
return XT_CONTINUE;
|
||||||
|
@@ -1,9 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* "SYSRQ" target extension for Netfilter
|
* "SYSRQ" target extension for Xtables
|
||||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008 - 2010
|
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008 - 2010
|
||||||
*
|
*
|
||||||
* Based upon the ipt_SYSRQ idea by Marek Zalem <marek [at] terminus sk>
|
* Based upon the ipt_SYSRQ idea by Marek Zalem <marek [at] terminus sk>
|
||||||
*
|
*
|
||||||
|
* Security additions John Haxby <john.haxby [at] oracle com>
|
||||||
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* version 2 or 3 as published by the Free Software Foundation.
|
* version 2 or 3 as published by the Free Software Foundation.
|
||||||
@@ -58,13 +60,13 @@ static char *sysrq_hexdigest;
|
|||||||
* is a series of sysrq requests; <seqno> is a sequence number that must be
|
* is a series of sysrq requests; <seqno> is a sequence number that must be
|
||||||
* greater than the last sequence number; <salt> is some random bytes; and
|
* greater than the last sequence number; <salt> is some random bytes; and
|
||||||
* <hash> is the hash of everything up to and including the preceding ","
|
* <hash> is the hash of everything up to and including the preceding ","
|
||||||
* together with the password.
|
* together with "<dstaddr>,<password>".
|
||||||
*
|
*
|
||||||
* For example
|
* For example
|
||||||
*
|
*
|
||||||
* salt=$RANDOM
|
* salt=$RANDOM
|
||||||
* req="s,$(date +%s),$salt"
|
* req="s,$(date +%s),$salt"
|
||||||
* echo "$req,$(echo -n $req,secret | sha1sum | cut -c1-40)"
|
* echo "$req,$(echo -n $req,10.10.25.1,secret | sha1sum | cut -c1-40)"
|
||||||
*
|
*
|
||||||
* You will want a better salt and password than that though :-)
|
* You will want a better salt and password than that though :-)
|
||||||
*/
|
*/
|
||||||
@@ -121,7 +123,6 @@ static unsigned int sysrq_tg(const void *pdata, uint16_t len)
|
|||||||
sg_init_table(sg, 2);
|
sg_init_table(sg, 2);
|
||||||
#endif
|
#endif
|
||||||
sg_set_buf(&sg[0], data, n);
|
sg_set_buf(&sg[0], data, n);
|
||||||
strcpy(sysrq_digest_password, sysrq_password);
|
|
||||||
i = strlen(sysrq_digest_password);
|
i = strlen(sysrq_digest_password);
|
||||||
sg_set_buf(&sg[1], sysrq_digest_password, i);
|
sg_set_buf(&sg[1], sysrq_digest_password, i);
|
||||||
ret = crypto_hash_digest(&desc, sg, n + i, sysrq_digest);
|
ret = crypto_hash_digest(&desc, sg, n + i, sysrq_digest);
|
||||||
@@ -223,6 +224,8 @@ sysrq_tg4(struct sk_buff **pskb, const struct xt_action_param *par)
|
|||||||
": " NIPQUAD_FMT ":%u -> :%u len=%u\n",
|
": " NIPQUAD_FMT ":%u -> :%u len=%u\n",
|
||||||
NIPQUAD(iph->saddr), htons(udph->source),
|
NIPQUAD(iph->saddr), htons(udph->source),
|
||||||
htons(udph->dest), len);
|
htons(udph->dest), len);
|
||||||
|
sprintf(sysrq_digest_password, NIPQUAD_FMT ",%s",
|
||||||
|
NIPQUAD(iph->daddr), sysrq_password);
|
||||||
return sysrq_tg((void *)udph + sizeof(struct udphdr), len);
|
return sysrq_tg((void *)udph + sizeof(struct udphdr), len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,7 +244,8 @@ sysrq_tg6(struct sk_buff **pskb, const struct xt_action_param *par)
|
|||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
|
|
||||||
iph = ipv6_hdr(skb);
|
iph = ipv6_hdr(skb);
|
||||||
if (ipv6_find_hdr(skb, &th_off, IPPROTO_UDP, &frag_off) < 0 ||
|
if ((ipv6_find_hdr(skb, &th_off, IPPROTO_UDP, &frag_off) < 0 &&
|
||||||
|
ipv6_find_hdr(skb, &th_off, IPPROTO_UDPLITE, &frag_off) < 0) ||
|
||||||
frag_off > 0)
|
frag_off > 0)
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
|
|
||||||
@@ -253,7 +257,9 @@ sysrq_tg6(struct sk_buff **pskb, const struct xt_action_param *par)
|
|||||||
": " NIP6_FMT ":%hu -> :%hu len=%u\n",
|
": " NIP6_FMT ":%hu -> :%hu len=%u\n",
|
||||||
NIP6(iph->saddr), ntohs(udph->source),
|
NIP6(iph->saddr), ntohs(udph->source),
|
||||||
ntohs(udph->dest), len);
|
ntohs(udph->dest), len);
|
||||||
return sysrq_tg(udph + sizeof(struct udphdr), len);
|
sprintf(sysrq_digest_password, NIP6_FMT ",%s",
|
||||||
|
NIP6(iph->daddr), sysrq_password);
|
||||||
|
return sysrq_tg((void *)udph + sizeof(struct udphdr), len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -340,7 +346,9 @@ static int __init sysrq_crypto_init(void)
|
|||||||
sysrq_hexdigest = kmalloc(2 * sysrq_digest_size + 1, GFP_KERNEL);
|
sysrq_hexdigest = kmalloc(2 * sysrq_digest_size + 1, GFP_KERNEL);
|
||||||
if (sysrq_hexdigest == NULL)
|
if (sysrq_hexdigest == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
sysrq_digest_password = kmalloc(sizeof(sysrq_password), GFP_KERNEL);
|
sysrq_digest_password =
|
||||||
|
kmalloc(sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255") +
|
||||||
|
sizeof(sysrq_password), GFP_KERNEL);
|
||||||
if (sysrq_digest_password == NULL)
|
if (sysrq_digest_password == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
do_gettimeofday(&now);
|
do_gettimeofday(&now);
|
||||||
@@ -376,6 +384,7 @@ module_init(sysrq_tg_init);
|
|||||||
module_exit(sysrq_tg_exit);
|
module_exit(sysrq_tg_exit);
|
||||||
MODULE_DESCRIPTION("Xtables: triggering SYSRQ remotely");
|
MODULE_DESCRIPTION("Xtables: triggering SYSRQ remotely");
|
||||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||||
|
MODULE_AUTHOR("John Haxby <john.haxby@oracle.com");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_ALIAS("ipt_SYSRQ");
|
MODULE_ALIAS("ipt_SYSRQ");
|
||||||
MODULE_ALIAS("ip6t_SYSRQ");
|
MODULE_ALIAS("ip6t_SYSRQ");
|
||||||
|
@@ -58,7 +58,7 @@ static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook,
|
|||||||
struct sk_buff *nskb;
|
struct sk_buff *nskb;
|
||||||
const struct iphdr *oldhdr;
|
const struct iphdr *oldhdr;
|
||||||
struct iphdr *niph;
|
struct iphdr *niph;
|
||||||
u_int16_t tmp;
|
uint16_t tmp, payload;
|
||||||
|
|
||||||
/* A truncated TCP header is not going to be useful */
|
/* A truncated TCP header is not going to be useful */
|
||||||
if (oldskb->len < ip_hdrlen(oldskb) + sizeof(struct tcphdr))
|
if (oldskb->len < ip_hdrlen(oldskb) + sizeof(struct tcphdr))
|
||||||
@@ -69,29 +69,6 @@ static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook,
|
|||||||
if (oth == NULL)
|
if (oth == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (mode == XTTARPIT_TARPIT) {
|
|
||||||
/* No replies for RST, FIN or !SYN,!ACK */
|
|
||||||
if (oth->rst || oth->fin || (!oth->syn && !oth->ack))
|
|
||||||
return;
|
|
||||||
#if 0
|
|
||||||
/* Rate-limit replies to !SYN,ACKs */
|
|
||||||
if (!oth->syn && oth->ack)
|
|
||||||
if (!xrlim_allow(rt_dst(ort), HZ))
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
} else if (mode == XTTARPIT_HONEYPOT) {
|
|
||||||
/* Do not answer any resets regardless of combination */
|
|
||||||
if (oth->rst || oth->seq == 0xDEADBEEF)
|
|
||||||
return;
|
|
||||||
} else if (mode == XTTARPIT_RESET) {
|
|
||||||
tcph->window = 0;
|
|
||||||
tcph->ack = false;
|
|
||||||
tcph->syn = false;
|
|
||||||
tcph->rst = true;
|
|
||||||
tcph->seq = oth->ack_seq;
|
|
||||||
tcph->ack_seq = oth->seq;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check checksum. */
|
/* Check checksum. */
|
||||||
if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP))
|
if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP))
|
||||||
return;
|
return;
|
||||||
@@ -127,6 +104,9 @@ static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook,
|
|||||||
tcph->source = tcph->dest;
|
tcph->source = tcph->dest;
|
||||||
tcph->dest = tmp;
|
tcph->dest = tmp;
|
||||||
|
|
||||||
|
/* Calculate payload size?? */
|
||||||
|
payload = nskb->len - ip_hdrlen(nskb) - sizeof(struct tcphdr);
|
||||||
|
|
||||||
/* Truncate to length (no data) */
|
/* Truncate to length (no data) */
|
||||||
tcph->doff = sizeof(struct tcphdr) / 4;
|
tcph->doff = sizeof(struct tcphdr) / 4;
|
||||||
skb_trim(nskb, ip_hdrlen(nskb) + sizeof(struct tcphdr));
|
skb_trim(nskb, ip_hdrlen(nskb) + sizeof(struct tcphdr));
|
||||||
@@ -136,7 +116,9 @@ static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook,
|
|||||||
((u_int8_t *)tcph)[13] = 0;
|
((u_int8_t *)tcph)[13] = 0;
|
||||||
|
|
||||||
if (mode == XTTARPIT_TARPIT) {
|
if (mode == XTTARPIT_TARPIT) {
|
||||||
/* Use supplied sequence number or make a new one */
|
/* No replies for RST, FIN or !SYN,!ACK */
|
||||||
|
if (oth->rst || oth->fin || (!oth->syn && !oth->ack))
|
||||||
|
return;
|
||||||
tcph->seq = oth->ack ? oth->ack_seq : 0;
|
tcph->seq = oth->ack ? oth->ack_seq : 0;
|
||||||
|
|
||||||
/* Our SYN-ACKs must have a >0 window */
|
/* Our SYN-ACKs must have a >0 window */
|
||||||
@@ -149,7 +131,16 @@ static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook,
|
|||||||
tcph->ack = true;
|
tcph->ack = true;
|
||||||
tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn);
|
tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn);
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
|
/* Rate-limit replies to !SYN,ACKs */
|
||||||
|
if (!oth->syn && oth->ack)
|
||||||
|
if (!xrlim_allow(rt_dst(ort), HZ))
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
} else if (mode == XTTARPIT_HONEYPOT) {
|
} else if (mode == XTTARPIT_HONEYPOT) {
|
||||||
|
/* Do not answer any resets regardless of combination */
|
||||||
|
if (oth->rst || oth->seq == 0xDEADBEEF)
|
||||||
|
return;
|
||||||
/* Send a reset to scanners. They like that. */
|
/* Send a reset to scanners. They like that. */
|
||||||
if (oth->syn && oth->ack) {
|
if (oth->syn && oth->ack) {
|
||||||
tcph->window = 0;
|
tcph->window = 0;
|
||||||
@@ -159,23 +150,29 @@ static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook,
|
|||||||
tcph->seq = oth->ack_seq;
|
tcph->seq = oth->ack_seq;
|
||||||
tcph->rst = true;
|
tcph->rst = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SYN > SYN-ACK */
|
/* SYN > SYN-ACK */
|
||||||
if (oth->syn && !oth->ack) {
|
if (oth->syn && !oth->ack) {
|
||||||
tcph->syn = true;
|
tcph->syn = true;
|
||||||
tcph->ack = true;
|
tcph->ack = true;
|
||||||
tcph->window = oth->window;
|
tcph->window = oth->window &
|
||||||
tcph->ack_seq = oth->seq;
|
((net_random() & 0x1f) - 0xf);
|
||||||
tcph->seq = htonl(net_random() | ~oth->seq);
|
tcph->seq = htonl(net_random() & ~oth->seq);
|
||||||
|
tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ACK > ACK */
|
/* ACK > ACK */
|
||||||
if (oth->ack && !oth->fin && !oth->syn) {
|
if (oth->ack && (!(oth->fin || oth->syn))) {
|
||||||
tcph->syn = false;
|
tcph->syn = false;
|
||||||
tcph->ack = true;
|
tcph->ack = true;
|
||||||
tcph->window = oth->window &
|
tcph->window = oth->window &
|
||||||
((net_random() & 0x1f) - 0xf);
|
((net_random() & 0x1f) - 0xf);
|
||||||
tcph->ack_seq = htonl(ntohl(oth->seq) + 1);
|
tcph->ack_seq = payload > 100 ?
|
||||||
|
htonl(ntohl(oth->seq) + payload) :
|
||||||
|
oth->seq;
|
||||||
tcph->seq = oth->ack_seq;
|
tcph->seq = oth->ack_seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIN > RST.
|
* FIN > RST.
|
||||||
* We cannot terminate gracefully so just be abrupt.
|
* We cannot terminate gracefully so just be abrupt.
|
||||||
@@ -188,6 +185,13 @@ static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook,
|
|||||||
tcph->ack = false;
|
tcph->ack = false;
|
||||||
tcph->rst = true;
|
tcph->rst = true;
|
||||||
}
|
}
|
||||||
|
} else if (mode == XTTARPIT_RESET) {
|
||||||
|
tcph->window = 0;
|
||||||
|
tcph->ack = false;
|
||||||
|
tcph->syn = false;
|
||||||
|
tcph->rst = true;
|
||||||
|
tcph->seq = oth->ack_seq;
|
||||||
|
tcph->ack_seq = oth->seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adjust TCP checksum */
|
/* Adjust TCP checksum */
|
||||||
@@ -204,7 +208,7 @@ static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook,
|
|||||||
|
|
||||||
/* Set DF, id = 0 */
|
/* Set DF, id = 0 */
|
||||||
niph->frag_off = htons(IP_DF);
|
niph->frag_off = htons(IP_DF);
|
||||||
if (mode == XTTARPIT_TARPIT)
|
if (mode == XTTARPIT_TARPIT || mode == XTTARPIT_RESET)
|
||||||
niph->id = 0;
|
niph->id = 0;
|
||||||
else if (mode == XTTARPIT_HONEYPOT)
|
else if (mode == XTTARPIT_HONEYPOT)
|
||||||
niph->id = ~oldhdr->id + 1;
|
niph->id = ~oldhdr->id + 1;
|
||||||
@@ -225,7 +229,14 @@ static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook,
|
|||||||
nskb->ip_summed = CHECKSUM_NONE;
|
nskb->ip_summed = CHECKSUM_NONE;
|
||||||
|
|
||||||
/* Adjust IP TTL */
|
/* Adjust IP TTL */
|
||||||
niph->ttl = dst_metric(skb_dst(nskb), RTAX_HOPLIMIT);
|
if (mode == XTTARPIT_HONEYPOT)
|
||||||
|
niph->ttl = 128;
|
||||||
|
else
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
|
||||||
|
niph->ttl = ip4_dst_hoplimit(skb_dst(nskb));
|
||||||
|
#else
|
||||||
|
niph->ttl = dst_metric(skb_dst(nskb), RTAX_HOPLIMIT);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Adjust IP checksum */
|
/* Adjust IP checksum */
|
||||||
niph->check = 0;
|
niph->check = 0;
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/route.h>
|
#include <linux/route.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
|
#include <linux/version.h>
|
||||||
#include <net/checksum.h>
|
#include <net/checksum.h>
|
||||||
#include <net/icmp.h>
|
#include <net/icmp.h>
|
||||||
#include <net/ip.h>
|
#include <net/ip.h>
|
||||||
@@ -21,6 +22,13 @@
|
|||||||
#include <net/route.h>
|
#include <net/route.h>
|
||||||
#include <linux/netfilter/x_tables.h>
|
#include <linux/netfilter/x_tables.h>
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
|
||||||
|
# error ----------------------------------------------------------
|
||||||
|
# error This module has been merged into, and is available in the
|
||||||
|
# error mainline since Linux kernel v2.6.35. Please use that.
|
||||||
|
# error ----------------------------------------------------------
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
|
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
|
||||||
# define WITH_CONNTRACK 1
|
# define WITH_CONNTRACK 1
|
||||||
# include <net/netfilter/nf_conntrack.h>
|
# include <net/netfilter/nf_conntrack.h>
|
||||||
|
@@ -868,6 +868,7 @@ ipp2p_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case IPPROTO_UDP: /* what to do with an UDP packet */
|
case IPPROTO_UDP: /* what to do with an UDP packet */
|
||||||
|
case IPPROTO_UDPLITE:
|
||||||
{
|
{
|
||||||
const struct udphdr *udph = (const void *)ip + ip_hdrlen(skb);
|
const struct udphdr *udph = (const void *)ip + ip_hdrlen(skb);
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* xt_ipv4opts - Netfilter module to match IPv4 options
|
* xt_ipv4opts - Xtables module to match IPv4 options
|
||||||
* Copyright © Jan Engelhardt, 2009
|
* Copyright © Jan Engelhardt, 2009
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* xt_length - Netfilter module to match packet length
|
* xt_length - Xtables module to match packet length
|
||||||
* Copyright © Jan Engelhardt <jengelh@medozas.de>, 2007 - 2009
|
* Copyright © Jan Engelhardt <jengelh@medozas.de>, 2007 - 2009
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* LSCAN match for netfilter
|
* LSCAN match for Xtables
|
||||||
* Copyright © Jan Engelhardt, 2006 - 2009
|
* Copyright © Jan Engelhardt, 2006 - 2009
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@@ -103,8 +103,12 @@ static bool
|
|||||||
xt_psd_match(const struct sk_buff *pskb, struct xt_action_param *match)
|
xt_psd_match(const struct sk_buff *pskb, struct xt_action_param *match)
|
||||||
{
|
{
|
||||||
const struct iphdr *iph;
|
const struct iphdr *iph;
|
||||||
const struct tcphdr *tcph;
|
const struct tcphdr *tcph = NULL;
|
||||||
struct tcphdr _tcph;
|
const struct udphdr *udph;
|
||||||
|
union {
|
||||||
|
struct tcphdr tcph;
|
||||||
|
struct udphdr udph;
|
||||||
|
} _buf;
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
u_int16_t src_port,dest_port;
|
u_int16_t src_port,dest_port;
|
||||||
u_int8_t tcp_flags, proto;
|
u_int8_t tcp_flags, proto;
|
||||||
@@ -125,29 +129,9 @@ xt_psd_match(const struct sk_buff *pskb, struct xt_action_param *match)
|
|||||||
|
|
||||||
/* TCP or UDP ? */
|
/* TCP or UDP ? */
|
||||||
proto = iph->protocol;
|
proto = iph->protocol;
|
||||||
|
|
||||||
if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
|
|
||||||
pr_debug("protocol not supported\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the source address, source & destination ports, and TCP flags */
|
/* Get the source address, source & destination ports, and TCP flags */
|
||||||
|
|
||||||
addr.s_addr = iph->saddr;
|
addr.s_addr = iph->saddr;
|
||||||
|
|
||||||
tcph = skb_header_pointer(pskb, match->thoff, sizeof(_tcph), &_tcph);
|
|
||||||
if (tcph == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* Yep, it's dirty */
|
|
||||||
src_port = tcph->source;
|
|
||||||
dest_port = tcph->dest;
|
|
||||||
|
|
||||||
if (proto == IPPROTO_TCP)
|
|
||||||
tcp_flags = *((u_int8_t*)tcph + 13);
|
|
||||||
else
|
|
||||||
tcp_flags = 0x00;
|
|
||||||
|
|
||||||
/* We're using IP address 0.0.0.0 for a special purpose here, so don't let
|
/* We're using IP address 0.0.0.0 for a special purpose here, so don't let
|
||||||
* them spoof us. [DHCP needs this feature - HW] */
|
* them spoof us. [DHCP needs this feature - HW] */
|
||||||
if (addr.s_addr == 0) {
|
if (addr.s_addr == 0) {
|
||||||
@@ -155,6 +139,29 @@ xt_psd_match(const struct sk_buff *pskb, struct xt_action_param *match)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (proto == IPPROTO_TCP) {
|
||||||
|
tcph = skb_header_pointer(pskb, match->thoff,
|
||||||
|
sizeof(_buf.tcph), &_buf.tcph);
|
||||||
|
if (tcph == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Yep, it's dirty */
|
||||||
|
src_port = tcph->source;
|
||||||
|
dest_port = tcph->dest;
|
||||||
|
tcp_flags = *((u_int8_t*)tcph + 13);
|
||||||
|
} else if (proto == IPPROTO_UDP || proto == IPPROTO_UDPLITE) {
|
||||||
|
udph = skb_header_pointer(pskb, match->thoff,
|
||||||
|
sizeof(_buf.udph), &_buf.udph);
|
||||||
|
if (udph == NULL)
|
||||||
|
return false;
|
||||||
|
src_port = udph->source;
|
||||||
|
dest_port = udph->dest;
|
||||||
|
tcp_flags = 0;
|
||||||
|
} else {
|
||||||
|
pr_debug("protocol not supported\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Use jiffies here not to depend on someone setting the time while we're
|
/* Use jiffies here not to depend on someone setting the time while we're
|
||||||
* running; we need to be careful with possible return value overflows. */
|
* running; we need to be careful with possible return value overflows. */
|
||||||
now = jiffies;
|
now = jiffies;
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
* by Jan Engelhardt <jengelh@medozas.de>, 2008
|
* by Jan Engelhardt <jengelh@medozas.de>, 2008
|
||||||
*
|
*
|
||||||
* Originally based on xt_quota.c:
|
* Originally based on xt_quota.c:
|
||||||
* netfilter module to enforce network quotas
|
* Xtables module to enforce network quotas
|
||||||
* Sam Johnston <samj@samj.net>
|
* Sam Johnston <samj@samj.net>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
4
mconfig
4
mconfig
@@ -20,8 +20,8 @@ build_geoip=m
|
|||||||
build_gradm=m
|
build_gradm=m
|
||||||
build_iface=m
|
build_iface=m
|
||||||
build_ipp2p=m
|
build_ipp2p=m
|
||||||
build_ipset4=m
|
build_ipset4=
|
||||||
build_ipset6=
|
build_ipset6=m
|
||||||
build_ipv4options=m
|
build_ipv4options=m
|
||||||
build_length2=m
|
build_length2=m
|
||||||
build_lscan=m
|
build_lscan=m
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
.TH xtables-addons 8 "v1.36 (2011-06-03)" "" "v1.36 (2011-06-03)"
|
.TH xtables-addons 8 "v1.38 (2011-08-20)" "" "v1.38 (2011-08-20)"
|
||||||
.SH Name
|
.SH Name
|
||||||
Xtables-addons \(em additional extensions for iptables, ip6tables, etc.
|
Xtables-addons \(em additional extensions for iptables, ip6tables, etc.
|
||||||
.SH Targets
|
.SH Targets
|
||||||
|
Reference in New Issue
Block a user