Compare commits

..

32 Commits
v3.0 ... v3.5

Author SHA1 Message Date
Jan Engelhardt
fa7bcbfb9b Xtables-addons 3.5 2019-09-10 11:14:13 +02:00
Jan Engelhardt
d86101e470 Merge MR-14 2019-09-10 11:12:30 +02:00
Jan Engelhardt
00114dea3d Xtables-addons 3.4 2019-09-06 10:43:58 +02:00
Jeremy Sowden
d4c2aac5f8 xt_pknock, xt_SYSRQ: do not set shash_desc::flags.
shash_desc::flags was removed from the kernel in 5.1.

That assignment was actually superfluous anyway, because crypto.desc
is zero-initialized when crypto is initialized (xt_pknock.c, ll.
110ff.).

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
2019-09-06 10:34:36 +02:00
Jan Engelhardt
5622c5f024 treewide: replace skb_make_writable
skb_make_writable was removed in v5.3-rc1~140^2~370^2~1 .
Replace it with skb_ensure_writable that was introduced in
v3.19-rc1~118^2~153^2~2 .
2019-09-06 10:34:36 +02:00
Jan Engelhardt
358991306c xt_PROTO: style fixes 2019-09-06 10:34:35 +02:00
Jan Engelhardt
2bbdcb1d58 Merge MR-11 2019-09-06 10:34:29 +02:00
Jeremy Sowden
b14728691d xt_DHCPMAC: replace skb_make_writable with skb_ensure_writable
skb_make_writable was removed from the kernel in
v5.3-rc1~140^2~370^2~1 , and its callers were converted to use
skb_ensure_writable. Updated dhcpmac_tg() accordingly.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
2019-09-06 10:28:37 +02:00
rantal
708f883635 add support for Linux 5.0 for DELUDE and TARPIT 2019-08-14 18:40:07 +00:00
Aron Xu
f822b8bc1b Add man page items for xt_PROTO
Signed-off-by: Aron Xu <happyaron.xu@gmail.com>
2019-05-07 03:31:24 +08:00
Aron Xu
4205900d9b Enable xt_PROTO in build system
Signed-off-by: Aron Xu <happyaron.xu@gmail.com>
2019-05-07 03:24:43 +08:00
Miao Wang
266638e41e Add xt_PROTO extension
Signed-off-by: Aron Xu <happyaron.xu@gmail.com>
2019-05-07 03:24:43 +08:00
Jan Engelhardt
ebcd176822 Xtables-addons 3.3 2019-03-07 10:24:08 +01:00
Jan Engelhardt
6b47d09a36 build: remove xa-download-more script
This mechanism has not seen any use in recent years (the "sources"
file is still the same) — drop it.
2019-03-07 10:20:05 +01:00
Jan Engelhardt
1849c47ae8 doc: update README and changelog 2019-03-07 10:18:43 +01:00
PGNet Dev
68d895f75c xt_SYSRQ: replace do_gettimeofday
Linux kernel commit v4.20-rc1-18-ge4b92b108c6c removed
do_gettimeofday in favor of ktime_get_real_ts64 introduced in
v3.16-rc5-59-gd6d29896c665 .
2019-03-07 10:07:28 +01:00
Jan Engelhardt
53b6b862cc Merge MR-10 2018-11-17 12:32:56 +01:00
Nataniel Santos
ed10cb9c17 xt_ACCOUNT: make table limit configurable
Add parameter option in module xt_ACCOUNT.ko to accept. Change in the
ACCOUN_MAX_TABLES table without the need to recompile the module.

References: MR-8
2018-11-17 12:13:00 +01:00
Jan Engelhardt
5903f4bcfc Xtables-addons 3.2 2018-09-07 15:04:28 +02:00
Jan Engelhardt
5e19871613 geoip: build tool should not rely on directory name
Fix this:

	GeoLite2-Country-CSV_20180905$ /usr/lib/xtables-addons/xt_geoip_build

	Use of uninitialized value $dir in concatenation (.) or string at
	/usr/lib/xtables-addons/xt_geoip_build line 59.
	Couldn't open list country names

Do not rely on any directory names (they change). Use the current
directory as the default source directory, similar to the older
xt_geoip_build (well, *.csv was passed as arguments).
2018-09-07 15:03:20 +02:00
Jan Engelhardt
30fb410003 Xtables-addons 3.1 2018-08-14 14:31:10 +02:00
Jan Engelhardt
3ea761a1ed build: add support for Linux 4.18 2018-08-14 14:29:30 +02:00
Jan Engelhardt
4603d3e0f4 build: add support for Linux 4.17 2018-08-14 14:23:04 +02:00
Jan Engelhardt
b0b2b5a74c build: fix 4.16 warning 2018-08-14 14:22:40 +02:00
Jan Engelhardt
082d42fb21 build: match documented and coded build requirements 2018-08-14 14:22:17 +02:00
Jan Engelhardt
b1f0e118a0 doc: add 3.0 headline in changelog 2018-08-14 14:15:07 +02:00
Philip Prindeville
56fba3ecff geoip: simplify handling table column names
Signed-off-by: Philip Prindeville <philipp@redfish-solutions.com>
2018-04-30 09:41:29 +02:00
Philip Prindeville
9057fb48f3 geoip: add database query tool for use with ipsets
Add a tool for retrieiving the IPv4 or IPv6 (or both!) CIDR ranges
for a given country, which can then be injected into an ipset if
one doesn't want to use (or have available) the xt_geoip extension.

Signed-off-by: Philip Prindeville <philipp@redfish-solutions.com>
2018-04-30 09:41:21 +02:00
Philip Prindeville
e19f91ddb4 geoip: update man page for xt_geoip_build
Signed-off-by: Philip Prindeville <philipp@redfish-solutions.com>
2018-04-30 09:40:54 +02:00
Philip Prindeville
256ac1a4f6 geoip: adapt to GeoLite2 database
Requires Net::CIDR::Lite for manipulating CIDR blocks, aggregation, etc.
since database is stored as subnet/mask pairs and may require compaction
into ranges (which can combine adjacent subnets).

We don't use Net::CIDR because it's a clunkier interface.

Signed-off-by: Philip Prindeville <philipp@redfish-solutions.com>
2018-04-30 09:40:51 +02:00
Philip Prindeville
b91dbd03c7 geoip: store database in network byte order
This allows a single database to be built and distributed as a
package that is accepted by both big- and little-endian hosts.

Signed-off-by: Philip Prindeville <philipp@redfish-solutions.com>
2018-02-19 01:42:29 +01:00
Philip Prindeville
425a035959 xt_geoip: fix typo in error message
Make both instances of the same message (about invalid country codes)
be consistent with each other.  If you have scripts which capture and
collate error messages, then having consistent strings to match against
is a win.

Signed-off-by: Philip Prindeville <philipp@redfish-solutions.com>
2017-11-02 21:14:00 -06:00
27 changed files with 770 additions and 298 deletions

