upgrade iptables to 1.8.11

Signed-off-by: HuangHaitao <huanghaitao16@huawei.com>
This commit is contained in:
HuangHaitao
2025-06-30 00:55:52 +08:00
parent 4bf2263360
commit e4107a428d
794 changed files with 95483 additions and 1125 deletions
+101
View File
@@ -0,0 +1,101 @@
Installation instructions for iptables
======================================
iptables uses the well-known configure(autotools) infrastructure.
$ ./configure
$ make
# make install
Prerequisites
=============
* no kernel-source required
* but obviously a compiler, glibc-devel and linux-kernel-headers
(/usr/include/linux)
Configuring and compiling
=========================
./configure [options]
--prefix=
The prefix to put all installed files under. It defaults to
/usr/local, so the binaries will go into /usr/local/bin, sbin,
manpages into /usr/local/share/man, etc.
--with-xtlibdir=
The path to where Xtables extensions should be installed to. It
defaults to ${libdir}/xtables.
--enable-devel (or --disable-devel)
This option causes development files to be installed to
${includedir}, which is needed for building additional packages,
such as Xtables-addons or other 3rd-party extensions.
It is enabled by default.
--enable-static
Produce additional binaries, iptables-static/ip6tables-static,
which have all shipped extensions compiled in.
--disable-shared
Produce binaries that have dynamic loading of extensions disabled.
This implies --enable-static.
(See some details below.)
--enable-libipq
This option causes libipq to be installed into ${libdir} and
${includedir}.
--with-ksource=
Xtables does not depend on kernel headers anymore, but you can
optionally specify a search path to include anyway. This is
probably only useful for development.
If you want to enable debugging, use
./configure CFLAGS="-ggdb3 -O0"
(-O0 is used to turn off instruction reordering, which makes debugging
much easier.)
To show debug traces you can add -DDEBUG to CFLAGS option
Other notes
===========
The make process will automatically build multipurpose binaries.
These have the core (iptables), -save, -restore and -xml code
compiled into one binary, but extensions remain as modules.
Static and shared
=================
Basically there are three configuration modes defined:
--disable-static --enable-shared (this is the default)
Build a binary that relies upon dynamic loading of extensions.
--enable-static --enable-shared
Build a binary that has the shipped extensions built-in, but
is still capable of loading additional extensions.
--enable-static --disable-shared
Shipped extensions are built-in, and dynamic loading is
deactivated.
+37
View File
@@ -0,0 +1,37 @@
# -*- Makefile -*-
ACLOCAL_AMFLAGS = -I m4
AUTOMAKE_OPTIONS = foreign subdir-objects dist-xz no-dist-gzip serial-tests
SUBDIRS = libiptc libxtables
if ENABLE_DEVEL
SUBDIRS += include
endif
if ENABLE_LIBIPQ
SUBDIRS += libipq
endif
SUBDIRS += utils
# Depends on libxtables:
SUBDIRS += extensions
# Depends on extensions/libext.a:
SUBDIRS += iptables
EXTRA_DIST = autogen.sh iptables-test.py xlate-test.py
if ENABLE_NFTABLES
confdir = $(sysconfdir)
dist_conf_DATA = etc/ethertypes
endif
.PHONY: tarball
tarball:
rm -Rf /tmp/${PACKAGE_TARNAME}-${PACKAGE_VERSION};
pushd ${top_srcdir} && git archive --prefix=${PACKAGE_TARNAME}-${PACKAGE_VERSION}/ HEAD | tar -C /tmp -x && popd;
pushd /tmp/${PACKAGE_TARNAME}-${PACKAGE_VERSION} && ./autogen.sh && popd;
tar -C /tmp -cJf ${PACKAGE_TARNAME}-${PACKAGE_VERSION}.tar.xz --owner=root --group=root ${PACKAGE_TARNAME}-${PACKAGE_VERSION}/;
rm -Rf /tmp/${PACKAGE_TARNAME}-${PACKAGE_VERSION};
config.status: extensions/GNUmakefile.in \
include/xtables-version.h.in
TESTS = xlate-test.py iptables-test.py iptables/tests/shell/run-tests.sh
+3 -3
View File
@@ -1,10 +1,10 @@
[
{
"Name" : "openEuler:iptables",
"Name" : "iptables",
"License" : "GPL V2.0",
"License File" : "COPYING",
"Version Number" : "1.8.7-14.oe2203sp3",
"Owner" : "lichunlin2@huawei.com",
"Version Number" : "1.8.11",
"Owner" : "heqianmo@huawei.com",
"Upstream URL" : "https://netfilter.org/",
"Description" : "iptables is the userspace command line program used to configure the Linux 2.4.x and later packet filtering ruleset. It is targeted towards system administrators."
}
Executable
+4
View File
@@ -0,0 +1,4 @@
#!/bin/sh -e
autoreconf -fi;
rm -Rf autom4te*.cache;
@@ -1,90 +0,0 @@
From 17534cb18ed0a5052dc45c117401251359dba6aa Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Fri, 11 Feb 2022 17:47:22 +0100
Subject: Improve error messages for unsupported extensions
If a given extension was not supported by the kernel, iptables would
print a rather confusing error message if extension parameters were
given:
| # rm /lib/modules/$(uname -r)/kernel/net/netfilter/xt_LOG.ko
| # iptables -A FORWARD -j LOG --log-prefix foo
| iptables v1.8.7 (legacy): unknown option "--log-prefix"
Avoid this by pretending extension revision 0 is always supported. It is
the same hack as used to successfully print extension help texts as
unprivileged user, extended to all error codes to serve privileged ones
as well.
In addition, print a warning if kernel rejected revision 0 and it's not
a permissions problem. This helps users find out which extension in a
rule the kernel didn't like.
Finally, the above commands result in these messages:
| Warning: Extension LOG revision 0 not supported, missing kernel
module?
| iptables: No chain/target/match by that name.
Or, for iptables-nft:
| Warning: Extension LOG revision 0 not supported, missing kernel
module?
| iptables v1.8.7 (nf_tables): RULE_APPEND failed (No such file or
directory): rule in chain FORWARD
Conflict: NA
Reference:
https://git.netfilter.org/iptables/commit/?id=17534cb18ed0a5052dc45c117401251359dba6aa
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/nft.c | 13 +++++++++----
libxtables/xtables.c | 7 ++++++-
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/iptables/nft.c b/iptables/nft.c
index c9a4940..18bf21c 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -3245,11 +3245,16 @@ int nft_compatible_revision(const char *name, uint8_t rev, int opt)
err:
mnl_socket_close(nl);
- /* pretend revision 0 is valid if not permitted to check -
- * this is required for printing extension help texts as user */
- if (ret < 0 && errno == EPERM && rev == 0)
+ /* pretend revision 0 is valid -
+ * this is required for printing extension help texts as user, also
+ * helps error messaging on unavailable kernel extension */
+ if (ret < 0 && rev == 0) {
+ if (errno != EPERM)
+ fprintf(stderr,
+ "Warning: Extension %s revision 0 not supported, missing kernel module?\n",
+ name);
return 1;
-
+ }
return ret < 0 ? 0 : 1;
}
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
index bc42ba8..1f585e5 100644
--- a/libxtables/xtables.c
+++ b/libxtables/xtables.c
@@ -923,7 +923,12 @@ int xtables_compatible_revision(const char *name, uint8_t revision, int opt)
/* Definitely don't support this? */
if (errno == ENOENT || errno == EPROTONOSUPPORT) {
close(sockfd);
- return 0;
+ /* Pretend revision 0 support for better error messaging */
+ if (revision == 0)
+ fprintf(stderr,
+ "Warning: Extension %s revision 0 not supported, missing kernel module?\n",
+ name);
+ return (revision == 0);
} else if (errno == ENOPROTOOPT) {
close(sockfd);
/* Assume only revision 0 support (old kernel) */
--
2.23.0
@@ -1,51 +0,0 @@
From b51aef061378b34fa9544b1af34021d89a76547a Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Thu, 26 Jan 2023 03:27:16 +0100
Subject: [PATCH] ebtables-translate: Print flush command after parsing is
finished
Otherwise, bad calls like 'ebtables-translate -F -F' produce wrong
output instead of an error message.
Conflict: NA
Reference: https://git.netfilter.org/iptables/commit?id=b51aef061378b34fa9544b1af34021d89a76547a
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/xtables-eb-translate.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/iptables/xtables-eb-translate.c b/iptables/xtables-eb-translate.c
index 99347c0c..da7e5e3d 100644
--- a/iptables/xtables-eb-translate.c
+++ b/iptables/xtables-eb-translate.c
@@ -247,13 +247,6 @@ static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char
ret = 1;
break;
case 'F': /* Flush */
- if (p.chain) {
- printf("flush chain bridge %s %s\n", p.table, p.chain);
- } else {
- printf("flush table bridge %s\n", p.table);
- }
- ret = 1;
- break;
case 'Z': /* Zero counters */
if (c == 'Z') {
if ((flags & OPT_ZERO) || (flags & OPT_COMMAND && command != 'L'))
@@ -506,6 +499,13 @@ print_zero:
if (command == 'P') {
return 0;
+ } else if (command == 'F') {
+ if (p.chain) {
+ printf("flush chain bridge %s %s\n", p.table, p.chain);
+ } else {
+ printf("flush table bridge %s\n", p.table);
+ }
+ ret = 1;
} else if (command == 'A') {
ret = nft_rule_eb_xlate_add(h, &p, &cs, true);
if (!ret)
--
2.23.0
@@ -1,58 +0,0 @@
From fca04aa7a53252464c289997e71de10189971da6 Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Fri, 30 Sep 2022 17:51:55 +0200
Subject: [PATCH] extensions: among: Fix for use with ebtables-restore
When restoring multiple rules which use among match, new size may be
smaller than the old one which caused invalid writes by the memcpy()
call. Expect this and realloc the match only if it needs to grow. Also
use realloc instead of freeing and allocating from scratch.
Conflict: NA
Reference: https://git.netfilter.org/iptables/commit?id=fca04aa7a53252464c289997e71de10189971da6
Fixes: 26753888720d8 ("nft: bridge: Rudimental among extension support")
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
extensions/libebt_among.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/extensions/libebt_among.c b/extensions/libebt_among.c
index c607a775..1eab2019 100644
--- a/extensions/libebt_among.c
+++ b/extensions/libebt_among.c
@@ -119,7 +119,6 @@ static int bramong_parse(int c, char **argv, int invert,
struct xt_entry_match **match)
{
struct nft_among_data *data = (struct nft_among_data *)(*match)->data;
- struct xt_entry_match *new_match;
bool have_ip, dst = false;
size_t new_size, cnt;
struct stat stats;
@@ -170,18 +169,17 @@ static int bramong_parse(int c, char **argv, int invert,
new_size *= sizeof(struct nft_among_pair);
new_size += XT_ALIGN(sizeof(struct xt_entry_match)) +
sizeof(struct nft_among_data);
- new_match = xtables_calloc(1, new_size);
- memcpy(new_match, *match, (*match)->u.match_size);
- new_match->u.match_size = new_size;
- data = (struct nft_among_data *)new_match->data;
+ if (new_size > (*match)->u.match_size) {
+ *match = xtables_realloc(*match, new_size);
+ (*match)->u.match_size = new_size;
+ data = (struct nft_among_data *)(*match)->data;
+ }
+
have_ip = nft_among_pairs_have_ip(optarg);
poff = nft_among_prepare_data(data, dst, cnt, invert, have_ip);
parse_nft_among_pairs(data->pairs + poff, optarg, cnt, have_ip);
- free(*match);
- *match = new_match;
-
if (c == AMONG_DST_F || c == AMONG_SRC_F) {
munmap(argv, flen);
close(fd);
--
2.23.0
@@ -1,31 +0,0 @@
From 8543b6f2f4a3a15a5ece7dd1b320b477ce36a8d5 Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Wed, 16 Nov 2022 13:03:05 +0100
Subject: [PATCH] extensions: libebt_redirect: Fix xlate return code
The callback is supposed to return 1 on success, not 0.
Conflict: NA
Reference: https://git.netfilter.org/iptables/commit?id=8543b6f2f4a3a15a5ece7dd1b320b477ce36a8d5
Fixes: 24ce7465056ae ("ebtables-compat: add redirect match extension")
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
extensions/libebt_redirect.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/extensions/libebt_redirect.c b/extensions/libebt_redirect.c
index 6e653997..4d4c7a02 100644
--- a/extensions/libebt_redirect.c
+++ b/extensions/libebt_redirect.c
@@ -86,7 +86,7 @@ static int brredir_xlate(struct xt_xlate *xl,
xt_xlate_add(xl, "meta set pkttype host");
if (red->target != EBT_ACCEPT)
xt_xlate_add(xl, " %s ", brredir_verdict(red->target));
- return 0;
+ return 1;
}
static struct xtables_target brredirect_target = {
--
2.23.0
@@ -1,40 +0,0 @@
From 800bed28b2b7bbd931166c7426640ae619f03342 Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Wed, 16 Nov 2022 13:09:16 +0100
Subject: [PATCH] extensions: libipt_ttl: Sanitize xlate callback
Catch unexpected values in info->mode, also fix indenting.
Conflict: NA
Reference: https://git.netfilter.org/iptables/commit?id=800bed28b2b7bbd931166c7426640ae619f03342
Fixes: 1b320a1a1dc1f ("extensions: libipt_ttl: Add translation to nft")
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
extensions/libipt_ttl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/extensions/libipt_ttl.c b/extensions/libipt_ttl.c
index 6bdd2196..86ba554e 100644
--- a/extensions/libipt_ttl.c
+++ b/extensions/libipt_ttl.c
@@ -106,7 +106,7 @@ static int ttl_xlate(struct xt_xlate *xl,
const struct ipt_ttl_info *info =
(struct ipt_ttl_info *) params->match->data;
- switch (info->mode) {
+ switch (info->mode) {
case IPT_TTL_EQ:
xt_xlate_add(xl, "ip ttl");
break;
@@ -121,7 +121,7 @@ static int ttl_xlate(struct xt_xlate *xl,
break;
default:
/* Should not happen. */
- break;
+ return 0;
}
xt_xlate_add(xl, " %u", info->ttl);
--
2.23.0
@@ -1,56 +0,0 @@
From 82ccfb488eeac5507471099b9b4e6d136cc06e3b Mon Sep 17 00:00:00 2001
From: Jacek Tomasiak <jacek.tomasiak@gmail.com>
Date: Mon, 19 Jun 2023 13:46:36 +0200
Subject: iptables: Fix handling of non-existent chains
Since 694612adf87 the "compatibility" check considers non-existent
chains as "incompatible". This broke some scripts which used calls
like `iptables -L CHAIN404` to test for chain existence and expect
"No chain/target/match by that name." in the output.
This patch changes the logic of `nft_is_table_compatible()` to
report non-existent chains as "compatible" which restores the old
behavior.
Fixes: 694612adf87 ("nft: Fix selective chain compatibility checks")
Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1648
Signed-off-by: Jacek Tomasiak <jtomasiak@arista.com>
Signed-off-by: Jacek Tomasiak <jacek.tomasiak@gmail.com>
Signed-off-by: Phil Sutter <phil@nwl.cc>
Conflict: NA
Reference: https://git.netfilter.org/iptables/commit?id=82ccfb488eeac5507471099b9b4e6d136cc06e3b
---
iptables/nft.c | 2 +-
iptables/tests/shell/testcases/iptables/0004-return-codes_0 | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/iptables/nft.c b/iptables/nft.c
index 1cb104e7..020553a4 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -3860,7 +3860,7 @@ bool nft_is_table_compatible(struct nft_handle *h,
if (chain) {
struct nft_chain *c = nft_chain_find(h, table, chain);
- return c && !nft_is_chain_compatible(c, h);
+ return !c || !nft_is_chain_compatible(c, h);
}
return !nft_chain_foreach(h, table, nft_is_chain_compatible, h);
diff --git a/iptables/tests/shell/testcases/iptables/0004-return-codes_0 b/iptables/tests/shell/testcases/iptables/0004-return-codes_0
index 33c5f1f3..234f3040 100755
--- a/iptables/tests/shell/testcases/iptables/0004-return-codes_0
+++ b/iptables/tests/shell/testcases/iptables/0004-return-codes_0
@@ -58,6 +58,7 @@ cmd 1 "$ENOENT" -Z bar
cmd 0 -E foo bar
cmd 1 "$EEXIST_F" -E foo bar
cmd 1 "$ENOENT" -E foo bar2
+cmd 1 "$ENOENT" -L foo
cmd 0 -N foo2
cmd 1 "$EEXIST_F" -E foo2 bar
--
cgit v1.2.3
@@ -1,92 +0,0 @@
From fb63f8b7337aa11a667537e6a3b399062ede2eb5 Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Fri, 25 Nov 2022 21:35:28 +0100
Subject: [PATCH] iptables: Plug memleaks in print_firewall()
When adding a rule in verbose mode, valgrind prints:
192 bytes in 1 blocks are definitely lost in loss record 1 of 2
at 0x48417E5: malloc (vg_replace_malloc.c:381)
by 0x486B158: xtables_malloc (xtables.c:446)
by 0x486C1F6: xtables_find_match (xtables.c:826)
by 0x10E684: print_match (iptables.c:115)
by 0x10E684: print_firewall (iptables.c:169)
by 0x10FC0C: print_firewall_line (iptables.c:196)
by 0x10FC0C: append_entry (iptables.c:221)
by 0x10FC0C: do_command4 (iptables.c:776)
by 0x10E45B: iptables_main (iptables-standalone.c:59)
by 0x49A2349: (below main) (in /lib64/libc.so.6)
200 bytes in 1 blocks are definitely lost in loss record 2 of 2
at 0x48417E5: malloc (vg_replace_malloc.c:381)
by 0x486B158: xtables_malloc (xtables.c:446)
by 0x486BBD6: xtables_find_target (xtables.c:956)
by 0x10E579: print_firewall (iptables.c:145)
by 0x10FC0C: print_firewall_line (iptables.c:196)
by 0x10FC0C: append_entry (iptables.c:221)
by 0x10FC0C: do_command4 (iptables.c:776)
by 0x10E45B: iptables_main (iptables-standalone.c:59)
by 0x49A2349: (below main) (in /lib64/libc.so.6)
If the match/target was cloned, it needs to be freed. Basically a bug since
day 1.
Conflict: NA
Reference: https://git.netfilter.org/iptables/commit?id=fb63f8b7337aa11a667537e6a3b399062ede2eb5
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/ip6tables.c | 6 ++++++
iptables/iptables.c | 6 ++++++
2 files changed, 12 insertions(+)
diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c
index 062b2b15..1d232657 100644
--- a/iptables/ip6tables.c
+++ b/iptables/ip6tables.c
@@ -122,6 +122,9 @@ print_match(const struct xt_entry_match *m,
printf("%s%s ", match->name, unsupported_rev);
else
printf("%s ", match->name);
+
+ if (match->next == match)
+ free(match);
} else {
if (name[0])
printf("UNKNOWN match `%s' ", name);
@@ -179,6 +182,9 @@ print_firewall(const struct ip6t_entry *fw,
tg->print(&fw->ipv6, t, format & FMT_NUMERIC);
else if (target->print)
printf(" %s%s", target->name, unsupported_rev);
+
+ if (target->next == target)
+ free(target);
} else if (t->u.target_size != sizeof(*t))
printf("[%u bytes of unknown target data] ",
(unsigned int)(t->u.target_size - sizeof(*t)));
diff --git a/iptables/iptables.c b/iptables/iptables.c
index 0351b39f..d246198f 100644
--- a/iptables/iptables.c
+++ b/iptables/iptables.c
@@ -122,6 +122,9 @@ print_match(const struct xt_entry_match *m,
printf("%s%s ", match->name, unsupported_rev);
else
printf("%s ", match->name);
+
+ if (match->next == match)
+ free(match);
} else {
if (name[0])
printf("UNKNOWN match `%s' ", name);
@@ -178,6 +181,9 @@ print_firewall(const struct ipt_entry *fw,
tg->print(&fw->ip, t, format & FMT_NUMERIC);
else if (target->print)
printf(" %s%s", target->name, unsupported_rev);
+
+ if (target->next == target)
+ free(target);
} else if (t->u.target_size != sizeof(*t))
printf("[%u bytes of unknown target data] ",
(unsigned int)(t->u.target_size - sizeof(*t)));
--
2.23.0
@@ -1,48 +0,0 @@
From 18880dbde615449d00a3e38f3713a19d4566258e Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Fri, 25 Nov 2022 19:24:38 +0100
Subject: [PATCH] iptables-restore: Free handle with --test also
When running 'iptables-restore -t', valgrind reports:
1,496 (160 direct, 1,336 indirect) bytes in 1 blocks are definitely lost in loss record 4 of 4
at 0x48417E5: malloc (vg_replace_malloc.c:381)
by 0x4857A46: alloc_handle (libiptc.c:1279)
by 0x4857A46: iptc_init (libiptc.c:1342)
by 0x1167CE: create_handle (iptables-restore.c:72)
by 0x1167CE: ip46tables_restore_main (iptables-restore.c:229)
by 0x116DAE: iptables_restore_main (iptables-restore.c:388)
by 0x49A2349: (below main) (in /lib64/libc.so.6)
Free the handle pointer before parsing the next table.
Conflict: NA
Reference: https://git.netfilter.org/iptables/commit?id=18880dbde615449d00a3e38f3713a19d4566258e
Fixes: 1c9015b2cb483 ("libiptc: remove indirections")
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/iptables-restore.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/iptables/iptables-restore.c b/iptables/iptables-restore.c
index 05661bf6..6f7ddf93 100644
--- a/iptables/iptables-restore.c
+++ b/iptables/iptables-restore.c
@@ -185,12 +185,12 @@ ip46tables_restore_main(const struct iptables_restore_cb *cb,
if (!testing) {
DEBUGP("Calling commit\n");
ret = cb->ops->commit(handle);
- cb->ops->free(handle);
- handle = NULL;
} else {
DEBUGP("Not calling commit, testing\n");
ret = 1;
}
+ cb->ops->free(handle);
+ handle = NULL;
/* Done with the current table, release the lock. */
if (lock >= 0) {
--
2.23.0
@@ -1,64 +0,0 @@
From 2dbb49d15fb44ddd521a734eca3be3f940b7c1ba Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Fri, 11 Feb 2022 17:39:24 +0100
Subject: libxtables: Register only the highest revision extension
When fully registering extensions, ignore all consecutive ones with same
name and family value. Since commit b3ac87038f4e4 ("libxtables: Make
sure extensions register in revision order"), one may safely assume the
list of pending extensions has highest revision numbers first. Since
iptables is only interested in the highest revision the kernel supports,
registration and compatibility checks may be skipped once the first
matching extension in pending list has validated.
Conflict: NA
Reference: https://git.netfilter.org/iptables/commit/?id=2dbb49d15fb44ddd521a734eca3be3f940b7c1ba
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
libxtables/xtables.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
index 50fd6a44..b34d62ac 100644
--- a/libxtables/xtables.c
+++ b/libxtables/xtables.c
@@ -697,6 +697,7 @@ xtables_find_match(const char *name, enum xtables_tryload tryload,
struct xtables_match **dptr;
struct xtables_match *ptr;
const char *icmp6 = "icmp6";
+ bool found = false;
if (strlen(name) >= XT_EXTENSION_MAXNAMELEN)
xtables_error(PARAMETER_PROBLEM,
@@ -715,7 +716,9 @@ xtables_find_match(const char *name, enum xtables_tryload tryload,
if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) {
ptr = *dptr;
*dptr = (*dptr)->next;
- if (xtables_fully_register_pending_match(ptr, prev)) {
+ if (!found &&
+ xtables_fully_register_pending_match(ptr, prev)) {
+ found = true;
prev = ptr;
continue;
} else if (prev) {
@@ -817,6 +820,7 @@ xtables_find_target(const char *name, enum xtables_tryload tryload)
struct xtables_target *prev = NULL;
struct xtables_target **dptr;
struct xtables_target *ptr;
+ bool found = false;
/* Standard target? */
if (strcmp(name, "") == 0
@@ -831,7 +835,9 @@ xtables_find_target(const char *name, enum xtables_tryload tryload)
if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) {
ptr = *dptr;
*dptr = (*dptr)->next;
- if (xtables_fully_register_pending_target(ptr, prev)) {
+ if (!found &&
+ xtables_fully_register_pending_target(ptr, prev)) {
+ found = true;
prev = ptr;
continue;
} else if (prev) {
--
cgit v1.2.3
@@ -1,95 +0,0 @@
From 0257293c68913dd5993c1cac44f2ee80af6d9792 Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Fri, 26 Aug 2022 16:53:52 +0200
Subject: [PATCH] nft: Expand extended error reporting to nft_cmd, too
Introduce the same embedded 'error' struct in nft_cmd and initialize it
with the current value from nft_handle. Then in preparation phase,
update nft_handle's error.lineno with the value from the current
nft_cmd.
This serves two purposes:
* Allocated batch objects (obj_update) get the right lineno value
instead of the COMMIT one.
* Any error during preparation may be reported with line number. Do this
and change the relevant fprintf() call to use nft_handle's lineno
instead of the global 'line' variable.
With this change, cryptic iptables-nft-restore error messages should
finally be gone:
| # iptables-nft-restore <<EOF
| *filter
| -A nonexist
| COMMIT
| EOF
| iptables-nft-restore: line 2 failed: No chain/target/match by that name.
Conflict: NA
Reference: https://git.netfilter.org/iptables/commit?id=0257293c68913dd5993c1cac44f2ee80af6d9792
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/nft-cmd.c | 1 +
iptables/nft-cmd.h | 3 +++
iptables/nft.c | 2 ++
iptables/xtables-restore.c | 2 +-
4 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/iptables/nft-cmd.c b/iptables/nft-cmd.c
index 9b0c964..f026c62 100644
--- a/iptables/nft-cmd.c
+++ b/iptables/nft-cmd.c
@@ -26,6 +26,7 @@ struct nft_cmd *nft_cmd_new(struct nft_handle *h, int command,
if (!cmd)
return NULL;
+ cmd->error.lineno = h->error.lineno;
cmd->command = command;
cmd->table = strdup(table);
if (chain)
diff --git a/iptables/nft-cmd.h b/iptables/nft-cmd.h
index ecf7655..3caa3ed 100644
--- a/iptables/nft-cmd.h
+++ b/iptables/nft-cmd.h
@@ -24,6 +24,9 @@ struct nft_cmd {
struct xt_counters counters;
const char *rename;
int counters_save;
+ struct {
+ unsigned int lineno;
+ } error;
};
struct nft_cmd *nft_cmd_new(struct nft_handle *h, int command,
diff --git a/iptables/nft.c b/iptables/nft.c
index 3e24c86..996d5bc 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -3050,6 +3050,8 @@ static int nft_prepare(struct nft_handle *h)
nft_cache_build(h);
list_for_each_entry_safe(cmd, next, &h->cmd_list, head) {
+ h->error.lineno = cmd->error.lineno;
+
switch (cmd->command) {
case NFT_COMPAT_TABLE_FLUSH:
ret = nft_table_flush(h, cmd->table);
diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c
index d273949..abeaf76 100644
--- a/iptables/xtables-restore.c
+++ b/iptables/xtables-restore.c
@@ -248,7 +248,7 @@ static void xtables_restore_parse_line(struct nft_handle *h,
return;
if (!ret) {
fprintf(stderr, "%s: line %u failed\n",
- xt_params->program_name, line);
+ xt_params->program_name, h->error.lineno);
exit(1);
}
}
--
2.33.0
@@ -1,69 +0,0 @@
From 8468fd4f7c85c21ab375402bc80d0188412b6cbf Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Wed, 4 May 2022 11:19:16 +0200
Subject: nft: Fix EPERM handling for extensions without rev 0
Treating revision 0 as compatible in EPERM case works fine as long as
there is a revision 0 of that extension defined in DSO. Fix the code for
others: Extend the EPERM handling to all revisions and keep the existing
warning for revision 0.
Conflict: NA
Reference:
https://git.netfilter.org/iptables/commit/?id=8468fd4f7c85c21ab375402bc80d0188412b6cbf
Fixes: 17534cb18ed0a ("Improve error messages for unsupported
extensions")
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/nft.c | 11 +++++++----
.../shell/testcases/iptables/0008-unprivileged_0 | 7 +++++++
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/iptables/nft.c b/iptables/nft.c
index 18bf21c..ebab3cc 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -3245,15 +3245,18 @@ int nft_compatible_revision(const char *name, uint8_t rev, int opt)
err:
mnl_socket_close(nl);
- /* pretend revision 0 is valid -
+ /* ignore EPERM and errors for revision 0 -
* this is required for printing extension help texts as user, also
* helps error messaging on unavailable kernel extension */
- if (ret < 0 && rev == 0) {
- if (errno != EPERM)
+ if (ret < 0) {
+ if (errno == EPERM)
+ return 1;
+ if (rev == 0) {
fprintf(stderr,
"Warning: Extension %s revision 0 not supported, missing kernel module?\n",
name);
- return 1;
+ return 1;
+ }
}
return ret < 0 ? 0 : 1;
}
diff --git a/iptables/tests/shell/testcases/iptables/0008-unprivileged_0 b/iptables/tests/shell/testcases/iptables/0008-unprivileged_0
index 0914c88..1f1d342 100644
--- a/iptables/tests/shell/testcases/iptables/0008-unprivileged_0
+++ b/iptables/tests/shell/testcases/iptables/0008-unprivileged_0
@@ -34,6 +34,13 @@ let "rc+=$?"
grep_or_rc "DNAT target options:" <<< "$out"
let "rc+=$?"
+# TEE has no revision 0
+out=$(run $XT_MULTI iptables -j TEE --help)
+let "rc+=$?"
+grep_or_rc "TEE target options:" <<< "$out"
+let "rc+=$?"
+
+
out=$(run $XT_MULTI iptables -p tcp -j DNAT --help)
let "rc+=$?"
grep_or_rc "tcp match options:" <<< "$out"
--
2.23.0
@@ -1,52 +0,0 @@
From aa0c54030300441e9fd66c7016d0090f6736d449 Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Fri, 25 Nov 2022 21:21:22 +0100
Subject: [PATCH] nft: Plug memleak in nft_rule_zero_counters()
When zeroing a specific rule, valgrind reports:
40 bytes in 1 blocks are definitely lost in loss record 1 of 1
at 0x484659F: calloc (vg_replace_malloc.c:1328)
by 0x48DE128: xtables_calloc (xtables.c:434)
by 0x11C7C6: nft_parse_immediate (nft-shared.c:1071)
by 0x11C7C6: nft_rule_to_iptables_command_state (nft-shared.c:1236)
by 0x119AF5: nft_rule_zero_counters (nft.c:2877)
by 0x11A3CA: nft_prepare (nft.c:3445)
by 0x11A7A8: nft_commit (nft.c:3479)
by 0x114258: xtables_main.isra.0 (xtables-standalone.c:94)
by 0x1142D9: xtables_ip6_main (xtables-standalone.c:118)
by 0x49F2349: (below main) (in /lib64/libc.so.6)
Have to free the matches/target in populated iptables_command_state object
again. While being at it, call the proper family_ops callbacks since this is
family-agnostic code.
Conflict: NA
Reference: https://git.netfilter.org/iptables/commit?id=aa0c54030300441e9fd66c7016d0090f6736d449
Fixes: a69cc575295ee ("xtables: allow to reset the counters of an existing rule")
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/nft.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/iptables/nft.c b/iptables/nft.c
index 67c5877c..430888e8 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -2874,10 +2874,11 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain,
goto error;
}
- nft_rule_to_iptables_command_state(h, r, &cs);
-
+ h->ops->rule_to_cs(h, r, &cs);
cs.counters.pcnt = cs.counters.bcnt = 0;
new_rule = nft_rule_new(h, chain, table, &cs);
+ h->ops->clear_cs(&cs);
+
if (!new_rule)
return 1;
--
2.23.0
@@ -1,130 +0,0 @@
From 26ecdf53960658771c0fc582f72a4025e2887f75 Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Tue, 18 Jan 2022 22:39:08 +0100
Subject: xshared: Fix response to unprivileged users
Expected behaviour in both variants is:
* Print help without error, append extension help if -m and/or -j
options are present
* Indicate lack of permissions in an error message for anything else
With iptables-nft, this was broken basically from day 1. Shared use of
do_parse() then somewhat broke legacy: it started complaining about
inability to create a lock file.
Fix this by making iptables-nft assume extension revision 0 is present
if permissions don't allow to verify. This is consistent with legacy.
Second part is to exit directly after printing help - this avoids having
to make the following code "nop-aware" to prevent privileged actions.
Conflict: NA
Reference:
https://git.netfilter.org/iptables/commit/?id=26ecdf53960658771c0fc582f72a4025e2887f75
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Florian Westphal <fw@strlen.de>
---
iptables/nft.c | 5 ++
.../testcases/iptables/0008-unprivileged_0 | 59 +++++++++++++++++++
iptables/xtables.c | 2 +-
3 files changed, 65 insertions(+), 1 deletion(-)
create mode 100644 iptables/tests/shell/testcases/iptables/0008-unprivileged_0
diff --git a/iptables/nft.c b/iptables/nft.c
index bde4ca7..c9a4940 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -3245,6 +3245,11 @@ int nft_compatible_revision(const char *name, uint8_t rev, int opt)
err:
mnl_socket_close(nl);
+ /* pretend revision 0 is valid if not permitted to check -
+ * this is required for printing extension help texts as user */
+ if (ret < 0 && errno == EPERM && rev == 0)
+ return 1;
+
return ret < 0 ? 0 : 1;
}
diff --git a/iptables/tests/shell/testcases/iptables/0008-unprivileged_0 b/iptables/tests/shell/testcases/iptables/0008-unprivileged_0
new file mode 100644
index 0000000..0914c88
--- /dev/null
+++ b/iptables/tests/shell/testcases/iptables/0008-unprivileged_0
@@ -0,0 +1,59 @@
+#!/bin/bash
+# iptables may print match/target specific help texts
+# help output should work for unprivileged users
+
+run() {
+ echo "running: $*" >&2
+ runuser -u nobody -- "$@"
+}
+
+grep_or_rc() {
+ declare -g rc
+ grep -q "$*" && return 0
+ echo "missing in output: $*" >&2
+ return 1
+}
+
+out=$(run $XT_MULTI iptables --help)
+let "rc+=$?"
+grep_or_rc "iptables -h (print this help information)" <<< "$out"
+let "rc+=$?"
+
+out=$(run $XT_MULTI iptables -m limit --help)
+let "rc+=$?"
+grep_or_rc "limit match options:" <<< "$out"
+let "rc+=$?"
+
+out=$(run $XT_MULTI iptables -p tcp --help)
+let "rc+=$?"
+grep_or_rc "tcp match options:" <<< "$out"
+let "rc+=$?"
+
+out=$(run $XT_MULTI iptables -j DNAT --help)
+let "rc+=$?"
+grep_or_rc "DNAT target options:" <<< "$out"
+let "rc+=$?"
+
+out=$(run $XT_MULTI iptables -p tcp -j DNAT --help)
+let "rc+=$?"
+grep_or_rc "tcp match options:" <<< "$out"
+let "rc+=$?"
+out=$(run $XT_MULTI iptables -p tcp -j DNAT --help)
+let "rc+=$?"
+grep_or_rc "DNAT target options:" <<< "$out"
+let "rc+=$?"
+
+
+run $XT_MULTI iptables -L 2>&1 | \
+ grep_or_rc "Permission denied"
+let "rc+=$?"
+
+run $XT_MULTI iptables -A FORWARD -p tcp --dport 123 2>&1 | \
+ grep_or_rc "Permission denied"
+let "rc+=$?"
+
+run $XT_MULTI iptables -A FORWARD -j DNAT --to-destination 1.2.3.4 2>&1 | \
+ grep_or_rc "Permission denied"
+let "rc+=$?"
+
+exit $rc
diff --git a/iptables/xtables.c b/iptables/xtables.c
index 9779bd8..a16bba7 100644
--- a/iptables/xtables.c
+++ b/iptables/xtables.c
@@ -645,7 +645,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
printhelp(cs->matches);
p->command = CMD_NONE;
- return;
+ exit(0);
/*
* Option selection
--
2.23.0
@@ -1,32 +0,0 @@
From e900d40afdb731d2270a5110833ae49192974355 Mon Sep 17 00:00:00 2001
From: Florian Westphal <fw@strlen.de>
Date: Tue, 14 Mar 2023 22:36:50 +0100
Subject: [PATCH] xtables-eb: fix crash when opts isn't reallocated
opts may point to statically allocated memory.
This fixes abort() from libc.
Conflict: NA
Reference: https://git.netfilter.org/iptables/commit?id=e900d40afdb731d2270a5110833ae49192974355
Signed-off-by: Florian Westphal <fw@strlen.de>
---
iptables/xtables-eb.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c
index 3a73e797..068dffd2 100644
--- a/iptables/xtables-eb.c
+++ b/iptables/xtables-eb.c
@@ -675,7 +675,8 @@ void nft_fini_eb(struct nft_handle *h)
free(target->t);
}
- free(opts);
+ if (opts != ebt_original_options)
+ free(opts);
nft_fini(h);
xtables_fini();
--
2.23.0
@@ -1,44 +0,0 @@
From c70a33d219ccb43e6f59aa1b9bbab5dcb13f3443 Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Thu, 25 Aug 2022 11:53:04 +0200
Subject: [PATCH] xtables-restore: Extend failure error message
If a line causes zero 'ret' value and errno is set, call nft_strerror()
for a more detailed error message. While not perfect, it helps with
debugging ominous "line NN failed" messages pointing at COMMIT:
| # iptables-nft-restore <<EOF
| *filter
| -A nonexist
| COMMIT
| EOF
| iptables-nft-restore: line 3 failed: No chain/target/match by that name.
Conflict: NA
Reference: https://git.netfilter.org/iptables/commit?id=c70a33d219ccb43e6f59aa1b9bbab5dcb13f3443
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
iptables/xtables-restore.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c
index abeaf76..5940e9a 100644
--- a/iptables/xtables-restore.c
+++ b/iptables/xtables-restore.c
@@ -247,8 +247,11 @@ static void xtables_restore_parse_line(struct nft_handle *h,
(strcmp(p->tablename, state->curtable->name) != 0))
return;
if (!ret) {
- fprintf(stderr, "%s: line %u failed\n",
+ fprintf(stderr, "%s: line %u failed",
xt_params->program_name, h->error.lineno);
+ if (errno)
+ fprintf(stderr, ": %s.", nft_strerror(errno));
+ fprintf(stderr, "\n");
exit(1);
}
}
--
2.33.0
-135
View File
@@ -1,135 +0,0 @@
From cbc3a30711701f0e8d7f5df14f84adfb2c9fec1f Mon Sep 17 00:00:00 2001
From: majun <majun65@huawei.com>
Date: Fri, 16 Apr 2021 14:52:42 +0800
Subject: [PATCH]
iptables: add null check for fw in X_entry
If the fw pointer is empty, a core dump occurs.
---
iptables/ip6tables.c | 21 +++++++++++++++++++++
iptables/iptables.c | 20 ++++++++++++++++++++
2 files changed, 41 insertions(+)
diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c
index c95355b..1902cb4 100644
--- a/iptables/ip6tables.c
+++ b/iptables/ip6tables.c
@@ -478,6 +478,10 @@ append_entry(const xt_chainlabel chain,
unsigned int i, j;
int ret = 1;
+ if (!fw) {
+ return 0;
+ }
+
for (i = 0; i < nsaddrs; i++) {
fw->ipv6.src = saddrs[i];
fw->ipv6.smsk = smasks[i];
@@ -502,6 +506,11 @@ replace_entry(const xt_chainlabel chain,
int verbose,
struct xtc_handle *handle)
{
+
+ if (!fw) {
+ return 0;
+ }
+
fw->ipv6.src = *saddr;
fw->ipv6.dst = *daddr;
fw->ipv6.smsk = *smask;
@@ -528,6 +537,10 @@ insert_entry(const xt_chainlabel chain,
unsigned int i, j;
int ret = 1;
+ if (!fw) {
+ return 0;
+ }
+
for (i = 0; i < nsaddrs; i++) {
fw->ipv6.src = saddrs[i];
fw->ipv6.smsk = smasks[i];
@@ -595,6 +608,10 @@ delete_entry(const xt_chainlabel chain,
int ret = 1;
unsigned char *mask;
+ if (!fw) {
+ return 0;
+ }
+
mask = make_delete_mask(matches, target);
for (i = 0; i < nsaddrs; i++) {
fw->ipv6.src = saddrs[i];
@@ -625,6 +642,10 @@ check_entry(const xt_chainlabel chain, struct ip6t_entry *fw,
int ret = 1;
unsigned char *mask;
+ if (!fw) {
+ return 0;
+ }
+
mask = make_delete_mask(matches, target);
for (i = 0; i < nsaddrs; i++) {
fw->ipv6.src = saddrs[i];
diff --git a/iptables/iptables.c b/iptables/iptables.c
index 7d61831..a206825 100644
--- a/iptables/iptables.c
+++ b/iptables/iptables.c
@@ -469,6 +469,10 @@ append_entry(const xt_chainlabel chain,
unsigned int i, j;
int ret = 1;
+ if (!fw) {
+ return 0;
+ }
+
for (i = 0; i < nsaddrs; i++) {
fw->ip.src.s_addr = saddrs[i].s_addr;
fw->ip.smsk.s_addr = smasks[i].s_addr;
@@ -493,6 +497,10 @@ replace_entry(const xt_chainlabel chain,
int verbose,
struct xtc_handle *handle)
{
+ if (!fw) {
+ return 0;
+ }
+
fw->ip.src.s_addr = saddr->s_addr;
fw->ip.dst.s_addr = daddr->s_addr;
fw->ip.smsk.s_addr = smask->s_addr;
@@ -519,6 +527,10 @@ insert_entry(const xt_chainlabel chain,
unsigned int i, j;
int ret = 1;
+ if (!fw) {
+ return 0;
+ }
+
for (i = 0; i < nsaddrs; i++) {
fw->ip.src.s_addr = saddrs[i].s_addr;
fw->ip.smsk.s_addr = smasks[i].s_addr;
@@ -586,6 +598,10 @@ delete_entry(const xt_chainlabel chain,
int ret = 1;
unsigned char *mask;
+ if (!fw) {
+ return 0;
+ }
+
mask = make_delete_mask(matches, target);
for (i = 0; i < nsaddrs; i++) {
fw->ip.src.s_addr = saddrs[i].s_addr;
@@ -616,6 +632,10 @@ check_entry(const xt_chainlabel chain, struct ipt_entry *fw,
int ret = 1;
unsigned char *mask;
+ if (!fw) {
+ return 0;
+ }
+
mask = make_delete_mask(matches, target);
for (i = 0; i < nsaddrs; i++) {
fw->ip.src.s_addr = saddrs[i].s_addr;
--
2.27.0
+313
View File
@@ -0,0 +1,313 @@
AC_INIT([iptables], [1.8.11])
# See libtool.info "Libtool's versioning system"
libxtables_vcurrent=19
libxtables_vage=7
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AC_PROG_INSTALL
AM_INIT_AUTOMAKE([-Wall])
AC_PROG_CC
AM_PROG_CC_C_O
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
LT_INIT([disable-static])
AC_ARG_WITH([kernel],
AS_HELP_STRING([--with-kernel=PATH],
[Path to kernel source/build directory]),
[kbuilddir="$withval"; ksourcedir="$withval";])
AC_ARG_WITH([kbuild],
AS_HELP_STRING([--with-kbuild=PATH],
[Path to kernel build directory [[/lib/modules/CURRENT/build]]]),
[kbuilddir="$withval"])
AC_ARG_WITH([ksource],
AS_HELP_STRING([--with-ksource=PATH],
[Path to kernel source directory [[/lib/modules/CURRENT/source]]]),
[ksourcedir="$withval"])
AC_ARG_WITH([xtlibdir],
AS_HELP_STRING([--with-xtlibdir=PATH],
[Path where to install Xtables extensions [[LIBEXECDIR/xtables]]]),
[xtlibdir="$withval"],
[xtlibdir="${libdir}/xtables"])
AC_ARG_ENABLE([ipv4],
AS_HELP_STRING([--disable-ipv4], [Do not build iptables]),
[enable_ipv4="$enableval"], [enable_ipv4="yes"])
AC_ARG_ENABLE([ipv6],
AS_HELP_STRING([--disable-ipv6], [Do not build ip6tables]),
[enable_ipv6="$enableval"], [enable_ipv6="yes"])
AC_ARG_ENABLE([largefile],
AS_HELP_STRING([--disable-largefile], [Do not build largefile support]),
[enable_largefile="$enableval"],
[enable_largefile="yes"])
AS_IF([test "$enable_largefile" = "yes"], [largefile_cppflags='-D_LARGEFILE_SOURCE=1 -D_LARGE_FILES -D_FILE_OFFSET_BITS=64'])
AC_ARG_ENABLE([devel],
AS_HELP_STRING([--enable-devel],
[Install Xtables development headers]),
[enable_devel="$enableval"], [enable_devel="yes"])
AC_ARG_ENABLE([libipq],
AS_HELP_STRING([--enable-libipq], [Build and install libipq]),
[enable_libipq="$enableval"], [enable_libipq="no"])
AC_ARG_ENABLE([bpf-compiler],
AS_HELP_STRING([--enable-bpf-compiler], [Build bpf compiler]),
[enable_bpfc="$enableval"], [enable_bpfc="no"])
AC_ARG_ENABLE([nfsynproxy],
AS_HELP_STRING([--enable-nfsynproxy], [Build SYNPROXY configuration tool]),
[enable_nfsynproxy="$enableval"], [enable_nfsynproxy="no"])
AC_ARG_WITH([pkgconfigdir], AS_HELP_STRING([--with-pkgconfigdir=PATH],
[Path to the pkgconfig directory [[LIBDIR/pkgconfig]]]),
[pkgconfigdir="$withval"], [pkgconfigdir='${libdir}/pkgconfig'])
AC_ARG_ENABLE([nftables],
AS_HELP_STRING([--disable-nftables], [Do not build nftables compat]),
[enable_nftables="$enableval"], [enable_nftables="yes"])
AC_ARG_ENABLE([libnfnetlink],
AS_HELP_STRING([--disable-libnfnetlink], [Do not use netfilter netlink library]),
[enable_libnfnetlink="$enableval"], [enable_libnfnetlink="auto"])
AC_ARG_ENABLE([connlabel],
AS_HELP_STRING([--disable-connlabel],
[Do not build libnetfilter_conntrack]),
[enable_connlabel="$enableval"], [enable_connlabel="yes"])
AC_ARG_WITH([xt-lock-name], AS_HELP_STRING([--with-xt-lock-name=PATH],
[Path to the xtables lock [[/run/xtables.lock]]]),
[xt_lock_name="$withval"],
[xt_lock_name="/run/xtables.lock"])
AC_ARG_ENABLE([profiling],
AS_HELP_STRING([--enable-profiling], [build for use of gcov/gprof]),
[enable_profiling="$enableval"], [enable_profiling="no"])
AC_MSG_CHECKING([whether $LD knows -Wl,--no-undefined])
saved_LDFLAGS="$LDFLAGS";
LDFLAGS="-Wl,--no-undefined";
AC_LINK_IFELSE([AC_LANG_SOURCE([int main(void) {}])],
[noundef_LDFLAGS="$LDFLAGS"; AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])]
)
LDFLAGS="$saved_LDFLAGS";
blacklist_modules=""
blacklist_x_modules=""
blacklist_b_modules=""
blacklist_a_modules=""
blacklist_4_modules=""
blacklist_6_modules=""
AC_CHECK_HEADERS([linux/dccp.h linux/ip_vs.h linux/magic.h linux/proc_fs.h linux/bpf.h])
if test "$ac_cv_header_linux_dccp_h" != "yes"; then
blacklist_modules="$blacklist_modules dccp";
fi;
if test "$ac_cv_header_linux_ip_vs_h" != "yes"; then
blacklist_modules="$blacklist_modules ipvs";
fi;
AC_CHECK_SIZEOF([struct ip6_hdr], [], [#include <netinet/ip6.h>])
AM_CONDITIONAL([ENABLE_STATIC], [test "$enable_static" = "yes"])
AM_CONDITIONAL([ENABLE_SHARED], [test "$enable_shared" = "yes"])
AM_CONDITIONAL([ENABLE_IPV4], [test "$enable_ipv4" = "yes"])
AM_CONDITIONAL([ENABLE_IPV6], [test "$enable_ipv6" = "yes"])
AM_CONDITIONAL([ENABLE_LARGEFILE], [test "$enable_largefile" = "yes"])
AM_CONDITIONAL([ENABLE_DEVEL], [test "$enable_devel" = "yes"])
AM_CONDITIONAL([ENABLE_LIBIPQ], [test "$enable_libipq" = "yes"])
AM_CONDITIONAL([ENABLE_BPFC], [test "$enable_bpfc" = "yes"])
AM_CONDITIONAL([ENABLE_SYNCONF], [test "$enable_nfsynproxy" = "yes"])
AM_CONDITIONAL([ENABLE_NFTABLES], [test "$enable_nftables" = "yes"])
AM_CONDITIONAL([ENABLE_CONNLABEL], [test "$enable_connlabel" = "yes"])
# If specified explicitly on the command line, error out when library was not found
# Otherwise, disable and continue
AS_IF([test "x$enable_libnfnetlink" = "xyes"],
[PKG_CHECK_MODULES([libnfnetlink], [libnfnetlink >= 1.0],
[nfnetlink=1])],
[test "x$enable_libnfnetlink" = "xauto"],
[PKG_CHECK_MODULES([libnfnetlink], [libnfnetlink >= 1.0],
[nfnetlink=1], [nfnetlink=0])])
AM_CONDITIONAL([HAVE_LIBNFNETLINK], [test "$nfnetlink" = 1])
if test "x$enable_bpfc" = "xyes" || test "x$enable_nfsynproxy" = "xyes"; then
PKG_CHECK_MODULES([libpcap], [libpcap], [], [
AC_MSG_ERROR(missing libpcap library required by bpf compiler or nfsynproxy tool)])
fi
if test "x$enable_nftables" = "xyes"; then
PKG_CHECK_MODULES([libmnl], [libmnl >= 1.0], [mnl=1], [mnl=0])
if test "$mnl" = 0;
then
echo "*** Error: No suitable libmnl found. ***"
echo " Please install the 'libmnl' package"
echo " Or consider --disable-nftables to skip"
echo " iptables-compat over nftables support."
exit 1
fi
PKG_CHECK_MODULES([libnftnl], [libnftnl >= 1.2.6], [nftables=1], [nftables=0])
if test "$nftables" = 0;
then
echo "*** Error: no suitable libnftnl found. ***"
echo " Please install the 'libnftnl' package"
echo " Or consider --disable-nftables to skip"
echo " iptables-compat over nftables support."
exit 1
fi
fi
AM_CONDITIONAL([HAVE_LIBMNL], [test "$mnl" = 1])
AM_CONDITIONAL([HAVE_LIBNFTNL], [test "$nftables" = 1])
if test "$nftables" != 1; then
blacklist_b_modules="$blacklist_b_modules limit mark nflog mangle"
blacklist_a_modules="$blacklist_a_modules mangle"
fi
if test "x$enable_connlabel" = "xyes"; then
PKG_CHECK_MODULES([libnetfilter_conntrack],
[libnetfilter_conntrack >= 1.0.6],
[nfconntrack=1], [nfconntrack=0])
if test "$nfconntrack" -ne 1; then
blacklist_modules="$blacklist_modules connlabel";
echo "WARNING: libnetfilter_conntrack not found, connlabel match will not be built";
enable_connlabel="no";
fi;
else
blacklist_modules="$blacklist_modules connlabel";
fi;
AM_CONDITIONAL([HAVE_LIBNETFILTER_CONNTRACK], [test "$nfconntrack" = 1])
AC_SUBST([blacklist_modules])
AC_SUBST([blacklist_x_modules])
AC_SUBST([blacklist_b_modules])
AC_SUBST([blacklist_a_modules])
AC_SUBST([blacklist_4_modules])
AC_SUBST([blacklist_6_modules])
regular_CFLAGS="-Wall -Waggregate-return -Wmissing-declarations \
-Wmissing-prototypes -Wredundant-decls -Wshadow -Wstrict-prototypes \
-Wlogical-op \
-Winline -pipe";
regular_CPPFLAGS="${largefile_cppflags} -D_REENTRANT \
-DXTABLES_LIBDIR=\\\"\${xtlibdir}\\\" -DXTABLES_INTERNAL";
kinclude_CPPFLAGS="";
if [[ -n "$kbuilddir" ]]; then
kinclude_CPPFLAGS="$kinclude_CPPFLAGS -I$kbuilddir/include/uapi -I$kbuilddir/include";
fi;
if [[ -n "$ksourcedir" ]]; then
kinclude_CPPFLAGS="$kinclude_CPPFLAGS -I$ksourcedir/include/uapi -I$ksourcedir/include";
fi;
pkgdatadir='${datadir}/xtables';
if test "x$enable_profiling" = "xyes"; then
regular_CFLAGS+=" -fprofile-arcs -ftest-coverage"
regular_LDFLAGS+=" -lgcov --coverage"
fi
AC_MSG_CHECKING([whether the build is using musl-libc])
enable_musl_build=""
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([[#include <netinet/if_ether.h>]],
[[
#if ! defined(__UAPI_DEF_ETHHDR) || __UAPI_DEF_ETHHDR != 0
#error error trying musl...
#endif
]]
)],
[enable_musl_build="yes"],[enable_musl_build="no"]
)
AC_MSG_RESULT([${enable_musl_build}])
if test "x$enable_musl_build" = "xyes"; then
regular_CFLAGS+=" -D__UAPI_DEF_ETHHDR=0"
fi
define([EXPAND_VARIABLE],
[$2=[$]$1
if test $prefix = 'NONE'; then
prefix="/usr/local"
fi
while true; do
case "[$]$2" in
*\[$]* ) eval "$2=[$]$2" ;;
*) break ;;
esac
done
eval "$2=[$]$2"
])dnl EXPAND_VARIABLE
AC_SUBST([regular_CFLAGS])
AC_SUBST([regular_CPPFLAGS])
AC_SUBST([noundef_LDFLAGS])
AC_SUBST([regular_LDFLAGS])
AC_SUBST([kinclude_CPPFLAGS])
AC_SUBST([kbuilddir])
AC_SUBST([ksourcedir])
AC_SUBST([xtlibdir])
AC_SUBST([pkgconfigdir])
AC_SUBST([pkgdatadir])
AC_SUBST([libxtables_vcurrent])
AC_SUBST([libxtables_vage])
libxtables_vmajor=$(($libxtables_vcurrent - $libxtables_vage));
AC_SUBST([libxtables_vmajor])
AC_DEFINE_UNQUOTED([XT_LOCK_NAME], "${xt_lock_name}",
[Location of the iptables lock file])
AC_SUBST([XT_LOCK_NAME], "${xt_lock_name}")
AC_CONFIG_FILES([Makefile extensions/GNUmakefile include/Makefile
iptables/Makefile iptables/xtables.pc
iptables/iptables.8 iptables/iptables-extensions.8.tmpl
iptables/iptables-save.8 iptables/iptables-restore.8
iptables/iptables-apply.8 iptables/iptables-xml.1
libipq/Makefile libipq/libipq.pc
libiptc/Makefile libiptc/libiptc.pc
libiptc/libip4tc.pc libiptc/libip6tc.pc
libxtables/Makefile utils/Makefile
include/xtables-version.h
iptables/xtables-monitor.8
utils/nfnl_osf.8
utils/nfbpf_compile.8])
AC_OUTPUT
EXPAND_VARIABLE(xtlibdir, e_xtlibdir)
EXPAND_VARIABLE(pkgconfigdir, e_pkgconfigdir)
echo "
Iptables Configuration:
IPv4 support: ${enable_ipv4}
IPv6 support: ${enable_ipv6}
Devel support: ${enable_devel}
IPQ support: ${enable_libipq}
Large file support: ${enable_largefile}
BPF utils support: ${enable_bpfc}
nfsynproxy util support: ${enable_nfsynproxy}
nftables support: ${enable_nftables}
connlabel support: ${enable_connlabel}
profiling support: ${enable_profiling}
Build parameters:
Put plugins into executable (static): ${enable_static}
Support plugins via dlopen (shared): ${enable_shared}
Installation prefix (--prefix): ${prefix}
Xtables extension directory: ${e_xtlibdir}
Pkg-config directory: ${e_pkgconfigdir}
Xtables lock file: ${xt_lock_name}
Build against musl-libc: ${enable_musl_build}"
if [[ -n "$ksourcedir" ]]; then
echo " Kernel source directory: ${ksourcedir}"
fi;
if [[ -n "$kbuilddir" ]]; then
echo " Kernel build directory: ${kbuilddir}"
fi;
echo " Host: ${host}
GCC binary: ${CC}"
test x"$blacklist_modules" = "x" || echo "
Iptables modules that will not be built: $blacklist_modules"
-35
View File
@@ -1,35 +0,0 @@
From 54c670ada541aa61ab9ab7907ab245718137efb8 Mon Sep 17 00:00:00 2001
From: huangyu <huangyu106@huawei.com>
Date: Sat, 26 Nov 2022 18:08:31 +0800
Subject: [PATCH] enable makecheck in extensions
Signed-off-by: huangyu <huangyu106@huawei.com>
---
extensions/GNUmakefile.in | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/extensions/GNUmakefile.in b/extensions/GNUmakefile.in
index 956ccb3..70515c4 100644
--- a/extensions/GNUmakefile.in
+++ b/extensions/GNUmakefile.in
@@ -79,7 +79,7 @@ targets_install :=
.SECONDARY:
-.PHONY: all install uninstall clean distclean FORCE
+.PHONY: all install uninstall check clean distclean FORCE
all: ${targets}
@@ -105,6 +105,8 @@ uninstall:
rmdir -p --ignore-fail-on-non-empty "$$dir"; \
}
+check:
+
clean:
rm -f *.o *.oo *.so *.a {matches,targets}.man initext.c initext4.c initext6.c initextb.c initexta.c;
rm -f .*.d .*.dd;
--
2.23.0
+39
View File
@@ -0,0 +1,39 @@
#
# Ethernet frame types
# This file describes some of the various Ethernet
# protocol types that are used on Ethernet networks.
#
# This list could be found on:
# http://www.iana.org/assignments/ethernet-numbers
# http://www.iana.org/assignments/ieee-802-numbers
#
# <name> <hexnumber> <alias1>...<alias35> #Comment
#
IPv4 0800 ip ip4 # Internet IP (IPv4)
X25 0805
ARP 0806 ether-arp #
FR_ARP 0808 # Frame Relay ARP [RFC1701]
BPQ 08FF # G8BPQ AX.25 Ethernet Packet
DEC 6000 # DEC Assigned proto
DNA_DL 6001 # DEC DNA Dump/Load
DNA_RC 6002 # DEC DNA Remote Console
DNA_RT 6003 # DEC DNA Routing
LAT 6004 # DEC LAT
DIAG 6005 # DEC Diagnostics
CUST 6006 # DEC Customer use
SCA 6007 # DEC Systems Comms Arch
TEB 6558 # Trans Ether Bridging [RFC1701]
RAW_FR 6559 # Raw Frame Relay [RFC1701]
RARP 8035 # Reverse ARP [RFC903]
AARP 80F3 # Appletalk AARP
ATALK 809B # Appletalk
802_1Q 8100 8021q 1q 802.1q dot1q # 802.1Q Virtual LAN tagged frame
IPX 8137 # Novell IPX
NetBEUI 8191 # NetBEUI
IPv6 86DD ip6 # IP version 6
PPP 880B # PPP
ATMMPOA 884C # MultiProtocol over ATM
PPP_DISC 8863 # PPPoE discovery messages
PPP_SES 8864 # PPPoE session messages
ATMFATE 8884 # Frame-based ATM Transport over Ethernet
LOOP 9000 loopback # loop proto
+266
View File
@@ -0,0 +1,266 @@
# -*- Makefile -*-
top_builddir = @top_builddir@
builddir = @builddir@
top_srcdir = @top_srcdir@
srcdir = @srcdir@
ksourcedir = @ksourcedir@
prefix = @prefix@
exec_prefix = @exec_prefix@
libdir = @libdir@
libexecdir = @libexecdir@
xtlibdir = @xtlibdir@
AR = @AR@
CC = @CC@
CCLD = ${CC}
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
regular_CFLAGS = @regular_CFLAGS@
regular_CPPFLAGS = @regular_CPPFLAGS@
kinclude_CPPFLAGS = @kinclude_CPPFLAGS@
AM_CFLAGS = ${regular_CFLAGS}
AM_CPPFLAGS = ${regular_CPPFLAGS} \
-I${top_builddir}/include \
-I${top_builddir} \
-I${top_srcdir}/include \
-I${top_srcdir} \
${kinclude_CPPFLAGS} \
${CPPFLAGS} \
@libnetfilter_conntrack_CFLAGS@ \
@libnftnl_CFLAGS@
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
AM_LDFLAGS = @noundef_LDFLAGS@ @regular_LDFLAGS@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
am__v_AR_0 = @echo " AR " $@;
am__v_CC_0 = @echo " CC " $@;
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_GEN_0 = @echo " GEN " $@;
am__v_LN_0 = @echo " LN " $@;
am__v_AR_ = ${am__v_AR_@AM_DEFAULT_V@}
am__v_CC_ = ${am__v_CC_@AM_DEFAULT_V@}
am__v_CCLD_ = ${am__v_CCLD_@AM_DEFAULT_V@}
am__v_GEN_ = ${am__v_GEN_@AM_DEFAULT_V@}
am__v_LN_ = ${am__v_LN_@AM_DEFAULT_V@}
AM_V_AR = ${am__v_AR_@AM_V@}
AM_V_CC = ${am__v_CC_@AM_V@}
AM_V_CCLD = ${am__v_CCLD_@AM_V@}
AM_V_GEN = ${am__v_GEN_@AM_V@}
AM_V_LN = ${am__v_LN_@AM_V@}
#
# Wildcard module list
#
pfx_build_mod := $(patsubst ${srcdir}/libxt_%.c,%,$(sort $(wildcard ${srcdir}/libxt_*.c)))
@ENABLE_NFTABLES_TRUE@ pfb_build_mod := $(patsubst ${srcdir}/libebt_%.c,%,$(sort $(wildcard ${srcdir}/libebt_*.c)))
@ENABLE_NFTABLES_TRUE@ pfa_build_mod := $(patsubst ${srcdir}/libarpt_%.c,%,$(sort $(wildcard ${srcdir}/libarpt_*.c)))
pfx_symlinks := NOTRACK state REDIRECT MASQUERADE SNAT DNAT
@ENABLE_IPV4_TRUE@ pf4_build_mod := $(patsubst ${srcdir}/libipt_%.c,%,$(sort $(wildcard ${srcdir}/libipt_*.c)))
@ENABLE_IPV6_TRUE@ pf6_build_mod := $(patsubst ${srcdir}/libip6t_%.c,%,$(sort $(wildcard ${srcdir}/libip6t_*.c)))
pfx_build_mod := $(filter-out @blacklist_modules@ @blacklist_x_modules@,${pfx_build_mod})
pfb_build_mod := $(filter-out @blacklist_modules@ @blacklist_b_modules@,${pfb_build_mod})
pfa_build_mod := $(filter-out @blacklist_modules@ @blacklist_a_modules@,${pfa_build_mod})
pf4_build_mod := $(filter-out @blacklist_modules@ @blacklist_4_modules@,${pf4_build_mod})
pf6_build_mod := $(filter-out @blacklist_modules@ @blacklist_6_modules@,${pf6_build_mod})
pfx_objs := $(patsubst %,libxt_%.o,${pfx_build_mod})
pfb_objs := $(patsubst %,libebt_%.o,${pfb_build_mod})
pfa_objs := $(patsubst %,libarpt_%.o,${pfa_build_mod})
pf4_objs := $(patsubst %,libipt_%.o,${pf4_build_mod})
pf6_objs := $(patsubst %,libip6t_%.o,${pf6_build_mod})
pfx_solibs := $(patsubst %,libxt_%.so,${pfx_build_mod})
pfb_solibs := $(patsubst %,libebt_%.so,${pfb_build_mod})
pfa_solibs := $(patsubst %,libarpt_%.so,${pfa_build_mod})
pf4_solibs := $(patsubst %,libipt_%.so,${pf4_build_mod})
pf6_solibs := $(patsubst %,libip6t_%.so,${pf6_build_mod})
pfx_symlink_files := $(patsubst %,libxt_%.so,${pfx_symlinks})
#
# Building blocks
#
targets := libext.a libext4.a libext6.a libext_ebt.a libext_arpt.a matches.man targets.man
targets_install :=
@ENABLE_STATIC_TRUE@ libext_objs := ${pfx_objs}
@ENABLE_STATIC_TRUE@ libext_ebt_objs := ${pfb_objs}
@ENABLE_STATIC_TRUE@ libext_arpt_objs := ${pfa_objs}
@ENABLE_STATIC_TRUE@ libext4_objs := ${pf4_objs}
@ENABLE_STATIC_TRUE@ libext6_objs := ${pf6_objs}
@ENABLE_STATIC_FALSE@ targets += ${pfx_solibs} ${pfb_solibs} ${pf4_solibs} ${pf6_solibs} ${pfa_solibs} ${pfx_symlink_files}
@ENABLE_STATIC_FALSE@ targets_install += ${pfx_solibs} ${pfb_solibs} ${pf4_solibs} ${pf6_solibs} ${pfa_solibs}
@ENABLE_STATIC_FALSE@ symlinks_install := ${pfx_symlink_files}
.SECONDARY:
.PHONY: all install uninstall clean distclean FORCE dvi check installcheck
all: ${targets}
install: ${targets_install} ${symlinks_install}
@mkdir -p "${DESTDIR}${xtlibdir}";
if test -n "${targets_install}"; then \
install -pm0755 ${targets_install} "${DESTDIR}${xtlibdir}/"; \
fi;
if test -n "${symlinks_install}"; then \
cp -P ${symlinks_install} "${DESTDIR}${xtlibdir}/"; \
fi;
uninstall:
dir=${DESTDIR}${xtlibdir}; { \
test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; \
} || { \
test -z "${targets_install}" || ( \
cd "$$dir" && rm -f ${targets_install} \
); \
test -z "${symlinks_install}" || ( \
cd "$$dir" && rm -f ${symlinks_install} \
); \
rmdir -p --ignore-fail-on-non-empty "$$dir"; \
}
clean:
rm -f *.o *.oo *.so *.a matches.man targets.man
rm -f initext.c initext4.c initext6.c initextb.c initexta.c
rm -f .*.d .*.dd;
distclean: clean
init%.o: init%.c
${AM_V_CC} ${CC} ${AM_CPPFLAGS} ${AM_DEPFLAGS} ${AM_CFLAGS} -D_INIT=$*_init ${CFLAGS} -o $@ -c $<;
-include .*.d
#
# Shared libraries
#
lib%.so: lib%.oo
${AM_V_CCLD} ${CCLD} ${AM_LDFLAGS} ${LDFLAGS} -shared -o $@ $< -L../libxtables/.libs -lxtables ${$*_LIBADD};
lib%.oo: ${srcdir}/lib%.c
${AM_V_CC} ${CC} ${AM_CPPFLAGS} ${AM_DEPFLAGS} ${AM_CFLAGS} -D_INIT=lib$*_init -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
libxt_NOTRACK.so: libxt_CT.so
${AM_V_LN} ln -fs $< $@
libxt_state.so: libxt_conntrack.so
${AM_V_LN} ln -fs $< $@
libxt_REDIRECT.so: libxt_NAT.so
${AM_V_LN} ln -fs $< $@
libxt_MASQUERADE.so: libxt_NAT.so
${AM_V_LN} ln -fs $< $@
libxt_SNAT.so: libxt_NAT.so
${AM_V_LN} ln -fs $< $@
libxt_DNAT.so: libxt_NAT.so
${AM_V_LN} ln -fs $< $@
# Need the LIBADDs in iptables/Makefile.am too for libxtables_la_LIBADD
xt_RATEEST_LIBADD = -lm
xt_statistic_LIBADD = -lm
xt_connlabel_LIBADD = @libnetfilter_conntrack_LIBS@
#
# Static bits
#
# If static building is disabled, libext*.a will still be generated,
# but will be empty. This is good since we can do with less case
# handling code in the Makefiles.
#
lib%.o: ${srcdir}/lib%.c
${AM_V_CC} ${CC} ${AM_CPPFLAGS} ${AM_DEPFLAGS} ${AM_CFLAGS} -DNO_SHARED_LIBS=1 -D_INIT=lib$*_init ${CFLAGS} -o $@ -c $<;
libext.a: initext.o ${libext_objs}
${AM_V_AR} ${AR} crs $@ $^;
libext_ebt.a: initextb.o ${libext_ebt_objs}
${AM_V_AR} ${AR} crs $@ $^;
libext_arpt.a: initexta.o ${libext_arpt_objs}
${AM_V_AR} ${AR} crs $@ $^;
libext4.a: initext4.o ${libext4_objs}
${AM_V_AR} ${AR} crs $@ $^;
libext6.a: initext6.o ${libext6_objs}
${AM_V_AR} ${AR} crs $@ $^;
initext_func := $(addprefix xt_,${pfx_build_mod})
initextb_func := $(addprefix ebt_,${pfb_build_mod})
initexta_func := $(addprefix arpt_,${pfa_build_mod})
initext4_func := $(addprefix ipt_,${pf4_build_mod})
initext6_func := $(addprefix ip6t_,${pf6_build_mod})
initexts := ext exta extb ext4 ext6
initext_depfiles = $(patsubst %,.init%.dd,${initexts})
initext_sources = $(patsubst %,init%.c,${initexts})
${initext_depfiles}: FORCE
@echo "$(value $(patsubst .%.dd,%,$@)_func)" >$@.tmp; \
cmp -s $@ $@.tmp || mv $@.tmp $@; \
rm -f $@.tmp;
${initext_sources}: %.c: .%.dd
${AM_V_GEN}
@( \
initext_func="$(value $(basename $@)_func)"; \
funcname="init_extensions$(patsubst initext%.c,%,$@)"; \
echo "" >$@; \
for i in $${initext_func}; do \
echo "extern void lib$${i}_init(void);" >>$@; \
done; \
echo "void $${funcname}(void);" >>$@; \
echo "void $${funcname}(void)" >>$@; \
echo "{" >>$@; \
for i in $${initext_func}; do \
echo " ""lib$${i}_init();" >>$@; \
done; \
echo "}" >>$@; \
);
#
# Manual pages
#
ex_matches = $(shell echo ${1} | LC_ALL=POSIX grep -Eo '\b[[:lower:][:digit:]_]+\b')
ex_targets = $(shell echo ${1} | LC_ALL=POSIX grep -Eo '\b[[:upper:][:digit:]_]+\b')
man_run = \
${AM_V_GEN} \
for ext in $(sort ${1}); do \
f="${srcdir}/libxt_$$ext.man"; \
if [ -f "$$f" ]; then \
printf "\t+ $$f\n" >&2; \
echo ".SS $$ext"; \
cat "$$f" || exit $$?; \
fi; \
f="${srcdir}/libip6t_$$ext.man"; \
if [ -f "$$f" ]; then \
printf "\t+ $$f\n" >&2; \
echo ".SS $$ext (IPv6-specific)"; \
cat "$$f" || exit $$?; \
fi; \
f="${srcdir}/libipt_$$ext.man"; \
if [ -f "$$f" ]; then \
printf "\t+ $$f\n" >&2; \
echo ".SS $$ext (IPv4-specific)"; \
cat "$$f" || exit $$?; \
fi; \
done >$@;
matches.man: ${initext_depfiles} $(wildcard ${srcdir}/lib*.man)
$(call man_run,$(call ex_matches,${pfx_build_mod} ${pfb_build_mod} ${pfa_build_mod} ${pf4_build_mod} ${pf6_build_mod} ${pfx_symlinks}))
targets.man: ${initext_depfiles} $(wildcard ${srcdir}/lib*.man)
$(call man_run,$(call ex_targets,${pfx_build_mod} ${pfb_build_mod} ${pfa_build_mod} ${pf4_build_mod} ${pf6_build_mod} ${pfx_symlinks}))
dist_initext_src = $(addprefix $(srcdir)/,${initext_sources})
dist_sources = $(filter-out ${dist_initext_src},$(wildcard $(srcdir)/*.[ch]))
distdir:
mkdir -p $(distdir)
cp -p ${dist_sources} $(distdir)/
cp -p $(wildcard ${srcdir}/lib*.man) $(distdir)/
cp -p $(wildcard ${srcdir}/*.t ${srcdir}/*.txlate) $(distdir)/
dvi:
check: all
installcheck:
+79
View File
@@ -0,0 +1,79 @@
/*
* DiffServ classname <-> DiffServ codepoint mapping functions.
*
* The latest list of the mappings can be found at:
* <http://www.iana.org/assignments/dscp-registry>
*
* This code is released under the GNU GPL v2, 1991
*
* Author: Iain Barnes
*/
#include <stdio.h>
#include <string.h>
#include <xtables.h>
static const struct ds_class
{
const char *name;
unsigned int dscp;
} ds_classes[] =
{
{ "CS0", 0x00 },
{ "CS1", 0x08 },
{ "CS2", 0x10 },
{ "CS3", 0x18 },
{ "CS4", 0x20 },
{ "CS5", 0x28 },
{ "CS6", 0x30 },
{ "CS7", 0x38 },
{ "BE", 0x00 },
{ "AF11", 0x0a },
{ "AF12", 0x0c },
{ "AF13", 0x0e },
{ "AF21", 0x12 },
{ "AF22", 0x14 },
{ "AF23", 0x16 },
{ "AF31", 0x1a },
{ "AF32", 0x1c },
{ "AF33", 0x1e },
{ "AF41", 0x22 },
{ "AF42", 0x24 },
{ "AF43", 0x26 },
{ "EF", 0x2e }
};
static unsigned int
class_to_dscp(const char *name)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(ds_classes); i++) {
if (!strncasecmp(name, ds_classes[i].name,
strlen(ds_classes[i].name)))
return ds_classes[i].dscp;
}
xtables_error(PARAMETER_PROBLEM,
"Invalid DSCP value `%s'", name);
}
#if 0
static const char *
dscp_to_name(unsigned int dscp)
{
int i;
for (i = 0; i < ARRAY_SIZE(ds_classes); ++i)
if (dscp == ds_classes[i].dscp)
return ds_classes[i].name;
xtables_error(PARAMETER_PROBLEM,
"Invalid DSCP value `%d'", dscp);
}
#endif
+126
View File
@@ -0,0 +1,126 @@
arptables-translate -A OUTPUT --proto-type ipv4 -s 1.2.3.4 -j ACCEPT
nft 'add rule arp filter OUTPUT arp htype 1 arp hlen 6 arp plen 4 arp ptype 0x800 arp saddr ip 1.2.3.4 counter accept'
arptables-translate -I OUTPUT -o oifname
nft 'insert rule arp filter OUTPUT oifname "oifname" arp htype 1 arp hlen 6 arp plen 4 counter'
iptables-translate -I OUTPUT -p udp -d 8.8.8.8 -j ACCEPT
nft 'insert rule ip filter OUTPUT ip protocol udp ip daddr 8.8.8.8 counter accept'
iptables-translate -F -t nat
nft flush table ip nat
iptables-translate -I INPUT -i iifname -s 10.0.0.0/8
nft 'insert rule ip filter INPUT iifname "iifname" ip saddr 10.0.0.0/8 counter'
iptables-translate -A INPUT -i iif+ ! -d 10.0.0.0/8
nft 'add rule ip filter INPUT iifname "iif*" ip daddr != 10.0.0.0/8 counter'
iptables-translate -I INPUT -s 10.11.12.13/255.255.0.0
nft 'insert rule ip filter INPUT ip saddr 10.11.0.0/16 counter'
iptables-translate -I INPUT -s 10.11.12.13/255.0.255.0
nft 'insert rule ip filter INPUT ip saddr & 255.0.255.0 == 10.0.12.0 counter'
iptables-translate -I INPUT -s 10.11.12.13/0.255.0.255
nft 'insert rule ip filter INPUT ip saddr & 0.255.0.255 == 0.11.0.13 counter'
iptables-translate -I INPUT ! -s 10.11.12.13/0.255.0.255
nft 'insert rule ip filter INPUT ip saddr & 0.255.0.255 != 0.11.0.13 counter'
iptables-translate -I INPUT -s 0.0.0.0/16
nft 'insert rule ip filter INPUT ip saddr 0.0.0.0/16 counter'
iptables-translate -I INPUT -s 0.0.0.0/0
nft 'insert rule ip filter INPUT counter'
iptables-translate -I INPUT ! -s 0.0.0.0/0
nft 'insert rule ip filter INPUT ip saddr != 0.0.0.0/0 counter'
ip6tables-translate -I INPUT -i iifname -s feed::/16
nft 'insert rule ip6 filter INPUT iifname "iifname" ip6 saddr feed::/16 counter'
ip6tables-translate -A INPUT -i iif+ ! -d feed::/16
nft 'add rule ip6 filter INPUT iifname "iif*" ip6 daddr != feed::/16 counter'
ip6tables-translate -I INPUT -s feed:babe::1/ffff:ff00::
nft 'insert rule ip6 filter INPUT ip6 saddr feed:ba00::/24 counter'
ip6tables-translate -I INPUT -s feed:babe:c0ff:ee00:c0be:1234:5678:90ab/ffff:0:ffff:0:ffff:0:ffff:0
nft 'insert rule ip6 filter INPUT ip6 saddr & ffff:0:ffff:0:ffff:0:ffff:0 == feed:0:c0ff:0:c0be:0:5678:0 counter'
ip6tables-translate -I INPUT -s feed:babe:c0ff:ee00:c0be:1234:5678:90ab/0:ffff:0:ffff:0:ffff:0:ffff
nft 'insert rule ip6 filter INPUT ip6 saddr & 0:ffff:0:ffff:0:ffff:0:ffff == 0:babe:0:ee00:0:1234:0:90ab counter'
ip6tables-translate -I INPUT ! -s feed:babe:c0ff:ee00:c0be:1234:5678:90ab/0:ffff:0:ffff:0:ffff:0:ffff
nft 'insert rule ip6 filter INPUT ip6 saddr & 0:ffff:0:ffff:0:ffff:0:ffff != 0:babe:0:ee00:0:1234:0:90ab counter'
ip6tables-translate -I INPUT -s ::/16
nft 'insert rule ip6 filter INPUT ip6 saddr ::/16 counter'
ip6tables-translate -I INPUT -s ::/0
nft 'insert rule ip6 filter INPUT counter'
ip6tables-translate -I INPUT ! -s ::/0
nft 'insert rule ip6 filter INPUT ip6 saddr != ::/0 counter'
iptables-translate -A FORWARD -p 132
nft 'add rule ip filter FORWARD ip protocol sctp counter'
ip6tables-translate -A FORWARD -p 132
nft 'add rule ip6 filter FORWARD meta l4proto sctp counter'
iptables-translate -A FORWARD ! -p 132
nft 'add rule ip filter FORWARD ip protocol != sctp counter'
ip6tables-translate -A FORWARD ! -p 132
nft 'add rule ip6 filter FORWARD meta l4proto != sctp counter'
iptables-translate -A FORWARD -p 141
nft 'add rule ip filter FORWARD ip protocol 141 counter'
ip6tables-translate -A FORWARD -p 141
nft 'add rule ip6 filter FORWARD meta l4proto 141 counter'
iptables-translate -A FORWARD ! -p 141
nft 'add rule ip filter FORWARD ip protocol != 141 counter'
ip6tables-translate -A FORWARD ! -p 141
nft 'add rule ip6 filter FORWARD meta l4proto != 141 counter'
iptables-translate -A FORWARD -m tcp --dport 22 -p tcp
nft 'add rule ip filter FORWARD tcp dport 22 counter'
ip6tables-translate -A FORWARD -m tcp --dport 22 -p tcp
nft 'add rule ip6 filter FORWARD tcp dport 22 counter'
ebtables-translate -I INPUT -i iname --logical-in ilogname -s 0:0:0:0:0:0
nft 'insert rule bridge filter INPUT iifname "iname" meta ibrname "ilogname" ether saddr 00:00:00:00:00:00 counter'
ebtables-translate -A FORWARD ! -i iname --logical-in ilogname -o out+ --logical-out lout+ -d 1:2:3:4:de:af
nft 'add rule bridge filter FORWARD iifname != "iname" meta ibrname "ilogname" oifname "out*" meta obrname "lout*" ether daddr 01:02:03:04:de:af counter'
ebtables-translate -I INPUT -p ip -d 1:2:3:4:5:6/ff:ff:ff:ff:00:00
nft 'insert rule bridge filter INPUT ether type 0x800 ether daddr and ff:ff:ff:ff:00:00 == 01:02:03:04:00:00 counter'
ebtables-translate -I INPUT -p Length
nft 'insert rule bridge filter INPUT ether type < 0x0600 counter'
ebtables-translate -I INPUT -p ! Length
nft 'insert rule bridge filter INPUT ether type >= 0x0600 counter'
# asterisk is not special in iptables and it is even a valid interface name
iptables-translate -A FORWARD -i * -o eth*foo
nft 'add rule ip filter FORWARD iifname "\*" oifname "eth*foo" counter'
# escape only suffix asterisk and translate only the last plus character
iptables-translate -A FORWARD -i eth*foo*+ -o eth++
nft 'add rule ip filter FORWARD iifname "eth*foo**" oifname "eth+*" counter'
# skip for always matching interface names
iptables-translate -A FORWARD -i +
nft 'add rule ip filter FORWARD counter'
# match against invalid interface name to simulate never matching rule
iptables-translate -A FORWARD ! -i +
nft 'add rule ip filter FORWARD iifname "INVAL/D" counter'
+13
View File
@@ -0,0 +1,13 @@
:FORWARD
-i alongifacename0;=;OK
-i thisinterfaceistoolong0;;FAIL
-i eth+ -o alongifacename+;=;OK
! -i eth0;=;OK
! -o eth+;=;OK
-i + -j ACCEPT;-j ACCEPT;OK
! -i +;=;OK
-c "";;FAIL
-c ,3;;FAIL
-c 3,;;FAIL
-c ,;;FAIL
-c 2,3 -j ACCEPT;-j ACCEPT;OK
+4
View File
@@ -0,0 +1,4 @@
:OUTPUT
-o lo --destination-mac 11:22:33:44:55:66;-o lo --dst-mac 11:22:33:44:55:66;OK
--dst-mac Broadcast ;--dst-mac ff:ff:ff:ff:ff:ff;OK
! -o eth+ -d 1.2.3.4/24 -j CLASSIFY --set-class 0:0;-j CLASSIFY ! -o eth+ -d 1.2.3.0/24 --set-class 0:0;OK
+4
View File
@@ -0,0 +1,4 @@
:INPUT,OUTPUT
-j MARK -d 0.0.0.0/8 --set-mark 1;=;OK
-s ! 0.0.0.0 -j MARK --and-mark 0x17;-j MARK ! -s 0.0.0.0 --and-mark 17;OK
-j MARK -s 0.0.0.0 --or-mark 17;=;OK
+199
View File
@@ -0,0 +1,199 @@
/*
* Arturo Borrero Gonzalez <arturo@debian.org> adapted
* this code to libxtables for arptables-compat in 2015
*/
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <getopt.h>
#include <netinet/ether.h>
#include <xtables.h>
#include <linux/netfilter_arp/arpt_mangle.h>
#include "iptables/nft.h"
static void arpmangle_print_help(void)
{
printf(
"mangle target options:\n"
"--mangle-ip-s IP address\n"
"--mangle-ip-d IP address\n"
"--mangle-mac-s MAC address\n"
"--mangle-mac-d MAC address\n"
"--mangle-target target (DROP, CONTINUE or ACCEPT -- default is ACCEPT)\n");
}
/* internal use only, explicitly not covered by ARPT_MANGLE_MASK */
#define ARPT_MANGLE_TARGET 0x10
static const struct xt_option_entry arpmangle_opts[] = {
{ .name = "mangle-ip-s", .id = ARPT_MANGLE_SIP, .type = XTTYPE_HOSTMASK },
{ .name = "mangle-ip-d", .id = ARPT_MANGLE_TIP, .type = XTTYPE_HOSTMASK },
{ .name = "mangle-mac-s", .id = ARPT_MANGLE_SDEV, .type = XTTYPE_ETHERMAC },
{ .name = "mangle-mac-d", .id = ARPT_MANGLE_TDEV, .type = XTTYPE_ETHERMAC },
{ .name = "mangle-target", .id = ARPT_MANGLE_TARGET, .type = XTTYPE_STRING },
XTOPT_TABLEEND,
};
static void arpmangle_init(struct xt_entry_target *target)
{
struct arpt_mangle *mangle = (struct arpt_mangle *)target->data;
mangle->target = NF_ACCEPT;
}
static void assert_hopts(const struct arpt_entry *e, const char *optname)
{
if (e->arp.arhln_mask == 0)
xtables_error(PARAMETER_PROBLEM, "no --h-length defined");
if (e->arp.invflags & IPT_INV_ARPHLN)
xtables_error(PARAMETER_PROBLEM,
"! hln not allowed for --%s", optname);
if (e->arp.arhln != 6)
xtables_error(PARAMETER_PROBLEM, "only --h-length 6 supported");
}
static void arpmangle_parse(struct xt_option_call *cb)
{
const struct arpt_entry *e = cb->xt_entry;
struct arpt_mangle *mangle = cb->data;
xtables_option_parse(cb);
mangle->flags |= (cb->entry->id & ARPT_MANGLE_MASK);
switch (cb->entry->id) {
case ARPT_MANGLE_SIP:
mangle->u_s.src_ip = cb->val.haddr.in;
break;
case ARPT_MANGLE_TIP:
mangle->u_t.tgt_ip = cb->val.haddr.in;
break;
case ARPT_MANGLE_SDEV:
assert_hopts(e, cb->entry->name);
memcpy(mangle->src_devaddr, cb->val.ethermac, ETH_ALEN);
case ARPT_MANGLE_TDEV:
assert_hopts(e, cb->entry->name);
memcpy(mangle->tgt_devaddr, cb->val.ethermac, ETH_ALEN);
break;
case ARPT_MANGLE_TARGET:
if (!strcmp(cb->arg, "DROP"))
mangle->target = NF_DROP;
else if (!strcmp(cb->arg, "ACCEPT"))
mangle->target = NF_ACCEPT;
else if (!strcmp(cb->arg, "CONTINUE"))
mangle->target = XT_CONTINUE;
else
xtables_error(PARAMETER_PROBLEM,
"bad target for --mangle-target");
break;
}
}
static const char *ipaddr_to(const struct in_addr *addrp, int numeric)
{
if (numeric)
return xtables_ipaddr_to_numeric(addrp);
else
return xtables_ipaddr_to_anyname(addrp);
}
static void
arpmangle_print(const void *ip, const struct xt_entry_target *target,
int numeric)
{
struct arpt_mangle *m = (struct arpt_mangle *)(target->data);
if (m->flags & ARPT_MANGLE_SIP) {
printf(" --mangle-ip-s %s",
ipaddr_to(&(m->u_s.src_ip), numeric));
}
if (m->flags & ARPT_MANGLE_SDEV) {
printf(" --mangle-mac-s ");
xtables_print_mac((unsigned char *)m->src_devaddr);
}
if (m->flags & ARPT_MANGLE_TIP) {
printf(" --mangle-ip-d %s",
ipaddr_to(&(m->u_t.tgt_ip), numeric));
}
if (m->flags & ARPT_MANGLE_TDEV) {
printf(" --mangle-mac-d ");
xtables_print_mac((unsigned char *)m->tgt_devaddr);
}
if (m->target != NF_ACCEPT) {
printf(" --mangle-target %s",
m->target == NF_DROP ? "DROP" : "CONTINUE");
}
}
static void arpmangle_save(const void *ip, const struct xt_entry_target *target)
{
arpmangle_print(ip, target, 0);
}
static void print_devaddr_xlate(const char *macaddress, struct xt_xlate *xl)
{
unsigned int i;
xt_xlate_add(xl, "%02x", macaddress[0]);
for (i = 1; i < ETH_ALEN; ++i)
xt_xlate_add(xl, ":%02x", macaddress[i]);
}
static int arpmangle_xlate(struct xt_xlate *xl,
const struct xt_xlate_tg_params *params)
{
const struct arpt_mangle *m = (const void *)params->target->data;
if (m->flags & ARPT_MANGLE_SIP)
xt_xlate_add(xl, "arp saddr ip set %s ",
xtables_ipaddr_to_numeric(&m->u_s.src_ip));
if (m->flags & ARPT_MANGLE_SDEV) {
xt_xlate_add(xl, "arp %caddr ether set ", 's');
print_devaddr_xlate(m->src_devaddr, xl);
}
if (m->flags & ARPT_MANGLE_TIP)
xt_xlate_add(xl, "arp daddr ip set %s ",
xtables_ipaddr_to_numeric(&m->u_t.tgt_ip));
if (m->flags & ARPT_MANGLE_TDEV) {
xt_xlate_add(xl, "arp %caddr ether set ", 'd');
print_devaddr_xlate(m->tgt_devaddr, xl);
}
switch (m->target) {
case NF_ACCEPT:
xt_xlate_add(xl, "accept");
break;
case NF_DROP:
xt_xlate_add(xl, "drop");
break;
default:
break;
}
return 1;
}
static struct xtables_target arpmangle_target = {
.name = "mangle",
.revision = 0,
.version = XTABLES_VERSION,
.family = NFPROTO_ARP,
.size = XT_ALIGN(sizeof(struct arpt_mangle)),
.userspacesize = XT_ALIGN(sizeof(struct arpt_mangle)),
.help = arpmangle_print_help,
.init = arpmangle_init,
.x6_parse = arpmangle_parse,
.print = arpmangle_print,
.save = arpmangle_save,
.x6_options = arpmangle_opts,
.xlate = arpmangle_xlate,
};
void _init(void)
{
xtables_register_target(&arpmangle_target);
}
+9
View File
@@ -0,0 +1,9 @@
:OUTPUT
-j mangle -s 1.2.3.4 --mangle-ip-s 1.2.3.5;=;OK
-j mangle -d 1.2.3.4 --mangle-ip-d 1.2.3.5;=;OK
-j mangle -d 1.2.3.4 --mangle-mac-d 00:01:02:03:04:05;=;OK
-d 1.2.3.4 --h-length 5 -j mangle --mangle-mac-s 00:01:02:03:04:05;=;FAIL
-j mangle --mangle-ip-s 1.2.3.4 --mangle-target DROP;=;OK
-j mangle --mangle-ip-s 1.2.3.4 --mangle-target ACCEPT;-j mangle --mangle-ip-s 1.2.3.4;OK
-j mangle --mangle-ip-s 1.2.3.4 --mangle-target CONTINUE;=;OK
-j mangle --mangle-ip-s 1.2.3.4 --mangle-target FOO;=;FAIL
+6
View File
@@ -0,0 +1,6 @@
arptables-translate -A OUTPUT -d 10.21.22.129 -j mangle --mangle-ip-s 10.21.22.161
nft 'add rule arp filter OUTPUT arp htype 1 arp hlen 6 arp plen 4 arp daddr ip 10.21.22.129 counter arp saddr ip set 10.21.22.161 accept'
arptables-translate -A OUTPUT -d 10.2.22.129/24 -j mangle --mangle-ip-d 10.2.22.1 --mangle-target CONTINUE
nft 'add rule arp filter OUTPUT arp htype 1 arp hlen 6 arp plen 4 arp daddr ip 10.2.22.0/24 counter arp daddr ip set 10.2.22.1'
arptables-translate -A OUTPUT -d 10.2.22.129/24 -j mangle --mangle-ip-d 10.2.22.1 --mangle-mac-d a:b:c:d:e:f
nft 'add rule arp filter OUTPUT arp htype 1 arp hlen 6 arp plen 4 arp daddr ip 10.2.22.0/24 counter arp daddr ip set 10.2.22.1 arp daddr ether set 0a:0b:0c:0d:0e:0f accept'
+25
View File
@@ -0,0 +1,25 @@
:INPUT
-s 192.168.0.1;=;OK
-s 0.0.0.0/8;=;OK
-s ! 0.0.0.0;! -s 0.0.0.0;OK
-d 192.168.0.1;=;OK
! -d 0.0.0.0;=;OK
-d 0.0.0.0/24;=;OK
-j DROP -i lo;=;OK
-j ACCEPT ! -i lo;=;OK
-i ppp+;=;OK
! -i ppp+;=;OK
-i + -j ACCEPT;-j ACCEPT;OK
! -i +;=;OK
-i lo --destination-mac 11:22:33:44:55:66;-i lo --dst-mac 11:22:33:44:55:66;OK
--source-mac Unicast;--src-mac 00:00:00:00:00:00/01:00:00:00:00:00;OK
! --src-mac Multicast;! --src-mac 01:00:00:00:00:00/01:00:00:00:00:00;OK
--src-mac=01:02:03:04:05:06 --dst-mac=07:08:09:0A:0B:0C --h-length=6 --opcode=Request --h-type=Ethernet --proto-type=ipv4;--src-mac 01:02:03:04:05:06 --dst-mac 07:08:09:0a:0b:0c --opcode 1 --proto-type 0x800;OK
--src-mac ! 01:02:03:04:05:06 --dst-mac ! 07:08:09:0A:0B:0C --h-length ! 6 --opcode ! Request --h-type ! Ethernet --proto-type ! ipv4;! --src-mac 01:02:03:04:05:06 ! --dst-mac 07:08:09:0a:0b:0c ! --h-length 6 ! --opcode 1 ! --h-type 0x1 ! --proto-type 0x800;OK
--h-type 10;--h-type 0x10;OK
--h-type 0x10;=;OK
--proto-type 10;--proto-type 0xa;OK
--proto-type 10/10;--proto-type 0xa/0xa;OK
--proto-type 0x10;=;OK
--proto-type 0x10/0x10;=;OK
--h-length 6/15 --opcode 1/235 --h-type 0x8/0xcf --proto-type 0x800/0xde00;=;OK
+86
View File
@@ -0,0 +1,86 @@
/* 802_3
*
* Author:
* Chris Vitale <csv@bluetail.com>
*
* May 2003
*
* Adapted by Arturo Borrero Gonzalez <arturo@debian.org>
* to use libxtables for ebtables-compat
*/
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <xtables.h>
#include <linux/netfilter_bridge/ebt_802_3.h>
static const struct xt_option_entry br802_3_opts[] =
{
{ .name = "802_3-sap", .id = EBT_802_3_SAP,
.type = XTTYPE_UINT8, .base = 16,
.flags = XTOPT_INVERT | XTOPT_PUT,
XTOPT_POINTER(struct ebt_802_3_info, sap) },
{ .name = "802_3-type", .id = EBT_802_3_TYPE,
.type = XTTYPE_UINT16, .base = 16,
.flags = XTOPT_INVERT | XTOPT_PUT | XTOPT_NBO,
XTOPT_POINTER(struct ebt_802_3_info, type) },
XTOPT_TABLEEND,
};
static void br802_3_print_help(void)
{
printf(
"802_3 options:\n"
"[!] --802_3-sap protocol : 802.3 DSAP/SSAP- 1 byte value (hex)\n"
" DSAP and SSAP are always the same. One SAP applies to both fields\n"
"[!] --802_3-type protocol : 802.3 SNAP Type- 2 byte value (hex)\n"
" Type implies SAP value 0xaa\n");
}
static void br802_3_parse(struct xt_option_call *cb)
{
struct ebt_802_3_info *info = cb->data;
xtables_option_parse(cb);
info->bitmask |= cb->entry->id;
if (cb->invert)
info->invflags |= cb->entry->id;
}
static void br802_3_print(const void *ip, const struct xt_entry_match *match,
int numeric)
{
struct ebt_802_3_info *info = (struct ebt_802_3_info *)match->data;
if (info->bitmask & EBT_802_3_SAP) {
if (info->invflags & EBT_802_3_SAP)
printf("! ");
printf("--802_3-sap 0x%.2x ", info->sap);
}
if (info->bitmask & EBT_802_3_TYPE) {
if (info->invflags & EBT_802_3_TYPE)
printf("! ");
printf("--802_3-type 0x%.4x ", ntohs(info->type));
}
}
static struct xtables_match br802_3_match =
{
.name = "802_3",
.revision = 0,
.version = XTABLES_VERSION,
.family = NFPROTO_BRIDGE,
.size = XT_ALIGN(sizeof(struct ebt_802_3_info)),
.userspacesize = XT_ALIGN(sizeof(struct ebt_802_3_info)),
.help = br802_3_print_help,
.x6_parse = br802_3_parse,
.print = br802_3_print,
.x6_options = br802_3_opts,
};
void _init(void)
{
xtables_register_match(&br802_3_match);
}
+7
View File
@@ -0,0 +1,7 @@
:INPUT,FORWARD,OUTPUT
! --802_3-sap 0x0a -j CONTINUE;=;FAIL
--802_3-type 0x000a -j RETURN;=;FAIL
-p Length --802_3-sap 0x0a -j CONTINUE;=;OK
-p Length ! --802_3-sap 0x0a -j CONTINUE;=;OK
-p Length --802_3-type 0x000a -j RETURN;=;OK
-p Length ! --802_3-type 0x000a -j RETURN;=;OK
+241
View File
@@ -0,0 +1,241 @@
/* ebt_among
*
* Authors:
* Grzegorz Borowiak <grzes@gnu.univ.gda.pl>
*
* August, 2003
*/
#include <errno.h>
#include <ctype.h>
#include <fcntl.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <xtables.h>
#include <arpa/inet.h>
#include <netinet/ether.h>
#include <netinet/in.h>
#include <linux/if_ether.h>
#include <linux/netfilter_bridge/ebt_among.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include "iptables/nft.h"
#include "iptables/nft-bridge.h"
#define AMONG_DST '1'
#define AMONG_SRC '2'
#define AMONG_DST_F '3'
#define AMONG_SRC_F '4'
static const struct option bramong_opts[] = {
{"among-dst", required_argument, 0, AMONG_DST},
{"among-src", required_argument, 0, AMONG_SRC},
{"among-dst-file", required_argument, 0, AMONG_DST_F},
{"among-src-file", required_argument, 0, AMONG_SRC_F},
{0}
};
static void bramong_print_help(void)
{
printf(
"`among' options:\n"
"[!] --among-dst list : matches if ether dst is in list\n"
"[!] --among-src list : matches if ether src is in list\n"
"[!] --among-dst-file file : obtain dst list from file\n"
"[!] --among-src-file file : obtain src list from file\n"
"list has form:\n"
" xx:xx:xx:xx:xx:xx[=ip.ip.ip.ip],yy:yy:yy:yy:yy:yy[=ip.ip.ip.ip]"
",...,zz:zz:zz:zz:zz:zz[=ip.ip.ip.ip][,]\n"
"Things in brackets are optional.\n"
"If you want to allow two (or more) IP addresses to one MAC address, you\n"
"can specify two (or more) pairs with the same MAC, e.g.\n"
" 00:00:00:fa:eb:fe=153.19.120.250,00:00:00:fa:eb:fe=192.168.0.1\n"
);
}
static void
parse_nft_among_pair(char *buf, struct nft_among_pair *pair, bool have_ip)
{
char *sep = index(buf, '=');
struct ether_addr *ether;
if (sep) {
*sep = '\0';
if (!inet_pton(AF_INET, sep + 1, &pair->in))
xtables_error(PARAMETER_PROBLEM,
"Invalid IP address '%s'", sep + 1);
}
ether = ether_aton(buf);
if (!ether)
xtables_error(PARAMETER_PROBLEM,
"Invalid MAC address '%s'", buf);
memcpy(&pair->ether, ether, sizeof(*ether));
}
static void
parse_nft_among_pairs(struct nft_among_pair *pairs, char *buf,
size_t cnt, bool have_ip)
{
size_t tmpcnt = 0;
buf = strtok(buf, ",");
while (buf) {
struct nft_among_pair pair = {};
parse_nft_among_pair(buf, &pair, have_ip);
nft_among_insert_pair(pairs, &tmpcnt, &pair);
buf = strtok(NULL, ",");
}
}
static size_t count_nft_among_pairs(char *buf)
{
size_t cnt = 0;
char *p = buf;
if (!*buf)
return 0;
do {
cnt++;
p = index(++p, ',');
} while (p);
return cnt;
}
static bool nft_among_pairs_have_ip(char *buf)
{
return !!index(buf, '=');
}
static int bramong_parse(int c, char **argv, int invert,
unsigned int *flags, const void *entry,
struct xt_entry_match **match)
{
struct nft_among_data *data = (struct nft_among_data *)(*match)->data;
bool have_ip, dst = false;
size_t new_size, cnt;
struct stat stats;
int fd = -1, poff;
long flen = 0;
switch (c) {
case AMONG_DST_F:
dst = true;
/* fall through */
case AMONG_SRC_F:
if ((fd = open(optarg, O_RDONLY)) == -1)
xtables_error(PARAMETER_PROBLEM,
"Couldn't open file '%s'", optarg);
if (fstat(fd, &stats) < 0)
xtables_error(PARAMETER_PROBLEM,
"fstat(%s) failed: '%s'",
optarg, strerror(errno));
flen = stats.st_size;
/* use mmap because the file will probably be big */
optarg = mmap(0, flen, PROT_READ | PROT_WRITE,
MAP_PRIVATE, fd, 0);
if (optarg == MAP_FAILED)
xtables_error(PARAMETER_PROBLEM,
"Couldn't map file to memory");
if (optarg[flen-1] != '\n')
xtables_error(PARAMETER_PROBLEM,
"File should end with a newline");
if (strchr(optarg, '\n') != optarg+flen-1)
xtables_error(PARAMETER_PROBLEM,
"File should only contain one line");
optarg[flen-1] = '\0';
break;
case AMONG_DST:
dst = true;
/* fall through */
case AMONG_SRC:
break;
default:
return 0;
}
cnt = count_nft_among_pairs(optarg);
if (cnt == 0)
return 0;
new_size = data->src.cnt + data->dst.cnt + cnt;
new_size *= sizeof(struct nft_among_pair);
new_size += XT_ALIGN(sizeof(struct xt_entry_match)) +
sizeof(struct nft_among_data);
if (new_size > (*match)->u.match_size) {
*match = xtables_realloc(*match, new_size);
(*match)->u.match_size = new_size;
data = (struct nft_among_data *)(*match)->data;
}
have_ip = nft_among_pairs_have_ip(optarg);
poff = nft_among_prepare_data(data, dst, cnt, invert, have_ip);
parse_nft_among_pairs(data->pairs + poff, optarg, cnt, have_ip);
if (c == AMONG_DST_F || c == AMONG_SRC_F) {
munmap(argv, flen);
close(fd);
}
return 1;
}
static void __bramong_print(struct nft_among_pair *pairs,
int cnt, bool have_ip)
{
char abuf[INET_ADDRSTRLEN];
const char *isep = "";
int i;
for (i = 0; i < cnt; i++) {
printf("%s", isep);
isep = ",";
printf("%s", ether_ntoa(&pairs[i].ether));
if (pairs[i].in.s_addr != INADDR_ANY)
printf("=%s", inet_ntop(AF_INET, &pairs[i].in,
abuf, sizeof(abuf)));
}
printf(" ");
}
static void bramong_print(const void *ip, const struct xt_entry_match *match,
int numeric)
{
struct nft_among_data *data = (struct nft_among_data *)match->data;
if (data->src.cnt) {
printf("%s--among-src ", data->src.inv ? "! " : "");
__bramong_print(data->pairs, data->src.cnt, data->src.ip);
}
if (data->dst.cnt) {
printf("%s--among-dst ", data->dst.inv ? "! " : "");
__bramong_print(data->pairs + data->src.cnt,
data->dst.cnt, data->dst.ip);
}
}
static struct xtables_match bramong_match = {
.name = "among",
.revision = 0,
.version = XTABLES_VERSION,
.family = NFPROTO_BRIDGE,
.size = XT_ALIGN(sizeof(struct nft_among_data)),
.userspacesize = XT_ALIGN(sizeof(struct nft_among_data)),
.help = bramong_print_help,
.parse = bramong_parse,
.print = bramong_print,
.extra_opts = bramong_opts,
};
void _init(void)
{
xtables_register_match(&bramong_match);
}
+16
View File
@@ -0,0 +1,16 @@
:INPUT,FORWARD,OUTPUT
--among-dst de:ad:0:be:ee:ff,c0:ff:ee:0:ba:be;--among-dst c0:ff:ee:0:ba:be,de:ad:0:be:ee:ff;OK
! --among-dst c0:ff:ee:0:ba:be,de:ad:0:be:ee:ff;=;OK
--among-src be:ef:0:c0:ff:ee,c0:ff:ee:0:ba:be,de:ad:0:be:ee:ff;=;OK
--among-src de:ad:0:be:ee:ff=10.0.0.1,c0:ff:ee:0:ba:be=192.168.1.1;--among-src c0:ff:ee:0:ba:be=192.168.1.1,de:ad:0:be:ee:ff=10.0.0.1;OK
! --among-src c0:ff:ee:0:ba:be=192.168.1.1,de:ad:0:be:ee:ff=10.0.0.1;=;OK
--among-src de:ad:0:be:ee:ff --among-dst c0:ff:ee:0:ba:be;=;OK
--among-src de:ad:0:be:ee:ff=10.0.0.1 --among-dst c0:ff:ee:0:ba:be=192.168.1.1;=;OK
! --among-src de:ad:0:be:ee:ff --among-dst c0:ff:ee:0:ba:be;=;OK
--among-src de:ad:0:be:ee:ff=10.0.0.1 ! --among-dst c0:ff:ee:0:ba:be=192.168.1.1;=;OK
! --among-src de:ad:0:be:ee:ff --among-dst c0:ff:ee:0:ba:be=192.168.1.1;=;OK
--among-src de:ad:0:be:ee:ff=10.0.0.1 ! --among-dst c0:ff:ee:0:ba:be=192.168.1.1;=;OK
--among-src;=;FAIL
--among-src 00:11=10.0.0.1;=;FAIL
--among-src de:ad:0:be:ee:ff=10.256.0.1;=;FAIL
--among-src c0:ff:ee:0:ba:be=192.168.1.1,de:ad:0:be:ee:ff;=;OK
+230
View File
@@ -0,0 +1,230 @@
/* ebt_arp
*
* Authors:
* Bart De Schuymer <bdschuym@pandora.be>
* Tim Gardner <timg@tpi.com>
*
* April, 2002
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <xtables.h>
#include <netinet/ether.h>
#include <xtables.h>
#include <net/if_arp.h>
#include <linux/netfilter_bridge/ebt_arp.h>
#include "iptables/nft.h"
#include "iptables/nft-bridge.h"
/* values must correspond with EBT_ARP_* bit positions */
enum {
O_OPCODE = 0,
O_HTYPE,
O_PTYPE,
O_SRC_IP,
O_DST_IP,
O_SRC_MAC,
O_DST_MAC,
O_GRAT,
};
static const struct xt_option_entry brarp_opts[] = {
#define ENTRY(n, i, t) { .name = n, .id = i, .type = t, .flags = XTOPT_INVERT }
ENTRY("arp-opcode", O_OPCODE, XTTYPE_STRING),
ENTRY("arp-op", O_OPCODE, XTTYPE_STRING),
ENTRY("arp-htype", O_HTYPE, XTTYPE_STRING),
ENTRY("arp-ptype", O_PTYPE, XTTYPE_STRING),
ENTRY("arp-ip-src", O_SRC_IP, XTTYPE_HOSTMASK),
ENTRY("arp-ip-dst", O_DST_IP, XTTYPE_HOSTMASK),
ENTRY("arp-mac-src", O_SRC_MAC, XTTYPE_ETHERMACMASK),
ENTRY("arp-mac-dst", O_DST_MAC, XTTYPE_ETHERMACMASK),
ENTRY("arp-gratuitous", O_GRAT, XTTYPE_NONE),
#undef ENTRY
XTOPT_TABLEEND
};
/* a few names */
static char *opcodes[] =
{
"Request",
"Reply",
"Request_Reverse",
"Reply_Reverse",
"DRARP_Request",
"DRARP_Reply",
"DRARP_Error",
"InARP_Request",
"ARP_NAK",
};
static void brarp_print_help(void)
{
int i;
printf(
"arp options:\n"
"[!] --arp-opcode opcode : ARP opcode (integer or string)\n"
"[!] --arp-htype type : ARP hardware type (integer or string)\n"
"[!] --arp-ptype type : ARP protocol type (hexadecimal or string)\n"
"[!] --arp-ip-src address[/mask]: ARP IP source specification\n"
"[!] --arp-ip-dst address[/mask]: ARP IP target specification\n"
"[!] --arp-mac-src address[/mask]: ARP MAC source specification\n"
"[!] --arp-mac-dst address[/mask]: ARP MAC target specification\n"
"[!] --arp-gratuitous : ARP gratuitous packet\n"
" opcode strings: \n");
for (i = 0; i < ARRAY_SIZE(opcodes); i++)
printf(" %d = %s\n", i + 1, opcodes[i]);
printf(
" hardware type string: 1 = Ethernet\n"
" protocol type string: see "XT_PATH_ETHERTYPES"\n");
}
static void brarp_parse(struct xt_option_call *cb)
{
struct ebt_arp_info *arpinfo = cb->data;
struct xt_ethertypeent *ent;
long int i;
char *end;
xtables_option_parse(cb);
arpinfo->bitmask |= 1 << cb->entry->id;
if (cb->invert)
arpinfo->invflags |= 1 << cb->entry->id;
switch (cb->entry->id) {
case O_OPCODE:
i = strtol(cb->arg, &end, 10);
if (i < 0 || i >= (0x1 << 16) || *end !='\0') {
for (i = 0; i < ARRAY_SIZE(opcodes); i++)
if (!strcasecmp(opcodes[i], cb->arg))
break;
if (i == ARRAY_SIZE(opcodes))
xtables_error(PARAMETER_PROBLEM,
"Problem with specified ARP opcode");
i++;
}
arpinfo->opcode = htons(i);
break;
case O_HTYPE:
i = strtol(cb->arg, &end, 10);
if (i < 0 || i >= (0x1 << 16) || *end !='\0') {
if (!strcasecmp("Ethernet", cb->arg))
i = 1;
else
xtables_error(PARAMETER_PROBLEM,
"Problem with specified ARP hardware type");
}
arpinfo->htype = htons(i);
break;
case O_PTYPE:
i = strtol(cb->arg, &end, 16);
if (i >= 0 && i < (0x1 << 16) && *end == '\0') {
arpinfo->ptype = htons(i);
break;
}
ent = xtables_getethertypebyname(cb->arg);
if (!ent)
xtables_error(PARAMETER_PROBLEM,
"Problem with specified ARP protocol type");
arpinfo->ptype = htons(ent->e_ethertype);
break;
case O_SRC_IP:
arpinfo->saddr = cb->val.haddr.ip & cb->val.hmask.ip;
arpinfo->smsk = cb->val.hmask.ip;
break;
case O_DST_IP:
arpinfo->daddr = cb->val.haddr.ip & cb->val.hmask.ip;
arpinfo->dmsk = cb->val.hmask.ip;
break;
case O_SRC_MAC:
memcpy(arpinfo->smaddr, cb->val.ethermac, ETH_ALEN);
memcpy(arpinfo->smmsk, cb->val.ethermacmask, ETH_ALEN);
break;
case O_DST_MAC:
memcpy(arpinfo->dmaddr, cb->val.ethermac, ETH_ALEN);
memcpy(arpinfo->dmmsk, cb->val.ethermacmask, ETH_ALEN);
break;
}
}
static void brarp_print(const void *ip, const struct xt_entry_match *match, int numeric)
{
const struct ebt_arp_info *arpinfo = (struct ebt_arp_info *)match->data;
if (arpinfo->bitmask & EBT_ARP_OPCODE) {
int opcode = ntohs(arpinfo->opcode);
if (arpinfo->invflags & EBT_ARP_OPCODE)
printf("! ");
printf("--arp-op ");
if (opcode > 0 && opcode <= ARRAY_SIZE(opcodes))
printf("%s ", opcodes[opcode - 1]);
else
printf("%d ", opcode);
}
if (arpinfo->bitmask & EBT_ARP_HTYPE) {
if (arpinfo->invflags & EBT_ARP_HTYPE)
printf("! ");
printf("--arp-htype %d ", ntohs(arpinfo->htype));
}
if (arpinfo->bitmask & EBT_ARP_PTYPE) {
if (arpinfo->invflags & EBT_ARP_PTYPE)
printf("! ");
printf("--arp-ptype 0x%x ", ntohs(arpinfo->ptype));
}
if (arpinfo->bitmask & EBT_ARP_SRC_IP) {
if (arpinfo->invflags & EBT_ARP_SRC_IP)
printf("! ");
printf("--arp-ip-src %s%s ",
xtables_ipaddr_to_numeric((void *)&arpinfo->saddr),
xtables_ipmask_to_numeric((void *)&arpinfo->smsk));
}
if (arpinfo->bitmask & EBT_ARP_DST_IP) {
if (arpinfo->invflags & EBT_ARP_DST_IP)
printf("! ");
printf("--arp-ip-dst %s%s ",
xtables_ipaddr_to_numeric((void *)&arpinfo->daddr),
xtables_ipmask_to_numeric((void *)&arpinfo->dmsk));
}
if (arpinfo->bitmask & EBT_ARP_SRC_MAC) {
if (arpinfo->invflags & EBT_ARP_SRC_MAC)
printf("! ");
printf("--arp-mac-src ");
xtables_print_mac_and_mask(arpinfo->smaddr, arpinfo->smmsk);
printf(" ");
}
if (arpinfo->bitmask & EBT_ARP_DST_MAC) {
if (arpinfo->invflags & EBT_ARP_DST_MAC)
printf("! ");
printf("--arp-mac-dst ");
xtables_print_mac_and_mask(arpinfo->dmaddr, arpinfo->dmmsk);
printf(" ");
}
if (arpinfo->bitmask & EBT_ARP_GRAT) {
if (arpinfo->invflags & EBT_ARP_GRAT)
printf("! ");
printf("--arp-gratuitous ");
}
}
static struct xtables_match brarp_match = {
.name = "arp",
.version = XTABLES_VERSION,
.family = NFPROTO_BRIDGE,
.size = XT_ALIGN(sizeof(struct ebt_arp_info)),
.userspacesize = XT_ALIGN(sizeof(struct ebt_arp_info)),
.help = brarp_print_help,
.x6_parse = brarp_parse,
.print = brarp_print,
.x6_options = brarp_opts,
};
void _init(void)
{
xtables_register_match(&brarp_match);
}
+22
View File
@@ -0,0 +1,22 @@
:INPUT,FORWARD,OUTPUT
-p ARP --arp-op Request;=;OK
-p ARP ! --arp-op Request;=;OK
-p ARP --arp-htype Ethernet;-p ARP --arp-htype 1;OK
-p ARP --arp-htype 1;=;OK
-p ARP ! --arp-htype 1;=;OK
-p ARP --arp-ptype 0x2;=;OK
-p ARP ! --arp-ptype 0x2;=;OK
-p ARP --arp-ip-src 1.2.3.4;=;OK
-p ARP --arp-ip-dst ! 1.2.3.4;-p ARP ! --arp-ip-dst 1.2.3.4 -j CONTINUE;OK
-p ARP ! --arp-ip-src 0.0.0.0;=;OK
-p ARP ! --arp-ip-dst 0.0.0.0/8;=;OK
-p ARP ! --arp-ip-src 1.2.3.4/32;-p ARP ! --arp-ip-src 1.2.3.4;OK
-p ARP ! --arp-ip-src 1.2.3.4/255.255.255.0;-p ARP ! --arp-ip-src 1.2.3.0/24;OK
-p ARP ! --arp-ip-src 1.2.3.4/255.0.255.255;-p ARP ! --arp-ip-src 1.0.3.4/255.0.255.255;OK
-p ARP --arp-mac-src 00:de:ad:be:ef:00;=;OK
-p ARP ! --arp-mac-src 00:de:ad:be:ef:00;=;OK
-p ARP --arp-mac-dst de:ad:be:ef:00:00/ff:ff:ff:ff:00:00;=;OK
-p ARP ! --arp-mac-dst de:ad:be:ef:00:00/ff:ff:ff:ff:00:00;=;OK
-p ARP --arp-gratuitous;=;OK
-p ARP ! --arp-gratuitous;=;OK
--arp-htype 1;=;FAIL
+85
View File
@@ -0,0 +1,85 @@
/* ebt_arpreply
*
* Authors:
* Grzegorz Borowiak <grzes@gnu.univ.gda.pl>
* Bart De Schuymer <bdschuym@pandora.be>
*
* August, 2003
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <xtables.h>
#include <netinet/ether.h>
#include <linux/netfilter_bridge/ebt_arpreply.h>
#include "iptables/nft.h"
#include "iptables/nft-bridge.h"
enum {
O_MAC,
O_TARGET,
};
static const struct xt_option_entry brarpreply_opts[] = {
{ .name = "arpreply-mac" , .id = O_MAC, .type = XTTYPE_ETHERMAC,
.flags = XTOPT_PUT, XTOPT_POINTER(struct ebt_arpreply_info, mac) },
{ .name = "arpreply-target" , .id = O_TARGET, .type = XTTYPE_STRING },
XTOPT_TABLEEND,
};
static void brarpreply_print_help(void)
{
printf(
"arpreply target options:\n"
" --arpreply-mac address : source MAC of generated reply\n"
" --arpreply-target target : ACCEPT, DROP, RETURN or CONTINUE\n"
" (standard target is DROP)\n");
}
static void brarpreply_init(struct xt_entry_target *target)
{
struct ebt_arpreply_info *replyinfo = (void *)target->data;
replyinfo->target = EBT_DROP;
}
static void brarpreply_parse(struct xt_option_call *cb)
{
struct ebt_arpreply_info *replyinfo = cb->data;
xtables_option_parse(cb);
if (cb->entry->id == O_TARGET &&
ebt_fill_target(cb->arg, (unsigned int *)&replyinfo->target))
xtables_error(PARAMETER_PROBLEM,
"Illegal --arpreply-target target");
}
static void brarpreply_print(const void *ip, const struct xt_entry_target *t, int numeric)
{
struct ebt_arpreply_info *replyinfo = (void *)t->data;
printf("--arpreply-mac ");
xtables_print_mac(replyinfo->mac);
if (replyinfo->target == EBT_DROP)
return;
printf(" --arpreply-target %s", ebt_target_name(replyinfo->target));
}
static struct xtables_target arpreply_target = {
.name = "arpreply",
.version = XTABLES_VERSION,
.family = NFPROTO_BRIDGE,
.init = brarpreply_init,
.size = XT_ALIGN(sizeof(struct ebt_arpreply_info)),
.userspacesize = XT_ALIGN(sizeof(struct ebt_arpreply_info)),
.help = brarpreply_print_help,
.x6_parse = brarpreply_parse,
.print = brarpreply_print,
.x6_options = brarpreply_opts,
};
void _init(void)
{
xtables_register_target(&arpreply_target);
}
+8
View File
@@ -0,0 +1,8 @@
:PREROUTING
*nat
-j arpreply;=;FAIL
-p ARP -i foo -j arpreply;-p ARP -i foo -j arpreply --arpreply-mac 00:00:00:00:00:00;OK
-p ARP -i foo -j arpreply --arpreply-mac de:ad:00:be:ee:ff --arpreply-target ACCEPT;=;OK
-p ARP -i foo -j arpreply --arpreply-mac de:ad:00:be:ee:ff;=;OK
-p ARP -j arpreply ! --arpreply-mac de:ad:00:be:ee:ff;;FAIL
-p ARP -j arpreply --arpreply-mac de:ad:00:be:ee:ff ! --arpreply-target ACCEPT;;FAIL
+119
View File
@@ -0,0 +1,119 @@
/* ebt_nat
*
* Authors:
* Bart De Schuymer <bdschuym@pandora.be>
*
* June, 2002
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/ether.h>
#include <xtables.h>
#include <linux/netfilter_bridge/ebt_nat.h>
#include "iptables/nft.h"
#include "iptables/nft-bridge.h"
enum {
O_DST,
O_TARGET,
};
static const struct xt_option_entry brdnat_opts[] =
{
{ .name = "to-destination", .id = O_DST, .type = XTTYPE_ETHERMAC,
.flags = XTOPT_PUT, XTOPT_POINTER(struct ebt_nat_info, mac) },
{ .name = "to-dst" , .id = O_DST, .type = XTTYPE_ETHERMAC,
.flags = XTOPT_PUT, XTOPT_POINTER(struct ebt_nat_info, mac) },
{ .name = "dnat-target" , .id = O_TARGET, .type = XTTYPE_STRING },
XTOPT_TABLEEND,
};
static void brdnat_print_help(void)
{
printf(
"dnat options:\n"
" --to-dst address : MAC address to map destination to\n"
" --dnat-target target : ACCEPT, DROP, RETURN or CONTINUE\n"
" (standard target is ACCEPT)\n");
}
static void brdnat_init(struct xt_entry_target *target)
{
struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
natinfo->target = EBT_ACCEPT;
}
static void brdnat_parse(struct xt_option_call *cb)
{
struct ebt_nat_info *natinfo = cb->data;
xtables_option_parse(cb);
if (cb->entry->id == O_TARGET &&
ebt_fill_target(cb->arg, (unsigned int *)&natinfo->target))
xtables_error(PARAMETER_PROBLEM,
"Illegal --dnat-target target");
}
static void brdnat_final_check(struct xt_fcheck_call *fc)
{
if (!fc->xflags)
xtables_error(PARAMETER_PROBLEM,
"You must specify proper arguments");
}
static void brdnat_print(const void *ip, const struct xt_entry_target *target, int numeric)
{
struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
printf("--to-dst ");
xtables_print_mac(natinfo->mac);
printf(" --dnat-target %s", ebt_target_name(natinfo->target));
}
static const char* brdnat_verdict(int verdict)
{
switch (verdict) {
case EBT_ACCEPT: return "accept";
case EBT_DROP: return "drop";
case EBT_CONTINUE: return "continue";
case EBT_RETURN: return "return";
}
return "";
}
static int brdnat_xlate(struct xt_xlate *xl,
const struct xt_xlate_tg_params *params)
{
const struct ebt_nat_info *natinfo = (const void*)params->target->data;
xt_xlate_add(xl, "ether daddr set %s %s ",
ether_ntoa((struct ether_addr *)natinfo->mac),
brdnat_verdict(natinfo->target));
return 1;
}
static struct xtables_target brdnat_target =
{
.name = "dnat",
.version = XTABLES_VERSION,
.family = NFPROTO_BRIDGE,
.size = XT_ALIGN(sizeof(struct ebt_nat_info)),
.userspacesize = XT_ALIGN(sizeof(struct ebt_nat_info)),
.help = brdnat_print_help,
.init = brdnat_init,
.x6_parse = brdnat_parse,
.x6_fcheck = brdnat_final_check,
.print = brdnat_print,
.xlate = brdnat_xlate,
.x6_options = brdnat_opts,
};
void _init(void)
{
xtables_register_target(&brdnat_target);
}
+5
View File
@@ -0,0 +1,5 @@
:PREROUTING
*nat
-i someport -j dnat --to-dst de:ad:0:be:ee:ff;-i someport -j dnat --to-dst de:ad:00:be:ee:ff --dnat-target ACCEPT;OK
-j dnat --to-dst de:ad:00:be:ee:ff --dnat-target ACCEPT;=;OK
-j dnat --to-dst de:ad:00:be:ee:ff --dnat-target CONTINUE;=;OK
+8
View File
@@ -0,0 +1,8 @@
ebtables-translate -t nat -A PREROUTING -i someport -j dnat --to-dst de:ad:00:be:ee:ff
nft 'add rule bridge nat PREROUTING iifname "someport" counter ether daddr set de:ad:0:be:ee:ff accept'
ebtables-translate -t nat -A PREROUTING -i someport -j dnat --to-dst de:ad:00:be:ee:ff --dnat-target ACCEPT
nft 'add rule bridge nat PREROUTING iifname "someport" counter ether daddr set de:ad:0:be:ee:ff accept'
ebtables-translate -t nat -A PREROUTING -i someport -j dnat --to-dst de:ad:00:be:ee:ff --dnat-target CONTINUE
nft 'add rule bridge nat PREROUTING iifname "someport" counter ether daddr set de:ad:0:be:ee:ff continue'
+461
View File
@@ -0,0 +1,461 @@
/* ebt_ip
*
* Authors:
* Bart De Schuymer <bdschuym@pandora.be>
*
* Changes:
* added ip-sport and ip-dport; parsing of port arguments is
* based on code from iptables-1.2.7a
* Innominate Security Technologies AG <mhopf@innominate.com>
* September, 2002
*
* Adapted by Arturo Borrero Gonzalez <arturo@debian.org>
* to use libxtables for ebtables-compat in 2015.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <inttypes.h>
#include <xtables.h>
#include <linux/netfilter_bridge/ebt_ip.h>
#include "libxt_icmp.h"
/* must correspond to the bit position in EBT_IP6_* defines */
enum {
O_SOURCE = 0,
O_DEST,
O_TOS,
O_PROTO,
O_SPORT,
O_DPORT,
O_ICMP,
O_IGMP,
F_PORT = 1 << O_ICMP | 1 << O_IGMP,
F_ICMP = 1 << O_SPORT | 1 << O_DPORT | 1 << O_IGMP,
F_IGMP = 1 << O_SPORT | 1 << O_DPORT | 1 << O_ICMP,
};
static const struct xt_option_entry brip_opts[] = {
{ .name = "ip-source", .id = O_SOURCE, .type = XTTYPE_HOSTMASK,
.flags = XTOPT_INVERT },
{ .name = "ip-src", .id = O_SOURCE, .type = XTTYPE_HOSTMASK,
.flags = XTOPT_INVERT },
{ .name = "ip-destination", .id = O_DEST, .type = XTTYPE_HOSTMASK,
.flags = XTOPT_INVERT },
{ .name = "ip-dst", .id = O_DEST, .type = XTTYPE_HOSTMASK,
.flags = XTOPT_INVERT },
{ .name = "ip-tos", .id = O_TOS, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT,
XTOPT_POINTER(struct ebt_ip_info, tos) },
{ .name = "ip-protocol", .id = O_PROTO, .type = XTTYPE_PROTOCOL,
.flags = XTOPT_INVERT | XTOPT_PUT,
XTOPT_POINTER(struct ebt_ip_info, protocol) },
{ .name = "ip-proto", .id = O_PROTO, .type = XTTYPE_PROTOCOL,
.flags = XTOPT_INVERT | XTOPT_PUT,
XTOPT_POINTER(struct ebt_ip_info, protocol) },
{ .name = "ip-source-port", .id = O_SPORT, .type = XTTYPE_PORTRC,
.excl = F_PORT, .flags = XTOPT_INVERT | XTOPT_PUT,
XTOPT_POINTER(struct ebt_ip_info, sport) },
{ .name = "ip-sport", .id = O_SPORT, .type = XTTYPE_PORTRC,
.excl = F_PORT, .flags = XTOPT_INVERT | XTOPT_PUT,
XTOPT_POINTER(struct ebt_ip_info, sport) },
{ .name = "ip-destination-port",.id = O_DPORT, .type = XTTYPE_PORTRC,
.excl = F_PORT, .flags = XTOPT_INVERT | XTOPT_PUT,
XTOPT_POINTER(struct ebt_ip_info, dport) },
{ .name = "ip-dport", .id = O_DPORT, .type = XTTYPE_PORTRC,
.excl = F_PORT, .flags = XTOPT_INVERT | XTOPT_PUT,
XTOPT_POINTER(struct ebt_ip_info, dport) },
{ .name = "ip-icmp-type", .id = O_ICMP, .type = XTTYPE_STRING,
.excl = F_ICMP, .flags = XTOPT_INVERT },
{ .name = "ip-igmp-type", .id = O_IGMP, .type = XTTYPE_STRING,
.excl = F_IGMP, .flags = XTOPT_INVERT },
XTOPT_TABLEEND,
};
static void brip_print_help(void)
{
printf(
"ip options:\n"
"[!] --ip-src address[/mask]: ip source specification\n"
"[!] --ip-dst address[/mask]: ip destination specification\n"
"[!] --ip-tos tos : ip tos specification\n"
"[!] --ip-proto protocol : ip protocol specification\n"
"[!] --ip-sport port[:port] : tcp/udp source port or port range\n"
"[!] --ip-dport port[:port] : tcp/udp destination port or port range\n"
"[!] --ip-icmp-type type[[:type]/code[:code]] : icmp type/code or type/code range\n"
"[!] --ip-igmp-type type[:type] : igmp type or type range\n");
printf("\nValid ICMP Types:\n");
xt_print_icmp_types(icmp_codes, ARRAY_SIZE(icmp_codes));
printf("\nValid IGMP Types:\n");
xt_print_icmp_types(igmp_types, ARRAY_SIZE(igmp_types));
}
/* original code from ebtables: useful_functions.c */
static void print_icmp_code(uint8_t *code)
{
if (!code)
return;
if (code[0] == code[1])
printf("/%"PRIu8 " ", code[0]);
else
printf("/%"PRIu8":%"PRIu8 " ", code[0], code[1]);
}
static void ebt_print_icmp_type(const struct xt_icmp_names *codes,
size_t n_codes, uint8_t *type, uint8_t *code)
{
unsigned int i;
if (type[0] != type[1]) {
printf("%"PRIu8 ":%" PRIu8, type[0], type[1]);
print_icmp_code(code);
return;
}
for (i = 0; i < n_codes; i++) {
if (codes[i].type != type[0])
continue;
if (!code || (codes[i].code_min == code[0] &&
codes[i].code_max == code[1])) {
printf("%s ", codes[i].name);
return;
}
}
printf("%"PRIu8, type[0]);
print_icmp_code(code);
}
static void brip_parse(struct xt_option_call *cb)
{
struct ebt_ip_info *info = cb->data;
xtables_option_parse(cb);
info->bitmask |= 1 << cb->entry->id;
info->invflags |= cb->invert ? 1 << cb->entry->id : 0;
switch (cb->entry->id) {
case O_SOURCE:
cb->val.haddr.all[0] &= cb->val.hmask.all[0];
info->saddr = cb->val.haddr.ip;
info->smsk = cb->val.hmask.ip;
break;
case O_DEST:
cb->val.haddr.all[0] &= cb->val.hmask.all[0];
info->daddr = cb->val.haddr.ip;
info->dmsk = cb->val.hmask.ip;
break;
case O_ICMP:
ebt_parse_icmp(cb->arg, info->icmp_type, info->icmp_code);
break;
case O_IGMP:
ebt_parse_igmp(cb->arg, info->igmp_type);
break;
}
}
static void brip_final_check(struct xt_fcheck_call *fc)
{
if (!fc->xflags)
xtables_error(PARAMETER_PROBLEM,
"You must specify proper arguments");
}
static void print_port_range(uint16_t *ports)
{
if (ports[0] == ports[1])
printf("%d ", ports[0]);
else
printf("%d:%d ", ports[0], ports[1]);
}
static void brip_print(const void *ip, const struct xt_entry_match *match,
int numeric)
{
struct ebt_ip_info *info = (struct ebt_ip_info *)match->data;
struct in_addr *addrp, *maskp;
if (info->bitmask & EBT_IP_SOURCE) {
if (info->invflags & EBT_IP_SOURCE)
printf("! ");
addrp = (struct in_addr *)&info->saddr;
maskp = (struct in_addr *)&info->smsk;
printf("--ip-src %s%s ",
xtables_ipaddr_to_numeric(addrp),
xtables_ipmask_to_numeric(maskp));
}
if (info->bitmask & EBT_IP_DEST) {
if (info->invflags & EBT_IP_DEST)
printf("! ");
addrp = (struct in_addr *)&info->daddr;
maskp = (struct in_addr *)&info->dmsk;
printf("--ip-dst %s%s ",
xtables_ipaddr_to_numeric(addrp),
xtables_ipmask_to_numeric(maskp));
}
if (info->bitmask & EBT_IP_TOS) {
if (info->invflags & EBT_IP_TOS)
printf("! ");
printf("--ip-tos 0x%02X ", info->tos);
}
if (info->bitmask & EBT_IP_PROTO) {
struct protoent *pe;
if (info->invflags & EBT_IP_PROTO)
printf("! ");
printf("--ip-proto ");
pe = getprotobynumber(info->protocol);
if (pe == NULL) {
printf("%d ", info->protocol);
} else {
printf("%s ", pe->p_name);
}
}
if (info->bitmask & EBT_IP_SPORT) {
if (info->invflags & EBT_IP_SPORT)
printf("! ");
printf("--ip-sport ");
print_port_range(info->sport);
}
if (info->bitmask & EBT_IP_DPORT) {
if (info->invflags & EBT_IP_DPORT)
printf("! ");
printf("--ip-dport ");
print_port_range(info->dport);
}
if (info->bitmask & EBT_IP_ICMP) {
if (info->invflags & EBT_IP_ICMP)
printf("! ");
printf("--ip-icmp-type ");
ebt_print_icmp_type(icmp_codes, ARRAY_SIZE(icmp_codes),
info->icmp_type, info->icmp_code);
}
if (info->bitmask & EBT_IP_IGMP) {
if (info->invflags & EBT_IP_IGMP)
printf("! ");
printf("--ip-igmp-type ");
ebt_print_icmp_type(igmp_types, ARRAY_SIZE(igmp_types),
info->igmp_type, NULL);
}
}
static const char *brip_xlate_proto_to_name(uint8_t proto)
{
switch (proto) {
case IPPROTO_TCP:
return "tcp";
case IPPROTO_UDP:
return "udp";
case IPPROTO_UDPLITE:
return "udplite";
case IPPROTO_SCTP:
return "sctp";
case IPPROTO_DCCP:
return "dccp";
default:
return NULL;
}
}
static void brip_xlate_icmp(struct xt_xlate *xl,
const struct ebt_ip_info *info, int bit)
{
if ((info->bitmask & bit) == 0)
return;
xt_xlate_add(xl, "icmp type ");
if (info->invflags & bit)
xt_xlate_add(xl, "!= ");
if (info->icmp_type[0] == info->icmp_type[1])
xt_xlate_add(xl, "%d ", info->icmp_type[0]);
else
xt_xlate_add(xl, "%d-%d ", info->icmp_type[0],
info->icmp_type[1]);
if (info->icmp_code[0] == 0 &&
info->icmp_code[1] == 0xff)
return;
xt_xlate_add(xl, "icmp code ");
if (info->invflags & bit)
xt_xlate_add(xl, "!= ");
if (info->icmp_code[0] == info->icmp_code[1])
xt_xlate_add(xl, "%d ", info->icmp_code[0]);
else
xt_xlate_add(xl, "%d-%d ", info->icmp_code[0],
info->icmp_code[1]);
}
static void brip_xlate_igmp(struct xt_xlate *xl,
const struct ebt_ip_info *info, int bit)
{
if ((info->bitmask & bit) == 0)
return;
xt_xlate_add(xl, "@th,0,8 ");
if (info->invflags & bit)
xt_xlate_add(xl, "!= ");
if (info->icmp_type[0] == info->icmp_type[1])
xt_xlate_add(xl, "%d ", info->icmp_type[0]);
else
xt_xlate_add(xl, "%d-%d ", info->icmp_type[0],
info->icmp_type[1]);
}
static void brip_xlate_th(struct xt_xlate *xl,
const struct ebt_ip_info *info, int bit,
const char *pname)
{
const uint16_t *ports;
if ((info->bitmask & bit) == 0)
return;
switch (bit) {
case EBT_IP_SPORT:
if (pname)
xt_xlate_add(xl, "%s sport ", pname);
else
xt_xlate_add(xl, "@th,0,16 ");
ports = info->sport;
break;
case EBT_IP_DPORT:
if (pname)
xt_xlate_add(xl, "%s dport ", pname);
else
xt_xlate_add(xl, "@th,16,16 ");
ports = info->dport;
break;
default:
return;
}
if (info->invflags & bit)
xt_xlate_add(xl, "!= ");
if (ports[0] == ports[1])
xt_xlate_add(xl, "%d ", ports[0]);
else
xt_xlate_add(xl, "%d-%d ", ports[0], ports[1]);
}
static void brip_xlate_nh(struct xt_xlate *xl,
const struct ebt_ip_info *info, int bit)
{
struct in_addr *addrp, *maskp;
if ((info->bitmask & bit) == 0)
return;
switch (bit) {
case EBT_IP_SOURCE:
xt_xlate_add(xl, "ip saddr ");
addrp = (struct in_addr *)&info->saddr;
maskp = (struct in_addr *)&info->smsk;
break;
case EBT_IP_DEST:
xt_xlate_add(xl, "ip daddr ");
addrp = (struct in_addr *)&info->daddr;
maskp = (struct in_addr *)&info->dmsk;
break;
default:
return;
}
if (info->invflags & bit)
xt_xlate_add(xl, "!= ");
xt_xlate_add(xl, "%s%s ", xtables_ipaddr_to_numeric(addrp),
xtables_ipmask_to_numeric(maskp));
}
static bool may_skip_ether_type_dep(uint8_t flags)
{
/* these convert to "ip (s|d)addr" matches */
if (flags & (EBT_IP_SOURCE | EBT_IP_DEST))
return true;
/* icmp match triggers implicit ether type dependency in nft */
if (flags & EBT_IP_ICMP)
return true;
/* allow if "ip protocol" match is created by brip_xlate() */
if (flags & EBT_IP_PROTO &&
!(flags & (EBT_IP_SPORT | EBT_IP_DPORT | EBT_IP_ICMP)))
return true;
return false;
}
static int brip_xlate(struct xt_xlate *xl,
const struct xt_xlate_mt_params *params)
{
const struct ebt_ip_info *info = (const void *)params->match->data;
const char *pname = NULL;
brip_xlate_nh(xl, info, EBT_IP_SOURCE);
brip_xlate_nh(xl, info, EBT_IP_DEST);
if (!may_skip_ether_type_dep(info->bitmask))
xt_xlate_add(xl, "ether type ip ");
if (info->bitmask & EBT_IP_TOS) {
xt_xlate_add(xl, "@nh,8,8 ");
if (info->invflags & EBT_IP_TOS)
xt_xlate_add(xl, "!= ");
xt_xlate_add(xl, "0x%02x ", info->tos);
}
if (info->bitmask & EBT_IP_PROTO) {
struct protoent *pe;
if (info->bitmask & (EBT_IP_SPORT|EBT_IP_DPORT|EBT_IP_ICMP) &&
(info->invflags & EBT_IP_PROTO) == 0) {
/* port number or icmp given and not inverted, no need to print this */
pname = brip_xlate_proto_to_name(info->protocol);
} else {
xt_xlate_add(xl, "ip protocol ");
if (info->invflags & EBT_IP_PROTO)
xt_xlate_add(xl, "!= ");
pe = getprotobynumber(info->protocol);
if (pe == NULL)
xt_xlate_add(xl, "%d ", info->protocol);
else
xt_xlate_add(xl, "%s ", pe->p_name);
}
}
brip_xlate_th(xl, info, EBT_IP_SPORT, pname);
brip_xlate_th(xl, info, EBT_IP_DPORT, pname);
brip_xlate_icmp(xl, info, EBT_IP_ICMP);
brip_xlate_igmp(xl, info, EBT_IP_IGMP);
return 1;
}
static struct xtables_match brip_match = {
.name = "ip",
.revision = 0,
.version = XTABLES_VERSION,
.family = NFPROTO_BRIDGE,
.size = XT_ALIGN(sizeof(struct ebt_ip_info)),
.userspacesize = XT_ALIGN(sizeof(struct ebt_ip_info)),
.help = brip_print_help,
.x6_parse = brip_parse,
.x6_fcheck = brip_final_check,
.print = brip_print,
.xlate = brip_xlate,
.x6_options = brip_opts,
};
void _init(void)
{
xtables_register_match(&brip_match);
}
+33
View File
@@ -0,0 +1,33 @@
:INPUT,FORWARD,OUTPUT
-p ip ! --ip-src 192.168.0.0/24 -j ACCEPT;-p IPv4 ! --ip-src 192.168.0.0/24 -j ACCEPT;OK
-p IPv4 --ip-dst 10.0.0.1;=;OK
-p IPv4 ! --ip-dst 10.0.0.1;=;OK
-p IPv4 --ip-tos 0xFF;=;OK
-p IPv4 ! --ip-tos 0xFF;=;OK
-p IPv4 --ip-proto tcp --ip-dport 22;=;OK
-p IPv4 --ip-proto udp --ip-sport 1024:65535;=;OK
-p IPv4 --ip-proto udp --ip-sport :;-p IPv4 --ip-proto udp --ip-sport 0:65535;OK
-p IPv4 --ip-proto udp --ip-sport :4;-p IPv4 --ip-proto udp --ip-sport 0:4;OK
-p IPv4 --ip-proto udp --ip-sport 4:;-p IPv4 --ip-proto udp --ip-sport 4:65535;OK
-p IPv4 --ip-proto udp --ip-sport 3:4;=;OK
-p IPv4 --ip-proto udp --ip-sport 4:4;-p IPv4 --ip-proto udp --ip-sport 4;OK
-p IPv4 --ip-proto udp --ip-sport 4:3;;FAIL
-p IPv4 --ip-proto udp --ip-dport :;-p IPv4 --ip-proto udp --ip-dport 0:65535;OK
-p IPv4 --ip-proto udp --ip-dport :4;-p IPv4 --ip-proto udp --ip-dport 0:4;OK
-p IPv4 --ip-proto udp --ip-dport 4:;-p IPv4 --ip-proto udp --ip-dport 4:65535;OK
-p IPv4 --ip-proto udp --ip-dport 3:4;=;OK
-p IPv4 --ip-proto udp --ip-dport 4:4;-p IPv4 --ip-proto udp --ip-dport 4;OK
-p IPv4 --ip-proto udp --ip-dport 4:3;;FAIL
-p IPv4 --ip-proto 253;=;OK
-p IPv4 ! --ip-proto 253;=;OK
-p IPv4 --ip-proto icmp --ip-icmp-type echo-request;=;OK
-p IPv4 --ip-proto icmp --ip-icmp-type 1/1;=;OK
-p ip --ip-protocol icmp ! --ip-icmp-type 1:10;-p IPv4 --ip-proto icmp ! --ip-icmp-type 1:10/0:255 -j CONTINUE;OK
--ip-proto icmp --ip-icmp-type 1/1;=;FAIL
! -p ip --ip-proto icmp --ip-icmp-type 1/1;=;FAIL
! -p ip --ip-proto tcp --ip-sport 22 --ip-icmp-type echo-reply;;FAIL
! -p ip --ip-proto tcp --ip-sport 22 --ip-igmp-type membership-query;;FAIL
! -p ip --ip-proto tcp --ip-dport 22 --ip-icmp-type echo-reply;;FAIL
! -p ip --ip-proto tcp --ip-dport 22 --ip-igmp-type membership-query;;FAIL
! -p ip --ip-proto icmp --ip-icmp-type echo-reply --ip-igmp-type membership-query;;FAIL
-p IPv4 --ip-proto icmp ! --ip-icmp-type echo-reply;=;OK
+26
View File
@@ -0,0 +1,26 @@
ebtables-translate -A FORWARD -p ip ! --ip-src 192.168.0.0/24 -j ACCEPT
nft 'add rule bridge filter FORWARD ip saddr != 192.168.0.0/24 counter accept'
ebtables-translate -I FORWARD -p ip --ip-dst 10.0.0.1
nft 'insert rule bridge filter FORWARD ip daddr 10.0.0.1 counter'
ebtables-translate -I OUTPUT -p ip -o eth0 --ip-tos 0xff
nft 'insert rule bridge filter OUTPUT oifname "eth0" ether type ip @nh,8,8 0xff counter'
ebtables-translate -A FORWARD -p ip --ip-proto tcp --ip-dport 22
nft 'add rule bridge filter FORWARD ether type ip tcp dport 22 counter'
ebtables-translate -A FORWARD -p ip --ip-proto udp --ip-sport 1024:65535
nft 'add rule bridge filter FORWARD ether type ip udp sport 1024-65535 counter'
ebtables-translate -A FORWARD -p ip --ip-proto 253
nft 'add rule bridge filter FORWARD ip protocol 253 counter'
ebtables-translate -A FORWARD -p ip --ip-protocol icmp --ip-icmp-type "echo-request"
nft 'add rule bridge filter FORWARD icmp type 8 counter'
ebtables-translate -A FORWARD -p ip --ip-proto icmp --ip-icmp-type 1/1
nft 'add rule bridge filter FORWARD icmp type 1 icmp code 1 counter'
ebtables-translate -A FORWARD -p ip --ip-protocol icmp ! --ip-icmp-type 1:10
nft 'add rule bridge filter FORWARD icmp type != 1-10 counter'
+404
View File
@@ -0,0 +1,404 @@
/* ebt_ip6
*
* Authors:
* Kuo-Lang Tseng <kuo-lang.tseng@intel.com>
* Manohar Castelino <manohar.castelino@intel.com>
*
* Summary:
* This is just a modification of the IPv4 code written by
* Bart De Schuymer <bdschuym@pandora.be>
* with the changes required to support IPv6
*
*/
#include <errno.h>
#include <arpa/inet.h>
#include <inttypes.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <xtables.h>
#include <linux/netfilter_bridge/ebt_ip6.h>
#include "libxt_icmp.h"
/* must correspond to the bit position in EBT_IP6_* defines */
enum {
O_SOURCE = 0,
O_DEST,
O_TCLASS,
O_PROTO,
O_SPORT,
O_DPORT,
O_ICMP6,
F_PORT = 1 << O_ICMP6,
F_ICMP6 = 1 << O_SPORT | 1 << O_DPORT,
};
static const struct xt_option_entry brip6_opts[] = {
{ .name = "ip6-source", .id = O_SOURCE, .type = XTTYPE_HOSTMASK,
.flags = XTOPT_INVERT },
{ .name = "ip6-src", .id = O_SOURCE, .type = XTTYPE_HOSTMASK,
.flags = XTOPT_INVERT },
{ .name = "ip6-destination", .id = O_DEST, .type = XTTYPE_HOSTMASK,
.flags = XTOPT_INVERT },
{ .name = "ip6-dst", .id = O_DEST, .type = XTTYPE_HOSTMASK,
.flags = XTOPT_INVERT },
{ .name = "ip6-tclass", .id = O_TCLASS, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT,
XTOPT_POINTER(struct ebt_ip6_info, tclass) },
{ .name = "ip6-protocol", .id = O_PROTO, .type = XTTYPE_PROTOCOL,
.flags = XTOPT_INVERT | XTOPT_PUT,
XTOPT_POINTER(struct ebt_ip6_info, protocol) },
{ .name = "ip6-proto", .id = O_PROTO, .type = XTTYPE_PROTOCOL,
.flags = XTOPT_INVERT | XTOPT_PUT,
XTOPT_POINTER(struct ebt_ip6_info, protocol) },
{ .name = "ip6-source-port", .id = O_SPORT, .type = XTTYPE_PORTRC,
.excl = F_PORT, .flags = XTOPT_INVERT | XTOPT_PUT,
XTOPT_POINTER(struct ebt_ip6_info, sport) },
{ .name = "ip6-sport", .id = O_SPORT, .type = XTTYPE_PORTRC,
.excl = F_PORT, .flags = XTOPT_INVERT | XTOPT_PUT,
XTOPT_POINTER(struct ebt_ip6_info, sport) },
{ .name = "ip6-destination-port",.id = O_DPORT, .type = XTTYPE_PORTRC,
.excl = F_PORT, .flags = XTOPT_INVERT | XTOPT_PUT,
XTOPT_POINTER(struct ebt_ip6_info, dport) },
{ .name = "ip6-dport", .id = O_DPORT, .type = XTTYPE_PORTRC,
.excl = F_PORT, .flags = XTOPT_INVERT | XTOPT_PUT,
XTOPT_POINTER(struct ebt_ip6_info, dport) },
{ .name = "ip6-icmp-type", .id = O_ICMP6, .type = XTTYPE_STRING,
.excl = F_ICMP6, .flags = XTOPT_INVERT },
XTOPT_TABLEEND,
};
static void print_port_range(uint16_t *ports)
{
if (ports[0] == ports[1])
printf("%d ", ports[0]);
else
printf("%d:%d ", ports[0], ports[1]);
}
static void print_icmp_code(uint8_t *code)
{
if (code[0] == code[1])
printf("/%"PRIu8 " ", code[0]);
else
printf("/%"PRIu8":%"PRIu8 " ", code[0], code[1]);
}
static void print_icmp_type(uint8_t *type, uint8_t *code)
{
unsigned int i;
if (type[0] != type[1]) {
printf("%"PRIu8 ":%" PRIu8, type[0], type[1]);
print_icmp_code(code);
return;
}
for (i = 0; i < ARRAY_SIZE(icmpv6_codes); i++) {
if (icmpv6_codes[i].type != type[0])
continue;
if (icmpv6_codes[i].code_min == code[0] &&
icmpv6_codes[i].code_max == code[1]) {
printf("%s ", icmpv6_codes[i].name);
return;
}
}
printf("%"PRIu8, type[0]);
print_icmp_code(code);
}
static void brip6_print_help(void)
{
printf(
"ip6 options:\n"
"[!] --ip6-src address[/mask]: ipv6 source specification\n"
"[!] --ip6-dst address[/mask]: ipv6 destination specification\n"
"[!] --ip6-tclass tclass : ipv6 traffic class specification\n"
"[!] --ip6-proto protocol : ipv6 protocol specification\n"
"[!] --ip6-sport port[:port] : tcp/udp source port or port range\n"
"[!] --ip6-dport port[:port] : tcp/udp destination port or port range\n"
"[!] --ip6-icmp-type type[[:type]/code[:code]] : ipv6-icmp type/code or type/code range\n");
printf("Valid ICMPv6 Types:");
xt_print_icmp_types(icmpv6_codes, ARRAY_SIZE(icmpv6_codes));
}
static void brip6_parse(struct xt_option_call *cb)
{
struct ebt_ip6_info *info = cb->data;
unsigned int i;
/* XXX: overriding afinfo family is dangerous, but
* required for XTTYPE_HOSTMASK parsing */
xtables_set_nfproto(NFPROTO_IPV6);
xtables_option_parse(cb);
xtables_set_nfproto(NFPROTO_BRIDGE);
info->bitmask |= 1 << cb->entry->id;
info->invflags |= cb->invert ? 1 << cb->entry->id : 0;
switch (cb->entry->id) {
case O_SOURCE:
for (i = 0; i < ARRAY_SIZE(cb->val.haddr.all); i++)
cb->val.haddr.all[i] &= cb->val.hmask.all[i];
info->saddr = cb->val.haddr.in6;
info->smsk = cb->val.hmask.in6;
break;
case O_DEST:
for (i = 0; i < ARRAY_SIZE(cb->val.haddr.all); i++)
cb->val.haddr.all[i] &= cb->val.hmask.all[i];
info->daddr = cb->val.haddr.in6;
info->dmsk = cb->val.hmask.in6;
break;
case O_ICMP6:
ebt_parse_icmpv6(cb->arg, info->icmpv6_type, info->icmpv6_code);
break;
}
}
static void brip6_final_check(struct xt_fcheck_call *fc)
{
if (!fc->xflags)
xtables_error(PARAMETER_PROBLEM,
"You must specify proper arguments");
}
static void brip6_print(const void *ip, const struct xt_entry_match *match,
int numeric)
{
struct ebt_ip6_info *ipinfo = (struct ebt_ip6_info *)match->data;
if (ipinfo->bitmask & EBT_IP6_SOURCE) {
if (ipinfo->invflags & EBT_IP6_SOURCE)
printf("! ");
printf("--ip6-src ");
printf("%s", xtables_ip6addr_to_numeric(&ipinfo->saddr));
printf("%s ", xtables_ip6mask_to_numeric(&ipinfo->smsk));
}
if (ipinfo->bitmask & EBT_IP6_DEST) {
if (ipinfo->invflags & EBT_IP6_DEST)
printf("! ");
printf("--ip6-dst ");
printf("%s", xtables_ip6addr_to_numeric(&ipinfo->daddr));
printf("%s ", xtables_ip6mask_to_numeric(&ipinfo->dmsk));
}
if (ipinfo->bitmask & EBT_IP6_TCLASS) {
if (ipinfo->invflags & EBT_IP6_TCLASS)
printf("! ");
printf("--ip6-tclass 0x%02X ", ipinfo->tclass);
}
if (ipinfo->bitmask & EBT_IP6_PROTO) {
struct protoent *pe;
if (ipinfo->invflags & EBT_IP6_PROTO)
printf("! ");
printf("--ip6-proto ");
pe = getprotobynumber(ipinfo->protocol);
if (pe == NULL) {
printf("%d ", ipinfo->protocol);
} else {
printf("%s ", pe->p_name);
}
}
if (ipinfo->bitmask & EBT_IP6_SPORT) {
if (ipinfo->invflags & EBT_IP6_SPORT)
printf("! ");
printf("--ip6-sport ");
print_port_range(ipinfo->sport);
}
if (ipinfo->bitmask & EBT_IP6_DPORT) {
if (ipinfo->invflags & EBT_IP6_DPORT)
printf("! ");
printf("--ip6-dport ");
print_port_range(ipinfo->dport);
}
if (ipinfo->bitmask & EBT_IP6_ICMP6) {
if (ipinfo->invflags & EBT_IP6_ICMP6)
printf("! ");
printf("--ip6-icmp-type ");
print_icmp_type(ipinfo->icmpv6_type, ipinfo->icmpv6_code);
}
}
static void brip_xlate_th(struct xt_xlate *xl,
const struct ebt_ip6_info *info, int bit,
const char *pname)
{
const uint16_t *ports;
if ((info->bitmask & bit) == 0)
return;
switch (bit) {
case EBT_IP6_SPORT:
if (pname)
xt_xlate_add(xl, "%s sport ", pname);
else
xt_xlate_add(xl, "@th,0,16 ");
ports = info->sport;
break;
case EBT_IP6_DPORT:
if (pname)
xt_xlate_add(xl, "%s dport ", pname);
else
xt_xlate_add(xl, "@th,16,16 ");
ports = info->dport;
break;
default:
return;
}
if (info->invflags & bit)
xt_xlate_add(xl, "!= ");
if (ports[0] == ports[1])
xt_xlate_add(xl, "%d ", ports[0]);
else
xt_xlate_add(xl, "%d-%d ", ports[0], ports[1]);
}
static void brip_xlate_nh(struct xt_xlate *xl,
const struct ebt_ip6_info *info, int bit)
{
struct in6_addr *addrp, *maskp;
if ((info->bitmask & bit) == 0)
return;
switch (bit) {
case EBT_IP6_SOURCE:
xt_xlate_add(xl, "ip6 saddr ");
addrp = (struct in6_addr *)&info->saddr;
maskp = (struct in6_addr *)&info->smsk;
break;
case EBT_IP6_DEST:
xt_xlate_add(xl, "ip6 daddr ");
addrp = (struct in6_addr *)&info->daddr;
maskp = (struct in6_addr *)&info->dmsk;
break;
default:
return;
}
if (info->invflags & bit)
xt_xlate_add(xl, "!= ");
xt_xlate_add(xl, "%s%s ", xtables_ip6addr_to_numeric(addrp),
xtables_ip6mask_to_numeric(maskp));
}
static const char *brip6_xlate_proto_to_name(uint8_t proto)
{
switch (proto) {
case IPPROTO_TCP:
return "tcp";
case IPPROTO_UDP:
return "udp";
case IPPROTO_UDPLITE:
return "udplite";
case IPPROTO_SCTP:
return "sctp";
case IPPROTO_DCCP:
return "dccp";
default:
return NULL;
}
}
static int brip6_xlate(struct xt_xlate *xl,
const struct xt_xlate_mt_params *params)
{
const struct ebt_ip6_info *info = (const void *)params->match->data;
const char *pname = NULL;
if ((info->bitmask & (EBT_IP6_SOURCE|EBT_IP6_DEST|EBT_IP6_ICMP6|EBT_IP6_TCLASS)) == 0)
xt_xlate_add(xl, "ether type ip6 ");
brip_xlate_nh(xl, info, EBT_IP6_SOURCE);
brip_xlate_nh(xl, info, EBT_IP6_DEST);
if (info->bitmask & EBT_IP6_TCLASS) {
xt_xlate_add(xl, "ip6 dscp ");
if (info->invflags & EBT_IP6_TCLASS)
xt_xlate_add(xl, "!= ");
xt_xlate_add(xl, "0x%02x ", info->tclass & 0x3f); /* remove ECN bits */
}
if (info->bitmask & EBT_IP6_PROTO) {
struct protoent *pe;
if (info->bitmask & (EBT_IP6_SPORT|EBT_IP6_DPORT|EBT_IP6_ICMP6) &&
(info->invflags & EBT_IP6_PROTO) == 0) {
/* port number given and not inverted, no need to
* add explicit 'meta l4proto'.
*/
pname = brip6_xlate_proto_to_name(info->protocol);
} else {
xt_xlate_add(xl, "meta l4proto ");
if (info->invflags & EBT_IP6_PROTO)
xt_xlate_add(xl, "!= ");
pe = getprotobynumber(info->protocol);
if (pe == NULL)
xt_xlate_add(xl, "%d ", info->protocol);
else
xt_xlate_add(xl, "%s ", pe->p_name);
}
}
brip_xlate_th(xl, info, EBT_IP6_SPORT, pname);
brip_xlate_th(xl, info, EBT_IP6_DPORT, pname);
if (info->bitmask & EBT_IP6_ICMP6) {
xt_xlate_add(xl, "icmpv6 type ");
if (info->invflags & EBT_IP6_ICMP6)
xt_xlate_add(xl, "!= ");
if (info->icmpv6_type[0] == info->icmpv6_type[1])
xt_xlate_add(xl, "%d ", info->icmpv6_type[0]);
else
xt_xlate_add(xl, "%d-%d ", info->icmpv6_type[0],
info->icmpv6_type[1]);
if (info->icmpv6_code[0] == 0 &&
info->icmpv6_code[1] == 0xff)
return 1;
xt_xlate_add(xl, "icmpv6 code ");
if (info->invflags & EBT_IP6_ICMP6)
xt_xlate_add(xl, "!= ");
if (info->icmpv6_code[0] == info->icmpv6_code[1])
xt_xlate_add(xl, "%d ", info->icmpv6_code[0]);
else
xt_xlate_add(xl, "%d-%d ", info->icmpv6_code[0],
info->icmpv6_code[1]);
}
return 1;
}
static struct xtables_match brip6_match = {
.name = "ip6",
.revision = 0,
.version = XTABLES_VERSION,
.family = NFPROTO_BRIDGE,
.size = XT_ALIGN(sizeof(struct ebt_ip6_info)),
.userspacesize = XT_ALIGN(sizeof(struct ebt_ip6_info)),
.help = brip6_print_help,
.x6_parse = brip6_parse,
.x6_fcheck = brip6_final_check,
.print = brip6_print,
.xlate = brip6_xlate,
.x6_options = brip6_opts,
};
void _init(void)
{
xtables_register_match(&brip6_match);
}
+35
View File
@@ -0,0 +1,35 @@
:INPUT,FORWARD,OUTPUT
-p ip6 ! --ip6-src dead::beef/64 -j ACCEPT;-p IPv6 ! --ip6-src dead::/64 -j ACCEPT;OK
-p IPv6 --ip6-dst dead:beef::/64 -j ACCEPT;=;OK
-p IPv6 --ip6-dst f00:ba::;=;OK
-p IPv6 ! --ip6-dst f00:ba::;=;OK
-p IPv6 --ip6-src 10.0.0.1;;FAIL
-p IPv6 --ip6-tclass 0xFF;=;OK
-p IPv6 ! --ip6-tclass 0xFF;=;OK
-p IPv6 --ip6-proto tcp --ip6-dport 22;=;OK
-p IPv6 --ip6-proto tcp ! --ip6-dport 22;=;OK
-p IPv6 --ip6-proto tcp ! --ip6-sport 22 --ip6-dport 22;=;OK
-p IPv6 --ip6-proto udp --ip6-sport 1024:65535;=;OK
-p IPv6 --ip6-proto udp --ip6-sport :;-p IPv6 --ip6-proto udp --ip6-sport 0:65535;OK
-p IPv6 --ip6-proto udp --ip6-sport :4;-p IPv6 --ip6-proto udp --ip6-sport 0:4;OK
-p IPv6 --ip6-proto udp --ip6-sport 4:;-p IPv6 --ip6-proto udp --ip6-sport 4:65535;OK
-p IPv6 --ip6-proto udp --ip6-sport 3:4;=;OK
-p IPv6 --ip6-proto udp --ip6-sport 4:4;-p IPv6 --ip6-proto udp --ip6-sport 4;OK
-p IPv6 --ip6-proto udp --ip6-sport 4:3;;FAIL
-p IPv6 --ip6-proto udp --ip6-dport :;-p IPv6 --ip6-proto udp --ip6-dport 0:65535;OK
-p IPv6 --ip6-proto udp --ip6-dport :4;-p IPv6 --ip6-proto udp --ip6-dport 0:4;OK
-p IPv6 --ip6-proto udp --ip6-dport 4:;-p IPv6 --ip6-proto udp --ip6-dport 4:65535;OK
-p IPv6 --ip6-proto udp --ip6-dport 3:4;=;OK
-p IPv6 --ip6-proto udp --ip6-dport 4:4;-p IPv6 --ip6-proto udp --ip6-dport 4;OK
-p IPv6 --ip6-proto udp --ip6-dport 4:3;;FAIL
-p IPv6 --ip6-proto 253;=;OK
-p IPv6 ! --ip6-proto 253;=;OK
-p IPv6 --ip6-proto ipv6-icmp --ip6-icmp-type echo-request -j CONTINUE;=;OK
-p IPv6 --ip6-proto ipv6-icmp --ip6-icmp-type echo-request;=;OK
-p IPv6 --ip6-proto ipv6-icmp ! --ip6-icmp-type echo-request;=;OK
-p ip6 --ip6-protocol icmpv6 --ip6-icmp-type 1/1;-p IPv6 --ip6-proto ipv6-icmp --ip6-icmp-type communication-prohibited -j CONTINUE;OK
-p IPv6 --ip6-proto ipv6-icmp ! --ip6-icmp-type 1:10/0:255;=;OK
--ip6-proto ipv6-icmp ! --ip6-icmp-type 1:10/0:255;=;FAIL
! -p IPv6 --ip6-proto ipv6-icmp ! --ip6-icmp-type 1:10/0:255;=;FAIL
-p IPv6 --ip6-proto tcp --ip6-sport 22 --ip6-icmp-type echo-request;;FAIL
-p IPv6 --ip6-proto tcp --ip6-dport 22 --ip6-icmp-type echo-request;;FAIL
+29
View File
@@ -0,0 +1,29 @@
ebtables-translate -A FORWARD -p ip6 --ip6-src ! dead::beef/64 -j ACCEPT
nft 'add rule bridge filter FORWARD ip6 saddr != dead::/64 counter accept'
ebtables-translate -A FORWARD -p ip6 ! --ip6-dst dead:beef::/64 -j ACCEPT
nft 'add rule bridge filter FORWARD ip6 daddr != dead:beef::/64 counter accept'
ebtables-translate -I FORWARD -p ip6 --ip6-dst f00:ba::
nft 'insert rule bridge filter FORWARD ip6 daddr f00:ba:: counter'
ebtables-translate -I OUTPUT -o eth0 -p ip6 --ip6-tclass 0xff
nft 'insert rule bridge filter OUTPUT oifname "eth0" ip6 dscp 0x3f counter'
ebtables-translate -A FORWARD -p ip6 --ip6-proto tcp --ip6-dport 22
nft 'add rule bridge filter FORWARD ether type ip6 tcp dport 22 counter'
ebtables-translate -A FORWARD -p ip6 --ip6-proto udp --ip6-sport 1024:65535
nft 'add rule bridge filter FORWARD ether type ip6 udp sport 1024-65535 counter'
ebtables-translate -A FORWARD -p ip6 --ip6-proto 253
nft 'add rule bridge filter FORWARD ether type ip6 meta l4proto 253 counter'
ebtables-translate -A FORWARD -p ip6 --ip6-protocol icmpv6 --ip6-icmp-type "echo-request"
nft 'add rule bridge filter FORWARD icmpv6 type 128 counter'
ebtables-translate -A FORWARD -p ip6 --ip6-protocol icmpv6 --ip6-icmp-type 1/1
nft 'add rule bridge filter FORWARD icmpv6 type 1 icmpv6 code 1 counter'
ebtables-translate -A FORWARD -p ip6 --ip6-protocol icmpv6 ! --ip6-icmp-type 1:10
nft 'add rule bridge filter FORWARD icmpv6 type != 1-10 counter'
+8
View File
@@ -0,0 +1,8 @@
ebtables-translate -A INPUT --limit 3/m --limit-burst 3
nft 'add rule bridge filter INPUT limit rate 3/minute burst 3 packets counter'
ebtables-translate -A INPUT --limit 10/s --limit-burst 5
nft 'add rule bridge filter INPUT limit rate 10/second burst 5 packets counter'
ebtables-translate -A INPUT --limit 10/s --limit-burst 0
nft 'add rule bridge filter INPUT limit rate 10/second counter'
+156
View File
@@ -0,0 +1,156 @@
/*
* Bart De Schuymer <bdschuym@pandora.be>
*
* 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.
*
* Giuseppe Longo <giuseppelng@gmail.com> adapted the original code to the
* xtables-compat environment in 2015.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include <string.h>
#include <xtables.h>
#include <linux/netfilter_bridge/ebt_log.h>
#define LOG_DEFAULT_LEVEL LOG_INFO
struct code {
char *c_name;
int c_val;
};
static struct code eight_priority[] = {
{ "emerg", LOG_EMERG },
{ "alert", LOG_ALERT },
{ "crit", LOG_CRIT },
{ "error", LOG_ERR },
{ "warning", LOG_WARNING },
{ "notice", LOG_NOTICE },
{ "info", LOG_INFO },
{ "debug", LOG_DEBUG }
};
enum {
/* first three must correspond with bit pos in respective EBT_LOG_* */
O_LOG_IP = 0,
O_LOG_ARP = 1,
O_LOG_IP6 = 3,
O_LOG_PREFIX,
O_LOG_LEVEL,
O_LOG_LOG,
};
static const struct xt_option_entry brlog_opts[] = {
{ .name = "log-prefix", .id = O_LOG_PREFIX, .type = XTTYPE_STRING,
.flags = XTOPT_PUT, XTOPT_POINTER(struct ebt_log_info, prefix) },
{ .name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL,
.flags = XTOPT_PUT, XTOPT_POINTER(struct ebt_log_info, loglevel) },
{ .name = "log-arp", .id = O_LOG_ARP, .type = XTTYPE_NONE },
{ .name = "log-ip", .id = O_LOG_IP, .type = XTTYPE_NONE },
{ .name = "log", .id = O_LOG_LOG, .type = XTTYPE_NONE },
{ .name = "log-ip6", .id = O_LOG_IP6, .type = XTTYPE_NONE },
XTOPT_TABLEEND,
};
static void brlog_help(void)
{
int i;
printf(
"log options:\n"
"--log : use this if you're not specifying anything\n"
"--log-level level : level = [1-8] or a string\n"
"--log-prefix prefix : max. %d chars.\n"
"--log-ip : put ip info. in the log for ip packets\n"
"--log-arp : put (r)arp info. in the log for (r)arp packets\n"
"--log-ip6 : put ip6 info. in the log for ip6 packets\n"
, EBT_LOG_PREFIX_SIZE - 1);
for (i = 0; i < 8; i++)
printf("%d = %s\n", eight_priority[i].c_val,
eight_priority[i].c_name);
}
static void brlog_init(struct xt_entry_target *t)
{
struct ebt_log_info *loginfo = (struct ebt_log_info *)t->data;
loginfo->loglevel = LOG_NOTICE;
}
static void brlog_parse(struct xt_option_call *cb)
{
struct ebt_log_info *loginfo = cb->data;
xtables_option_parse(cb);
switch (cb->entry->id) {
case O_LOG_IP:
case O_LOG_ARP:
case O_LOG_IP6:
loginfo->bitmask |= 1 << cb->entry->id;
break;
}
}
static void brlog_print(const void *ip, const struct xt_entry_target *target,
int numeric)
{
struct ebt_log_info *loginfo = (struct ebt_log_info *)target->data;
printf("--log-level %s", eight_priority[loginfo->loglevel].c_name);
if (loginfo->prefix[0])
printf(" --log-prefix \"%s\"", loginfo->prefix);
if (loginfo->bitmask & EBT_LOG_IP)
printf(" --log-ip");
if (loginfo->bitmask & EBT_LOG_ARP)
printf(" --log-arp");
if (loginfo->bitmask & EBT_LOG_IP6)
printf(" --log-ip6");
printf(" ");
}
static int brlog_xlate(struct xt_xlate *xl,
const struct xt_xlate_tg_params *params)
{
const struct ebt_log_info *loginfo = (const void *)params->target->data;
xt_xlate_add(xl, "log");
if (loginfo->prefix[0])
xt_xlate_add(xl, " prefix \"%s\"", loginfo->prefix);
if (loginfo->loglevel != LOG_DEFAULT_LEVEL)
xt_xlate_add(xl, " level %s", eight_priority[loginfo->loglevel].c_name);
/* ebt_log always decodes MAC header, nft_log always decodes upper header -
* so set flags ether and ignore EBT_LOG_IP, EBT_LOG_ARP and EBT_LOG_IP6 */
xt_xlate_add(xl, " flags ether ");
return 1;
}
static struct xtables_target brlog_target = {
.name = "log",
.revision = 0,
.ext_flags = XTABLES_EXT_WATCHER,
.version = XTABLES_VERSION,
.family = NFPROTO_BRIDGE,
.size = XT_ALIGN(sizeof(struct ebt_log_info)),
.userspacesize = XT_ALIGN(sizeof(struct ebt_log_info)),
.init = brlog_init,
.help = brlog_help,
.x6_parse = brlog_parse,
.print = brlog_print,
.xlate = brlog_xlate,
.x6_options = brlog_opts,
};
void _init(void)
{
xtables_register_target(&brlog_target);
}
+6
View File
@@ -0,0 +1,6 @@
:INPUT,FORWARD,OUTPUT
--log;--log-level notice;OK
--log-level crit;=;OK
--log-level 1;--log-level alert;OK
--log-level emerg --log-ip --log-arp --log-ip6;=;OK
--log-level crit --log-ip --log-arp --log-ip6 --log-prefix foo;--log-level crit --log-prefix "foo" --log-ip --log-arp --log-ip6 -j CONTINUE;OK
+15
View File
@@ -0,0 +1,15 @@
ebtables-translate -A INPUT --log
nft 'add rule bridge filter INPUT log level notice flags ether counter'
ebtables-translate -A INPUT --log-level 1
nft 'add rule bridge filter INPUT log level alert flags ether counter'
ebtables-translate -A INPUT --log-level crit
nft 'add rule bridge filter INPUT log level crit flags ether counter'
ebtables-translate -A INPUT --log-level emerg --log-ip --log-arp --log-ip6
nft 'add rule bridge filter INPUT log level emerg flags ether counter'
ebtables-translate -A INPUT --log-level crit --log-ip --log-arp --log-ip6 --log-prefix foo
nft 'add rule bridge filter INPUT log prefix "foo" level crit flags ether counter'
+196
View File
@@ -0,0 +1,196 @@
/* ebt_mark
*
* Authors:
* Bart De Schuymer <bdschuym@pandora.be>
*
* July, 2002, September 2006
*
* Adapted by Arturo Borrero Gonzalez <arturo@debian.org>
* to use libxtables for ebtables-compat in 2015.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <xtables.h>
#include <linux/netfilter_bridge/ebt_mark_t.h>
#include "iptables/nft.h"
#include "iptables/nft-bridge.h"
enum {
O_SET_MARK = 0,
O_AND_MARK,
O_OR_MARK,
O_XOR_MARK,
O_MARK_TARGET,
F_SET_MARK = 1 << O_SET_MARK,
F_AND_MARK = 1 << O_AND_MARK,
F_OR_MARK = 1 << O_OR_MARK,
F_XOR_MARK = 1 << O_XOR_MARK,
F_ANY = F_SET_MARK | F_AND_MARK | F_OR_MARK | F_XOR_MARK,
};
static const struct xt_option_entry brmark_opts[] = {
{ .name = "mark-target",.id = O_MARK_TARGET, .type = XTTYPE_STRING },
/* an oldtime messup, we should have always used the scheme
* <extension-name>-<option> */
{ .name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_UINT32,
.excl = F_ANY },
{ .name = "mark-set", .id = O_SET_MARK, .type = XTTYPE_UINT32,
.excl = F_ANY },
{ .name = "mark-or", .id = O_OR_MARK, .type = XTTYPE_UINT32,
.excl = F_ANY },
{ .name = "mark-and", .id = O_AND_MARK, .type = XTTYPE_UINT32,
.excl = F_ANY },
{ .name = "mark-xor", .id = O_XOR_MARK, .type = XTTYPE_UINT32,
.excl = F_ANY },
XTOPT_TABLEEND,
};
static void brmark_print_help(void)
{
printf(
"mark target options:\n"
" --mark-set value : Set nfmark value\n"
" --mark-or value : Or nfmark with value (nfmark |= value)\n"
" --mark-and value : And nfmark with value (nfmark &= value)\n"
" --mark-xor value : Xor nfmark with value (nfmark ^= value)\n"
" --mark-target target : ACCEPT, DROP, RETURN or CONTINUE\n");
}
static void brmark_init(struct xt_entry_target *target)
{
struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)target->data;
info->target = EBT_ACCEPT;
info->mark = 0;
}
static void brmark_parse(struct xt_option_call *cb)
{
static const unsigned long target_orval[] = {
[O_SET_MARK] = MARK_SET_VALUE,
[O_AND_MARK] = MARK_AND_VALUE,
[O_OR_MARK] = MARK_OR_VALUE,
[O_XOR_MARK] = MARK_XOR_VALUE,
};
struct ebt_mark_t_info *info = cb->data;
unsigned int tmp;
xtables_option_parse(cb);
switch (cb->entry->id) {
case O_MARK_TARGET:
if (ebt_fill_target(cb->arg, &tmp))
xtables_error(PARAMETER_PROBLEM,
"Illegal --mark-target target");
/* the 4 lsb are left to designate the target */
info->target = (info->target & ~EBT_VERDICT_BITS) |
(tmp & EBT_VERDICT_BITS);
return;
case O_SET_MARK:
case O_OR_MARK:
case O_AND_MARK:
case O_XOR_MARK:
break;
default:
return;
}
/* mutual code */
info->mark = cb->val.u32;
info->target = (info->target & EBT_VERDICT_BITS) |
target_orval[cb->entry->id];
}
static void brmark_print(const void *ip, const struct xt_entry_target *target,
int numeric)
{
struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)target->data;
int tmp;
tmp = info->target & ~EBT_VERDICT_BITS;
if (tmp == MARK_SET_VALUE)
printf("--mark-set");
else if (tmp == MARK_OR_VALUE)
printf("--mark-or");
else if (tmp == MARK_XOR_VALUE)
printf("--mark-xor");
else if (tmp == MARK_AND_VALUE)
printf("--mark-and");
else
xtables_error(PARAMETER_PROBLEM, "Unknown mark action");
printf(" 0x%lx", info->mark);
tmp = info->target | ~EBT_VERDICT_BITS;
printf(" --mark-target %s", ebt_target_name(tmp));
}
static void brmark_final_check(struct xt_fcheck_call *fc)
{
if (!fc->xflags)
xtables_error(PARAMETER_PROBLEM,
"You must specify some option");
}
static const char* brmark_verdict(int verdict)
{
switch (verdict) {
case EBT_ACCEPT: return "accept";
case EBT_DROP: return "drop";
case EBT_CONTINUE: return "continue";
case EBT_RETURN: return "return";
}
return "";
}
static int brmark_xlate(struct xt_xlate *xl,
const struct xt_xlate_tg_params *params)
{
const struct ebt_mark_t_info *info = (const void*)params->target->data;
int tmp;
tmp = info->target & ~EBT_VERDICT_BITS;
xt_xlate_add(xl, "meta mark set ");
switch (tmp) {
case MARK_SET_VALUE:
break;
case MARK_OR_VALUE:
xt_xlate_add(xl, "meta mark or ");
break;
case MARK_XOR_VALUE:
xt_xlate_add(xl, "meta mark xor ");
break;
case MARK_AND_VALUE:
xt_xlate_add(xl, "meta mark and ");
break;
default:
return 0;
}
tmp = info->target | ~EBT_VERDICT_BITS;
xt_xlate_add(xl, "0x%lx %s ", info->mark, brmark_verdict(tmp));
return 1;
}
static struct xtables_target brmark_target = {
.name = "mark",
.revision = 0,
.version = XTABLES_VERSION,
.family = NFPROTO_BRIDGE,
.size = XT_ALIGN(sizeof(struct ebt_mark_t_info)),
.userspacesize = XT_ALIGN(sizeof(struct ebt_mark_t_info)),
.help = brmark_print_help,
.init = brmark_init,
.x6_parse = brmark_parse,
.x6_fcheck = brmark_final_check,
.print = brmark_print,
.xlate = brmark_xlate,
.x6_options = brmark_opts,
};
void _init(void)
{
xtables_register_target(&brmark_target);
}
+5
View File
@@ -0,0 +1,5 @@
:INPUT,FORWARD,OUTPUT
-j mark --mark-set 1;-j mark --mark-set 0x1 --mark-target ACCEPT;OK
-j mark --mark-or 0xa --mark-target CONTINUE;=;OK
-j mark --mark-and 0x1 --mark-target RETURN;=;OK
-j mark --mark-xor 0x1 --mark-target CONTINUE;=;OK
+11
View File
@@ -0,0 +1,11 @@
ebtables-translate -A INPUT -j mark --mark-set 42
nft 'add rule bridge filter INPUT counter meta mark set 0x2a accept'
ebtables-translate -A INPUT -j mark --mark-or 42 --mark-target RETURN
nft 'add rule bridge filter INPUT counter meta mark set meta mark or 0x2a return'
ebtables-translate -A INPUT -j mark --mark-and 42 --mark-target ACCEPT
nft 'add rule bridge filter INPUT counter meta mark set meta mark and 0x2a accept'
ebtables-translate -A INPUT -j mark --mark-xor 42 --mark-target DROP
nft 'add rule bridge filter INPUT counter meta mark set meta mark xor 0x2a drop'
+118
View File
@@ -0,0 +1,118 @@
/* ebt_mark_m
*
* Authors:
* Bart De Schuymer <bdschuym@pandora.be>
*
* July, 2002
*
* Adapted by Arturo Borrero Gonzalez <arturo@debian.org>
* to use libxtables for ebtables-compat in 2015.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <xtables.h>
#include <linux/netfilter_bridge/ebt_mark_m.h>
enum {
O_MARK = 0,
};
static const struct xt_option_entry brmark_m_opts[] = {
{ .name = "mark", .id = O_MARK, .type = XTTYPE_STRING,
.flags = XTOPT_INVERT | XTOPT_MAND },
XTOPT_TABLEEND,
};
static void brmark_m_print_help(void)
{
printf(
"mark option:\n"
"[!] --mark [value][/mask]: Match nfmask value (see man page)\n");
}
static void brmark_m_parse(struct xt_option_call *cb)
{
struct ebt_mark_m_info *info = cb->data;
char *end;
xtables_option_parse(cb);
switch (cb->entry->id) {
case O_MARK:
info->invert = cb->invert;
info->mark = strtoul(cb->arg, &end, 0);
info->bitmask = EBT_MARK_AND;
if (*end == '/') {
if (end == cb->arg)
info->bitmask = EBT_MARK_OR;
info->mask = strtoul(end+1, &end, 0);
} else {
info->mask = UINT32_MAX;
}
if (*end != '\0' || end == cb->arg)
xtables_error(PARAMETER_PROBLEM, "Bad mark value '%s'",
cb->arg);
break;
}
}
static void brmark_m_print(const void *ip, const struct xt_entry_match *match,
int numeric)
{
struct ebt_mark_m_info *info = (struct ebt_mark_m_info *)match->data;
if (info->invert)
printf("! ");
printf("--mark ");
if (info->bitmask == EBT_MARK_OR)
printf("/0x%lx ", info->mask);
else if (info->mask != 0xffffffff)
printf("0x%lx/0x%lx ", info->mark, info->mask);
else
printf("0x%lx ", info->mark);
}
static int brmark_m_xlate(struct xt_xlate *xl,
const struct xt_xlate_mt_params *params)
{
const struct ebt_mark_m_info *info = (const void*)params->match->data;
enum xt_op op = XT_OP_EQ;
if (info->invert)
op = XT_OP_NEQ;
xt_xlate_add(xl, "meta mark ");
if (info->bitmask == EBT_MARK_OR) {
xt_xlate_add(xl, "and 0x%x %s0 ", (uint32_t)info->mask,
info->invert ? "" : "!= ");
} else if (info->mask != UINT32_MAX) {
xt_xlate_add(xl, "and 0x%x %s0x%x ", (uint32_t)info->mask,
op == XT_OP_EQ ? "" : "!= ", (uint32_t)info->mark);
} else {
xt_xlate_add(xl, "%s0x%x ",
op == XT_OP_EQ ? "" : "!= ", (uint32_t)info->mark);
}
return 1;
}
static struct xtables_match brmark_m_match = {
.name = "mark_m",
.revision = 0,
.version = XTABLES_VERSION,
.family = NFPROTO_BRIDGE,
.size = XT_ALIGN(sizeof(struct ebt_mark_m_info)),
.userspacesize = XT_ALIGN(sizeof(struct ebt_mark_m_info)),
.help = brmark_m_print_help,
.x6_parse = brmark_m_parse,
.print = brmark_m_print,
.xlate = brmark_m_xlate,
.x6_options = brmark_m_opts,
};
void _init(void)
{
xtables_register_match(&brmark_m_match);
}
+6
View File
@@ -0,0 +1,6 @@
:INPUT,FORWARD,OUTPUT
--mark 42;--mark 0x2a;OK
! --mark 42;! --mark 0x2a;OK
--mark 42/0xff;--mark 0x2a/0xff;OK
! --mark 0x1/0xff;=;OK
--mark /0x2;=;OK
+14
View File
@@ -0,0 +1,14 @@
ebtables-translate -A INPUT --mark 42
nft 'add rule bridge filter INPUT meta mark 0x2a counter'
ebtables-translate -A INPUT ! --mark 42
nft 'add rule bridge filter INPUT meta mark != 0x2a counter'
ebtables-translate -A INPUT --mark ! 42
nft 'add rule bridge filter INPUT meta mark != 0x2a counter'
ebtables-translate -A INPUT ! --mark 0x1/0xff
nft 'add rule bridge filter INPUT meta mark and 0xff != 0x1 counter'
ebtables-translate -A INPUT --mark /0x02
nft 'add rule bridge filter INPUT meta mark and 0x2 != 0 counter'
+119
View File
@@ -0,0 +1,119 @@
/* ebt_nflog
*
* Authors:
* Peter Warasin <peter@endian.com>
*
* February, 2008
*
* Based on:
* ebt_ulog.c, (C) 2004, Bart De Schuymer <bdschuym@pandora.be>
* libxt_NFLOG.c
*
* Adapted to libxtables for ebtables-compat in 2015 by
* Arturo Borrero Gonzalez <arturo@debian.org>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <xtables.h>
#include "iptables/nft.h"
#include "iptables/nft-bridge.h"
#include <linux/netfilter_bridge/ebt_nflog.h>
enum {
O_GROUP = 0,
O_PREFIX,
O_RANGE,
O_THRESHOLD,
O_NFLOG,
};
static const struct xt_option_entry brnflog_opts[] = {
{ .name = "nflog-group", .id = O_GROUP, .type = XTTYPE_UINT16,
.flags = XTOPT_PUT, XTOPT_POINTER(struct ebt_nflog_info, group) },
{ .name = "nflog-prefix", .id = O_PREFIX, .type = XTTYPE_STRING,
.flags = XTOPT_PUT, XTOPT_POINTER(struct ebt_nflog_info, prefix) },
{ .name = "nflog-range", .id = O_RANGE, .type = XTTYPE_UINT32,
.flags = XTOPT_PUT, XTOPT_POINTER(struct ebt_nflog_info, len) },
{ .name = "nflog-threshold", .id = O_THRESHOLD, .type = XTTYPE_UINT16,
.flags = XTOPT_PUT, XTOPT_POINTER(struct ebt_nflog_info, threshold) },
{ .name = "nflog", .id = O_NFLOG, .type = XTTYPE_NONE },
XTOPT_TABLEEND,
};
static void brnflog_help(void)
{
printf("nflog options:\n"
"--nflog : use the default nflog parameters\n"
"--nflog-prefix prefix : Prefix string for log message\n"
"--nflog-group group : NETLINK group used for logging\n"
"--nflog-range range : Number of byte to copy\n"
"--nflog-threshold : Message threshold of"
"in-kernel queue\n");
}
static void brnflog_init(struct xt_entry_target *t)
{
struct ebt_nflog_info *info = (struct ebt_nflog_info *)t->data;
info->prefix[0] = '\0';
info->group = EBT_NFLOG_DEFAULT_GROUP;
info->threshold = EBT_NFLOG_DEFAULT_THRESHOLD;
}
static void
brnflog_print(const void *ip, const struct xt_entry_target *target,
int numeric)
{
struct ebt_nflog_info *info = (struct ebt_nflog_info *)target->data;
if (info->prefix[0] != '\0')
printf("--nflog-prefix \"%s\" ", info->prefix);
if (info->group)
printf("--nflog-group %d ", info->group);
if (info->len)
printf("--nflog-range %d ", info->len);
if (info->threshold != EBT_NFLOG_DEFAULT_THRESHOLD)
printf("--nflog-threshold %d ", info->threshold);
}
static int brnflog_xlate(struct xt_xlate *xl,
const struct xt_xlate_tg_params *params)
{
const struct ebt_nflog_info *info = (void *)params->target->data;
xt_xlate_add(xl, "log ");
if (info->prefix[0] != '\0')
xt_xlate_add(xl, "prefix \"%s\" ", info->prefix);
xt_xlate_add(xl, "group %u ", info->group);
if (info->len)
xt_xlate_add(xl, "snaplen %u ", info->len);
if (info->threshold != EBT_NFLOG_DEFAULT_THRESHOLD)
xt_xlate_add(xl, "queue-threshold %u ", info->threshold);
return 1;
}
static struct xtables_target brnflog_watcher = {
.name = "nflog",
.revision = 0,
.ext_flags = XTABLES_EXT_WATCHER,
.version = XTABLES_VERSION,
.family = NFPROTO_BRIDGE,
.size = XT_ALIGN(sizeof(struct ebt_nflog_info)),
.userspacesize = XT_ALIGN(sizeof(struct ebt_nflog_info)),
.init = brnflog_init,
.help = brnflog_help,
.x6_parse = xtables_option_parse,
.print = brnflog_print,
.xlate = brnflog_xlate,
.x6_options = brnflog_opts,
};
void _init(void)
{
xtables_register_target(&brnflog_watcher);
}
+5
View File
@@ -0,0 +1,5 @@
:INPUT,FORWARD,OUTPUT
--nflog;--nflog-group 1;OK
--nflog-group 42;=;OK
--nflog-range 42;--nflog-group 1 --nflog-range 42 -j CONTINUE;OK
--nflog-threshold 100 --nflog-prefix foo;--nflog-prefix "foo" --nflog-group 1 --nflog-threshold 100 -j CONTINUE;OK
+11
View File
@@ -0,0 +1,11 @@
ebtables-translate -A INPUT --nflog
nft 'add rule bridge filter INPUT log group 1 counter'
ebtables-translate -A INPUT --nflog-group 42
nft 'add rule bridge filter INPUT log group 42 counter'
ebtables-translate -A INPUT --nflog-range 42
nft 'add rule bridge filter INPUT log group 1 snaplen 42 counter'
ebtables-translate -A INPUT --nflog-threshold 100 --nflog-prefix foo
nft 'add rule bridge filter INPUT log prefix "foo" group 1 queue-threshold 100 counter'
+120
View File
@@ -0,0 +1,120 @@
/* ebt_pkttype
*
* Authors:
* Bart De Schuymer <bdschuym@pandora.be>
*
* April, 2003
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <xtables.h>
#include <linux/if_packet.h>
#include <linux/netfilter_bridge/ebt_pkttype.h>
static const char *classes[] = {
"host",
"broadcast",
"multicast",
"otherhost",
"outgoing",
"loopback",
"fastroute",
};
enum {
O_TYPE,
};
static const struct xt_option_entry brpkttype_opts[] = {
{ .name = "pkttype-type", .id = O_TYPE, .type = XTTYPE_STRING,
.flags = XTOPT_INVERT },
XTOPT_TABLEEND,
};
static void brpkttype_print_help(void)
{
printf(
"pkttype options:\n"
"[!] --pkttype-type type: class the packet belongs to\n"
"Possible values: broadcast, multicast, host, otherhost, or any other byte value (which would be pretty useless).\n");
}
static void brpkttype_parse(struct xt_option_call *cb)
{
struct ebt_pkttype_info *ptinfo = cb->data;
long int i;
char *end;
xtables_option_parse(cb);
switch (cb->entry->id) {
case O_TYPE:
ptinfo->invert = cb->invert;
i = strtol(cb->arg, &end, 16);
if (*end != '\0') {
for (i = 0; i < ARRAY_SIZE(classes); i++) {
if (!strcasecmp(cb->arg, classes[i]))
break;
}
if (i >= ARRAY_SIZE(classes))
xtables_error(PARAMETER_PROBLEM,
"Could not parse class '%s'",
cb->arg);
}
if (i < 0 || i > 255)
xtables_error(PARAMETER_PROBLEM, "Problem with specified pkttype class");
ptinfo->pkt_type = (uint8_t)i;
break;
}
}
static void brpkttype_print(const void *ip, const struct xt_entry_match *match, int numeric)
{
struct ebt_pkttype_info *pt = (struct ebt_pkttype_info *)match->data;
printf("%s--pkttype-type ", pt->invert ? "! " : "");
if (pt->pkt_type < ARRAY_SIZE(classes))
printf("%s ", classes[pt->pkt_type]);
else
printf("%d ", pt->pkt_type);
}
static int brpkttype_xlate(struct xt_xlate *xl,
const struct xt_xlate_mt_params *params)
{
const struct ebt_pkttype_info *info = (const void*)params->match->data;
xt_xlate_add(xl, "meta pkttype %s", info->invert ? "!= " : "");
if (info->pkt_type < 3)
xt_xlate_add(xl, "%s ", classes[info->pkt_type]);
else if (info->pkt_type == 3)
xt_xlate_add(xl, "other ");
else
xt_xlate_add(xl, "%d ", info->pkt_type);
return 1;
}
static struct xtables_match brpkttype_match = {
.name = "pkttype",
.version = XTABLES_VERSION,
.family = NFPROTO_BRIDGE,
.size = XT_ALIGN(sizeof(struct ebt_pkttype_info)),
.userspacesize = XT_ALIGN(sizeof(struct ebt_pkttype_info)),
.help = brpkttype_print_help,
.x6_parse = brpkttype_parse,
.print = brpkttype_print,
.xlate = brpkttype_xlate,
.x6_options = brpkttype_opts,
};
void _init(void)
{
xtables_register_match(&brpkttype_match);
}
+14
View File
@@ -0,0 +1,14 @@
:INPUT,FORWARD,OUTPUT
--pkttype-type ! host;! --pkttype-type host -j CONTINUE;OK
--pkttype-type host;=;OK
! --pkttype-type host;=;OK
--pkttype-type broadcast;=;OK
! --pkttype-type broadcast;=;OK
--pkttype-type multicast;=;OK
! --pkttype-type multicast;=;OK
--pkttype-type otherhost;=;OK
! --pkttype-type otherhost;=;OK
--pkttype-type outgoing;=;OK
! --pkttype-type outgoing;=;OK
--pkttype-type loopback;=;OK
! --pkttype-type loopback;=;OK
+20
View File
@@ -0,0 +1,20 @@
ebtables-translate -A INPUT --pkttype-type host
nft 'add rule bridge filter INPUT meta pkttype host counter'
ebtables-translate -A INPUT ! --pkttype-type broadcast
nft 'add rule bridge filter INPUT meta pkttype != broadcast counter'
ebtables-translate -A INPUT --pkttype-type ! multicast
nft 'add rule bridge filter INPUT meta pkttype != multicast counter'
ebtables-translate -A INPUT --pkttype-type otherhost
nft 'add rule bridge filter INPUT meta pkttype other counter'
ebtables-translate -A INPUT --pkttype-type outgoing
nft 'add rule bridge filter INPUT meta pkttype 4 counter'
ebtables-translate -A INPUT --pkttype-type loopback
nft 'add rule bridge filter INPUT meta pkttype 5 counter'
ebtables-translate -A INPUT --pkttype-type fastroute
nft 'add rule bridge filter INPUT meta pkttype 6 counter'
+103
View File
@@ -0,0 +1,103 @@
/* ebt_redirect
*
* Authors:
* Bart De Schuymer <bdschuym@pandora.be>
*
* April, 2002
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <xtables.h>
#include <linux/netfilter_bridge/ebt_redirect.h>
#include "iptables/nft.h"
#include "iptables/nft-bridge.h"
enum {
O_TARGET,
};
static const struct xt_option_entry brredir_opts[] =
{
{ .name = "redirect-target", .id = O_TARGET, .type = XTTYPE_STRING },
XTOPT_TABLEEND,
};
static void brredir_print_help(void)
{
printf(
"redirect option:\n"
" --redirect-target target : ACCEPT, DROP, RETURN or CONTINUE\n");
}
static void brredir_init(struct xt_entry_target *target)
{
struct ebt_redirect_info *redirectinfo =
(struct ebt_redirect_info *)target->data;
redirectinfo->target = EBT_ACCEPT;
}
static void brredir_parse(struct xt_option_call *cb)
{
struct ebt_redirect_info *redirectinfo = cb->data;
xtables_option_parse(cb);
if (cb->entry->id == O_TARGET &&
ebt_fill_target(cb->arg, (unsigned int *)&redirectinfo->target))
xtables_error(PARAMETER_PROBLEM,
"Illegal --redirect-target target");
}
static void brredir_print(const void *ip, const struct xt_entry_target *target, int numeric)
{
struct ebt_redirect_info *redirectinfo =
(struct ebt_redirect_info *)target->data;
if (redirectinfo->target == EBT_ACCEPT)
return;
printf("--redirect-target %s", ebt_target_name(redirectinfo->target));
}
static const char* brredir_verdict(int verdict)
{
switch (verdict) {
case EBT_ACCEPT: return "accept";
case EBT_DROP: return "drop";
case EBT_CONTINUE: return "continue";
case EBT_RETURN: return "return";
}
return "";
}
static int brredir_xlate(struct xt_xlate *xl,
const struct xt_xlate_tg_params *params)
{
const struct ebt_redirect_info *red = (const void*)params->target->data;
xt_xlate_add(xl, "meta pkttype set host");
if (red->target != EBT_CONTINUE)
xt_xlate_add(xl, " %s ", brredir_verdict(red->target));
return 1;
}
static struct xtables_target brredirect_target = {
.name = "redirect",
.version = XTABLES_VERSION,
.family = NFPROTO_BRIDGE,
.size = XT_ALIGN(sizeof(struct ebt_redirect_info)),
.userspacesize = XT_ALIGN(sizeof(struct ebt_redirect_info)),
.help = brredir_print_help,
.init = brredir_init,
.x6_parse = brredir_parse,
.print = brredir_print,
.xlate = brredir_xlate,
.x6_options = brredir_opts,
};
void _init(void)
{
xtables_register_target(&brredirect_target);
}
+4
View File
@@ -0,0 +1,4 @@
:PREROUTING
*nat
-j redirect ;=;OK
-j redirect --redirect-target RETURN;=;OK
+8
View File
@@ -0,0 +1,8 @@
ebtables-translate -t nat -A PREROUTING -d de:ad:00:00:be:ef -j redirect
nft 'add rule bridge nat PREROUTING ether daddr de:ad:00:00:be:ef counter meta pkttype set host accept'
ebtables-translate -t nat -A PREROUTING -d de:ad:00:00:be:ef -j redirect --redirect-target RETURN
nft 'add rule bridge nat PREROUTING ether daddr de:ad:00:00:be:ef counter meta pkttype set host return'
ebtables-translate -t nat -A PREROUTING -d de:ad:00:00:be:ef -j redirect --redirect-target CONTINUE
nft 'add rule bridge nat PREROUTING ether daddr de:ad:00:00:be:ef counter meta pkttype set host'
+136
View File
@@ -0,0 +1,136 @@
/* ebt_nat
*
* Authors:
* Bart De Schuymer <bdschuym@pandora.be>
*
* June, 2002
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/ether.h>
#include <xtables.h>
#include <linux/netfilter_bridge/ebt_nat.h>
#include "iptables/nft.h"
#include "iptables/nft-bridge.h"
enum {
O_SRC,
O_TARGET,
O_ARP,
};
static const struct xt_option_entry brsnat_opts[] =
{
{ .name = "to-source", .id = O_SRC, .type = XTTYPE_ETHERMAC,
.flags = XTOPT_PUT, XTOPT_POINTER(struct ebt_nat_info, mac) },
{ .name = "to-src", .id = O_SRC, .type = XTTYPE_ETHERMAC,
.flags = XTOPT_PUT, XTOPT_POINTER(struct ebt_nat_info, mac) },
{ .name = "snat-target", .id = O_TARGET, .type = XTTYPE_STRING },
{ .name = "snat-arp", .id = O_ARP, .type = XTTYPE_NONE },
XTOPT_TABLEEND,
};
static void brsnat_print_help(void)
{
printf(
"snat options:\n"
" --to-src address : MAC address to map source to\n"
" --snat-target target : ACCEPT, DROP, RETURN or CONTINUE\n"
" --snat-arp : also change src address in arp msg\n");
}
static void brsnat_init(struct xt_entry_target *target)
{
struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
natinfo->target = EBT_ACCEPT;
}
static void brsnat_parse(struct xt_option_call *cb)
{
struct ebt_nat_info *natinfo = cb->data;
unsigned int tmp;
xtables_option_parse(cb);
switch (cb->entry->id) {
case O_TARGET:
if (ebt_fill_target(cb->arg, &tmp))
xtables_error(PARAMETER_PROBLEM,
"Illegal --snat-target target");
natinfo->target &= ~EBT_VERDICT_BITS;
natinfo->target |= tmp & EBT_VERDICT_BITS;
break;
case O_ARP:
natinfo->target ^= NAT_ARP_BIT;
break;
}
}
static void brsnat_final_check(struct xt_fcheck_call *fc)
{
if (!fc->xflags)
xtables_error(PARAMETER_PROBLEM,
"You must specify proper arguments");
}
static void brsnat_print(const void *ip, const struct xt_entry_target *target, int numeric)
{
struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
printf("--to-src ");
xtables_print_mac(natinfo->mac);
if (!(natinfo->target&NAT_ARP_BIT))
printf(" --snat-arp");
printf(" --snat-target %s", ebt_target_name((natinfo->target|~EBT_VERDICT_BITS)));
}
static const char* brsnat_verdict(int verdict)
{
switch (verdict) {
case EBT_ACCEPT: return "accept";
case EBT_DROP: return "drop";
case EBT_CONTINUE: return "continue";
case EBT_RETURN: return "return";
}
return "";
}
static int brsnat_xlate(struct xt_xlate *xl,
const struct xt_xlate_tg_params *params)
{
const struct ebt_nat_info *natinfo = (const void*)params->target->data;
xt_xlate_add(xl, "ether saddr set %s ",
ether_ntoa((struct ether_addr *)natinfo->mac));
/* NAT_ARP_BIT set -> no arp mangling, not set -> arp mangling (yes, its inverted) */
if (!(natinfo->target&NAT_ARP_BIT))
return 0;
xt_xlate_add(xl, "%s ", brsnat_verdict(natinfo->target | ~EBT_VERDICT_BITS));
return 1;
}
static struct xtables_target brsnat_target =
{
.name = "snat",
.version = XTABLES_VERSION,
.family = NFPROTO_BRIDGE,
.size = XT_ALIGN(sizeof(struct ebt_nat_info)),
.userspacesize = XT_ALIGN(sizeof(struct ebt_nat_info)),
.help = brsnat_print_help,
.init = brsnat_init,
.x6_parse = brsnat_parse,
.x6_fcheck = brsnat_final_check,
.print = brsnat_print,
.xlate = brsnat_xlate,
.x6_options = brsnat_opts,
};
void _init(void)
{
xtables_register_target(&brsnat_target);
}
+6
View File
@@ -0,0 +1,6 @@
:POSTROUTING
*nat
-o someport -j snat --to-source a:b:c:d:e:f;-o someport -j snat --to-src 0a:0b:0c:0d:0e:0f --snat-target ACCEPT;OK
-o someport+ -j snat --to-src de:ad:00:be:ee:ff --snat-target CONTINUE;=;OK
-j snat;;FAIL
-j snat --to-src de:ad:00:be:ee:ff;-j snat --to-src de:ad:00:be:ee:ff --snat-target ACCEPT;OK
+5
View File
@@ -0,0 +1,5 @@
ebtables-translate -t nat -A POSTROUTING -s 0:0:0:0:0:0 -o someport+ -j snat --to-source de:ad:00:be:ee:ff
nft 'add rule bridge nat POSTROUTING oifname "someport*" ether saddr 00:00:00:00:00:00 counter ether saddr set de:ad:0:be:ee:ff accept'
ebtables-translate -t nat -A POSTROUTING -o someport -j snat --to-src de:ad:00:be:ee:ff --snat-target CONTINUE
nft 'add rule bridge nat POSTROUTING oifname "someport" counter ether saddr set de:ad:0:be:ee:ff continue'
+40
View File
@@ -0,0 +1,40 @@
:INPUT,FORWARD,OUTPUT
-d de:ad:be:ef:00:00;=;OK
-s 0:0:0:0:0:0;-s 00:00:00:00:00:00;OK
-d 00:00:00:00:00:00;=;OK
-s de:ad:be:ef:0:00 -j RETURN;-s de:ad:be:ef:00:00 -j RETURN;OK
-d de:ad:be:ef:00:00 -j CONTINUE;=;OK
-d de:ad:be:ef:0:00/ff:ff:ff:ff:0:0 -j DROP;-d de:ad:be:ef:00:00/ff:ff:ff:ff:00:00 -j DROP;OK
-p ARP -j ACCEPT;=;OK
! -p ARP -j ACCEPT;=;OK
-p ! ARP -j ACCEPT;! -p ARP -j ACCEPT;OK
-p 0 -j ACCEPT;=;FAIL
-p ! 0 -j ACCEPT;=;FAIL
:INPUT
-i foobar;=;OK
-o foobar;=;FAIL
--logical-in br0;=;OK
--logical-out br1;=;FAIL
-i + -d 00:0f:ee:d0:ba:be;-d 00:0f:ee:d0:ba:be;OK
-i + -p ip;-p IPv4;OK
! -i +;=;OK
--logical-in + -d 00:0f:ee:d0:ba:be;-d 00:0f:ee:d0:ba:be;OK
--logical-in + -p ip;-p IPv4;OK
! --logical-in +;=;OK
:FORWARD
-i foobar;=;OK
-o foobar;=;OK
--logical-in br0 --logical-out br1;=;OK
:OUTPUT
-i foobar;=;FAIL
-o foobar;=;OK
--logical-in br0;=;FAIL
--logical-out br1;=;OK
:PREROUTING
*nat
-i foobar;=;OK
-o foobar;=;FAIL
:POSTROUTING
*nat
-i foobar;=;FAIL
-o foobar;=;OK
+241
View File
@@ -0,0 +1,241 @@
/* ebt_stp
*
* Authors:
* Bart De Schuymer <bdschuym@pandora.be>
*
* July, 2003
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/ether.h>
#include <linux/netfilter_bridge/ebt_stp.h>
#include <xtables.h>
#include "iptables/nft.h"
#include "iptables/nft-bridge.h"
/* These must correspond to the bit position in EBT_STP_* defines */
enum {
O_TYPE = 0,
O_FLAGS,
O_RPRIO,
O_RADDR,
O_RCOST,
O_SPRIO,
O_SADDR,
O_PORT,
O_MSGAGE,
O_MAXAGE,
O_HTIME,
O_FWDD,
};
static const struct xt_option_entry brstp_opts[] = {
#define ENTRY(n, i, t) { .name = n, .id = i, .type = t, .flags = XTOPT_INVERT }
ENTRY("stp-type", O_TYPE, XTTYPE_STRING),
ENTRY("stp-flags", O_FLAGS, XTTYPE_STRING),
ENTRY("stp-root-prio", O_RPRIO, XTTYPE_UINT16RC),
ENTRY("stp-root-addr", O_RADDR, XTTYPE_ETHERMACMASK),
ENTRY("stp-root-cost", O_RCOST, XTTYPE_UINT32RC),
ENTRY("stp-sender-prio", O_SPRIO, XTTYPE_UINT16RC),
ENTRY("stp-sender-addr", O_SADDR, XTTYPE_ETHERMACMASK),
ENTRY("stp-port", O_PORT, XTTYPE_UINT16RC),
ENTRY("stp-msg-age", O_MSGAGE, XTTYPE_UINT16RC),
ENTRY("stp-max-age", O_MAXAGE, XTTYPE_UINT16RC),
ENTRY("stp-hello-time", O_HTIME, XTTYPE_UINT16RC),
ENTRY("stp-forward-delay", O_FWDD, XTTYPE_UINT16RC),
XTOPT_TABLEEND,
};
#define BPDU_TYPE_CONFIG 0
#define BPDU_TYPE_TCN 0x80
#define BPDU_TYPE_CONFIG_STRING "config"
#define BPDU_TYPE_TCN_STRING "tcn"
#define FLAG_TC 0x01
#define FLAG_TC_ACK 0x80
#define FLAG_TC_STRING "topology-change"
#define FLAG_TC_ACK_STRING "topology-change-ack"
static void brstp_print_help(void)
{
printf(
"stp options:\n"
"[!] --stp-type type : BPDU type\n"
"[!] --stp-flags flag : control flag\n"
"[!] --stp-root-prio prio[:prio] : root priority (16-bit) range\n"
"[!] --stp-root-addr address[/mask] : MAC address of root\n"
"[!] --stp-root-cost cost[:cost] : root cost (32-bit) range\n"
"[!] --stp-sender-prio prio[:prio] : sender priority (16-bit) range\n"
"[!] --stp-sender-addr address[/mask] : MAC address of sender\n"
"[!] --stp-port port[:port] : port id (16-bit) range\n"
"[!] --stp-msg-age age[:age] : message age timer (16-bit) range\n"
"[!] --stp-max-age age[:age] : maximum age timer (16-bit) range\n"
"[!] --stp-hello-time time[:time] : hello time timer (16-bit) range\n"
"[!] --stp-forward-delay delay[:delay]: forward delay timer (16-bit) range\n"
" Recognized BPDU type strings:\n"
" \"config\": configuration BPDU (=0)\n"
" \"tcn\" : topology change notification BPDU (=0x80)\n"
" Recognized control flag strings:\n"
" \"topology-change\" : topology change flag (0x01)\n"
" \"topology-change-ack\": topology change acknowledgement flag (0x80)");
}
static void print_range(unsigned int l, unsigned int u)
{
if (l == u)
printf("%u", l);
else
printf("%u:%u", l, u);
}
static void brstp_parse(struct xt_option_call *cb)
{
struct ebt_stp_info *stpinfo = cb->data;
char *end = NULL;
long int i;
xtables_option_parse(cb);
stpinfo->bitmask |= 1 << cb->entry->id;
if (cb->invert)
stpinfo->invflags |= 1 << cb->entry->id;
switch (cb->entry->id) {
case O_TYPE:
i = strtol(cb->arg, &end, 0);
if (i < 0 || i > 255 || *end != '\0') {
if (!strcasecmp(cb->arg, BPDU_TYPE_CONFIG_STRING))
stpinfo->type = BPDU_TYPE_CONFIG;
else if (!strcasecmp(cb->arg, BPDU_TYPE_TCN_STRING))
stpinfo->type = BPDU_TYPE_TCN;
else
xtables_error(PARAMETER_PROBLEM, "Bad --stp-type argument");
} else
stpinfo->type = i;
break;
case O_FLAGS:
i = strtol(cb->arg, &end, 0);
if (i < 0 || i > 255 || *end != '\0') {
if (!strcasecmp(cb->arg, FLAG_TC_STRING))
stpinfo->config.flags = FLAG_TC;
else if (!strcasecmp(cb->arg, FLAG_TC_ACK_STRING))
stpinfo->config.flags = FLAG_TC_ACK;
else
xtables_error(PARAMETER_PROBLEM, "Bad --stp-flags argument");
} else
stpinfo->config.flags = i;
break;
case O_RADDR:
memcpy(stpinfo->config.root_addr, cb->val.ethermac, ETH_ALEN);
memcpy(stpinfo->config.root_addrmsk,
cb->val.ethermacmask, ETH_ALEN);
break;
case O_SADDR:
memcpy(stpinfo->config.sender_addr, cb->val.ethermac, ETH_ALEN);
memcpy(stpinfo->config.sender_addrmsk,
cb->val.ethermacmask, ETH_ALEN);
break;
#define RANGE_ASSIGN(fname, val) { \
stpinfo->config.fname##l = val[0]; \
stpinfo->config.fname##u = cb->nvals > 1 ? val[1] : val[0]; \
}
case O_RPRIO:
RANGE_ASSIGN(root_prio, cb->val.u16_range);
break;
case O_RCOST:
RANGE_ASSIGN(root_cost, cb->val.u32_range);
break;
case O_SPRIO:
RANGE_ASSIGN(sender_prio, cb->val.u16_range);
break;
case O_PORT:
RANGE_ASSIGN(port, cb->val.u16_range);
break;
case O_MSGAGE:
RANGE_ASSIGN(msg_age, cb->val.u16_range);
break;
case O_MAXAGE:
RANGE_ASSIGN(max_age, cb->val.u16_range);
break;
case O_HTIME:
RANGE_ASSIGN(hello_time, cb->val.u16_range);
break;
case O_FWDD:
RANGE_ASSIGN(forward_delay, cb->val.u16_range);
break;
#undef RANGE_ASSIGN
}
}
static void brstp_print(const void *ip, const struct xt_entry_match *match,
int numeric)
{
const struct ebt_stp_info *stpinfo = (struct ebt_stp_info *)match->data;
const struct ebt_stp_config_info *c = &(stpinfo->config);
int i;
for (i = 0; (1 << i) < EBT_STP_MASK; i++) {
if (!(stpinfo->bitmask & (1 << i)))
continue;
printf("%s--%s ",
(stpinfo->invflags & (1 << i)) ? "! " : "",
brstp_opts[i].name);
if (EBT_STP_TYPE == (1 << i)) {
if (stpinfo->type == BPDU_TYPE_CONFIG)
printf("%s", BPDU_TYPE_CONFIG_STRING);
else if (stpinfo->type == BPDU_TYPE_TCN)
printf("%s", BPDU_TYPE_TCN_STRING);
else
printf("%d", stpinfo->type);
} else if (EBT_STP_FLAGS == (1 << i)) {
if (c->flags == FLAG_TC)
printf("%s", FLAG_TC_STRING);
else if (c->flags == FLAG_TC_ACK)
printf("%s", FLAG_TC_ACK_STRING);
else
printf("%d", c->flags);
} else if (EBT_STP_ROOTPRIO == (1 << i))
print_range(c->root_priol, c->root_priou);
else if (EBT_STP_ROOTADDR == (1 << i))
xtables_print_mac_and_mask((unsigned char *)c->root_addr,
(unsigned char*)c->root_addrmsk);
else if (EBT_STP_ROOTCOST == (1 << i))
print_range(c->root_costl, c->root_costu);
else if (EBT_STP_SENDERPRIO == (1 << i))
print_range(c->sender_priol, c->sender_priou);
else if (EBT_STP_SENDERADDR == (1 << i))
xtables_print_mac_and_mask((unsigned char *)c->sender_addr,
(unsigned char *)c->sender_addrmsk);
else if (EBT_STP_PORT == (1 << i))
print_range(c->portl, c->portu);
else if (EBT_STP_MSGAGE == (1 << i))
print_range(c->msg_agel, c->msg_ageu);
else if (EBT_STP_MAXAGE == (1 << i))
print_range(c->max_agel, c->max_ageu);
else if (EBT_STP_HELLOTIME == (1 << i))
print_range(c->hello_timel, c->hello_timeu);
else if (EBT_STP_FWDD == (1 << i))
print_range(c->forward_delayl, c->forward_delayu);
printf(" ");
}
}
static struct xtables_match brstp_match = {
.name = "stp",
.version = XTABLES_VERSION,
.family = NFPROTO_BRIDGE,
.size = sizeof(struct ebt_stp_info),
.help = brstp_print_help,
.x6_parse = brstp_parse,
.print = brstp_print,
.x6_options = brstp_opts
};
void _init(void)
{
xtables_register_match(&brstp_match);
}
+74
View File
@@ -0,0 +1,74 @@
:INPUT,FORWARD,OUTPUT
--stp-type 1;=;OK
! --stp-type 1;=;OK
--stp-flags 0x1;--stp-flags topology-change -j CONTINUE;OK
! --stp-flags topology-change;=;OK
--stp-root-prio 1 -j ACCEPT;=;OK
! --stp-root-prio 1 -j ACCEPT;=;OK
--stp-root-addr 0d:ea:d0:0b:ee:f0;=;OK
! --stp-root-addr 0d:ea:d0:0b:ee:f0;=;OK
--stp-root-addr 0d:ea:d0:00:00:00/ff:ff:ff:00:00:00;=;OK
! --stp-root-addr 0d:ea:d0:00:00:00/ff:ff:ff:00:00:00;=;OK
--stp-root-cost 1;=;OK
! --stp-root-cost 1;=;OK
--stp-sender-prio 1;=;OK
! --stp-sender-prio 1;=;OK
--stp-sender-addr de:ad:be:ef:00:00;=;OK
! --stp-sender-addr de:ad:be:ef:00:00;=;OK
--stp-sender-addr de:ad:be:ef:00:00/ff:ff:ff:ff:00:00;=;OK
! --stp-sender-addr de:ad:be:ef:00:00/ff:ff:ff:ff:00:00;=;OK
--stp-port 1;=;OK
! --stp-port 1;=;OK
--stp-msg-age 1;=;OK
! --stp-msg-age 1;=;OK
--stp-max-age 1;=;OK
! --stp-max-age 1;=;OK
--stp-hello-time 1;=;OK
! --stp-hello-time 1;=;OK
--stp-forward-delay 1;=;OK
! --stp-forward-delay 1;=;OK
--stp-root-prio :2;--stp-root-prio 0:2;OK
--stp-root-prio 2:;--stp-root-prio 2:65535;OK
--stp-root-prio 1:2;=;OK
--stp-root-prio 1:1;--stp-root-prio 1;OK
--stp-root-prio 2:1;;FAIL
--stp-root-cost :2;--stp-root-cost 0:2;OK
--stp-root-cost 2:;--stp-root-cost 2:4294967295;OK
--stp-root-cost 1:2;=;OK
--stp-root-cost 1:1;--stp-root-cost 1;OK
--stp-root-cost 2:1;;FAIL
--stp-sender-prio :2;--stp-sender-prio 0:2;OK
--stp-sender-prio 2:;--stp-sender-prio 2:65535;OK
--stp-sender-prio 1:2;=;OK
--stp-sender-prio 1:1;--stp-sender-prio 1;OK
--stp-sender-prio 2:1;;FAIL
--stp-port :;--stp-port 0:65535;OK
--stp-port :2;--stp-port 0:2;OK
--stp-port 2:;--stp-port 2:65535;OK
--stp-port 1:2;=;OK
--stp-port 1:1;--stp-port 1;OK
--stp-port 2:1;;FAIL
--stp-msg-age :;--stp-msg-age 0:65535;OK
--stp-msg-age :2;--stp-msg-age 0:2;OK
--stp-msg-age 2:;--stp-msg-age 2:65535;OK
--stp-msg-age 1:2;=;OK
--stp-msg-age 1:1;--stp-msg-age 1;OK
--stp-msg-age 2:1;;FAIL
--stp-max-age :;--stp-max-age 0:65535;OK
--stp-max-age :2;--stp-max-age 0:2;OK
--stp-max-age 2:;--stp-max-age 2:65535;OK
--stp-max-age 1:2;=;OK
--stp-max-age 1:1;--stp-max-age 1;OK
--stp-max-age 2:1;;FAIL
--stp-hello-time :;--stp-hello-time 0:65535;OK
--stp-hello-time :2;--stp-hello-time 0:2;OK
--stp-hello-time 2:;--stp-hello-time 2:65535;OK
--stp-hello-time 1:2;=;OK
--stp-hello-time 1:1;--stp-hello-time 1;OK
--stp-hello-time 2:1;;FAIL
--stp-forward-delay :;--stp-forward-delay 0:65535;OK
--stp-forward-delay :2;--stp-forward-delay 0:2;OK
--stp-forward-delay 2:;--stp-forward-delay 2:65535;OK
--stp-forward-delay 1:2;=;OK
--stp-forward-delay 1:1;--stp-forward-delay 1;OK
--stp-forward-delay 2:1;;FAIL
+127
View File
@@ -0,0 +1,127 @@
/* ebt_vlan
*
* Authors:
* Bart De Schuymer <bdschuym@pandora.be>
* Nick Fedchik <nick@fedchik.org.ua>
* June, 2002
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <xtables.h>
#include <netinet/if_ether.h>
#include <linux/netfilter_bridge/ebt_vlan.h>
#include <linux/if_ether.h>
#include "iptables/nft.h"
#include "iptables/nft-bridge.h"
static const struct xt_option_entry brvlan_opts[] =
{
{ .name = "vlan-id", .id = EBT_VLAN_ID, .type = XTTYPE_UINT16,
.max = 4094, .flags = XTOPT_INVERT | XTOPT_PUT,
XTOPT_POINTER(struct ebt_vlan_info, id) },
{ .name = "vlan-prio", .id = EBT_VLAN_PRIO, .type = XTTYPE_UINT8,
.max = 7, .flags = XTOPT_INVERT | XTOPT_PUT,
XTOPT_POINTER(struct ebt_vlan_info, prio) },
{ .name = "vlan-encap", .id = EBT_VLAN_ENCAP, .type = XTTYPE_STRING,
.flags = XTOPT_INVERT },
XTOPT_TABLEEND,
};
static void brvlan_print_help(void)
{
printf(
"vlan options:\n"
"[!] --vlan-id id : vlan-tagged frame identifier, 0,1-4096 (integer)\n"
"[!] --vlan-prio prio : Priority-tagged frame's user priority, 0-7 (integer)\n"
"[!] --vlan-encap encap : Encapsulated frame protocol (hexadecimal or name)\n");
}
static void brvlan_parse(struct xt_option_call *cb)
{
struct ebt_vlan_info *vlaninfo = cb->data;
struct xt_ethertypeent *ethent;
char *end;
xtables_option_parse(cb);
vlaninfo->bitmask |= cb->entry->id;
if (cb->invert)
vlaninfo->invflags |= cb->entry->id;
if (cb->entry->id == EBT_VLAN_ENCAP) {
vlaninfo->encap = strtoul(cb->arg, &end, 16);
if (*end != '\0') {
ethent = xtables_getethertypebyname(cb->arg);
if (ethent == NULL)
xtables_error(PARAMETER_PROBLEM,
"Unknown --vlan-encap value ('%s')",
cb->arg);
vlaninfo->encap = ethent->e_ethertype;
}
if (vlaninfo->encap < ETH_ZLEN)
xtables_error(PARAMETER_PROBLEM,
"Invalid --vlan-encap range ('%s')",
cb->arg);
vlaninfo->encap = htons(vlaninfo->encap);
}
}
static void brvlan_print(const void *ip, const struct xt_entry_match *match,
int numeric)
{
struct ebt_vlan_info *vlaninfo = (struct ebt_vlan_info *) match->data;
if (vlaninfo->bitmask & EBT_VLAN_ID) {
printf("%s--vlan-id %d ",
(vlaninfo->invflags & EBT_VLAN_ID) ? "! " : "",
vlaninfo->id);
}
if (vlaninfo->bitmask & EBT_VLAN_PRIO) {
printf("%s--vlan-prio %d ",
(vlaninfo->invflags & EBT_VLAN_PRIO) ? "! " : "",
vlaninfo->prio);
}
if (vlaninfo->bitmask & EBT_VLAN_ENCAP) {
printf("%s--vlan-encap %4.4X ",
(vlaninfo->invflags & EBT_VLAN_ENCAP) ? "! " : "",
ntohs(vlaninfo->encap));
}
}
static int brvlan_xlate(struct xt_xlate *xl,
const struct xt_xlate_mt_params *params)
{
const struct ebt_vlan_info *vlaninfo = (const void*)params->match->data;
if (vlaninfo->bitmask & EBT_VLAN_ID)
xt_xlate_add(xl, "vlan id %s%d ", (vlaninfo->invflags & EBT_VLAN_ID) ? "!= " : "", vlaninfo->id);
if (vlaninfo->bitmask & EBT_VLAN_PRIO)
xt_xlate_add(xl, "vlan pcp %s%d ", (vlaninfo->invflags & EBT_VLAN_PRIO) ? "!= " : "", vlaninfo->prio);
if (vlaninfo->bitmask & EBT_VLAN_ENCAP)
xt_xlate_add(xl, "vlan type %s0x%4.4x ", (vlaninfo->invflags & EBT_VLAN_ENCAP) ? "!= " : "", ntohs(vlaninfo->encap));
return 1;
}
static struct xtables_match brvlan_match = {
.name = "vlan",
.version = XTABLES_VERSION,
.family = NFPROTO_BRIDGE,
.size = XT_ALIGN(sizeof(struct ebt_vlan_info)),
.userspacesize = XT_ALIGN(sizeof(struct ebt_vlan_info)),
.help = brvlan_print_help,
.x6_parse = brvlan_parse,
.print = brvlan_print,
.xlate = brvlan_xlate,
.x6_options = brvlan_opts,
};
void _init(void)
{
xtables_register_match(&brvlan_match);
}
+13
View File
@@ -0,0 +1,13 @@
:INPUT,FORWARD,OUTPUT
-p 802_1Q --vlan-id 42;=;OK
-p 802_1Q ! --vlan-id 42;=;OK
-p 802_1Q --vlan-prio 1;=;OK
-p 802_1Q ! --vlan-prio 1;=;OK
-p 802_1Q --vlan-encap ip;-p 802_1Q --vlan-encap 0800 -j CONTINUE;OK
-p 802_1Q --vlan-encap 0800;=;OK
-p 802_1Q ! --vlan-encap 0800;=;OK
-p 802_1Q --vlan-encap IPv6 --vlan-id ! 1;-p 802_1Q ! --vlan-id 1 --vlan-encap 86DD -j CONTINUE;OK
-p 802_1Q ! --vlan-id 1 --vlan-encap 86DD;=;OK
--vlan-encap ip;=;FAIL
--vlan-id 2;=;FAIL
--vlan-prio 1;=;FAIL
+11
View File
@@ -0,0 +1,11 @@
ebtables-translate -A INPUT -p 802_1Q --vlan-id 42
nft 'add rule bridge filter INPUT vlan id 42 counter'
ebtables-translate -A INPUT -p 802_1Q ! --vlan-prio 1
nft 'add rule bridge filter INPUT vlan pcp != 1 counter'
ebtables-translate -A INPUT -p 802_1Q --vlan-encap ip
nft 'add rule bridge filter INPUT vlan type 0x0800 counter'
ebtables-translate -A INPUT -p 802_1Q --vlan-encap ipv6 ! --vlan-id 1
nft 'add rule bridge filter INPUT vlan id != 1 vlan type 0x86dd counter'
+20
View File
@@ -0,0 +1,20 @@
:PREROUTING
*nat
-j DNAT --to-destination dead::beef;=;OK
-j DNAT --to-destination dead::beef-dead::fee7;=;OK
-j DNAT --to-destination [dead::beef]:1025-65535;;FAIL
-j DNAT --to-destination [dead::beef] --to-destination [dead::fee7];;FAIL
-p tcp -j DNAT --to-destination [dead::beef]:1025-65535;=;OK
-p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1025-65535;=;OK
-p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1025-65536;;FAIL
-p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1025-65535 --to-destination [dead::beef-dead::fee8]:1025-65535;;FAIL
-p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1000-2000/1000;=;OK
-p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1000-2000/3000;=;OK
-p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1000-2000/65535;=;OK
-p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1000-2000/0;;FAIL
-p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1000-2000/65536;;FAIL
-p tcp -j DNAT --to-destination [dead::beef]:ssh;-p tcp -j DNAT --to-destination [dead::beef]:22;OK
-p tcp -j DNAT --to-destination [dead::beef]:ftp-data;-p tcp -j DNAT --to-destination [dead::beef]:20;OK
-p tcp -j DNAT --to-destination [dead::beef]:echo-ssh;;FAIL
-p tcp -j DNAT --to-destination [dead::beef]:10-20/ftp;-p tcp -j DNAT --to-destination [dead::beef]:10-20/21;OK
-j DNAT;;FAIL
+94
View File
@@ -0,0 +1,94 @@
/*
* Copyright (c) 2012-2013 Patrick McHardy <kaber@trash.net>
*/
#include <stdio.h>
#include <string.h>
#include <xtables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/netfilter_ipv6/ip6t_NPT.h>
enum {
O_SRC_PFX = 1 << 0,
O_DST_PFX = 1 << 1,
};
static const struct xt_option_entry DNPT_options[] = {
{ .name = "src-pfx", .id = O_SRC_PFX, .type = XTTYPE_HOSTMASK,
.flags = XTOPT_MAND },
{ .name = "dst-pfx", .id = O_DST_PFX, .type = XTTYPE_HOSTMASK,
.flags = XTOPT_MAND },
{ }
};
static void DNPT_help(void)
{
printf("DNPT target options:"
"\n"
" --src-pfx prefix/length\n"
" --dst-pfx prefix/length\n"
"\n");
}
static void DNPT_parse(struct xt_option_call *cb)
{
struct ip6t_npt_tginfo *npt = cb->data;
xtables_option_parse(cb);
switch (cb->entry->id) {
case O_SRC_PFX:
npt->src_pfx = cb->val.haddr;
npt->src_pfx_len = cb->val.hlen;
break;
case O_DST_PFX:
npt->dst_pfx = cb->val.haddr;
npt->dst_pfx_len = cb->val.hlen;
break;
}
}
static void DNPT_print(const void *ip, const struct xt_entry_target *target,
int numeric)
{
const struct ip6t_npt_tginfo *npt = (const void *)target->data;
printf(" DNPT src-pfx %s/%u", xtables_ip6addr_to_numeric(&npt->src_pfx.in6),
npt->src_pfx_len);
printf(" dst-pfx %s/%u", xtables_ip6addr_to_numeric(&npt->dst_pfx.in6),
npt->dst_pfx_len);
}
static void DNPT_save(const void *ip, const struct xt_entry_target *target)
{
static const struct in6_addr zero_addr;
const struct ip6t_npt_tginfo *info = (const void *)target->data;
if (memcmp(&info->src_pfx.in6, &zero_addr, sizeof(zero_addr)) != 0 ||
info->src_pfx_len != 0)
printf(" --src-pfx %s/%u",
xtables_ip6addr_to_numeric(&info->src_pfx.in6),
info->src_pfx_len);
if (memcmp(&info->dst_pfx.in6, &zero_addr, sizeof(zero_addr)) != 0 ||
info->dst_pfx_len != 0)
printf(" --dst-pfx %s/%u",
xtables_ip6addr_to_numeric(&info->dst_pfx.in6),
info->dst_pfx_len);
}
static struct xtables_target snpt_tg_reg = {
.name = "DNPT",
.version = XTABLES_VERSION,
.family = NFPROTO_IPV6,
.size = XT_ALIGN(sizeof(struct ip6t_npt_tginfo)),
.userspacesize = offsetof(struct ip6t_npt_tginfo, adjustment),
.help = DNPT_help,
.x6_parse = DNPT_parse,
.print = DNPT_print,
.save = DNPT_save,
.x6_options = DNPT_options,
};
void _init(void)
{
xtables_register_target(&snpt_tg_reg);
}
+30
View File
@@ -0,0 +1,30 @@
Provides stateless destination IPv6-to-IPv6 Network Prefix Translation (as
described by RFC 6296).
.PP
You have to use this target in the
.B mangle
table, not in the
.B nat
table. It takes the following options:
.TP
\fB\-\-src\-pfx\fP [\fIprefix/\fP\fIlength]
Set source prefix that you want to translate and length
.TP
\fB\-\-dst\-pfx\fP [\fIprefix/\fP\fIlength]
Set destination prefix that you want to use in the translation and length
.PP
You have to use the SNPT target to undo the translation. Example:
.IP
ip6tables \-t mangle \-I POSTROUTING \-s fd00::/64 ! \-o vboxnet0
\-j SNPT \-\-src-pfx fd00::/64 \-\-dst-pfx 2001:e20:2000:40f::/64
.IP
ip6tables \-t mangle \-I PREROUTING \-i wlan0 \-d 2001:e20:2000:40f::/64
\-j DNPT \-\-src-pfx 2001:e20:2000:40f::/64 \-\-dst\-pfx fd00::/64
.PP
You may need to enable IPv6 neighbor proxy:
.IP
sysctl \-w net.ipv6.conf.all.proxy_ndp=1
.PP
You also have to use the
.B NOTRACK
target to disable connection tracking for translated flows.
+7
View File
@@ -0,0 +1,7 @@
:PREROUTING
*mangle
-j DNPT --src-pfx dead::/64 --dst-pfx 1c3::/64;=;OK
-j DNPT --src-pfx dead::beef --dst-pfx 1c3::/64;;FAIL
-j DNPT --src-pfx dead::/64;;FAIL
-j DNPT --dst-pfx dead::/64;;FAIL
-j DNPT;;FAIL
+127
View File
@@ -0,0 +1,127 @@
/*
* IPv6 Hop Limit Target module
* Maciej Soltysiak <solt@dns.toxicfilms.tv>
* Based on HW's ttl target
* This program is distributed under the terms of GNU GPL
*/
#include <stdio.h>
#include <xtables.h>
#include <linux/netfilter_ipv6/ip6t_HL.h>
enum {
O_HL_SET = 0,
O_HL_INC,
O_HL_DEC,
F_HL_SET = 1 << O_HL_SET,
F_HL_INC = 1 << O_HL_INC,
F_HL_DEC = 1 << O_HL_DEC,
F_ANY = F_HL_SET | F_HL_INC | F_HL_DEC,
};
#define s struct ip6t_HL_info
static const struct xt_option_entry HL_opts[] = {
{.name = "hl-set", .type = XTTYPE_UINT8, .id = O_HL_SET,
.excl = F_ANY, .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit)},
{.name = "hl-dec", .type = XTTYPE_UINT8, .id = O_HL_DEC,
.excl = F_ANY, .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit),
.min = 1},
{.name = "hl-inc", .type = XTTYPE_UINT8, .id = O_HL_INC,
.excl = F_ANY, .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit),
.min = 1},
XTOPT_TABLEEND,
};
#undef s
static void HL_help(void)
{
printf(
"HL target options\n"
" --hl-set value Set HL to <value 0-255>\n"
" --hl-dec value Decrement HL by <value 1-255>\n"
" --hl-inc value Increment HL by <value 1-255>\n");
}
static void HL_parse(struct xt_option_call *cb)
{
struct ip6t_HL_info *info = cb->data;
xtables_option_parse(cb);
switch (cb->entry->id) {
case O_HL_SET:
info->mode = IP6T_HL_SET;
break;
case O_HL_INC:
info->mode = IP6T_HL_INC;
break;
case O_HL_DEC:
info->mode = IP6T_HL_DEC;
break;
}
}
static void HL_check(struct xt_fcheck_call *cb)
{
if (!(cb->xflags & F_ANY))
xtables_error(PARAMETER_PROBLEM,
"HL: You must specify an action");
}
static void HL_save(const void *ip, const struct xt_entry_target *target)
{
const struct ip6t_HL_info *info =
(struct ip6t_HL_info *) target->data;
switch (info->mode) {
case IP6T_HL_SET:
printf(" --hl-set");
break;
case IP6T_HL_DEC:
printf(" --hl-dec");
break;
case IP6T_HL_INC:
printf(" --hl-inc");
break;
}
printf(" %u", info->hop_limit);
}
static void HL_print(const void *ip, const struct xt_entry_target *target,
int numeric)
{
const struct ip6t_HL_info *info =
(struct ip6t_HL_info *) target->data;
printf(" HL ");
switch (info->mode) {
case IP6T_HL_SET:
printf("set to");
break;
case IP6T_HL_DEC:
printf("decrement by");
break;
case IP6T_HL_INC:
printf("increment by");
break;
}
printf(" %u", info->hop_limit);
}
static struct xtables_target hl_tg6_reg = {
.name = "HL",
.version = XTABLES_VERSION,
.family = NFPROTO_IPV6,
.size = XT_ALIGN(sizeof(struct ip6t_HL_info)),
.userspacesize = XT_ALIGN(sizeof(struct ip6t_HL_info)),
.help = HL_help,
.print = HL_print,
.save = HL_save,
.x6_parse = HL_parse,
.x6_fcheck = HL_check,
.x6_options = HL_opts,
};
void _init(void)
{
xtables_register_target(&hl_tg6_reg);
}
+17
View File
@@ -0,0 +1,17 @@
This is used to modify the Hop Limit field in IPv6 header. The Hop Limit field
is similar to what is known as TTL value in IPv4. Setting or incrementing the
Hop Limit field can potentially be very dangerous, so it should be avoided at
any cost. This target is only valid in
.B mangle
table.
.PP
.B Don't ever set or increment the value on packets that leave your local network!
.TP
\fB\-\-hl\-set\fP \fIvalue\fP
Set the Hop Limit to `value'.
.TP
\fB\-\-hl\-dec\fP \fIvalue\fP
Decrement the Hop Limit `value' times.
.TP
\fB\-\-hl\-inc\fP \fIvalue\fP
Increment the Hop Limit `value' times.
+10
View File
@@ -0,0 +1,10 @@
:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
*mangle
-j HL --hl-set 42;=;OK
-j HL --hl-inc 1;=;OK
-j HL --hl-dec 1;=;OK
-j HL --hl-set 256;;FAIL
-j HL --hl-inc 0;;FAIL
-j HL --hl-dec 0;;FAIL
-j HL --hl-dec 1 --hl-inc 1;;FAIL
-j HL --hl-set --hl-inc 1;;FAIL
+12
View File
@@ -0,0 +1,12 @@
:INPUT,FORWARD,OUTPUT
-j LOG;-j LOG;OK
-j LOG --log-prefix "test: ";=;OK
-j LOG --log-prefix "test: " --log-level 1;=;OK
# iptables displays the log-level output using the number; not the string
-j LOG --log-prefix "test: " --log-level alert;-j LOG --log-prefix "test: " --log-level 1;OK
-j LOG --log-prefix "test: " --log-tcp-sequence;=;OK
-j LOG --log-prefix "test: " --log-tcp-options;=;OK
-j LOG --log-prefix "test: " --log-ip-options;=;OK
-j LOG --log-prefix "test: " --log-uid;=;OK
-j LOG --log-prefix "test: " --log-level bad;;FAIL
-j LOG --log-prefix;;FAIL
+8
View File
@@ -0,0 +1,8 @@
iptables-translate -I INPUT -j LOG
nft 'insert rule ip filter INPUT counter log'
ip6tables-translate -A FORWARD -p tcp -j LOG --log-level debug
nft 'add rule ip6 filter FORWARD meta l4proto tcp counter log level debug'
ip6tables-translate -A FORWARD -p tcp -j LOG --log-prefix "Checking log"
nft 'add rule ip6 filter FORWARD meta l4proto tcp counter log prefix "Checking log"'
+9
View File
@@ -0,0 +1,9 @@
:POSTROUTING
*nat
-j MASQUERADE;=;OK
-j MASQUERADE --random;=;OK
-j MASQUERADE --random-fully;=;OK
-p tcp -j MASQUERADE --to-ports 1024;=;OK
-p udp -j MASQUERADE --to-ports 1024-65535;=;OK
-p udp -j MASQUERADE --to-ports 1024-65536;;FAIL
-p udp -j MASQUERADE --to-ports -1;;FAIL
+17
View File
@@ -0,0 +1,17 @@
ip6tables-translate -t nat -A POSTROUTING -j MASQUERADE
nft 'add rule ip6 nat POSTROUTING counter masquerade'
ip6tables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --to-ports 10
nft 'add rule ip6 nat POSTROUTING meta l4proto tcp counter masquerade to :10'
ip6tables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --to-ports 10-20 --random
nft 'add rule ip6 nat POSTROUTING meta l4proto tcp counter masquerade to :10-20 random'
ip6tables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --random
nft 'add rule ip6 nat POSTROUTING meta l4proto tcp counter masquerade random'
ip6tables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --random-fully
nft 'add rule ip6 nat POSTROUTING meta l4proto tcp counter masquerade fully-random'
ip6tables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --random --random-fully
nft 'add rule ip6 nat POSTROUTING meta l4proto tcp counter masquerade random,fully-random'
+100
View File
@@ -0,0 +1,100 @@
/*
* Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
*
* Based on Svenning Soerensen's IPv4 NETMAP target. Development of IPv6 NAT
* funded by Astaro.
*/
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <xtables.h>
#include <libiptc/libip6tc.h>
#include <linux/netfilter/nf_nat.h>
#define MODULENAME "NETMAP"
enum {
O_TO = 0,
};
static const struct xt_option_entry NETMAP_opts[] = {
{.name = "to", .id = O_TO, .type = XTTYPE_HOSTMASK,
.flags = XTOPT_MAND},
XTOPT_TABLEEND,
};
static void NETMAP_help(void)
{
printf(MODULENAME" target options:\n"
" --%s address[/mask]\n"
" Network address to map to.\n\n",
NETMAP_opts[0].name);
}
static void NETMAP_parse(struct xt_option_call *cb)
{
struct nf_nat_range *range = cb->data;
unsigned int i;
xtables_option_parse(cb);
range->flags |= NF_NAT_RANGE_MAP_IPS;
for (i = 0; i < 4; i++) {
range->min_addr.ip6[i] = cb->val.haddr.ip6[i] &
cb->val.hmask.ip6[i];
range->max_addr.ip6[i] = range->min_addr.ip6[i] |
~cb->val.hmask.ip6[i];
}
}
static void __NETMAP_print(const void *ip, const struct xt_entry_target *target,
int numeric)
{
const struct nf_nat_range *r = (const void *)target->data;
struct in6_addr a;
unsigned int i;
int bits;
a = r->min_addr.in6;
printf("%s", xtables_ip6addr_to_numeric(&a));
for (i = 0; i < 4; i++)
a.s6_addr32[i] = ~(r->min_addr.ip6[i] ^ r->max_addr.ip6[i]);
bits = xtables_ip6mask_to_cidr(&a);
if (bits < 0)
printf("/%s", xtables_ip6addr_to_numeric(&a));
else
printf("/%d", bits);
}
static void NETMAP_print(const void *ip, const struct xt_entry_target *target,
int numeric)
{
printf(" to:");
__NETMAP_print(ip, target, numeric);
}
static void NETMAP_save(const void *ip, const struct xt_entry_target *target)
{
printf(" --%s ", NETMAP_opts[0].name);
__NETMAP_print(ip, target, 0);
}
static struct xtables_target netmap_tg_reg = {
.name = MODULENAME,
.version = XTABLES_VERSION,
.family = NFPROTO_IPV6,
.size = XT_ALIGN(sizeof(struct nf_nat_range)),
.userspacesize = XT_ALIGN(sizeof(struct nf_nat_range)),
.help = NETMAP_help,
.x6_parse = NETMAP_parse,
.print = NETMAP_print,
.save = NETMAP_save,
.x6_options = NETMAP_opts,
};
void _init(void)
{
xtables_register_target(&netmap_tg_reg);
}
+4
View File
@@ -0,0 +1,4 @@
:PREROUTING,INPUT,OUTPUT,POSTROUTING
*nat
-j NETMAP --to dead::/64;=;OK
-j NETMAP --to dead::beef;-j NETMAP --to dead::beef/128;OK
+185
View File
@@ -0,0 +1,185 @@
/* Shared library add-on to ip6tables to add customized REJECT support.
*
* (C) 2000 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
*
* ported to IPv6 by Harald Welte <laforge@gnumonks.org>
*
*/
#include <stdio.h>
#include <string.h>
#include <xtables.h>
#include <linux/netfilter_ipv6/ip6t_REJECT.h>
struct reject_names {
const char *name;
const char *alias;
const char *desc;
const char *xlate;
};
enum {
O_REJECT_WITH = 0,
};
static const struct reject_names reject_table[] = {
[IP6T_ICMP6_NO_ROUTE] = {
"icmp6-no-route", "no-route",
"ICMPv6 no route",
"no-route",
},
[IP6T_ICMP6_ADM_PROHIBITED] = {
"icmp6-adm-prohibited", "adm-prohibited",
"ICMPv6 administratively prohibited",
"admin-prohibited",
},
#if 0
[IP6T_ICMP6_NOT_NEIGHBOR] = {
"icmp6-not-neighbor", "not-neighbor",
"ICMPv6 not a neighbor",
},
#endif
[IP6T_ICMP6_ADDR_UNREACH] = {
"icmp6-addr-unreachable", "addr-unreach",
"ICMPv6 address unreachable",
"addr-unreachable",
},
[IP6T_ICMP6_PORT_UNREACH] = {
"icmp6-port-unreachable", "port-unreach",
"ICMPv6 port unreachable",
"port-unreachable",
},
#if 0
[IP6T_ICMP6_ECHOREPLY] = {},
#endif
[IP6T_TCP_RESET] = {
"tcp-reset", "tcp-reset",
"TCP RST packet",
"tcp reset",
},
[IP6T_ICMP6_POLICY_FAIL] = {
"icmp6-policy-fail", "policy-fail",
"ICMPv6 policy fail",
"policy-fail",
},
[IP6T_ICMP6_REJECT_ROUTE] = {
"icmp6-reject-route", "reject-route",
"ICMPv6 reject route",
"reject-route",
},
};
static void
print_reject_types(void)
{
unsigned int i;
printf("Valid reject types:\n");
for (i = 0; i < ARRAY_SIZE(reject_table); ++i) {
if (!reject_table[i].name)
continue;
printf(" %-25s\t%s\n", reject_table[i].name, reject_table[i].desc);
printf(" %-25s\talias\n", reject_table[i].alias);
}
printf("\n");
}
static void REJECT_help(void)
{
printf(
"REJECT target options:\n"
"--reject-with type drop input packet and send back\n"
" a reply packet according to type:\n");
print_reject_types();
}
static const struct xt_option_entry REJECT_opts[] = {
{.name = "reject-with", .id = O_REJECT_WITH, .type = XTTYPE_STRING},
XTOPT_TABLEEND,
};
static void REJECT_init(struct xt_entry_target *t)
{
struct ip6t_reject_info *reject = (struct ip6t_reject_info *)t->data;
/* default */
reject->with = IP6T_ICMP6_PORT_UNREACH;
}
static void REJECT_parse(struct xt_option_call *cb)
{
struct ip6t_reject_info *reject = cb->data;
unsigned int i;
xtables_option_parse(cb);
for (i = 0; i < ARRAY_SIZE(reject_table); ++i) {
if (!reject_table[i].name)
continue;
if (strncasecmp(reject_table[i].name,
cb->arg, strlen(cb->arg)) == 0 ||
strncasecmp(reject_table[i].alias,
cb->arg, strlen(cb->arg)) == 0) {
reject->with = i;
return;
}
}
xtables_error(PARAMETER_PROBLEM,
"unknown reject type \"%s\"", cb->arg);
}
static void REJECT_print(const void *ip, const struct xt_entry_target *target,
int numeric)
{
const struct ip6t_reject_info *reject
= (const struct ip6t_reject_info *)target->data;
printf(" reject-with %s", reject_table[reject->with].name);
}
static void REJECT_save(const void *ip, const struct xt_entry_target *target)
{
const struct ip6t_reject_info *reject
= (const struct ip6t_reject_info *)target->data;
printf(" --reject-with %s", reject_table[reject->with].name);
}
static int REJECT_xlate(struct xt_xlate *xl,
const struct xt_xlate_tg_params *params)
{
const struct ip6t_reject_info *reject =
(const struct ip6t_reject_info *)params->target->data;
if (reject->with == IP6T_ICMP6_PORT_UNREACH)
xt_xlate_add(xl, "reject");
else if (reject->with == IP6T_TCP_RESET)
xt_xlate_add(xl, "reject with %s",
reject_table[reject->with].xlate);
else
xt_xlate_add(xl, "reject with icmpv6 type %s",
reject_table[reject->with].xlate);
return 1;
}
static struct xtables_target reject_tg6_reg = {
.name = "REJECT",
.version = XTABLES_VERSION,
.family = NFPROTO_IPV6,
.size = XT_ALIGN(sizeof(struct ip6t_reject_info)),
.userspacesize = XT_ALIGN(sizeof(struct ip6t_reject_info)),
.help = REJECT_help,
.init = REJECT_init,
.print = REJECT_print,
.save = REJECT_save,
.x6_parse = REJECT_parse,
.x6_options = REJECT_opts,
.xlate = REJECT_xlate,
};
void _init(void)
{
xtables_register_target(&reject_tg6_reg);
}
+53
View File
@@ -0,0 +1,53 @@
This is used to send back an error packet in response to the matched
packet: otherwise it is equivalent to
.B DROP
so it is a terminating TARGET, ending rule traversal.
This target is only valid in the
.BR INPUT ,
.B FORWARD
and
.B OUTPUT
chains, and user-defined chains which are only called from those
chains. The following option controls the nature of the error packet
returned:
.TP
\fB\-\-reject\-with\fP \fItype\fP
The type given can be
\fBicmp6\-no\-route\fP,
\fBno\-route\fP,
\fBicmp6\-adm\-prohibited\fP,
\fBadm\-prohibited\fP,
\fBicmp6\-addr\-unreachable\fP,
\fBaddr\-unreach\fP, or
\fBicmp6\-port\-unreachable\fP,
which return the appropriate ICMPv6 error message (\fBicmp6\-port\-unreachable\fP is
the default). Finally, the option
\fBtcp\-reset\fP
can be used on rules which only match the TCP protocol: this causes a
TCP RST packet to be sent back. This is mainly useful for blocking
.I ident
(113/tcp) probes which frequently occur when sending mail to broken mail
hosts (which won't accept your mail otherwise).
\fBtcp\-reset\fP
can only be used with kernel versions 2.6.14 or later.
.PP
\fIWarning:\fP You should not indiscriminately apply the REJECT target to
packets whose connection state is classified as INVALID; instead, you should
only DROP these.
.PP
Consider a source host transmitting a packet P, with P experiencing so much
delay along its path that the source host issues a retransmission, P_2, with
P_2 being successful in reaching its destination and advancing the connection
state normally. It is conceivable that the late-arriving P may be considered
not to be associated with any connection tracking entry. Generating a reject
response for a packet so classed would then terminate the healthy connection.
.PP
So, instead of:
.PP
\-A INPUT ... \-j REJECT
.PP
do consider using:
.PP
\-A INPUT ... \-m conntrack \-\-ctstate INVALID \-j DROP
.br
\-A INPUT ... \-j REJECT
+11
View File
@@ -0,0 +1,11 @@
:INPUT,FORWARD,OUTPUT
-j REJECT;-j REJECT --reject-with icmp6-port-unreachable;OK
# manpage for IPv6 variant of REJECT does not show up for some reason?
-j REJECT --reject-with icmp6-no-route;=;OK
-j REJECT --reject-with icmp6-adm-prohibited;=;OK
-j REJECT --reject-with icmp6-addr-unreachable;=;OK
-j REJECT --reject-with icmp6-port-unreachable;=;OK
-j REJECT --reject-with icmp6-policy-fail;=;OK
-j REJECT --reject-with icmp6-reject-route;=;OK
-p tcp -j REJECT --reject-with tcp-reset;=;OK
-j REJECT --reject-with tcp-reset;;FAIL
+8
View File
@@ -0,0 +1,8 @@
ip6tables-translate -A FORWARD -p TCP --dport 22 -j REJECT
nft 'add rule ip6 filter FORWARD tcp dport 22 counter reject'
ip6tables-translate -A FORWARD -p TCP --dport 22 -j REJECT --reject-with icmp6-reject-route
nft 'add rule ip6 filter FORWARD tcp dport 22 counter reject with icmpv6 type reject-route'
ip6tables-translate -A FORWARD -p TCP --dport 22 -j REJECT --reject-with tcp-reset
nft 'add rule ip6 filter FORWARD tcp dport 22 counter reject with tcp reset'
+17
View File
@@ -0,0 +1,17 @@
:POSTROUTING
*nat
-j SNAT --to-source dead::beef;=;OK
-j SNAT --to-source dead::beef-dead::fee7;=;OK
-j SNAT --to-source [dead::beef]:1025-65535;;FAIL
-j SNAT --to-source [dead::beef] --to-source [dead::fee7];;FAIL
-j SNAT --to-source dead::beef --random;=;OK
-j SNAT --to-source dead::beef --random-fully;=;OK
-j SNAT --to-source dead::beef --persistent;=;OK
-j SNAT --to-source dead::beef --random --persistent;=;OK
-j SNAT --to-source dead::beef --random --random-fully;=;OK
-j SNAT --to-source dead::beef --random --random-fully --persistent;=;OK
-p tcp -j SNAT --to-source [dead::beef]:1025-65535;=;OK
-p tcp -j SNAT --to-source [dead::beef-dead::fee7]:1025-65535;=;OK
-p tcp -j SNAT --to-source [dead::beef-dead::fee7]:1025-65536;;FAIL
-p tcp -j SNAT --to-source [dead::beef-dead::fee7]:1025-65535 --to-source [dead::beef-dead::fee8]:1025-65535;;FAIL
-j SNAT;;FAIL
+11
View File
@@ -0,0 +1,11 @@
ip6tables-translate -t nat -A postrouting -o eth0 -p tcp -j SNAT --to [fec0::1234]:80
nft 'add rule ip6 nat postrouting oifname "eth0" meta l4proto tcp counter snat to [fec0::1234]:80'
ip6tables-translate -t nat -A postrouting -o eth0 -p tcp -j SNAT --to [fec0::1234]:1-20
nft 'add rule ip6 nat postrouting oifname "eth0" meta l4proto tcp counter snat to [fec0::1234]:1-20'
ip6tables-translate -t nat -A postrouting -o eth0 -p tcp -j SNAT --to [fec0::1234]:123 --random
nft 'add rule ip6 nat postrouting oifname "eth0" meta l4proto tcp counter snat to [fec0::1234]:123 random'
ip6tables-translate -t nat -A postrouting -o eth0 -p tcp -j SNAT --to [fec0::1234]:123 --random-fully --persistent
nft 'add rule ip6 nat postrouting oifname "eth0" meta l4proto tcp counter snat to [fec0::1234]:123 fully-random,persistent'
+94
View File
@@ -0,0 +1,94 @@
/*
* Copyright (c) 2012-2013 Patrick McHardy <kaber@trash.net>
*/
#include <stdio.h>
#include <string.h>
#include <xtables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/netfilter_ipv6/ip6t_NPT.h>
enum {
O_SRC_PFX = 1 << 0,
O_DST_PFX = 1 << 1,
};
static const struct xt_option_entry SNPT_options[] = {
{ .name = "src-pfx", .id = O_SRC_PFX, .type = XTTYPE_HOSTMASK,
.flags = XTOPT_MAND },
{ .name = "dst-pfx", .id = O_DST_PFX, .type = XTTYPE_HOSTMASK,
.flags = XTOPT_MAND },
{ }
};
static void SNPT_help(void)
{
printf("SNPT target options:"
"\n"
" --src-pfx prefix/length\n"
" --dst-pfx prefix/length\n"
"\n");
}
static void SNPT_parse(struct xt_option_call *cb)
{
struct ip6t_npt_tginfo *npt = cb->data;
xtables_option_parse(cb);
switch (cb->entry->id) {
case O_SRC_PFX:
npt->src_pfx = cb->val.haddr;
npt->src_pfx_len = cb->val.hlen;
break;
case O_DST_PFX:
npt->dst_pfx = cb->val.haddr;
npt->dst_pfx_len = cb->val.hlen;
break;
}
}
static void SNPT_print(const void *ip, const struct xt_entry_target *target,
int numeric)
{
const struct ip6t_npt_tginfo *npt = (const void *)target->data;
printf(" SNPT src-pfx %s/%u", xtables_ip6addr_to_numeric(&npt->src_pfx.in6),
npt->src_pfx_len);
printf(" dst-pfx %s/%u", xtables_ip6addr_to_numeric(&npt->dst_pfx.in6),
npt->dst_pfx_len);
}
static void SNPT_save(const void *ip, const struct xt_entry_target *target)
{
static const struct in6_addr zero_addr;
const struct ip6t_npt_tginfo *info = (const void *)target->data;
if (memcmp(&info->src_pfx.in6, &zero_addr, sizeof(zero_addr)) != 0 ||
info->src_pfx_len != 0)
printf(" --src-pfx %s/%u",
xtables_ip6addr_to_numeric(&info->src_pfx.in6),
info->src_pfx_len);
if (memcmp(&info->dst_pfx.in6, &zero_addr, sizeof(zero_addr)) != 0 ||
info->dst_pfx_len != 0)
printf(" --dst-pfx %s/%u",
xtables_ip6addr_to_numeric(&info->dst_pfx.in6),
info->dst_pfx_len);
}
static struct xtables_target snpt_tg_reg = {
.name = "SNPT",
.version = XTABLES_VERSION,
.family = NFPROTO_IPV6,
.size = XT_ALIGN(sizeof(struct ip6t_npt_tginfo)),
.userspacesize = offsetof(struct ip6t_npt_tginfo, adjustment),
.help = SNPT_help,
.x6_parse = SNPT_parse,
.print = SNPT_print,
.save = SNPT_save,
.x6_options = SNPT_options,
};
void _init(void)
{
xtables_register_target(&snpt_tg_reg);
}
+30
View File
@@ -0,0 +1,30 @@
Provides stateless source IPv6-to-IPv6 Network Prefix Translation (as described
by RFC 6296).
.PP
You have to use this target in the
.B mangle
table, not in the
.B nat
table. It takes the following options:
.TP
\fB\-\-src\-pfx\fP [\fIprefix/\fP\fIlength]
Set source prefix that you want to translate and length
.TP
\fB\-\-dst\-pfx\fP [\fIprefix/\fP\fIlength]
Set destination prefix that you want to use in the translation and length
.PP
You have to use the DNPT target to undo the translation. Example:
.IP
ip6tables \-t mangle \-I POSTROUTING \-s fd00::/64 ! \-o vboxnet0
\-j SNPT \-\-src-pfx fd00::/64 \-\-dst-pfx 2001:e20:2000:40f::/64
.IP
ip6tables \-t mangle \-I PREROUTING \-i wlan0 \-d 2001:e20:2000:40f::/64
\-j DNPT \-\-src-pfx 2001:e20:2000:40f::/64 \-\-dst\-pfx fd00::/64
.PP
You may need to enable IPv6 neighbor proxy:
.IP
sysctl \-w net.ipv6.conf.all.proxy_ndp=1
.PP
You also have to use the
.B NOTRACK
target to disable connection tracking for translated flows.
+7
View File
@@ -0,0 +1,7 @@
:INPUT,POSTROUTING
*mangle
-j SNPT --src-pfx dead::/64 --dst-pfx 1c3::/64;=;OK
-j SNPT --src-pfx dead::beef --dst-pfx 1c3::/64;;FAIL
-j SNPT --src-pfx dead::/64;;FAIL
-j SNPT --dst-pfx dead::/64;;FAIL
-j SNPT;;FAIL

Some files were not shown because too many files have changed in this diff Show More