1
.gitignore vendored
View File

@@ -3,6 +3,7 @@
*.lo
*.loT
*.o
.cache.mk
.deps/
.dirstamp
.libs/

54
README
View File

@@ -1,57 +1,15 @@
Xtables-addons
==============
Xtables-addons is the proclaimed successor to patch-o-matic(-ng). It
contains extensions that were not accepted in the main Xtables
package.
Xtables-addons is a set of extensions that were not accepted in the
Linux kernel and/or main Xtables/iptables package.
Xtables-addons is different from patch-o-matic in that you do not
have to patch or recompile either kernel or Xtables(iptables). But
please see the INSTALL file for the minimum requirements of this
package.
All code imported from patch-o-matic has been reviewed and all
apparent bugs like binary stability across multiarches, missing
sanity checks and incorrect endianess handling have been fixed,
simplified, and sped up.
It superseded the earlier patch-o-matic(-ng) package in that no
patching and/or recompilation of either the kernel or
Xtables/iptables is required. However, do see the INSTALL file for
the minimum requirements of Xtables-addons.
Included in this package
========================
- xt_ACCOUNT 1.16, libxt_ACCOUNT 1.3
Inclusion into a kernel tree
============================
External extensions
===================
The program "xa-download-more" can be used to download more
extensions from 3rd parties into the source tree. The URLs are listed
in the "sources" file. If the "sources" file contains an entry like
http://foobar.org/xa/
xa-download-more will inspect http://foobar.org/xa/xa-index.txt for
files to download. That file may contain
foobar.tar.bz2
and xa-download-more will then retrieve and unpack
http://foobar.org/xa/foobar.tar.bz2.
Files that should be contained in the tarball are an mconfig and
Kbuild files to control building the extension, libxt_foobar.c for
the userspace extension and xt_foobar.c for the kernel extension.
mconfig.foobar
extensions/Kbuild.foobar
extensions/Mbuild.foobar
extensions/libxt_foobar.c
extensions/libxt_foobar.man
extensions/xt_foobar.c
extensions/xt_foobar.h

View File

@@ -1,4 +1,4 @@
AC_INIT([xtables-addons], [3.0])
AC_INIT([xtables-addons], [3.5])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
@@ -26,7 +26,7 @@ fi
AC_CHECK_HEADERS([linux/netfilter/x_tables.h], [],
[AC_MSG_ERROR([You need to have linux/netfilter/x_tables.h, see INSTALL file for details])])
PKG_CHECK_MODULES([libxtables], [xtables >= 1.4.5])
PKG_CHECK_MODULES([libxtables], [xtables >= 1.6.0])
xtlibdir="$(pkg-config --variable=xtlibdir xtables)"
AC_ARG_WITH([xtlibdir],
@@ -57,9 +57,11 @@ if test -n "$kbuilddir"; then
echo "WARNING: Version detection did not succeed. Continue at own luck.";
else
echo "$kmajor.$kminor.$kmicro.$kstable in $kbuilddir";
if test "$kmajor" -gt 4 -o "$kmajor" -eq 4 -a "$kminor" -gt 16; then
if test "$kmajor" -gt 5 -o "$kmajor" -eq 5 -a "$kminor" -gt 3; then
echo "WARNING: That kernel version is not officially supported yet. Continue at own luck.";
elif test "$kmajor" -eq 4 -a "$kminor" -ge 15; then
elif test "$kmajor" -eq 5 -a "$kminor" -ge 0; then
:
elif test "$kmajor" -eq 4 -a "$kminor" -ge 18; then
:
else
echo "WARNING: That kernel version is not officially supported.";

View File

@@ -1,6 +1,43 @@
HEAD
====
v3.5 (2019-09-10)
=================
Enhancements:
- xt_DELUDE, xt_TARPIT: added additional code needed to work with
bridges from Linux 5.0 onwards.
v3.4 (2019-09-06)
=================
Enhancements:
- support for up to Linux 5.3
- xt_PROTO module
v3.3 (2019-03-07)
=================
Enhancements:
- support for Linux 5.0
v3.2 (2018-09-07)
=================
Changes:
- rework xt_geoip_build to scan the immediate directory for .csv,
not to scan for GeoLite2-Country-CSV_\d+.
v3.1 (2018-08-14)
=================
Enhancements:
- support for Linux 4.17, 4.18
v3.0 (2018-02-12)
=================
Enhancements:
- support for Linux 4.15, 4.16
Changes:

View File

@@ -40,6 +40,9 @@
#error "ipt_ACCOUNT needs at least a PAGE_SIZE of 4096"
#endif
static unsigned int max_tables_limit = 128;
module_param(max_tables_limit, uint, 0);
/**
* Internal table structure, generated by check_entry()
* @name: name of the table
@@ -185,7 +188,7 @@ static int ipt_acc_table_insert(struct ipt_acc_table *ipt_acc_tables,
name, NIPQUAD(ip), NIPQUAD(netmask));
/* Look for existing table */
for (i = 0; i < ACCOUNT_MAX_TABLES; i++) {
for (i = 0; i < max_tables_limit; i++) {
if (strncmp(ipt_acc_tables[i].name, name,
ACCOUNT_TABLE_NAME_LEN) == 0) {
pr_debug("ACCOUNT: Found existing slot: %d - "
@@ -209,7 +212,7 @@ static int ipt_acc_table_insert(struct ipt_acc_table *ipt_acc_tables,
}
/* Insert new table */
for (i = 0; i < ACCOUNT_MAX_TABLES; i++) {
for (i = 0; i < max_tables_limit; i++) {
/* Found free slot */
if (ipt_acc_tables[i].name[0] == 0) {
unsigned int netsize = 0;
@@ -258,7 +261,7 @@ static int ipt_acc_table_insert(struct ipt_acc_table *ipt_acc_tables,
/* No free slot found */
printk("ACCOUNT: No free table slot found (max: %d). "
"Please increase ACCOUNT_MAX_TABLES.\n", ACCOUNT_MAX_TABLES);
"Please increase the \"max_tables_limit\" module parameter.\n", max_tables_limit);
return -1;
}
@@ -299,7 +302,7 @@ static void ipt_acc_destroy(const struct xt_tgdtor_param *par)
info->table_nr = -1; /* Set back to original state */
/* Look for table */
for (i = 0; i < ACCOUNT_MAX_TABLES; i++) {
for (i = 0; i < max_tables_limit; i++) {
if (strncmp(ian->ipt_acc_tables[i].name, info->table_name,
ACCOUNT_TABLE_NAME_LEN) == 0) {
pr_debug("ACCOUNT: Found table at slot: %d\n", i);
@@ -604,12 +607,12 @@ static int ipt_acc_handle_prepare_read(struct ipt_acc_table *ipt_acc_tables,
int table_nr = -1;
uint8_t depth;
for (table_nr = 0; table_nr < ACCOUNT_MAX_TABLES; table_nr++)
for (table_nr = 0; table_nr < max_tables_limit; table_nr++)
if (strncmp(ipt_acc_tables[table_nr].name, tablename,
ACCOUNT_TABLE_NAME_LEN) == 0)
break;
if (table_nr == ACCOUNT_MAX_TABLES) {
if (table_nr == max_tables_limit) {
printk("ACCOUNT: ipt_acc_handle_prepare_read(): "
"Table %s not found\n", tablename);
return -1;
@@ -707,12 +710,12 @@ static int ipt_acc_handle_prepare_read_flush(struct ipt_acc_table *ipt_acc_table
int table_nr;
void *new_data_page;
for (table_nr = 0; table_nr < ACCOUNT_MAX_TABLES; table_nr++)
for (table_nr = 0; table_nr < max_tables_limit; table_nr++)
if (strncmp(ipt_acc_tables[table_nr].name, tablename,
ACCOUNT_TABLE_NAME_LEN) == 0)
break;
if (table_nr == ACCOUNT_MAX_TABLES) {
if (table_nr == max_tables_limit) {
printk("ACCOUNT: ipt_acc_handle_prepare_read_flush(): "
"Table %s not found\n", tablename);
return -1;
@@ -1052,7 +1055,7 @@ static int ipt_acc_get_ctl(struct sock *sk, int cmd, void *user, int *len)
spin_lock_bh(&ian->ipt_acc_lock);
/* Determine size of table names */
for (i = 0; i < ACCOUNT_MAX_TABLES; i++) {
for (i = 0; i < max_tables_limit; i++) {
if (ian->ipt_acc_tables[i].name[0] != 0)
size += strlen(ian->ipt_acc_tables[i].name) + 1;
}
@@ -1067,7 +1070,7 @@ static int ipt_acc_get_ctl(struct sock *sk, int cmd, void *user, int *len)
}
/* Copy table names to userspace */
tnames = ian->ipt_acc_tmpbuf;
for (i = 0; i < ACCOUNT_MAX_TABLES; i++) {
for (i = 0; i < max_tables_limit; i++) {
if (ian->ipt_acc_tables[i].name[0] != 0) {
name_len = strlen(ian->ipt_acc_tables[i].name) + 1;
memcpy(tnames, ian->ipt_acc_tables[i].name, name_len);
@@ -1100,7 +1103,7 @@ static int __net_init ipt_acc_net_init(struct net *net)
memset(ian, 0, sizeof(*ian));
sema_init(&ian->ipt_acc_userspace_mutex, 1);
ian->ipt_acc_tables = kcalloc(ACCOUNT_MAX_TABLES,
ian->ipt_acc_tables = kcalloc(max_tables_limit,
sizeof(struct ipt_acc_table), GFP_KERNEL);
if (ian->ipt_acc_tables == NULL) {
printk("ACCOUNT: Out of memory allocating account_tables structure");

View File

@@ -34,7 +34,6 @@
#define IPT_SO_GET_ACCOUNT_GET_TABLE_NAMES (SO_ACCOUNT_BASE_CTL + 8)
#define IPT_SO_GET_ACCOUNT_MAX IPT_SO_GET_ACCOUNT_GET_TABLE_NAMES
#define ACCOUNT_MAX_TABLES 128
#define ACCOUNT_TABLE_NAME_LEN 32
#define ACCOUNT_MAX_HANDLES 10

View File

@@ -13,6 +13,7 @@ obj-${build_DNETMAP} += xt_DNETMAP.o
obj-${build_ECHO} += xt_ECHO.o
obj-${build_IPMARK} += xt_IPMARK.o
obj-${build_LOGMARK} += xt_LOGMARK.o
obj-${build_PROTO} += xt_PROTO.o
obj-${build_SYSRQ} += xt_SYSRQ.o
obj-${build_TARPIT} += xt_TARPIT.o
obj-${build_condition} += xt_condition.o

View File

@@ -8,6 +8,7 @@ obj-${build_DNETMAP} += libxt_DNETMAP.so
obj-${build_ECHO} += libxt_ECHO.so
obj-${build_IPMARK} += libxt_IPMARK.so
obj-${build_LOGMARK} += libxt_LOGMARK.so
obj-${build_PROTO} += libxt_PROTO.so
obj-${build_SYSRQ} += libxt_SYSRQ.so
obj-${build_TARPIT} += libxt_TARPIT.so
obj-${build_condition} += libxt_condition.so

105
extensions/libxt_PROTO.c Normal file
View File

@@ -0,0 +1,105 @@
/*
* PROTO Target module
* This program is distributed under the terms of GNU GPL
*/
#include <stdio.h>
#include <xtables.h>
#include "xt_PROTO.h"
enum {
O_PROTO_SET = 0,
O_PROTO_STOP_AT_FRAG = 1,
O_PROTO_STOP_AT_AUTH = 2,
F_PROTO_SET = 1 << O_PROTO_SET,
F_PROTO_STOP_AT_FRAG = 1 << O_PROTO_STOP_AT_FRAG,
F_PROTO_STOP_AT_AUTH = 1 << O_PROTO_STOP_AT_AUTH,
};
#define s struct xt_PROTO_info
static const struct xt_option_entry PROTO_opts[] = {
{.name = "proto-set", .type = XTTYPE_UINT8, .id = O_PROTO_SET,
.flags = XTOPT_PUT | XTOPT_MAND, XTOPT_POINTER(s, proto)},
{.name = "stop-at-frag", .type = XTTYPE_NONE, .id = O_PROTO_STOP_AT_FRAG},
{.name = "stop-at-auth", .type = XTTYPE_NONE, .id = O_PROTO_STOP_AT_AUTH},
XTOPT_TABLEEND,
};
#undef s
static void PROTO_help(void)
{
printf(
"PROTO target options\n"
" --proto-set value Set protocol to <value 0-255>\n"
);
}
static void PROTO_parse(struct xt_option_call *cb)
{
struct xt_PROTO_info *info = cb->data;
xtables_option_parse(cb);
switch (cb->entry->id) {
case O_PROTO_SET:
info->mode |= 1 << XT_PROTO_SET;
break;
case O_PROTO_STOP_AT_FRAG:
info->mode |= 1 << XT_PROTO_STOP_AT_FRAG;
break;
case O_PROTO_STOP_AT_AUTH:
info->mode |= 1 << XT_PROTO_STOP_AT_AUTH;
break;
}
}
static void PROTO_check(struct xt_fcheck_call *cb)
{
if (!(cb->xflags & F_PROTO_SET))
xtables_error(PARAMETER_PROBLEM,
"PROTO: You must specify the proto to be set");
}
static void PROTO_save(const void *ip, const struct xt_entry_target *target)
{
const struct xt_PROTO_info *info = (void *)target->data;
if (info->mode & (1 << XT_PROTO_SET))
printf(" --proto-set %u", info->proto);
if (info->mode & (1 << XT_PROTO_STOP_AT_FRAG))
printf(" --stop-at-frag");
if (info->mode & (1 << XT_PROTO_STOP_AT_AUTH))
printf(" --stop-at-auth");
}
static void PROTO_print(const void *ip, const struct xt_entry_target *target,
int numeric)
{
const struct xt_PROTO_info *info = (void *)target->data;
printf(" PROTO ");
if (info->mode & (1 << XT_PROTO_SET))
printf("set to %u", info->proto);
if (info->mode & (1 << XT_PROTO_STOP_AT_FRAG))
printf(" stop-at-frag");
if (info->mode & (1 << XT_PROTO_STOP_AT_AUTH))
printf(" stop-at-auth");
}
static struct xtables_target proto_tg_reg = {
.name = "PROTO",
.version = XTABLES_VERSION,
.family = NFPROTO_UNSPEC,
.size = XT_ALIGN(sizeof(struct xt_PROTO_info)),
.userspacesize = XT_ALIGN(sizeof(struct xt_PROTO_info)),
.help = PROTO_help,
.print = PROTO_print,
.save = PROTO_save,
.x6_parse = PROTO_parse,
.x6_fcheck = PROTO_check,
.x6_options = PROTO_opts,
};
static __attribute__((constructor)) void _init(void)
{
xtables_register_target(&proto_tg_reg);
}

View File

@@ -0,0 +1,30 @@
.PP
The PROTO target modifies the protocol number in IP packet header.
.TP
\fB\-\-proto-set\fP \fIproto_num\fP
This option is mandatory. \fIproto_num\fP is the protocol number to which you want to
modify the packets.
.TP
\fB\-\-stop-at-frag\fP
This option is only valid for IPv6 rules. When specifying this option, the
fragment extension header will be seen as a non-extension header.
.TP
\fB\-\-stop-at-auth\fP
This option is only valid for IPv6 rules. When specifying this option, the
authentication extension header will be seen as a non-extension header.
.PP
For IPv4 packets, the \fBProtocol\fP field is modified and the checksum is
re-calculated.
.PP
For IPv6 packets, the scenario can be more complex due to the introduction of
the extension headers mechanism. By default, the PROTO target will scan the IPv6
packet, finding the last extension header and modify its \fBNext-header\fP field.
Normally, the following headers will be seen as an extension header:
\fINEXTHDR_HOP\fP,
\fINEXTHDR_ROUTING\fP,
\fINEXTHDR_FRAGMENT\fP,
\fINEXTHDR_AUTH\fP,
\fINEXTHDR_DEST\fP.
.PP
For fragmented packets, only the first fragment is processed and other fragments
are not touched.

View File

@@ -49,6 +49,38 @@ static struct option geoip_opts[] = {
{NULL},
};
#if __BYTE_ORDER == __LITTLE_ENDIAN
static void geoip_swap_le16(uint16_t *buf)
{
unsigned char *p = (void *)buf;
uint16_t n= p[0] + (p[1] << 8);
p[0] = (n >> 8) & 0xff;
p[1] = n & 0xff;
}
static void geoip_swap_in6(struct in6_addr *in6)
{
geoip_swap_le16(&in6->s6_addr16[0]);
geoip_swap_le16(&in6->s6_addr16[1]);
geoip_swap_le16(&in6->s6_addr16[2]);
geoip_swap_le16(&in6->s6_addr16[3]);
geoip_swap_le16(&in6->s6_addr16[4]);
geoip_swap_le16(&in6->s6_addr16[5]);
geoip_swap_le16(&in6->s6_addr16[6]);
geoip_swap_le16(&in6->s6_addr16[7]);
}
static void geoip_swap_le32(uint32_t *buf)
{
unsigned char *p = (void *)buf;
uint32_t n = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24);
p[0] = (n >> 24) & 0xff;
p[1] = (n >> 16) & 0xff;
p[2] = (n >> 8) & 0xff;
p[3] = n & 0xff;
}
#endif
static void *
geoip_get_subnets(const char *code, uint32_t *count, uint8_t nfproto)
{
@@ -56,21 +88,15 @@ geoip_get_subnets(const char *code, uint32_t *count, uint8_t nfproto)
struct stat sb;
char buf[256];
int fd;
#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned int n;
#endif
/* Use simple integer vector files */
if (nfproto == NFPROTO_IPV6) {
#if __BYTE_ORDER == _BIG_ENDIAN
snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/BE/%s.iv6", code);
#else
snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/LE/%s.iv6", code);
#endif
} else {
#if __BYTE_ORDER == _BIG_ENDIAN
snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/BE/%s.iv4", code);
#else
snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/LE/%s.iv4", code);
#endif
}
if (nfproto == NFPROTO_IPV6)
snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/%s.iv6", code);
else
snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/%s.iv4", code);
if ((fd = open(buf, O_RDONLY)) < 0) {
fprintf(stderr, "Could not open %s: %s\n", buf, strerror(errno));
@@ -98,6 +124,25 @@ geoip_get_subnets(const char *code, uint32_t *count, uint8_t nfproto)
xtables_error(OTHER_PROBLEM, "geoip: insufficient memory");
read(fd, subnets, sb.st_size);
close(fd);
#if __BYTE_ORDER == __LITTLE_ENDIAN
for (n = 0; n < *count; ++n) {
switch (nfproto) {
case NFPROTO_IPV6: {
struct geoip_subnet6 *gs6 = &(((struct geoip_subnet6 *)subnets)[n]);
geoip_swap_in6(&gs6->begin);
geoip_swap_in6(&gs6->end);
break;
}
case NFPROTO_IPV4: {
struct geoip_subnet4 *gs4 = &(((struct geoip_subnet4 *)subnets)[n]);
geoip_swap_le32(&gs4->begin);
geoip_swap_le32(&gs4->end);
break;
}
}
}
#endif
return subnets;
}
@@ -135,7 +180,7 @@ check_geoip_cc(char *cc, u_int16_t cc_used[], u_int8_t count)
cc[i] = toupper(cc[i]);
else
xtables_error(PARAMETER_PROBLEM,
"geoip: invalid country code '%s'", cc);
"geoip: invalid country code '%s'", cc);
/* Convert chars into a single 16 bit integer.
* FIXME: This assumes that a country code is

View File

@@ -1125,7 +1125,6 @@ static int __init xt_pknock_mt_init(void)
crypto.size = crypto_shash_digestsize(crypto.tfm);
crypto.desc.tfm = crypto.tfm;
crypto.desc.flags = 0;
pde = proc_mkdir("xt_pknock", init_net.proc_net);
if (pde == NULL) {

View File

@@ -107,8 +107,13 @@ static void delude_send_reset(struct net *net, struct sk_buff *oldskb,
addr_type = RTN_UNSPEC;
#ifdef CONFIG_BRIDGE_NETFILTER
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
if (hook != NF_INET_FORWARD || ((struct nf_bridge_info *)skb_ext_find(nskb, SKB_EXT_BRIDGE_NF) != NULL &&
((struct nf_bridge_info *)skb_ext_find(nskb, SKB_EXT_BRIDGE_NF))->physoutdev))
#else
if (hook != NF_INET_FORWARD || (nskb->nf_bridge != NULL &&
nskb->nf_bridge->physoutdev))
#endif
#else
if (hook != NF_INET_FORWARD)
#endif

View File

@@ -96,7 +96,8 @@ dhcpmac_tg(struct sk_buff *skb, const struct xt_action_param *par)
struct udphdr udpbuf, *udph;
unsigned int i;
if (!skb_make_writable(skb, 0))
if (skb_ensure_writable(skb, ip_hdrlen(skb) + sizeof(udpbuf) +
sizeof(dhcpbuf)))
return NF_DROP;
udph = skb_header_pointer(skb, ip_hdrlen(skb),

View File

@@ -363,7 +363,11 @@ dnetmap_tg(struct sk_buff *skb, const struct xt_action_param *par)
__be32 prenat_ip, postnat_ip, prenat_ip_prev;
const struct xt_DNETMAP_tginfo *tginfo = par->targinfo;
const struct nf_nat_range *mr = &tginfo->prefix;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0)
struct nf_nat_range2 newrange;
#else
struct nf_nat_range newrange;
#endif
struct dnetmap_entry *e;
struct dnetmap_prefix *p;
__s32 jttl;

156
extensions/xt_PROTO.c Normal file
View File

@@ -0,0 +1,156 @@
/*
* Protocol modification target for IP tables
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <net/ipv6.h>
#include <net/checksum.h>
#include <linux/netfilter/x_tables.h>
#include "xt_PROTO.h"
MODULE_AUTHOR("Shanker Wang <i@innull.com>");
MODULE_DESCRIPTION("Xtables: Protocol field modification target");
MODULE_LICENSE("GPL");
static unsigned int
proto_tg(struct sk_buff *skb, const struct xt_action_param *par)
{
struct iphdr *iph;
const struct xt_PROTO_info *info = par->targinfo;
int new_proto;
if (skb_ensure_writable(skb, skb->len))
return NF_DROP;
iph = ip_hdr(skb);
new_proto = iph->protocol;
if (info->mode & (1 << XT_PROTO_SET))
new_proto = info->proto;
if (new_proto != iph->protocol) {
csum_replace2(&iph->check, htons(iph->protocol & 0xff),
htons(new_proto & 0xff));
iph->protocol = new_proto;
}
return XT_CONTINUE;
}
static unsigned int
proto_tg6(struct sk_buff *skb, const struct xt_action_param *par)
{
struct ipv6hdr *ip6h;
const struct xt_PROTO_info *info = par->targinfo;
u8 *nexthdr;
unsigned int hdr_offset;
__be16 *fp;
if (skb_ensure_writable(skb, skb->len))
return NF_DROP;
ip6h = ipv6_hdr(skb);
nexthdr = &ip6h->nexthdr;
hdr_offset = sizeof(struct ipv6hdr);
for (;;) {
struct ipv6_opt_hdr _opthdr, *opthp;
unsigned int hdrlen;
unsigned short _frag_off;
if (!ipv6_ext_hdr(*nexthdr) || *nexthdr == NEXTHDR_NONE)
break;
opthp = skb_header_pointer(skb, skb_network_offset(skb) + hdr_offset, sizeof(_opthdr), &_opthdr);
if (!opthp)
return NF_DROP;
if (*nexthdr == NEXTHDR_FRAGMENT) {
if (info->mode & (1 << XT_PROTO_STOP_AT_FRAG))
break;
fp = skb_header_pointer(skb, skb_network_offset(skb) +
hdr_offset + offsetof(struct frag_hdr, frag_off),
sizeof(_frag_off), &_frag_off);
if (!fp)
return NF_DROP;
_frag_off = ntohs(*fp) & ~0x7;
if (_frag_off) { // if the packet is not the first fragment
if (!ipv6_ext_hdr(opthp->nexthdr) || opthp->nexthdr == NEXTHDR_NONE ||
(info->mode & (1 << XT_PROTO_STOP_AT_AUTH) && opthp->nexthdr == NEXTHDR_AUTH)) {
nexthdr = &((struct ipv6_opt_hdr *)(skb_network_header(skb) + hdr_offset))->nexthdr;
break;
} else {
return XT_CONTINUE;
}
}
hdrlen = 8;
} else if(*nexthdr == NEXTHDR_AUTH) {
if (info->mode & (1 << XT_PROTO_STOP_AT_AUTH))
break;
hdrlen = (opthp->hdrlen + 2) << 2;
} else {
hdrlen = ipv6_optlen(opthp);
}
nexthdr = &((struct ipv6_opt_hdr *)(skb_network_header(skb) + hdr_offset))->nexthdr;
hdr_offset += hdrlen;
}
if (info->mode & (1 << XT_PROTO_SET))
*nexthdr = info->proto;
return XT_CONTINUE;
}
static int proto_tg_check(const struct xt_tgchk_param *par)
{
const struct xt_PROTO_info *info = par->targinfo;
if ((info->mode & (1 << XT_PROTO_SET)) == 0) {
pr_info_ratelimited("Did not specify any proto to set\n");
return -EINVAL;
}
if (par->family != NFPROTO_IPV6 && (info->mode & ((1 << XT_PROTO_STOP_AT_FRAG) | (1 << XT_PROTO_STOP_AT_AUTH))) != 0) {
pr_info_ratelimited("Must not specify stop-at-frag and stop-at-auth on non-ipv6 targets\n");
return -EPROTOTYPE;
}
return 0;
}
static struct xt_target proto_tg_reg[] __read_mostly = {
{
.name = "PROTO",
.revision = 0,
.family = NFPROTO_IPV4,
.target = proto_tg,
.targetsize = sizeof(struct xt_PROTO_info),
.table = "mangle",
.checkentry = proto_tg_check,
.me = THIS_MODULE,
},
{
.name = "PROTO",
.revision = 0,
.family = NFPROTO_IPV6,
.target = proto_tg6,
.targetsize = sizeof(struct xt_PROTO_info),
.table = "mangle",
.checkentry = proto_tg_check,
.me = THIS_MODULE,
},
};
static int __init proto_tg_init(void)
{
return xt_register_targets(proto_tg_reg, ARRAY_SIZE(proto_tg_reg));
}
static void __exit proto_tg_exit(void)
{
xt_unregister_targets(proto_tg_reg, ARRAY_SIZE(proto_tg_reg));
}
module_init(proto_tg_init);
module_exit(proto_tg_exit);
MODULE_ALIAS("ipt_PROTO");
MODULE_ALIAS("ip6t_PROTO");

20
extensions/xt_PROTO.h Normal file
View File

@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/* Protocol modification module for IP tables */
#ifndef _XT_PROTO_H
#define _XT_PROTO_H
#include <linux/types.h>
enum {
XT_PROTO_SET = 0,
XT_PROTO_STOP_AT_FRAG = 1,
XT_PROTO_STOP_AT_AUTH = 2
};
struct xt_PROTO_info {
__u8 mode;
__u8 proto;
};
#endif

View File

@@ -114,7 +114,6 @@ static unsigned int sysrq_tg(const void *pdata, uint16_t len)
}
desc.tfm = sysrq_tfm;
desc.flags = 0;
ret = crypto_shash_init(&desc);
if (ret != 0)
goto hash_fail;
@@ -314,7 +313,7 @@ static void sysrq_crypto_exit(void)
static int __init sysrq_crypto_init(void)
{
#if defined(WITH_CRYPTO)
struct timeval now;
struct timespec64 now;
int ret;
sysrq_tfm = crypto_alloc_shash(sysrq_hash, 0, 0);
@@ -339,7 +338,7 @@ static int __init sysrq_crypto_init(void)
sizeof(sysrq_password), GFP_KERNEL);
if (sysrq_digest_password == NULL)
goto fail;
do_gettimeofday(&now);
ktime_get_real_ts64(&now);
sysrq_seqno = now.tv_sec;
return 0;

View File

@@ -249,8 +249,13 @@ static void tarpit_tcp4(struct net *net, struct sk_buff *oldskb,
niph->id = ~oldhdr->id + 1;
#ifdef CONFIG_BRIDGE_NETFILTER
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
if (hook != NF_INET_FORWARD || ((struct nf_bridge_info *)skb_ext_find(nskb, SKB_EXT_BRIDGE_NF) != NULL &&
((struct nf_bridge_info *)skb_ext_find(nskb, SKB_EXT_BRIDGE_NF))->physoutdev))
#else
if (hook != NF_INET_FORWARD || (nskb->nf_bridge != NULL &&
nskb->nf_bridge->physoutdev != NULL))
#endif
#else
if (hook != NF_INET_FORWARD)
#endif

View File

@@ -1,86 +1,216 @@
#!/usr/bin/perl
#
# Converter for MaxMind CSV database to binary, for xt_geoip
# Copyright © Jan Engelhardt, 2008-2011
# Converter for MaxMind (GeoLite2) CSV database to binary, for xt_geoip
# Copyright Jan Engelhardt, 2008-2011
# Copyright Philip Prindeville, 2018
#
use Getopt::Long;
use IO::Handle;
use Net::CIDR::Lite;
use Socket qw(AF_INET AF_INET6 inet_pton);
use warnings;
use Text::CSV_XS; # or trade for Text::CSV
use strict;
my $le32 = pack("V", 0x10000000);
my $be32 = pack("N", 0x10000000);
my $u32 = undef;
sub wantBE { return !$u32 || $u32 eq $be32; }
sub wantLE { return !$u32 || $u32 eq $le32; }
my $csv = Text::CSV_XS->new({
allow_whitespace => 1,
binary => 1,
eol => $/,
}); # or Text::CSV
my $source_dir = ".";
my $target_dir = ".";
my $native_only = 0;
&Getopt::Long::Configure(qw(bundling));
&GetOptions(
"D=s" => \$target_dir,
"n" => \$native_only,
"S=s" => \$source_dir,
);
if (!-d $target_dir) {
print STDERR "Target directory $target_dir does not exist.\n";
if (!-d $source_dir) {
print STDERR "Source directory \"$source_dir\" does not exist.\n";
exit 1;
}
my @dbs = qw(LE BE);
if ($native_only) {
$u32 = pack("L", 0x10000000);
if ($u32 eq $le32) {
@dbs = qw(LE);
} elsif ($u32 eq $be32) {
@dbs = qw(BE);
} else {
print STDERRR "Cannot determine endianness.\n";
exit 1;
}
}
foreach (@dbs) {
my $dir = "$target_dir/$_";
if (!-e $dir && !mkdir($dir)) {
print STDERR "Could not mkdir $dir: $!\n";
exit 1;
}
if (!-d $target_dir) {
print STDERR "Target directory \"$target_dir\" does not exist.\n";
exit 1;
}
my %countryId;
my %countryName;
&loadCountries();
&dump(&collect());
sub loadCountries
{
sub id; sub cc; sub long; sub ct; sub cn;
%countryId = ();
%countryName = ();
my $file = "$source_dir/GeoLite2-Country-Locations-en.csv";
open(my $fh, '<', $file) || die "Couldn't open list country names\n";
# first line is headers
my $row = $csv->getline($fh);
my %header = map { ($row->[$_], $_); } (0..$#{$row});
my %pairs = (
country_iso_code => 'ISO Country Code',
geoname_id => 'ID',
country_name => 'Country Name',
continent_code => 'Continent Code',
continent_name => 'Continent Name',
);
# verify that the columns we need are present
map { die "Table has no $pairs{$_} column\n" unless (exists $header{$_}); } keys %pairs;
my %remapping = (
id => 'geoname_id',
cc => 'country_iso_code',
long => 'country_name',
ct => 'continent_code',
cn => 'continent_name',
);
# now create a function which returns the value of that column #
map { eval "sub $_ () { \$header{\$remapping{$_}}; }" ; } keys %remapping;
while (my $row = $csv->getline($fh)) {
if ($row->[cc] eq '' && $row->[long] eq '') {
$countryId{$row->[id]} = $row->[ct];
$countryName{$row->[ct]} = $row->[cn];
} else {
$countryId{$row->[id]} = $row->[cc];
$countryName{$row->[cc]} = $row->[long];
}
}
$countryName{A1} = 'Anonymous Proxy';
$countryName{A2} = 'Satellite Provider';
$countryName{O1} = 'Other Country';
close($fh);
# clean up the namespace
undef &id; undef &cc; undef &long; undef &ct; undef &cn;
}
sub lookupCountry
{
my ($id, $rid, $proxy, $sat) = @_;
if ($proxy) {
return 'A1';
} elsif ($sat) {
return 'A2';
}
$id ||= $rid;
if ($id eq '') {
return 'O1';
}
die "Unknown id: $id line $.\n" unless (exists $countryId{$id});
return $countryId{$id};
}
sub collect
{
my %country;
my ($file, $fh, $row);
my (%country, %header);
sub net; sub id; sub rid; sub proxy; sub sat;
my %pairs = (
network => 'Network',
registered_country_geoname_id => 'Registered Country ID',
geoname_id => 'Country ID',
is_anonymous_proxy => 'Anonymous Proxy',
is_satellite_provider => 'Satellite',
);
foreach (sort keys %countryName) {
$country{$_} = {
name => $countryName{$_},
pool_v4 => Net::CIDR::Lite->new(),
pool_v6 => Net::CIDR::Lite->new(),
};
}
$file = "$source_dir/GeoLite2-Country-Blocks-IPv4.csv";
open($fh, '<', $file) || die "Can't open IPv4 database\n";
# first line is headers
$row = $csv->getline($fh);
%header = map { ($row->[$_], $_); } (0..$#{$row});
# verify that the columns we need are present
map { die "Table has no %pairs{$_} column\n" unless (exists $header{$_}); } keys %pairs;
my %remapping = (
net => 'network',
id => 'geoname_id',
rid => 'registered_country_geoname_id',
proxy => 'is_anonymous_proxy',
sat => 'is_satellite_provider',
);
# now create a function which returns the value of that column #
map { eval "sub $_ () { \$header{\$remapping{$_}}; }" ; } keys %remapping;
while ($row = $csv->getline($fh)) {
my ($cc, $cidr);
$cc = lookupCountry($row->[id], $row->[rid], $row->[proxy], $row->[sat]);
$cidr = $row->[net];
$country{$cc}->{pool_v4}->add($cidr);
while (my $row = $csv->getline(*ARGV)) {
if (!defined($country{$row->[4]})) {
$country{$row->[4]} = {
name => $row->[5],
pool_v4 => [],
pool_v6 => [],
};
}
my $c = $country{$row->[4]};
if ($row->[0] =~ /:/) {
push(@{$c->{pool_v6}},
[&ip6_pack($row->[0]), &ip6_pack($row->[1])]);
} else {
push(@{$c->{pool_v4}}, [$row->[2], $row->[3]]);
}
if ($. % 4096 == 0) {
print STDERR "\r\e[2K$. entries";
}
}
print STDERR "\r\e[2K$. entries total\n";
close($fh);
# clean up the namespace
undef &net; undef &id; undef &rid; undef &proxy; undef &sat;
$file = "$source_dir/GeoLite2-Country-Blocks-IPv6.csv";
open($fh, '<', $file) || die "Can't open IPv6 database\n";
# first line is headers
$row = $csv->getline($fh);
%header = map { ($row->[$_], $_); } (0..$#{$row});
# verify that the columns we need are present
map { die "Table has no %pairs{$_} column\n" unless (exists $header{$_}); } keys %pairs;
# unlikely the IPv6 table has different columns, but just to be sure
# create a function which returns the value of that column #
map { eval "sub $_ () { \$header{\$remapping{$_}}; }" ; } keys %remapping;
while ($row = $csv->getline($fh)) {
my ($cc, $cidr);
$cc = lookupCountry($row->[id], $row->[rid], $row->[proxy], $row->[sat]);
$cidr = $row->[net];
$country{$cc}->{pool_v6}->add($cidr);
if ($. % 4096 == 0) {
print STDERR "\r\e[2K$. entries";
}
}
print STDERR "\r\e[2K$. entries total\n";
close($fh);
# clean up the namespace
undef &net; undef &id; undef &rid; undef &proxy; undef &sat;
return \%country;
}
@@ -88,7 +218,7 @@ sub dump
{
my $country = shift @_;
foreach my $iso_code (sort keys %$country) {
foreach my $iso_code (sort keys %{$country}) {
&dump_one($iso_code, $country->{$iso_code});
}
}
@@ -96,80 +226,40 @@ sub dump
sub dump_one
{
my($iso_code, $country) = @_;
my($file, $fh_le, $fh_be);
my @ranges;
printf "%5u IPv6 ranges for %s %s\n",
scalar(@{$country->{pool_v6}}),
$iso_code, $country->{name};
@ranges = $country->{pool_v4}->list_range();
if (wantLE) {
$file = "$target_dir/LE/".uc($iso_code).".iv6";
if (!open($fh_le, "> $file")) {
print STDERR "Error opening $file: $!\n";
exit 1;
}
foreach my $range (@{$country->{pool_v6}}) {
print $fh_le &ip6_swap($range->[0]), &ip6_swap($range->[1]);
}
close $fh_le;
}
if (wantBE) {
$file = "$target_dir/BE/".uc($iso_code).".iv6";
if (!open($fh_be, "> $file")) {
print STDERR "Error opening $file: $!\n";
exit 1;
}
foreach my $range (@{$country->{pool_v6}}) {
print $fh_be $range->[0], $range->[1];
}
close $fh_be;
}
writeCountry($iso_code, $country->{name}, AF_INET, @ranges);
printf "%5u IPv4 ranges for %s %s\n",
scalar(@{$country->{pool_v4}}),
$iso_code, $country->{name};
@ranges = $country->{pool_v6}->list_range();
if (wantLE) {
$file = "$target_dir/LE/".uc($iso_code).".iv4";
if (!open($fh_le, "> $file")) {
print STDERR "Error opening $file: $!\n";
exit 1;
}
foreach my $range (@{$country->{pool_v4}}) {
print $fh_le pack("VV", $range->[0], $range->[1]);
}
close $fh_le;
}
if (wantBE) {
$file = "$target_dir/BE/".uc($iso_code).".iv4";
if (!open($fh_be, "> $file")) {
print STDERR "Error opening $file: $!\n";
exit 1;
}
foreach my $range (@{$country->{pool_v4}}) {
print $fh_be pack("NN", $range->[0], $range->[1]);
}
close $fh_be;
}
writeCountry($iso_code, $country->{name}, AF_INET6, @ranges);
}
sub ip6_pack
sub writeCountry
{
my $addr = shift @_;
$addr =~ s{::}{:!:};
my @addr = split(/:/, $addr);
my @e = (0) x 8;
foreach (@addr) {
if ($_ eq "!") {
$_ = join(':', @e[0..(8-scalar(@addr))]);
}
}
@addr = split(/:/, join(':', @addr));
$_ = hex($_) foreach @addr;
return pack("n*", @addr);
}
my ($iso_code, $name, $family, @ranges) = @_;
my $fh;
sub ip6_swap
{
return pack("V*", unpack("N*", shift @_));
printf "%5u IPv%s ranges for %s %s\n",
scalar(@ranges),
($family == AF_INET ? '4' : '6'),
$iso_code, $name;
my $file = "$target_dir/".uc($iso_code).".iv".($family == AF_INET ? '4' : '6');
if (!open($fh, '>', $file)) {
print STDERR "Error opening $file: $!\n";
exit 1;
}
binmode($fh);
foreach my $range (@ranges) {
my ($start, $end) = split('-', $range);
$start = inet_pton($family, $start);
$end = inet_pton($family, $end);
print $fh $start, $end;
}
close $fh;
}

View File

@@ -5,7 +5,7 @@ xt_geoip_build \(em convert GeoIP.csv to packed format for xt_geoip
.SH Syntax
.PP
\fI/usr/libexec/xt_geoip/\fP\fBxt_geoip_build\fP [\fB\-D\fP
\fItarget_dir\fP] [\fIfile\fP...]
\fItarget_dir\fP] [\fB\-S\fP \fIsource_dir\fP]
.SH Description
.PP
xt_geoip_build is used to build packed raw representations of the range
@@ -16,15 +16,19 @@ required to be loaded into memory. The ranges in the packed database files are
also ordered, as xt_geoip relies on this property for its bisection approach to
work.
.PP
Input is processed from the listed files, or if none is given, from stdin.
.PP
Since the script is usually installed to the libexec directory of the
xtables-addons package and this is outside $PATH (on purpose), invoking the
script requires it to be called with a path.
.PP Options
.TP
\fB\-D\fP \fItarget_dir\fP
Specify a target directory into which the files are to be put.
Specifies the target directory into which the files are to be put. Defaults to ".".
.TP
\fB\-S\fP \fIsource_dir\fP
Specifies the source directory from which to read the three files by the name
of \fBGeoLite2\-Country\-Blocks\-IPv4.csv\fP,
\fBGeoLite2\-Country\-Blocks\-IPv6.csv\fP and
\fBGeoLite2\-Country\-Locations\-en.csv\fP. Defaults to ".".
.SH Application
.PP
Shell commands to build the databases and put them to where they are expected:

View File

@@ -1,8 +1,7 @@
#!/bin/sh
rm -f GeoIPv6.csv GeoIPv6.csv.gz GeoIPCountryCSV.zip GeoIPCountryWhois.csv;
wget \
http://geolite.maxmind.com/download/geoip/database/GeoIPv6.csv.gz \
http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip;
gzip -d GeoIPv6.csv.gz;
unzip GeoIPCountryCSV.zip;
rm -rf GeoLite2-Country-CSV_*
wget -q http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country-CSV.zip
unzip -q GeoLite2-Country-CSV.zip
rm -f GeoLite2-Country-CSV.zip

93
geoip/xt_geoip_fetch Executable file
View File

@@ -0,0 +1,93 @@
#!/usr/bin/perl
#
# Utility to query GeoIP database
# Copyright Philip Prindeville, 2018
#
use Getopt::Long;
use Socket qw(AF_INET AF_INET6 inet_ntop);
use warnings;
use strict;
sub AF_INET_SIZE() { 4 }
sub AF_INET6_SIZE() { 16 }
my $target_dir = ".";
my $ipv4 = 0;
my $ipv6 = 0;
&Getopt::Long::Configure(qw(bundling));
&GetOptions(
"D=s" => \$target_dir,
"4" => \$ipv4,
"6" => \$ipv6,
);
if (!-d $target_dir) {
print STDERR "Target directory $target_dir does not exit.\n";
exit 1;
}
# if neither specified, assume both
if (! $ipv4 && ! $ipv6) {
$ipv4 = $ipv6 = 1;
}
foreach my $cc (@ARGV) {
if ($cc !~ m/^([a-z]{2}|a[12]|o1)$/i) {
print STDERR "Invalid country code '$cc'\n";
exit 1;
}
my $file = $target_dir . '/' . uc($cc) . '.iv4';
if (! -f $file) {
printf STDERR "Can't find data for country '$cc'\n";
exit 1;
}
my ($contents, $buffer, $bytes, $fh);
if ($ipv4) {
open($fh, '<', $file) || die "Couldn't open file for '$cc'\n";
binmode($fh);
while (($bytes = read($fh, $buffer, AF_INET_SIZE * 2)) == AF_INET_SIZE * 2) {
my $start = inet_ntop(AF_INET, substr($buffer, 0, AF_INET_SIZE));
my $end = inet_ntop(AF_INET, substr($buffer, AF_INET_SIZE));
print $start, '-', $end, "\n";
}
close($fh);
if (! defined $bytes) {
printf STDERR "Error reading file for '$cc'\n";
exit 1;
} elsif ($bytes != 0) {
printf STDERR "Short read on file for '$cc'\n";
exit 1;
}
}
substr($file, -1) = '6';
if ($ipv6) {
open($fh, '<', $file) || die "Couldn't open file for '$cc'\n";
binmode($fh);
while (($bytes = read($fh, $buffer, AF_INET6_SIZE * 2)) == AF_INET6_SIZE * 2) {
my $start = inet_ntop(AF_INET6, substr($buffer, 0, AF_INET6_SIZE));
my $end = inet_ntop(AF_INET6, substr($buffer, AF_INET6_SIZE));
print $start, '-', $end, "\n";
}
close($fh);
if (! defined $bytes) {
printf STDERR "Error reading file for '$cc'\n";
exit 1;
} elsif ($bytes != 0) {
printf STDERR "Short read on file for '$cc'\n";
exit 1;
}
}
}
exit 0;

View File

@@ -8,6 +8,7 @@ build_DNETMAP=m
build_ECHO=m
build_IPMARK=m
build_LOGMARK=m
build_PROTO=m
build_SYSRQ=m
build_TARPIT=m
build_condition=m

View File

@@ -1,3 +0,0 @@
#
# Source URLs for external patchlets
#

View File

@@ -1,83 +0,0 @@
#!/usr/bin/perl -w
use HTTP::Request;
use LWP::UserAgent;
use strict;
&main(\@ARGV);
sub main
{
local *FH;
if (!-d "downloads") {
if (!mkdir("downloads")) {
die "Could not create downloads/ directory";
}
}
open(FH, "<sources");
while (defined($_ = <FH>)) {
chomp $_;
$_ =~ s/#.*//gs;
$_ =~ s/^\s+|\s+$//gs;
if (length($_) == 0) {
next;
}
&process_index($_);
}
close FH;
}
sub process_index
{
my $top = shift @_;
my($agent, $res, $url);
local *FH;
$agent = LWP::UserAgent->new();
$agent->env_proxy();
$url = &slash_remove("$top/xa-index.txt");
print " GET $url\n";
$res = $agent->get($url);
if (!$res->is_success()) {
print STDERR " `-> ", $res->status_line(), "\n";
return;
}
foreach my $ext (split(/\s+/, $res->content())) {
my($ex_url, $ex_res);
$ex_url = &slash_remove("$top/$ext");
print " GET $ex_url\n";
$ex_res = $agent->mirror($ex_url, "downloads/$ext");
if ($ex_res->code() == 304) {
# "Not modified" = up to date
next;
}
if (!$ex_res->is_success()) {
print STDERR " `-> ", $ex_res->status_line(), "\n";
next;
}
print " UNPACK downloads/$ext\n";
system "tar", "-xjf", "downloads/$ext";
}
}
sub slash_remove
{
my $s = shift @_;
$s =~ s{(\w+://)(.*)}{$1.&slash_remove2($2)}eg;
return $s;
}
sub slash_remove2
{
my $s = shift @_;
$s =~ s{/+}{/}g;
return $s;
}

View File

@@ -1,4 +1,4 @@
.TH xtables-addons 8 "Lilac" "" "v3.0 (2018-02-12)"
.TH xtables-addons 8 "" "" "v3.5 (2019-09-10)"
.SH Name
Xtables-addons \(em additional extensions for iptables, ip6tables, etc.
.SH Targets