mirror of
https://github.com/openharmony/third_party_iptables.git
synced 2026-07-19 18:23:54 -04:00
update to 1.8.7-5.oe2203
Signed-off-by: maosiping <maosiping@huawei.com> Signed-off-by: liyufan <liyufan5@huawei.com> Signed-off-by: maosiping <maosiping@huawei.com>
This commit is contained in:
@@ -25,3 +25,4 @@ Makefile.in
|
||||
|
||||
# vim/nano swap file
|
||||
*.swp
|
||||
.idea
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
import("//build/ohos.gni")
|
||||
|
||||
iptables_path = rebase_path("//third_party/iptables")
|
||||
exec_script("install.sh", [ "$iptables_path" ])
|
||||
|
||||
config("iptables_config") {
|
||||
cflags = [
|
||||
"-D_LARGEFILE_SOURCE=1",
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
A quick list of rules for committing stuff into netfilter git:
|
||||
|
||||
- Always add an appropriate description, in git format
|
||||
(i.e. first line is a summary)
|
||||
|
||||
- Please try to include references to bugs when the description does not
|
||||
include total discussion coverage or when the bug report is external to
|
||||
netfilter-devel, e.g.
|
||||
"Closes: netfilter bugzilla #123", or
|
||||
"Reference: http://bugs.{debian,gentoo}.org/..."
|
||||
|
||||
- If you touch any parts of libxtables (xtables.c, include/xtables.h.in),
|
||||
make sure the so-version is updated _appropriately_ (i.e. read the
|
||||
libtool manual about Versioning:: first, if need be) in configure.ac.
|
||||
Adding fields to a struct always entails a vcurrent bump.
|
||||
|
||||
- Check, whether a bump (vcurrent,vage) has already been made since the
|
||||
last release (no more than one per release), e.g.:
|
||||
git log v1.4.4.. configure.ac
|
||||
@@ -1,14 +0,0 @@
|
||||
INCOMPATIBILITIES:
|
||||
|
||||
- The REJECT target has an '--reject-with admin-prohib' option which used
|
||||
with kernels that do not support it, will result in a plain DROP instead
|
||||
of REJECT. Use with caution.
|
||||
Kernels that do support it:
|
||||
2.4 - since 2.4.22-pre9
|
||||
2.6 - all
|
||||
|
||||
- There are some issues related to upgrading from 1.2.x to 1.3.x on a system
|
||||
with dynamic ruleset changes during runtime. (Please see
|
||||
https://bugzilla.netfilter.org/bugzilla/show_bug.cgi?id=334).
|
||||
After upgrading from 1.2 to 1.3, it suggest go do an iptables-save, then
|
||||
iptables-restore to ensure your dynamic rule changes continue to work.
|
||||
@@ -1,101 +0,0 @@
|
||||
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.
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
AUTOMAKE_OPTIONS = foreign subdir-objects
|
||||
|
||||
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
|
||||
|
||||
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.bz2 --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
|
||||
@@ -59,6 +59,9 @@
|
||||
<licensematcher name="GPL" desc="">
|
||||
<licensetext name='This program is distributed under the terms of GNU GPL' desc=""/>
|
||||
</licensematcher>
|
||||
<licensematcher name="GPLv2" desc="">
|
||||
<licensetext name='GPLv2 and Artistic Licence 2.0 and ISC' desc=""/>
|
||||
</licensematcher>
|
||||
<licensematcher name="libipt_CLUSTERIP.man" desc="">
|
||||
<licensetext name='This module allows you to configure a simple cluster of nodes that share
|
||||
a certain IP and MAC address without an explicit load balancer in front of
|
||||
@@ -178,10 +181,17 @@ cluster.' desc=""/>
|
||||
<policyitem type="compatibility" name="GPL" path="extensions/libipt_TTL.c" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter" desc="use iptables by independent process"/>
|
||||
<policyitem type="compatibility" name="GPL" path="extensions/libip6t_HL.c" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter" desc="use iptables by independent process"/>
|
||||
<policyitem type="compatibility" name="libipt_CLUSTERIP.man" path="extensions/libipt_CLUSTERIP.man" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter" desc="use iptables by independent process"/>
|
||||
<policyitem type="compatibility" name="GPLv2" path="iptables.spec" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter" desc="use iptables by independent process"/>
|
||||
<policyitem type="license" name="*" path=".*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter" desc=""/>
|
||||
<policyitem type="copyright" name="*" path=".*" rule="may" group="defaultGroup" filefilter="copyrightPolicyFilter" desc=""/>
|
||||
</policy>
|
||||
</policylist>
|
||||
|
||||
<filefilterlist>
|
||||
<filefilter name="binaryFileTypePolicyFilter" desc="Filters for binary file policies">
|
||||
<filteritem type="filename" name="iptables-1.8.7.tar.bz2"/>
|
||||
</filefilter>
|
||||
</filefilterlist>
|
||||
</oatconfig>
|
||||
</configuration>
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
autoreconf -fi;
|
||||
rm -Rf autom4te*.cache;
|
||||
@@ -0,0 +1,135 @@
|
||||
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
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `pcap' library (-lpcap). */
|
||||
/* #undef HAVE_LIBPCAP */
|
||||
|
||||
/* Define to 1 if you have the <linux/bpf.h> header file. */
|
||||
#define HAVE_LINUX_BPF_H 1
|
||||
|
||||
/* Define to 1 if you have the <linux/dccp.h> header file. */
|
||||
#define HAVE_LINUX_DCCP_H 1
|
||||
|
||||
/* Define to 1 if you have the <linux/ip_vs.h> header file. */
|
||||
#define HAVE_LINUX_IP_VS_H 1
|
||||
|
||||
/* Define to 1 if you have the <linux/magic.h> header file. */
|
||||
#define HAVE_LINUX_MAGIC_H 1
|
||||
|
||||
/* Define to 1 if you have the <linux/proc_fs.h> header file. */
|
||||
/* #undef HAVE_LINUX_PROC_FS_H */
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#define LT_OBJDIR ".libs/"
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "iptables"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT ""
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "iptables"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "iptables 1.8.7"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "iptables"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "1.8.7"
|
||||
|
||||
/* The size of `struct ip6_hdr', as computed by sizeof. */
|
||||
#define SIZEOF_STRUCT_IP6_HDR 40
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "1.8.7"
|
||||
|
||||
/* Location of the iptables lock file */
|
||||
#define XT_LOCK_NAME "/system/etc/xtables.lock"
|
||||
-274
@@ -1,274 +0,0 @@
|
||||
|
||||
AC_INIT([iptables], [1.8.7])
|
||||
|
||||
# See libtool.info "Libtool's versioning system"
|
||||
libxtables_vcurrent=16
|
||||
libxtables_vage=4
|
||||
|
||||
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
|
||||
AC_DISABLE_STATIC
|
||||
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
|
||||
AM_PROG_LIBTOOL
|
||||
|
||||
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([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_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 test "x$enable_bpfc" = "xyes" || test "x$enable_nfsynproxy" = "xyes"; then
|
||||
AC_CHECK_LIB(pcap, pcap_compile,, AC_MSG_ERROR(missing libpcap library required by bpf compiler or nfsynproxy tool))
|
||||
fi
|
||||
|
||||
PKG_CHECK_MODULES([libnfnetlink], [libnfnetlink >= 1.0],
|
||||
[nfnetlink=1], [nfnetlink=0])
|
||||
AM_CONDITIONAL([HAVE_LIBNFNETLINK], [test "$nfnetlink" = 1])
|
||||
|
||||
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.1.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';
|
||||
|
||||
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([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}
|
||||
|
||||
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}"
|
||||
|
||||
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"
|
||||
@@ -1,39 +0,0 @@
|
||||
#
|
||||
# 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
|
||||
@@ -1,74 +0,0 @@
|
||||
family ipv4 {
|
||||
table raw {
|
||||
chain PREROUTING hook NF_INET_PRE_ROUTING prio -300
|
||||
chain OUTPUT hook NF_INET_LOCAL_OUT prio -300
|
||||
}
|
||||
|
||||
table mangle {
|
||||
chain PREROUTING hook NF_INET_PRE_ROUTING prio -150
|
||||
chain INPUT hook NF_INET_LOCAL_IN prio -150
|
||||
chain FORWARD hook NF_INET_FORWARD prio -150
|
||||
chain OUTPUT hook NF_INET_LOCAL_OUT prio -150
|
||||
chain POSTROUTING hook NF_INET_POST_ROUTING prio -150
|
||||
}
|
||||
|
||||
table filter {
|
||||
chain INPUT hook NF_INET_LOCAL_IN prio 0
|
||||
chain FORWARD hook NF_INET_FORWARD prio 0
|
||||
chain OUTPUT hook NF_INET_LOCAL_OUT prio 0
|
||||
}
|
||||
|
||||
table nat {
|
||||
chain PREROUTING hook NF_INET_PRE_ROUTING prio -100
|
||||
chain INPUT hook NF_INET_LOCAL_IN prio 100
|
||||
chain OUTPUT hook NF_INET_LOCAL_OUT prio -100
|
||||
chain POSTROUTING hook NF_INET_POST_ROUTING prio 100
|
||||
}
|
||||
|
||||
table security {
|
||||
chain INPUT hook NF_INET_LOCAL_IN prio 50
|
||||
chain FORWARD hook NF_INET_FORWARD prio 50
|
||||
chain OUTPUT hook NF_INET_LOCAL_OUT prio 50
|
||||
}
|
||||
}
|
||||
|
||||
family ipv6 {
|
||||
table raw {
|
||||
chain PREROUTING hook NF_INET_PRE_ROUTING prio -300
|
||||
chain OUTPUT hook NF_INET_LOCAL_OUT prio -300
|
||||
}
|
||||
|
||||
table mangle {
|
||||
chain PREROUTING hook NF_INET_PRE_ROUTING prio -150
|
||||
chain INPUT hook NF_INET_LOCAL_IN prio -150
|
||||
chain FORWARD hook NF_INET_FORWARD prio -150
|
||||
chain OUTPUT hook NF_INET_LOCAL_OUT prio -150
|
||||
chain POSTROUTING hook NF_INET_POST_ROUTING prio -150
|
||||
}
|
||||
|
||||
table filter {
|
||||
chain INPUT hook NF_INET_LOCAL_IN prio 0
|
||||
chain FORWARD hook NF_INET_FORWARD prio 0
|
||||
chain OUTPUT hook NF_INET_LOCAL_OUT prio 0
|
||||
}
|
||||
|
||||
table nat {
|
||||
chain PREROUTING hook NF_INET_PRE_ROUTING prio -100
|
||||
chain INPUT hook NF_INET_LOCAL_IN prio 100
|
||||
chain OUTPUT hook NF_INET_LOCAL_OUT prio -100
|
||||
chain POSTROUTING hook NF_INET_POST_ROUTING prio 100
|
||||
}
|
||||
|
||||
table security {
|
||||
chain INPUT hook NF_INET_LOCAL_IN prio 50
|
||||
chain FORWARD hook NF_INET_FORWARD prio 50
|
||||
chain OUTPUT hook NF_INET_LOCAL_OUT prio 50
|
||||
}
|
||||
}
|
||||
|
||||
family arp {
|
||||
table filter {
|
||||
chain INPUT hook NF_ARP_IN prio 0
|
||||
chain OUTPUT hook NF_ARP_OUT prio 0
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
.*.d
|
||||
.*.dd
|
||||
*.oo
|
||||
|
||||
/GNUmakefile
|
||||
/initext.c
|
||||
/initext?.c
|
||||
/matches.man
|
||||
/targets.man
|
||||
@@ -1,254 +0,0 @@
|
||||
# Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//build/ohos.gni")
|
||||
LIBEXT_COMMON_PATH = "//out/gen"
|
||||
config("ext_config") {
|
||||
cflags = [
|
||||
"-D_LARGEFILE_SOURCE=1",
|
||||
"-D_LARGE_FILES",
|
||||
"-D_FILE_OFFSET_BITS=64",
|
||||
"-D_REENTRANT",
|
||||
"-DENABLE_IPV4",
|
||||
"-DENABLE_IPV6",
|
||||
"-Wall",
|
||||
"-Wno-error",
|
||||
"-Wno-pointer-arith",
|
||||
"-Wno-sign-compare",
|
||||
"-Wno-unused-parameter",
|
||||
"-DNO_SHARED_LIBS=1",
|
||||
"-DXTABLES_INTERNAL",
|
||||
"-Wno-format",
|
||||
"-Wno-missing-field-initializers",
|
||||
"-Wno-pointer-bool-conversion",
|
||||
"-Wno-tautological-pointer-compare",
|
||||
]
|
||||
}
|
||||
|
||||
args_libext = [
|
||||
"libxt_",
|
||||
"[libxt_cgroup.c,libxt_ipvs.c,libxt_TCPOPTSTRIP.c,libxt_connlabel.c,libxt_dccp.c]",
|
||||
"initext.c",
|
||||
"extensions",
|
||||
]
|
||||
|
||||
exec_script("genInit.py", args_libext)
|
||||
|
||||
ohos_static_library("libext") {
|
||||
sources = [
|
||||
"$LIBEXT_COMMON_PATH/initext.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_AUDIT.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_CHECKSUM.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_CLASSIFY.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_CONNMARK.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_CONNSECMARK.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_CT.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_DSCP.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_HMARK.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_IDLETIMER.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_LED.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_MARK.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_NFLOG.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_NFQUEUE.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_RATEEST.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_SECMARK.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_SET.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_SYNPROXY.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_TCPMSS.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_TEE.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_TOS.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_TPROXY.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_TRACE.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_addrtype.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_bpf.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_cluster.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_comment.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_connbytes.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_connlimit.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_connmark.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_conntrack.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_cpu.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_devgroup.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_dscp.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_ecn.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_esp.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_hashlimit.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_helper.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_ipcomp.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_iprange.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_length.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_limit.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_mac.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_mark.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_multiport.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_nfacct.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_osf.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_owner.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_physdev.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_pkttype.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_policy.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_quota.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_quota2.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_rateest.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_recent.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_rpfilter.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_sctp.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_set.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_socket.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_standard.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_statistic.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_string.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_tcp.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_tcpmss.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_time.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_tos.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_u32.c",
|
||||
"$LIBEXT_COMMON_PATH/libxt_udp.c",
|
||||
]
|
||||
include_dirs = [
|
||||
"//third_party/iptables",
|
||||
"//third_party/iptables/extensions",
|
||||
"//third_party/iptables/include",
|
||||
"//third_party/iptables/iptables",
|
||||
"//third_party/iptables/libiptc",
|
||||
]
|
||||
configs = [ ":ext_config" ]
|
||||
deps = []
|
||||
part_name = "netmanager_standard"
|
||||
subsystem_name = "communication"
|
||||
}
|
||||
|
||||
args_libext4 = [
|
||||
"libipt",
|
||||
"[]",
|
||||
"initext4.c",
|
||||
"extensions4",
|
||||
]
|
||||
|
||||
exec_script("genInit.py", args_libext4)
|
||||
|
||||
ohos_static_library("libext4") {
|
||||
sources = [
|
||||
"$LIBEXT_COMMON_PATH/initext4.c",
|
||||
"$LIBEXT_COMMON_PATH/libipt_CLUSTERIP.c",
|
||||
"$LIBEXT_COMMON_PATH/libipt_DNAT.c",
|
||||
"$LIBEXT_COMMON_PATH/libipt_ECN.c",
|
||||
"$LIBEXT_COMMON_PATH/libipt_LOG.c",
|
||||
"$LIBEXT_COMMON_PATH/libipt_MASQUERADE.c",
|
||||
"$LIBEXT_COMMON_PATH/libipt_NETMAP.c",
|
||||
"$LIBEXT_COMMON_PATH/libipt_REDIRECT.c",
|
||||
"$LIBEXT_COMMON_PATH/libipt_REJECT.c",
|
||||
"$LIBEXT_COMMON_PATH/libipt_SNAT.c",
|
||||
"$LIBEXT_COMMON_PATH/libipt_TTL.c",
|
||||
"$LIBEXT_COMMON_PATH/libipt_ULOG.c",
|
||||
"$LIBEXT_COMMON_PATH/libipt_ah.c",
|
||||
"$LIBEXT_COMMON_PATH/libipt_icmp.c",
|
||||
"$LIBEXT_COMMON_PATH/libipt_realm.c",
|
||||
"$LIBEXT_COMMON_PATH/libipt_ttl.c",
|
||||
]
|
||||
include_dirs = [
|
||||
"//third_party/iptables",
|
||||
"//third_party/iptables/extensions",
|
||||
"//third_party/iptables/include",
|
||||
"//third_party/iptables/iptables",
|
||||
"//third_party/iptables/libiptc",
|
||||
]
|
||||
cflags = [
|
||||
"-D_LARGEFILE_SOURCE=1",
|
||||
"-D_LARGE_FILES",
|
||||
"-D_FILE_OFFSET_BITS=64",
|
||||
"-D_REENTRANT",
|
||||
"-DENABLE_IPV4",
|
||||
"-DENABLE_IPV6",
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
"-Wno-pointer-arith",
|
||||
"-Wno-sign-compare",
|
||||
"-Wno-unused-parameter",
|
||||
"-DNO_SHARED_LIBS=1",
|
||||
"-DXTABLES_INTERNAL",
|
||||
"-Wno-format",
|
||||
"-Wno-missing-field-initializers",
|
||||
"-Wno-pointer-bool-conversion",
|
||||
"-Wno-tautological-pointer-compare",
|
||||
]
|
||||
deps = []
|
||||
part_name = "netmanager_base"
|
||||
subsystem_name = "communication"
|
||||
}
|
||||
|
||||
args_libext6 = [
|
||||
"libip6t_",
|
||||
"[]",
|
||||
"initext6.c",
|
||||
"extensions6",
|
||||
]
|
||||
|
||||
exec_script("genInit.py", args_libext6)
|
||||
|
||||
ohos_static_library("libext6") {
|
||||
sources = [
|
||||
"$LIBEXT_COMMON_PATH/initext6.c",
|
||||
"$LIBEXT_COMMON_PATH/libip6t_DNAT.c",
|
||||
"$LIBEXT_COMMON_PATH/libip6t_DNPT.c",
|
||||
"$LIBEXT_COMMON_PATH/libip6t_HL.c",
|
||||
"$LIBEXT_COMMON_PATH/libip6t_LOG.c",
|
||||
"$LIBEXT_COMMON_PATH/libip6t_MASQUERADE.c",
|
||||
"$LIBEXT_COMMON_PATH/libip6t_NETMAP.c",
|
||||
"$LIBEXT_COMMON_PATH/libip6t_REDIRECT.c",
|
||||
"$LIBEXT_COMMON_PATH/libip6t_REJECT.c",
|
||||
"$LIBEXT_COMMON_PATH/libip6t_SNAT.c",
|
||||
"$LIBEXT_COMMON_PATH/libip6t_SNPT.c",
|
||||
"$LIBEXT_COMMON_PATH/libip6t_ah.c",
|
||||
"$LIBEXT_COMMON_PATH/libip6t_dst.c",
|
||||
"$LIBEXT_COMMON_PATH/libip6t_eui64.c",
|
||||
"$LIBEXT_COMMON_PATH/libip6t_frag.c",
|
||||
"$LIBEXT_COMMON_PATH/libip6t_hbh.c",
|
||||
"$LIBEXT_COMMON_PATH/libip6t_hl.c",
|
||||
"$LIBEXT_COMMON_PATH/libip6t_icmp6.c",
|
||||
"$LIBEXT_COMMON_PATH/libip6t_ipv6header.c",
|
||||
"$LIBEXT_COMMON_PATH/libip6t_mh.c",
|
||||
"$LIBEXT_COMMON_PATH/libip6t_rt.c",
|
||||
"$LIBEXT_COMMON_PATH/libip6t_srh.c",
|
||||
]
|
||||
include_dirs = [
|
||||
"//third_party/iptables",
|
||||
"//third_party/iptables/extensions",
|
||||
"//third_party/iptables/include",
|
||||
"//third_party/iptables/iptables",
|
||||
"//third_party/iptables/libiptc",
|
||||
]
|
||||
license_file = "//third_party/iptables/COPYING"
|
||||
cflags = [
|
||||
"-D_LARGEFILE_SOURCE=1",
|
||||
"-D_LARGE_FILES",
|
||||
"-D_FILE_OFFSET_BITS=64",
|
||||
"-D_REENTRANT",
|
||||
"-DENABLE_IPV4",
|
||||
"-DENABLE_IPV6",
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
"-Wno-pointer-arith",
|
||||
"-Wno-sign-compare",
|
||||
"-Wno-unused-parameter",
|
||||
"-DNO_SHARED_LIBS=1",
|
||||
"-DXTABLES_INTERNAL",
|
||||
"-Wno-format",
|
||||
"-Wno-missing-field-initializers",
|
||||
"-Wno-pointer-bool-conversion",
|
||||
"-Wno-tautological-pointer-compare",
|
||||
]
|
||||
deps = []
|
||||
part_name = "netmanager_base"
|
||||
subsystem_name = "communication"
|
||||
}
|
||||
@@ -1,307 +0,0 @@
|
||||
# -*- 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@
|
||||
|
||||
ifeq (${V},)
|
||||
AM_LIBTOOL_SILENT = --silent
|
||||
AM_VERBOSE_CC = @echo " CC " $@;
|
||||
AM_VERBOSE_CCLD = @echo " CCLD " $@;
|
||||
AM_VERBOSE_CXX = @echo " CXX " $@;
|
||||
AM_VERBOSE_CXXLD = @echo " CXXLD " $@;
|
||||
AM_VERBOSE_AR = @echo " AR " $@;
|
||||
AM_VERBOSE_GEN = @echo " GEN " $@;
|
||||
endif
|
||||
|
||||
#
|
||||
# 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
|
||||
@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
|
||||
|
||||
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,targets}.man initext.c initext4.c initext6.c initextb.c initexta.c;
|
||||
rm -f .*.d .*.dd;
|
||||
|
||||
distclean: clean
|
||||
|
||||
init%.o: init%.c
|
||||
${AM_VERBOSE_CC} ${CC} ${AM_CPPFLAGS} ${AM_DEPFLAGS} ${AM_CFLAGS} -D_INIT=$*_init ${CFLAGS} -o $@ -c $<;
|
||||
|
||||
-include .*.d
|
||||
|
||||
|
||||
#
|
||||
# Shared libraries
|
||||
#
|
||||
lib%.so: lib%.oo
|
||||
${AM_VERBOSE_CCLD} ${CCLD} ${AM_LDFLAGS} ${LDFLAGS} -shared -o $@ $< -L../libxtables/.libs -lxtables ${$*_LIBADD};
|
||||
|
||||
lib%.oo: ${srcdir}/lib%.c
|
||||
${AM_VERBOSE_CC} ${CC} ${AM_CPPFLAGS} ${AM_DEPFLAGS} ${AM_CFLAGS} -D_INIT=lib$*_init -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
|
||||
|
||||
libxt_NOTRACK.so: libxt_CT.so
|
||||
ln -fs $< $@
|
||||
libxt_state.so: libxt_conntrack.so
|
||||
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_VERBOSE_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_VERBOSE_AR} ${AR} crs $@ $^;
|
||||
|
||||
libext_ebt.a: initextb.o ${libext_ebt_objs}
|
||||
${AM_VERBOSE_AR} ${AR} crs $@ $^;
|
||||
|
||||
libext_arpt.a: initexta.o ${libext_arpt_objs}
|
||||
${AM_VERBOSE_AR} ${AR} crs $@ $^;
|
||||
|
||||
libext4.a: initext4.o ${libext4_objs}
|
||||
${AM_VERBOSE_AR} ${AR} crs $@ $^;
|
||||
|
||||
libext6.a: initext6.o ${libext6_objs}
|
||||
${AM_VERBOSE_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})
|
||||
|
||||
.initext.dd: FORCE
|
||||
@echo "${initext_func}" >$@.tmp; \
|
||||
cmp -s $@ $@.tmp || mv $@.tmp $@; \
|
||||
rm -f $@.tmp;
|
||||
|
||||
.initextb.dd: FORCE
|
||||
@echo "${initextb_func}" >$@.tmp; \
|
||||
cmp -s $@ $@.tmp || mv $@.tmp $@; \
|
||||
rm -f $@.tmp;
|
||||
|
||||
.initexta.dd: FORCE
|
||||
@echo "${initexta_func}" >$@.tmp; \
|
||||
cmp -s $@ $@.tmp || mv $@.tmp $@; \
|
||||
rm -f $@.tmp;
|
||||
|
||||
.initext4.dd: FORCE
|
||||
@echo "${initext4_func}" >$@.tmp; \
|
||||
cmp -s $@ $@.tmp || mv $@.tmp $@; \
|
||||
rm -f $@.tmp;
|
||||
|
||||
.initext6.dd: FORCE
|
||||
@echo "${initext6_func}" >$@.tmp; \
|
||||
cmp -s $@ $@.tmp || mv $@.tmp $@; \
|
||||
rm -f $@.tmp;
|
||||
|
||||
initext.c: .initext.dd
|
||||
${AM_VERBOSE_GEN}
|
||||
@( \
|
||||
echo "" >$@; \
|
||||
for i in ${initext_func}; do \
|
||||
echo "extern void lib$${i}_init(void);" >>$@; \
|
||||
done; \
|
||||
echo "void init_extensions(void);" >>$@; \
|
||||
echo "void init_extensions(void)" >>$@; \
|
||||
echo "{" >>$@; \
|
||||
for i in ${initext_func}; do \
|
||||
echo " ""lib$${i}_init();" >>$@; \
|
||||
done; \
|
||||
echo "}" >>$@; \
|
||||
);
|
||||
|
||||
initextb.c: .initextb.dd
|
||||
${AM_VERBOSE_GEN}
|
||||
@( \
|
||||
echo "" >$@; \
|
||||
for i in ${initextb_func}; do \
|
||||
echo "extern void lib$${i}_init(void);" >>$@; \
|
||||
done; \
|
||||
echo "void init_extensionsb(void);" >>$@; \
|
||||
echo "void init_extensionsb(void)" >>$@; \
|
||||
echo "{" >>$@; \
|
||||
for i in ${initextb_func}; do \
|
||||
echo " ""lib$${i}_init();" >>$@; \
|
||||
done; \
|
||||
echo "}" >>$@; \
|
||||
);
|
||||
|
||||
initexta.c: .initexta.dd
|
||||
${AM_VERBOSE_GEN}
|
||||
@( \
|
||||
echo "" >$@; \
|
||||
for i in ${initexta_func}; do \
|
||||
echo "extern void lib$${i}_init(void);" >>$@; \
|
||||
done; \
|
||||
echo "void init_extensionsa(void);" >>$@; \
|
||||
echo "void init_extensionsa(void)" >>$@; \
|
||||
echo "{" >>$@; \
|
||||
for i in ${initexta_func}; do \
|
||||
echo " ""lib$${i}_init();" >>$@; \
|
||||
done; \
|
||||
echo "}" >>$@; \
|
||||
);
|
||||
|
||||
initext4.c: .initext4.dd
|
||||
${AM_VERBOSE_GEN}
|
||||
@( \
|
||||
echo "" >$@; \
|
||||
for i in ${initext4_func}; do \
|
||||
echo "extern void lib$${i}_init(void);" >>$@; \
|
||||
done; \
|
||||
echo "void init_extensions4(void);" >>$@; \
|
||||
echo "void init_extensions4(void)" >>$@; \
|
||||
echo "{" >>$@; \
|
||||
for i in ${initext4_func}; do \
|
||||
echo " ""lib$${i}_init();" >>$@; \
|
||||
done; \
|
||||
echo "}" >>$@; \
|
||||
);
|
||||
|
||||
initext6.c: .initext6.dd
|
||||
${AM_VERBOSE_GEN}
|
||||
@( \
|
||||
echo "" >$@; \
|
||||
for i in ${initext6_func}; do \
|
||||
echo "extern void lib$${i}_init(void);" >>$@; \
|
||||
done; \
|
||||
echo "void init_extensions6(void);" >>$@; \
|
||||
echo "void init_extensions6(void)" >>$@; \
|
||||
echo "{" >>$@; \
|
||||
for i in ${initext6_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_VERBOSE_GEN} \
|
||||
for ext in $(sort ${1}); do \
|
||||
f="${srcdir}/libxt_$$ext.man"; \
|
||||
if [ -f "$$f" ]; then \
|
||||
echo -e "\t+ $$f" >&2; \
|
||||
echo ".SS $$ext"; \
|
||||
cat "$$f" || exit $$?; \
|
||||
fi; \
|
||||
f="${srcdir}/libip6t_$$ext.man"; \
|
||||
if [ -f "$$f" ]; then \
|
||||
echo -e "\t+ $$f" >&2; \
|
||||
echo ".SS $$ext (IPv6-specific)"; \
|
||||
cat "$$f" || exit $$?; \
|
||||
fi; \
|
||||
f="${srcdir}/libipt_$$ext.man"; \
|
||||
if [ -f "$$f" ]; then \
|
||||
echo -e "\t+ $$f" >&2; \
|
||||
echo ".SS $$ext (IPv4-specific)"; \
|
||||
cat "$$f" || exit $$?; \
|
||||
fi; \
|
||||
done >$@;
|
||||
|
||||
matches.man: .initext.dd .initextb.dd .initexta.dd .initext4.dd .initext6.dd $(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.dd .initextb.dd .initexta.dd .initext4.dd .initext6.dd $(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}))
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* 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'\n", 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'\n", dscp);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from dataclasses import replace
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
|
||||
def _run_cmd(cmd):
|
||||
print(cmd)
|
||||
res = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
sout, serr = res.communicate()
|
||||
return sout.rstrip().decode('utf-8'), serr, res.returncode
|
||||
|
||||
|
||||
def _make_dir(file_path):
|
||||
is_exist = os.path.exists(file_path)
|
||||
print (file_path)
|
||||
if not is_exist:
|
||||
os.makedirs(file_path)
|
||||
print (file_path)
|
||||
|
||||
|
||||
def _read_file(file_path):
|
||||
file_handler = open(file_path, 'r+', encoding='utf-8')
|
||||
content = file_handler.read()
|
||||
file_handler.close
|
||||
|
||||
return content
|
||||
|
||||
def _write_file(file_path, content):
|
||||
file_handler = open(file_path, 'w', encoding='utf-8')
|
||||
file_handler.write(content)
|
||||
file_handler.close
|
||||
|
||||
|
||||
def _write_internal_methods(new_init_file, internal_method_name, init_file_list):
|
||||
new_init_file.write("void init_" + internal_method_name + "(void);\n")
|
||||
new_init_file.write("void init_" + internal_method_name + "(void)\n{\n")
|
||||
for init_file_name in init_file_list:
|
||||
new_init_file.write(init_file_name)
|
||||
new_init_file.write("}")
|
||||
|
||||
|
||||
def _need_rebuild(src_file, dest_file, src_md5_file):
|
||||
if os.path.exists(src_file) and os.path.exists(dest_file) and os.path.exists(src_md5_file):
|
||||
this_md5, err, returncode = _run_cmd("md5sum " + src_file + " | awk '{print $1}'")
|
||||
last_md5, err, returncode = _run_cmd("cat " + src_md5_file)
|
||||
if this_md5 == last_md5:
|
||||
return 0
|
||||
else:
|
||||
return 1
|
||||
else:
|
||||
print("src_file, dest_file or src_md5_file doesn't exist. Generate new md5 file.")
|
||||
this_md5, err, returncode = _run_cmd("md5sum " + src_file + " | awk '{print $1}' >" + src_md5_file)
|
||||
return 1
|
||||
|
||||
|
||||
def main():
|
||||
# sys.argv[1]: filter pattern
|
||||
# sys.argv[2]: exclude file list
|
||||
# sys.argv[3]: output file
|
||||
# sys.argv[4]: internal method name
|
||||
ori_path = os.path.dirname(os.path.abspath(__file__))
|
||||
out_path = os.path.dirname(os.path.dirname(os.path.dirname(ori_path)))
|
||||
out_path += "/out"
|
||||
gen_path = out_path + "/gen"
|
||||
md5_path = out_path + "/gen/md5"
|
||||
_make_dir(gen_path)
|
||||
_make_dir(md5_path)
|
||||
new_init_file_name = gen_path + "/" + sys.argv[3]
|
||||
if os.path.exists(new_init_file_name):
|
||||
os.remove(new_init_file_name)
|
||||
os.mknod(new_init_file_name)
|
||||
new_init_file = open(new_init_file_name, 'a', encoding='utf-8')
|
||||
|
||||
init_file_list = []
|
||||
for filter_file in os.listdir(ori_path):
|
||||
file_name, extension = os.path.splitext(filter_file)
|
||||
if (sys.argv[1] in filter_file) & (extension == ".c") & (filter_file not in sys.argv[2]):
|
||||
print(filter_file)
|
||||
src_path = os.path.join(ori_path, filter_file)
|
||||
src_md5_file = os.path.join(md5_path, filter_file + ".md5")
|
||||
dst_path = os.path.join(gen_path, filter_file)
|
||||
need_rebuild = _need_rebuild(src_path, dst_path, src_md5_file)
|
||||
if need_rebuild:
|
||||
shutil.copy(src_path, dst_path)
|
||||
content = _read_file(dst_path)
|
||||
if "_init(void)" in content:
|
||||
replace_init_text = filter_file.rstrip("\.c") + "_init(void)"
|
||||
new_content = content.replace("_init(void)", replace_init_text)
|
||||
if need_rebuild:
|
||||
_write_file(dst_path, new_content)
|
||||
|
||||
new_init_file.write("extern " + "void " + replace_init_text + ";\n")
|
||||
init_file_list.append(filter_file.rstrip("\.c") + "_init" + "();\n")
|
||||
|
||||
internal_method_name = sys.argv[4]
|
||||
_write_internal_methods(new_init_file, internal_method_name, init_file_list)
|
||||
new_init_file.close
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
@@ -1,36 +0,0 @@
|
||||
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
|
||||
|
||||
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 01:02:03:04:00:00 and ff:ff:ff:ff:00:00 == 01:02:03:04:00:00 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 all asterisks but translate only the first 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
|
||||
@@ -1,6 +0,0 @@
|
||||
:FORWARD
|
||||
-i alongifacename0;=;OK
|
||||
-i thisinterfaceistoolong0;;FAIL
|
||||
-i eth+ -o alongifacename+;=;OK
|
||||
! -i eth0;=;OK
|
||||
! -o eth+;=;OK
|
||||
@@ -1,4 +0,0 @@
|
||||
: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
|
||||
@@ -1,4 +0,0 @@
|
||||
: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
|
||||
@@ -1,193 +0,0 @@
|
||||
/*
|
||||
* 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"
|
||||
#include "iptables/nft-arp.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");
|
||||
}
|
||||
|
||||
#define MANGLE_IPS '1'
|
||||
#define MANGLE_IPT '2'
|
||||
#define MANGLE_DEVS '3'
|
||||
#define MANGLE_DEVT '4'
|
||||
#define MANGLE_TARGET '5'
|
||||
|
||||
static const struct option arpmangle_opts[] = {
|
||||
{ .name = "mangle-ip-s", .has_arg = true, .val = MANGLE_IPS },
|
||||
{ .name = "mangle-ip-d", .has_arg = true, .val = MANGLE_IPT },
|
||||
{ .name = "mangle-mac-s", .has_arg = true, .val = MANGLE_DEVS },
|
||||
{ .name = "mangle-mac-d", .has_arg = true, .val = MANGLE_DEVT },
|
||||
{ .name = "mangle-target", .has_arg = true, .val = MANGLE_TARGET },
|
||||
XT_GETOPT_TABLEEND,
|
||||
};
|
||||
|
||||
static void arpmangle_init(struct xt_entry_target *target)
|
||||
{
|
||||
struct arpt_mangle *mangle = (struct arpt_mangle *)target->data;
|
||||
|
||||
mangle->target = NF_ACCEPT;
|
||||
}
|
||||
|
||||
static int
|
||||
arpmangle_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct arpt_mangle *mangle = (struct arpt_mangle *)(*target)->data;
|
||||
struct in_addr *ipaddr, mask;
|
||||
struct ether_addr *macaddr;
|
||||
const struct arpt_entry *e = (const struct arpt_entry *)entry;
|
||||
unsigned int nr;
|
||||
int ret = 1;
|
||||
|
||||
memset(&mask, 0, sizeof(mask));
|
||||
|
||||
switch (c) {
|
||||
case MANGLE_IPS:
|
||||
xtables_ipparse_any(optarg, &ipaddr, &mask, &nr);
|
||||
mangle->u_s.src_ip.s_addr = ipaddr->s_addr;
|
||||
free(ipaddr);
|
||||
mangle->flags |= ARPT_MANGLE_SIP;
|
||||
break;
|
||||
case MANGLE_IPT:
|
||||
xtables_ipparse_any(optarg, &ipaddr, &mask, &nr);
|
||||
mangle->u_t.tgt_ip.s_addr = ipaddr->s_addr;
|
||||
free(ipaddr);
|
||||
mangle->flags |= ARPT_MANGLE_TIP;
|
||||
break;
|
||||
case MANGLE_DEVS:
|
||||
if (e->arp.arhln_mask == 0)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"no --h-length defined");
|
||||
if (e->arp.invflags & ARPT_INV_ARPHLN)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"! --h-length not allowed for "
|
||||
"--mangle-mac-s");
|
||||
if (e->arp.arhln != 6)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"only --h-length 6 supported");
|
||||
macaddr = ether_aton(optarg);
|
||||
if (macaddr == NULL)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"invalid source MAC");
|
||||
memcpy(mangle->src_devaddr, macaddr, e->arp.arhln);
|
||||
mangle->flags |= ARPT_MANGLE_SDEV;
|
||||
break;
|
||||
case MANGLE_DEVT:
|
||||
if (e->arp.arhln_mask == 0)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"no --h-length defined");
|
||||
if (e->arp.invflags & ARPT_INV_ARPHLN)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"! hln not allowed for --mangle-mac-d");
|
||||
if (e->arp.arhln != 6)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"only --h-length 6 supported");
|
||||
macaddr = ether_aton(optarg);
|
||||
if (macaddr == NULL)
|
||||
xtables_error(PARAMETER_PROBLEM, "invalid target MAC");
|
||||
memcpy(mangle->tgt_devaddr, macaddr, e->arp.arhln);
|
||||
mangle->flags |= ARPT_MANGLE_TDEV;
|
||||
break;
|
||||
case MANGLE_TARGET:
|
||||
if (!strcmp(optarg, "DROP"))
|
||||
mangle->target = NF_DROP;
|
||||
else if (!strcmp(optarg, "ACCEPT"))
|
||||
mangle->target = NF_ACCEPT;
|
||||
else if (!strcmp(optarg, "CONTINUE"))
|
||||
mangle->target = XT_CONTINUE;
|
||||
else
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"bad target for --mangle-target");
|
||||
break;
|
||||
default:
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void arpmangle_final_check(unsigned int flags)
|
||||
{
|
||||
}
|
||||
|
||||
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 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,
|
||||
.parse = arpmangle_parse,
|
||||
.final_check = arpmangle_final_check,
|
||||
.print = arpmangle_print,
|
||||
.save = arpmangle_save,
|
||||
.extra_opts = arpmangle_opts,
|
||||
};
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_target(&arpmangle_target);
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
: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
|
||||
@@ -1,14 +0,0 @@
|
||||
: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 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
|
||||
@@ -1,133 +0,0 @@
|
||||
/* 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 <getopt.h>
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter_bridge/ebt_802_3.h>
|
||||
|
||||
#define _802_3_SAP '1'
|
||||
#define _802_3_TYPE '2'
|
||||
|
||||
static const struct option br802_3_opts[] = {
|
||||
{ .name = "802_3-sap", .has_arg = true, .val = _802_3_SAP },
|
||||
{ .name = "802_3-type", .has_arg = true, .val = _802_3_TYPE },
|
||||
XT_GETOPT_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_init(struct xt_entry_match *match)
|
||||
{
|
||||
struct ebt_802_3_info *info = (struct ebt_802_3_info *)match->data;
|
||||
|
||||
info->invflags = 0;
|
||||
info->bitmask = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
br802_3_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct ebt_802_3_info *info = (struct ebt_802_3_info *) (*match)->data;
|
||||
unsigned int i;
|
||||
char *end;
|
||||
|
||||
switch (c) {
|
||||
case _802_3_SAP:
|
||||
if (invert)
|
||||
info->invflags |= EBT_802_3_SAP;
|
||||
i = strtoul(optarg, &end, 16);
|
||||
if (i > 255 || *end != '\0')
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Problem with specified "
|
||||
"sap hex value, %x",i);
|
||||
info->sap = i; /* one byte, so no byte order worries */
|
||||
info->bitmask |= EBT_802_3_SAP;
|
||||
break;
|
||||
case _802_3_TYPE:
|
||||
if (invert)
|
||||
info->invflags |= EBT_802_3_TYPE;
|
||||
i = strtoul(optarg, &end, 16);
|
||||
if (i > 65535 || *end != '\0') {
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Problem with the specified "
|
||||
"type hex value, %x",i);
|
||||
}
|
||||
info->type = htons(i);
|
||||
info->bitmask |= EBT_802_3_TYPE;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
*flags |= info->bitmask;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
br802_3_final_check(unsigned int flags)
|
||||
{
|
||||
if (!flags)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"You must specify proper arguments");
|
||||
}
|
||||
|
||||
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) {
|
||||
printf("--802_3-sap ");
|
||||
if (info->invflags & EBT_802_3_SAP)
|
||||
printf("! ");
|
||||
printf("0x%.2x ", info->sap);
|
||||
}
|
||||
if (info->bitmask & EBT_802_3_TYPE) {
|
||||
printf("--802_3-type ");
|
||||
if (info->invflags & EBT_802_3_TYPE)
|
||||
printf("! ");
|
||||
printf("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)),
|
||||
.init = br802_3_init,
|
||||
.help = br802_3_print_help,
|
||||
.parse = br802_3_parse,
|
||||
.final_check = br802_3_final_check,
|
||||
.print = br802_3_print,
|
||||
.extra_opts = br802_3_opts,
|
||||
};
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_match(&br802_3_match);
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
:INPUT,FORWARD,OUTPUT
|
||||
--802_3-sap ! 0x0a -j CONTINUE;=;OK
|
||||
--802_3-type 0x000a -j RETURN;=;OK
|
||||
@@ -1,243 +0,0 @@
|
||||
/* 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_aton(sep + 1, &pair->in))
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Invalid IP address '%s'\n", sep + 1);
|
||||
}
|
||||
ether = ether_aton(buf);
|
||||
if (!ether)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Invalid MAC address '%s'\n", 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;
|
||||
struct xt_entry_match *new_match;
|
||||
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';
|
||||
/* fall through */
|
||||
case AMONG_DST:
|
||||
if (c == 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);
|
||||
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;
|
||||
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);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void __bramong_print(struct nft_among_pair *pairs,
|
||||
int cnt, bool inv, bool have_ip)
|
||||
{
|
||||
const char *isep = inv ? "! " : "";
|
||||
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_ntoa(pairs[i].in));
|
||||
}
|
||||
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("--among-src ");
|
||||
__bramong_print(data->pairs,
|
||||
data->src.cnt, data->src.inv, data->src.ip);
|
||||
}
|
||||
if (data->dst.cnt) {
|
||||
printf("--among-dst ");
|
||||
__bramong_print(data->pairs + data->src.cnt,
|
||||
data->dst.cnt, data->dst.inv, 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);
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
: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
|
||||
@@ -1,363 +0,0 @@
|
||||
/* 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 <getopt.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"
|
||||
|
||||
#define ARP_OPCODE '1'
|
||||
#define ARP_HTYPE '2'
|
||||
#define ARP_PTYPE '3'
|
||||
#define ARP_IP_S '4'
|
||||
#define ARP_IP_D '5'
|
||||
#define ARP_MAC_S '6'
|
||||
#define ARP_MAC_D '7'
|
||||
#define ARP_GRAT '8'
|
||||
|
||||
static const struct option brarp_opts[] = {
|
||||
{ "arp-opcode" , required_argument, 0, ARP_OPCODE },
|
||||
{ "arp-op" , required_argument, 0, ARP_OPCODE },
|
||||
{ "arp-htype" , required_argument, 0, ARP_HTYPE },
|
||||
{ "arp-ptype" , required_argument, 0, ARP_PTYPE },
|
||||
{ "arp-ip-src" , required_argument, 0, ARP_IP_S },
|
||||
{ "arp-ip-dst" , required_argument, 0, ARP_IP_D },
|
||||
{ "arp-mac-src" , required_argument, 0, ARP_MAC_S },
|
||||
{ "arp-mac-dst" , required_argument, 0, ARP_MAC_D },
|
||||
{ "arp-gratuitous", no_argument, 0, ARP_GRAT },
|
||||
XT_GETOPT_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");
|
||||
}
|
||||
|
||||
#define OPT_OPCODE 0x01
|
||||
#define OPT_HTYPE 0x02
|
||||
#define OPT_PTYPE 0x04
|
||||
#define OPT_IP_S 0x08
|
||||
#define OPT_IP_D 0x10
|
||||
#define OPT_MAC_S 0x20
|
||||
#define OPT_MAC_D 0x40
|
||||
#define OPT_GRAT 0x80
|
||||
|
||||
static int undot_ip(char *ip, unsigned char *ip2)
|
||||
{
|
||||
char *p, *q, *end;
|
||||
long int onebyte;
|
||||
int i;
|
||||
char buf[20];
|
||||
|
||||
strncpy(buf, ip, sizeof(buf) - 1);
|
||||
|
||||
p = buf;
|
||||
for (i = 0; i < 3; i++) {
|
||||
if ((q = strchr(p, '.')) == NULL)
|
||||
return -1;
|
||||
*q = '\0';
|
||||
onebyte = strtol(p, &end, 10);
|
||||
if (*end != '\0' || onebyte > 255 || onebyte < 0)
|
||||
return -1;
|
||||
ip2[i] = (unsigned char)onebyte;
|
||||
p = q + 1;
|
||||
}
|
||||
|
||||
onebyte = strtol(p, &end, 10);
|
||||
if (*end != '\0' || onebyte > 255 || onebyte < 0)
|
||||
return -1;
|
||||
ip2[3] = (unsigned char)onebyte;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ip_mask(char *mask, unsigned char *mask2)
|
||||
{
|
||||
char *end;
|
||||
long int bits;
|
||||
uint32_t mask22;
|
||||
|
||||
if (undot_ip(mask, mask2)) {
|
||||
/* not the /a.b.c.e format, maybe the /x format */
|
||||
bits = strtol(mask, &end, 10);
|
||||
if (*end != '\0' || bits > 32 || bits < 0)
|
||||
return -1;
|
||||
if (bits != 0) {
|
||||
mask22 = htonl(0xFFFFFFFF << (32 - bits));
|
||||
memcpy(mask2, &mask22, 4);
|
||||
} else {
|
||||
mask22 = 0xFFFFFFFF;
|
||||
memcpy(mask2, &mask22, 4);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ebt_parse_ip_address(char *address, uint32_t *addr, uint32_t *msk)
|
||||
{
|
||||
char *p;
|
||||
|
||||
/* first the mask */
|
||||
if ((p = strrchr(address, '/')) != NULL) {
|
||||
*p = '\0';
|
||||
if (ip_mask(p + 1, (unsigned char *)msk)) {
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Problem with the IP mask '%s'", p + 1);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
*msk = 0xFFFFFFFF;
|
||||
|
||||
if (undot_ip(address, (unsigned char *)addr)) {
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Problem with the IP address '%s'", address);
|
||||
return;
|
||||
}
|
||||
*addr = *addr & *msk;
|
||||
}
|
||||
|
||||
static int
|
||||
brarp_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct ebt_arp_info *arpinfo = (struct ebt_arp_info *)(*match)->data;
|
||||
long int i;
|
||||
char *end;
|
||||
uint32_t *addr;
|
||||
uint32_t *mask;
|
||||
unsigned char *maddr;
|
||||
unsigned char *mmask;
|
||||
|
||||
switch (c) {
|
||||
case ARP_OPCODE:
|
||||
EBT_CHECK_OPTION(flags, OPT_OPCODE);
|
||||
if (invert)
|
||||
arpinfo->invflags |= EBT_ARP_OPCODE;
|
||||
i = strtol(optarg, &end, 10);
|
||||
if (i < 0 || i >= (0x1 << 16) || *end !='\0') {
|
||||
for (i = 0; i < ARRAY_SIZE(opcodes); i++)
|
||||
if (!strcasecmp(opcodes[i], optarg))
|
||||
break;
|
||||
if (i == ARRAY_SIZE(opcodes))
|
||||
xtables_error(PARAMETER_PROBLEM, "Problem with specified ARP opcode");
|
||||
i++;
|
||||
}
|
||||
arpinfo->opcode = htons(i);
|
||||
arpinfo->bitmask |= EBT_ARP_OPCODE;
|
||||
break;
|
||||
|
||||
case ARP_HTYPE:
|
||||
EBT_CHECK_OPTION(flags, OPT_HTYPE);
|
||||
if (invert)
|
||||
arpinfo->invflags |= EBT_ARP_HTYPE;
|
||||
i = strtol(optarg, &end, 10);
|
||||
if (i < 0 || i >= (0x1 << 16) || *end !='\0') {
|
||||
if (!strcasecmp("Ethernet", argv[optind - 1]))
|
||||
i = 1;
|
||||
else
|
||||
xtables_error(PARAMETER_PROBLEM, "Problem with specified ARP hardware type");
|
||||
}
|
||||
arpinfo->htype = htons(i);
|
||||
arpinfo->bitmask |= EBT_ARP_HTYPE;
|
||||
break;
|
||||
case ARP_PTYPE: {
|
||||
uint16_t proto;
|
||||
|
||||
EBT_CHECK_OPTION(flags, OPT_PTYPE);
|
||||
if (invert)
|
||||
arpinfo->invflags |= EBT_ARP_PTYPE;
|
||||
|
||||
i = strtol(optarg, &end, 16);
|
||||
if (i < 0 || i >= (0x1 << 16) || *end !='\0') {
|
||||
struct xt_ethertypeent *ent;
|
||||
|
||||
ent = xtables_getethertypebyname(argv[optind - 1]);
|
||||
if (!ent)
|
||||
xtables_error(PARAMETER_PROBLEM, "Problem with specified ARP "
|
||||
"protocol type");
|
||||
proto = ent->e_ethertype;
|
||||
|
||||
} else
|
||||
proto = i;
|
||||
arpinfo->ptype = htons(proto);
|
||||
arpinfo->bitmask |= EBT_ARP_PTYPE;
|
||||
break;
|
||||
}
|
||||
|
||||
case ARP_IP_S:
|
||||
case ARP_IP_D:
|
||||
if (c == ARP_IP_S) {
|
||||
EBT_CHECK_OPTION(flags, OPT_IP_S);
|
||||
addr = &arpinfo->saddr;
|
||||
mask = &arpinfo->smsk;
|
||||
arpinfo->bitmask |= EBT_ARP_SRC_IP;
|
||||
} else {
|
||||
EBT_CHECK_OPTION(flags, OPT_IP_D);
|
||||
addr = &arpinfo->daddr;
|
||||
mask = &arpinfo->dmsk;
|
||||
arpinfo->bitmask |= EBT_ARP_DST_IP;
|
||||
}
|
||||
if (invert) {
|
||||
if (c == ARP_IP_S)
|
||||
arpinfo->invflags |= EBT_ARP_SRC_IP;
|
||||
else
|
||||
arpinfo->invflags |= EBT_ARP_DST_IP;
|
||||
}
|
||||
ebt_parse_ip_address(optarg, addr, mask);
|
||||
break;
|
||||
case ARP_MAC_S:
|
||||
case ARP_MAC_D:
|
||||
if (c == ARP_MAC_S) {
|
||||
EBT_CHECK_OPTION(flags, OPT_MAC_S);
|
||||
maddr = arpinfo->smaddr;
|
||||
mmask = arpinfo->smmsk;
|
||||
arpinfo->bitmask |= EBT_ARP_SRC_MAC;
|
||||
} else {
|
||||
EBT_CHECK_OPTION(flags, OPT_MAC_D);
|
||||
maddr = arpinfo->dmaddr;
|
||||
mmask = arpinfo->dmmsk;
|
||||
arpinfo->bitmask |= EBT_ARP_DST_MAC;
|
||||
}
|
||||
if (invert) {
|
||||
if (c == ARP_MAC_S)
|
||||
arpinfo->invflags |= EBT_ARP_SRC_MAC;
|
||||
else
|
||||
arpinfo->invflags |= EBT_ARP_DST_MAC;
|
||||
}
|
||||
if (xtables_parse_mac_and_mask(optarg, maddr, mmask))
|
||||
xtables_error(PARAMETER_PROBLEM, "Problem with ARP MAC address argument");
|
||||
break;
|
||||
case ARP_GRAT:
|
||||
EBT_CHECK_OPTION(flags, OPT_GRAT);
|
||||
arpinfo->bitmask |= EBT_ARP_GRAT;
|
||||
if (invert)
|
||||
arpinfo->invflags |= EBT_ARP_GRAT;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
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);
|
||||
printf("--arp-op ");
|
||||
if (arpinfo->invflags & EBT_ARP_OPCODE)
|
||||
printf("! ");
|
||||
if (opcode > 0 && opcode <= ARRAY_SIZE(opcodes))
|
||||
printf("%s ", opcodes[opcode - 1]);
|
||||
else
|
||||
printf("%d ", opcode);
|
||||
}
|
||||
if (arpinfo->bitmask & EBT_ARP_HTYPE) {
|
||||
printf("--arp-htype ");
|
||||
if (arpinfo->invflags & EBT_ARP_HTYPE)
|
||||
printf("! ");
|
||||
printf("%d ", ntohs(arpinfo->htype));
|
||||
}
|
||||
if (arpinfo->bitmask & EBT_ARP_PTYPE) {
|
||||
printf("--arp-ptype ");
|
||||
if (arpinfo->invflags & EBT_ARP_PTYPE)
|
||||
printf("! ");
|
||||
printf("0x%x ", ntohs(arpinfo->ptype));
|
||||
}
|
||||
if (arpinfo->bitmask & EBT_ARP_SRC_IP) {
|
||||
printf("--arp-ip-src ");
|
||||
if (arpinfo->invflags & EBT_ARP_SRC_IP)
|
||||
printf("! ");
|
||||
printf("%s%s ", xtables_ipaddr_to_numeric((const struct in_addr*) &arpinfo->saddr),
|
||||
xtables_ipmask_to_numeric((const struct in_addr*)&arpinfo->smsk));
|
||||
}
|
||||
if (arpinfo->bitmask & EBT_ARP_DST_IP) {
|
||||
printf("--arp-ip-dst ");
|
||||
if (arpinfo->invflags & EBT_ARP_DST_IP)
|
||||
printf("! ");
|
||||
printf("%s%s ", xtables_ipaddr_to_numeric((const struct in_addr*) &arpinfo->daddr),
|
||||
xtables_ipmask_to_numeric((const struct in_addr*)&arpinfo->dmsk));
|
||||
}
|
||||
if (arpinfo->bitmask & EBT_ARP_SRC_MAC) {
|
||||
printf("--arp-mac-src ");
|
||||
if (arpinfo->invflags & EBT_ARP_SRC_MAC)
|
||||
printf("! ");
|
||||
xtables_print_mac_and_mask(arpinfo->smaddr, arpinfo->smmsk);
|
||||
printf(" ");
|
||||
}
|
||||
if (arpinfo->bitmask & EBT_ARP_DST_MAC) {
|
||||
printf("--arp-mac-dst ");
|
||||
if (arpinfo->invflags & EBT_ARP_DST_MAC)
|
||||
printf("! ");
|
||||
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,
|
||||
.parse = brarp_parse,
|
||||
.print = brarp_print,
|
||||
.extra_opts = brarp_opts,
|
||||
};
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_match(&brarp_match);
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
:INPUT,FORWARD,OUTPUT
|
||||
-p ARP --arp-op Request;=;OK
|
||||
-p ARP --arp-htype ! 1;=;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-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-gratuitous;=;OK
|
||||
--arp-htype 1;=;FAIL
|
||||
@@ -1,101 +0,0 @@
|
||||
/* 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 <getopt.h>
|
||||
#include <xtables.h>
|
||||
#include <netinet/ether.h>
|
||||
#include <linux/netfilter_bridge/ebt_arpreply.h>
|
||||
#include "iptables/nft.h"
|
||||
#include "iptables/nft-bridge.h"
|
||||
|
||||
#define OPT_REPLY_MAC 0x01
|
||||
#define OPT_REPLY_TARGET 0x02
|
||||
|
||||
#define REPLY_MAC '1'
|
||||
#define REPLY_TARGET '2'
|
||||
static const struct option brarpreply_opts[] = {
|
||||
{ "arpreply-mac" , required_argument, 0, REPLY_MAC },
|
||||
{ "arpreply-target" , required_argument, 0, REPLY_TARGET },
|
||||
XT_GETOPT_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 int
|
||||
brarpreply_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **tg)
|
||||
|
||||
{
|
||||
struct ebt_arpreply_info *replyinfo = (void *)(*tg)->data;
|
||||
struct ether_addr *addr;
|
||||
|
||||
switch (c) {
|
||||
case REPLY_MAC:
|
||||
EBT_CHECK_OPTION(flags, OPT_REPLY_MAC);
|
||||
if (!(addr = ether_aton(optarg)))
|
||||
xtables_error(PARAMETER_PROBLEM, "Problem with specified --arpreply-mac mac");
|
||||
memcpy(replyinfo->mac, addr, ETH_ALEN);
|
||||
break;
|
||||
case REPLY_TARGET:
|
||||
EBT_CHECK_OPTION(flags, OPT_REPLY_TARGET);
|
||||
if (ebt_fill_target(optarg, (unsigned int *)&replyinfo->target))
|
||||
xtables_error(PARAMETER_PROBLEM, "Illegal --arpreply-target target");
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
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,
|
||||
.parse = brarpreply_parse,
|
||||
.print = brarpreply_print,
|
||||
.extra_opts = brarpreply_opts,
|
||||
};
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_target(&arpreply_target);
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
:PREROUTING
|
||||
*nat
|
||||
-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
|
||||
@@ -1,129 +0,0 @@
|
||||
/* ebt_nat
|
||||
*
|
||||
* Authors:
|
||||
* Bart De Schuymer <bdschuym@pandora.be>
|
||||
*
|
||||
* June, 2002
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <netinet/ether.h>
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter_bridge/ebt_nat.h>
|
||||
#include "iptables/nft.h"
|
||||
#include "iptables/nft-bridge.h"
|
||||
|
||||
#define NAT_D '1'
|
||||
#define NAT_D_TARGET '2'
|
||||
static const struct option brdnat_opts[] =
|
||||
{
|
||||
{ "to-destination", required_argument, 0, NAT_D },
|
||||
{ "to-dst" , required_argument, 0, NAT_D },
|
||||
{ "dnat-target" , required_argument, 0, NAT_D_TARGET },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
static void brdnat_init(struct xt_entry_target *target)
|
||||
{
|
||||
struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
|
||||
|
||||
natinfo->target = EBT_ACCEPT;
|
||||
}
|
||||
|
||||
#define OPT_DNAT 0x01
|
||||
#define OPT_DNAT_TARGET 0x02
|
||||
static int brdnat_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct ebt_nat_info *natinfo = (struct ebt_nat_info *)(*target)->data;
|
||||
struct ether_addr *addr;
|
||||
|
||||
switch (c) {
|
||||
case NAT_D:
|
||||
EBT_CHECK_OPTION(flags, OPT_DNAT);
|
||||
if (!(addr = ether_aton(optarg)))
|
||||
xtables_error(PARAMETER_PROBLEM, "Problem with specified --to-destination mac");
|
||||
memcpy(natinfo->mac, addr, ETH_ALEN);
|
||||
break;
|
||||
case NAT_D_TARGET:
|
||||
EBT_CHECK_OPTION(flags, OPT_DNAT_TARGET);
|
||||
if (ebt_fill_target(optarg, (unsigned int *)&natinfo->target))
|
||||
xtables_error(PARAMETER_PROBLEM, "Illegal --dnat-target target");
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void brdnat_final_check(unsigned int flags)
|
||||
{
|
||||
if (!flags)
|
||||
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,
|
||||
.parse = brdnat_parse,
|
||||
.final_check = brdnat_final_check,
|
||||
.print = brdnat_print,
|
||||
.xlate = brdnat_xlate,
|
||||
.extra_opts = brdnat_opts,
|
||||
};
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_target(&brdnat_target);
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
: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
|
||||
@@ -1,8 +0,0 @@
|
||||
ebtables-translate -t nat -A PREROUTING -i someport --to-dst de:ad:00:be:ee:ff
|
||||
nft add rule bridge nat PREROUTING iifname "someport" ether daddr set de:ad:0:be:ee:ff accept counter
|
||||
|
||||
ebtables-translate -t nat -A PREROUTING -i someport --to-dst de:ad:00:be:ee:ff --dnat-target ACCEPT
|
||||
nft add rule bridge nat PREROUTING iifname "someport" ether daddr set de:ad:0:be:ee:ff accept counter
|
||||
|
||||
ebtables-translate -t nat -A PREROUTING -i someport --to-dst de:ad:00:be:ee:ff --dnat-target CONTINUE
|
||||
nft add rule bridge nat PREROUTING iifname "someport" ether daddr set de:ad:0:be:ee:ff continue counter
|
||||
@@ -1,732 +0,0 @@
|
||||
/* 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 <getopt.h>
|
||||
#include <netdb.h>
|
||||
#include <inttypes.h>
|
||||
#include <xtables.h>
|
||||
|
||||
#include "libxt_icmp.h"
|
||||
|
||||
#define EBT_IP_SOURCE 0x01
|
||||
#define EBT_IP_DEST 0x02
|
||||
#define EBT_IP_TOS 0x04
|
||||
#define EBT_IP_PROTO 0x08
|
||||
#define EBT_IP_SPORT 0x10
|
||||
#define EBT_IP_DPORT 0x20
|
||||
#define EBT_IP_ICMP 0x40
|
||||
#define EBT_IP_IGMP 0x80
|
||||
#define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO |\
|
||||
EBT_IP_SPORT | EBT_IP_DPORT | EBT_IP_ICMP | EBT_IP_IGMP)
|
||||
|
||||
struct ebt_ip_info {
|
||||
__be32 saddr;
|
||||
__be32 daddr;
|
||||
__be32 smsk;
|
||||
__be32 dmsk;
|
||||
__u8 tos;
|
||||
__u8 protocol;
|
||||
__u8 bitmask;
|
||||
__u8 invflags;
|
||||
union {
|
||||
__u16 sport[2];
|
||||
__u8 icmp_type[2];
|
||||
__u8 igmp_type[2];
|
||||
};
|
||||
union {
|
||||
__u16 dport[2];
|
||||
__u8 icmp_code[2];
|
||||
};
|
||||
};
|
||||
|
||||
#define IP_SOURCE '1'
|
||||
#define IP_DEST '2'
|
||||
#define IP_EBT_TOS '3' /* include/bits/in.h seems to already define IP_TOS */
|
||||
#define IP_PROTO '4'
|
||||
#define IP_SPORT '5'
|
||||
#define IP_DPORT '6'
|
||||
#define IP_EBT_ICMP '7'
|
||||
#define IP_EBT_IGMP '8'
|
||||
|
||||
static const struct option brip_opts[] = {
|
||||
{ .name = "ip-source", .has_arg = true, .val = IP_SOURCE },
|
||||
{ .name = "ip-src", .has_arg = true, .val = IP_SOURCE },
|
||||
{ .name = "ip-destination", .has_arg = true, .val = IP_DEST },
|
||||
{ .name = "ip-dst", .has_arg = true, .val = IP_DEST },
|
||||
{ .name = "ip-tos", .has_arg = true, .val = IP_EBT_TOS },
|
||||
{ .name = "ip-protocol", .has_arg = true, .val = IP_PROTO },
|
||||
{ .name = "ip-proto", .has_arg = true, .val = IP_PROTO },
|
||||
{ .name = "ip-source-port", .has_arg = true, .val = IP_SPORT },
|
||||
{ .name = "ip-sport", .has_arg = true, .val = IP_SPORT },
|
||||
{ .name = "ip-destination-port",.has_arg = true, .val = IP_DPORT },
|
||||
{ .name = "ip-dport", .has_arg = true, .val = IP_DPORT },
|
||||
{ .name = "ip-icmp-type", .has_arg = true, .val = IP_EBT_ICMP },
|
||||
{ .name = "ip-igmp-type", .has_arg = true, .val = IP_EBT_IGMP },
|
||||
XT_GETOPT_TABLEEND,
|
||||
};
|
||||
|
||||
static const struct xt_icmp_names icmp_codes[] = {
|
||||
{ "echo-reply", 0, 0, 0xFF },
|
||||
/* Alias */ { "pong", 0, 0, 0xFF },
|
||||
|
||||
{ "destination-unreachable", 3, 0, 0xFF },
|
||||
{ "network-unreachable", 3, 0, 0 },
|
||||
{ "host-unreachable", 3, 1, 1 },
|
||||
{ "protocol-unreachable", 3, 2, 2 },
|
||||
{ "port-unreachable", 3, 3, 3 },
|
||||
{ "fragmentation-needed", 3, 4, 4 },
|
||||
{ "source-route-failed", 3, 5, 5 },
|
||||
{ "network-unknown", 3, 6, 6 },
|
||||
{ "host-unknown", 3, 7, 7 },
|
||||
{ "network-prohibited", 3, 9, 9 },
|
||||
{ "host-prohibited", 3, 10, 10 },
|
||||
{ "TOS-network-unreachable", 3, 11, 11 },
|
||||
{ "TOS-host-unreachable", 3, 12, 12 },
|
||||
{ "communication-prohibited", 3, 13, 13 },
|
||||
{ "host-precedence-violation", 3, 14, 14 },
|
||||
{ "precedence-cutoff", 3, 15, 15 },
|
||||
|
||||
{ "source-quench", 4, 0, 0xFF },
|
||||
|
||||
{ "redirect", 5, 0, 0xFF },
|
||||
{ "network-redirect", 5, 0, 0 },
|
||||
{ "host-redirect", 5, 1, 1 },
|
||||
{ "TOS-network-redirect", 5, 2, 2 },
|
||||
{ "TOS-host-redirect", 5, 3, 3 },
|
||||
|
||||
{ "echo-request", 8, 0, 0xFF },
|
||||
/* Alias */ { "ping", 8, 0, 0xFF },
|
||||
|
||||
{ "router-advertisement", 9, 0, 0xFF },
|
||||
|
||||
{ "router-solicitation", 10, 0, 0xFF },
|
||||
|
||||
{ "time-exceeded", 11, 0, 0xFF },
|
||||
/* Alias */ { "ttl-exceeded", 11, 0, 0xFF },
|
||||
{ "ttl-zero-during-transit", 11, 0, 0 },
|
||||
{ "ttl-zero-during-reassembly", 11, 1, 1 },
|
||||
|
||||
{ "parameter-problem", 12, 0, 0xFF },
|
||||
{ "ip-header-bad", 12, 0, 0 },
|
||||
{ "required-option-missing", 12, 1, 1 },
|
||||
|
||||
{ "timestamp-request", 13, 0, 0xFF },
|
||||
|
||||
{ "timestamp-reply", 14, 0, 0xFF },
|
||||
|
||||
{ "address-mask-request", 17, 0, 0xFF },
|
||||
|
||||
{ "address-mask-reply", 18, 0, 0xFF }
|
||||
};
|
||||
|
||||
static const struct xt_icmp_names igmp_types[] = {
|
||||
{ "membership-query", 0x11 },
|
||||
{ "membership-report-v1", 0x12 },
|
||||
{ "membership-report-v2", 0x16 },
|
||||
{ "leave-group", 0x17 },
|
||||
{ "membership-report-v3", 0x22 },
|
||||
};
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
static void brip_init(struct xt_entry_match *match)
|
||||
{
|
||||
struct ebt_ip_info *info = (struct ebt_ip_info *)match->data;
|
||||
|
||||
info->invflags = 0;
|
||||
info->bitmask = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_port_range(const char *protocol, const char *portstring, uint16_t *ports)
|
||||
{
|
||||
char *buffer;
|
||||
char *cp;
|
||||
|
||||
buffer = strdup(portstring);
|
||||
if ((cp = strchr(buffer, ':')) == NULL)
|
||||
ports[0] = ports[1] = xtables_parse_port(buffer, NULL);
|
||||
else {
|
||||
*cp = '\0';
|
||||
cp++;
|
||||
|
||||
ports[0] = buffer[0] ? xtables_parse_port(buffer, NULL) : 0;
|
||||
ports[1] = cp[0] ? xtables_parse_port(cp, NULL) : 0xFFFF;
|
||||
|
||||
if (ports[0] > ports[1])
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"invalid portrange (min > max)");
|
||||
}
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
/* original code from ebtables: useful_functions.c */
|
||||
static int undot_ip(char *ip, unsigned char *ip2)
|
||||
{
|
||||
char *p, *q, *end;
|
||||
long int onebyte;
|
||||
int i;
|
||||
char buf[20];
|
||||
|
||||
strncpy(buf, ip, sizeof(buf) - 1);
|
||||
|
||||
p = buf;
|
||||
for (i = 0; i < 3; i++) {
|
||||
if ((q = strchr(p, '.')) == NULL)
|
||||
return -1;
|
||||
*q = '\0';
|
||||
onebyte = strtol(p, &end, 10);
|
||||
if (*end != '\0' || onebyte > 255 || onebyte < 0)
|
||||
return -1;
|
||||
ip2[i] = (unsigned char)onebyte;
|
||||
p = q + 1;
|
||||
}
|
||||
|
||||
onebyte = strtol(p, &end, 10);
|
||||
if (*end != '\0' || onebyte > 255 || onebyte < 0)
|
||||
return -1;
|
||||
ip2[3] = (unsigned char)onebyte;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ip_mask(char *mask, unsigned char *mask2)
|
||||
{
|
||||
char *end;
|
||||
long int bits;
|
||||
uint32_t mask22;
|
||||
|
||||
if (undot_ip(mask, mask2)) {
|
||||
/* not the /a.b.c.e format, maybe the /x format */
|
||||
bits = strtol(mask, &end, 10);
|
||||
if (*end != '\0' || bits > 32 || bits < 0)
|
||||
return -1;
|
||||
if (bits != 0) {
|
||||
mask22 = htonl(0xFFFFFFFF << (32 - bits));
|
||||
memcpy(mask2, &mask22, 4);
|
||||
} else {
|
||||
mask22 = 0xFFFFFFFF;
|
||||
memcpy(mask2, &mask22, 4);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ebt_parse_ip_address(char *address, uint32_t *addr, uint32_t *msk)
|
||||
{
|
||||
char *p;
|
||||
|
||||
/* first the mask */
|
||||
if ((p = strrchr(address, '/')) != NULL) {
|
||||
*p = '\0';
|
||||
if (ip_mask(p + 1, (unsigned char *)msk)) {
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Problem with the IP mask '%s'", p + 1);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
*msk = 0xFFFFFFFF;
|
||||
|
||||
if (undot_ip(address, (unsigned char *)addr)) {
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Problem with the IP address '%s'", address);
|
||||
return;
|
||||
}
|
||||
*addr = *addr & *msk;
|
||||
}
|
||||
|
||||
static char *parse_range(const char *str, unsigned int res[])
|
||||
{
|
||||
char *next;
|
||||
|
||||
if (!xtables_strtoui(str, &next, &res[0], 0, 255))
|
||||
return NULL;
|
||||
|
||||
res[1] = res[0];
|
||||
if (*next == ':') {
|
||||
str = next + 1;
|
||||
if (!xtables_strtoui(str, &next, &res[1], 0, 255))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
static int ebt_parse_icmp(const struct xt_icmp_names *codes, size_t n_codes,
|
||||
const char *icmptype, uint8_t type[], uint8_t code[])
|
||||
{
|
||||
unsigned int match = n_codes;
|
||||
unsigned int i, number[2];
|
||||
|
||||
for (i = 0; i < n_codes; i++) {
|
||||
if (strncasecmp(codes[i].name, icmptype, strlen(icmptype)))
|
||||
continue;
|
||||
if (match != n_codes)
|
||||
xtables_error(PARAMETER_PROBLEM, "Ambiguous ICMP type `%s':"
|
||||
" `%s' or `%s'?",
|
||||
icmptype, codes[match].name,
|
||||
codes[i].name);
|
||||
match = i;
|
||||
}
|
||||
|
||||
if (match < n_codes) {
|
||||
type[0] = type[1] = codes[match].type;
|
||||
if (code) {
|
||||
code[0] = codes[match].code_min;
|
||||
code[1] = codes[match].code_max;
|
||||
}
|
||||
} else {
|
||||
char *next = parse_range(icmptype, number);
|
||||
if (!next) {
|
||||
xtables_error(PARAMETER_PROBLEM, "Unknown ICMP type `%s'",
|
||||
icmptype);
|
||||
return -1;
|
||||
}
|
||||
|
||||
type[0] = (uint8_t) number[0];
|
||||
type[1] = (uint8_t) number[1];
|
||||
switch (*next) {
|
||||
case 0:
|
||||
if (code) {
|
||||
code[0] = 0;
|
||||
code[1] = 255;
|
||||
}
|
||||
return 0;
|
||||
case '/':
|
||||
if (code) {
|
||||
next = parse_range(next+1, number);
|
||||
code[0] = (uint8_t) number[0];
|
||||
code[1] = (uint8_t) number[1];
|
||||
if (next == NULL)
|
||||
return -1;
|
||||
if (next && *next == 0)
|
||||
return 0;
|
||||
}
|
||||
/* fallthrough */
|
||||
default:
|
||||
xtables_error(PARAMETER_PROBLEM, "unknown character %c", *next);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 int
|
||||
brip_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct ebt_ip_info *info = (struct ebt_ip_info *)(*match)->data;
|
||||
|
||||
switch (c) {
|
||||
case IP_SOURCE:
|
||||
if (invert)
|
||||
info->invflags |= EBT_IP_SOURCE;
|
||||
ebt_parse_ip_address(optarg, &info->saddr, &info->smsk);
|
||||
info->bitmask |= EBT_IP_SOURCE;
|
||||
break;
|
||||
case IP_DEST:
|
||||
if (invert)
|
||||
info->invflags |= EBT_IP_DEST;
|
||||
ebt_parse_ip_address(optarg, &info->daddr, &info->dmsk);
|
||||
info->bitmask |= EBT_IP_DEST;
|
||||
break;
|
||||
case IP_SPORT:
|
||||
if (invert)
|
||||
info->invflags |= EBT_IP_SPORT;
|
||||
parse_port_range(NULL, optarg, info->sport);
|
||||
info->bitmask |= EBT_IP_SPORT;
|
||||
break;
|
||||
case IP_DPORT:
|
||||
if (invert)
|
||||
info->invflags |= EBT_IP_DPORT;
|
||||
parse_port_range(NULL, optarg, info->dport);
|
||||
info->bitmask |= EBT_IP_DPORT;
|
||||
break;
|
||||
case IP_EBT_ICMP:
|
||||
if (invert)
|
||||
info->invflags |= EBT_IP_ICMP;
|
||||
ebt_parse_icmp(icmp_codes, ARRAY_SIZE(icmp_codes), optarg,
|
||||
info->icmp_type, info->icmp_code);
|
||||
info->bitmask |= EBT_IP_ICMP;
|
||||
break;
|
||||
case IP_EBT_IGMP:
|
||||
if (invert)
|
||||
info->invflags |= EBT_IP_IGMP;
|
||||
ebt_parse_icmp(igmp_types, ARRAY_SIZE(igmp_types), optarg,
|
||||
info->igmp_type, NULL);
|
||||
info->bitmask |= EBT_IP_IGMP;
|
||||
break;
|
||||
case IP_EBT_TOS: {
|
||||
uintmax_t tosvalue;
|
||||
|
||||
if (invert)
|
||||
info->invflags |= EBT_IP_TOS;
|
||||
if (!xtables_strtoul(optarg, NULL, &tosvalue, 0, 255))
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Problem with specified IP tos");
|
||||
info->tos = tosvalue;
|
||||
info->bitmask |= EBT_IP_TOS;
|
||||
}
|
||||
break;
|
||||
case IP_PROTO:
|
||||
if (invert)
|
||||
info->invflags |= EBT_IP_PROTO;
|
||||
info->protocol = xtables_parse_protocol(optarg);
|
||||
info->bitmask |= EBT_IP_PROTO;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
*flags |= info->bitmask;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void brip_final_check(unsigned int flags)
|
||||
{
|
||||
if (!flags)
|
||||
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) {
|
||||
printf("--ip-src ");
|
||||
if (info->invflags & EBT_IP_SOURCE)
|
||||
printf("! ");
|
||||
addrp = (struct in_addr *)&info->saddr;
|
||||
maskp = (struct in_addr *)&info->smsk;
|
||||
printf("%s%s ", xtables_ipaddr_to_numeric(addrp),
|
||||
xtables_ipmask_to_numeric(maskp));
|
||||
}
|
||||
if (info->bitmask & EBT_IP_DEST) {
|
||||
printf("--ip-dst ");
|
||||
if (info->invflags & EBT_IP_DEST)
|
||||
printf("! ");
|
||||
addrp = (struct in_addr *)&info->daddr;
|
||||
maskp = (struct in_addr *)&info->dmsk;
|
||||
printf("%s%s ", xtables_ipaddr_to_numeric(addrp),
|
||||
xtables_ipmask_to_numeric(maskp));
|
||||
}
|
||||
if (info->bitmask & EBT_IP_TOS) {
|
||||
printf("--ip-tos ");
|
||||
if (info->invflags & EBT_IP_TOS)
|
||||
printf("! ");
|
||||
printf("0x%02X ", info->tos);
|
||||
}
|
||||
if (info->bitmask & EBT_IP_PROTO) {
|
||||
struct protoent *pe;
|
||||
|
||||
printf("--ip-proto ");
|
||||
if (info->invflags & EBT_IP_PROTO)
|
||||
printf("! ");
|
||||
pe = getprotobynumber(info->protocol);
|
||||
if (pe == NULL) {
|
||||
printf("%d ", info->protocol);
|
||||
} else {
|
||||
printf("%s ", pe->p_name);
|
||||
}
|
||||
}
|
||||
if (info->bitmask & EBT_IP_SPORT) {
|
||||
printf("--ip-sport ");
|
||||
if (info->invflags & EBT_IP_SPORT)
|
||||
printf("! ");
|
||||
print_port_range(info->sport);
|
||||
}
|
||||
if (info->bitmask & EBT_IP_DPORT) {
|
||||
printf("--ip-dport ");
|
||||
if (info->invflags & EBT_IP_DPORT)
|
||||
printf("! ");
|
||||
print_port_range(info->dport);
|
||||
}
|
||||
if (info->bitmask & EBT_IP_ICMP) {
|
||||
printf("--ip-icmp-type ");
|
||||
if (info->invflags & EBT_IP_ICMP)
|
||||
printf("! ");
|
||||
ebt_print_icmp_type(icmp_codes, ARRAY_SIZE(icmp_codes),
|
||||
info->icmp_type, info->icmp_code);
|
||||
}
|
||||
if (info->bitmask & EBT_IP_IGMP) {
|
||||
printf("--ip-igmp-type ");
|
||||
if (info->invflags & EBT_IP_IGMP)
|
||||
printf("! ");
|
||||
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 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 (info->bitmask & EBT_IP_TOS) {
|
||||
xt_xlate_add(xl, "ip dscp ");
|
||||
if (info->invflags & EBT_IP_TOS)
|
||||
xt_xlate_add(xl, "!= ");
|
||||
xt_xlate_add(xl, "0x%02x ", info->tos & 0x3f); /* remove ECN bits */
|
||||
}
|
||||
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)),
|
||||
.init = brip_init,
|
||||
.help = brip_print_help,
|
||||
.parse = brip_parse,
|
||||
.final_check = brip_final_check,
|
||||
.print = brip_print,
|
||||
.xlate = brip_xlate,
|
||||
.extra_opts = brip_opts,
|
||||
};
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_match(&brip_match);
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
: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-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 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
|
||||
@@ -1,26 +0,0 @@
|
||||
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 3 -p ip -o eth0 --ip-tos 0xff
|
||||
nft insert rule bridge filter OUTPUT oifname "eth0" ip dscp 0x3f counter
|
||||
|
||||
ebtables-translate -A FORWARD -p ip --ip-proto tcp --ip-dport 22
|
||||
nft add rule bridge filter FORWARD tcp dport 22 counter
|
||||
|
||||
ebtables-translate -A FORWARD -p ip --ip-proto udp --ip-sport 1024:65535
|
||||
nft add rule bridge filter FORWARD 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
|
||||
@@ -1,632 +0,0 @@
|
||||
/* 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 <getopt.h>
|
||||
#include <netdb.h>
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter_bridge/ebt_ip6.h>
|
||||
|
||||
#include "libxt_icmp.h"
|
||||
|
||||
#define IP_SOURCE '1'
|
||||
#define IP_DEST '2'
|
||||
#define IP_TCLASS '3'
|
||||
#define IP_PROTO '4'
|
||||
#define IP_SPORT '5'
|
||||
#define IP_DPORT '6'
|
||||
#define IP_ICMP6 '7'
|
||||
|
||||
static const struct option brip6_opts[] = {
|
||||
{ .name = "ip6-source", .has_arg = true, .val = IP_SOURCE },
|
||||
{ .name = "ip6-src", .has_arg = true, .val = IP_SOURCE },
|
||||
{ .name = "ip6-destination", .has_arg = true, .val = IP_DEST },
|
||||
{ .name = "ip6-dst", .has_arg = true, .val = IP_DEST },
|
||||
{ .name = "ip6-tclass", .has_arg = true, .val = IP_TCLASS },
|
||||
{ .name = "ip6-protocol", .has_arg = true, .val = IP_PROTO },
|
||||
{ .name = "ip6-proto", .has_arg = true, .val = IP_PROTO },
|
||||
{ .name = "ip6-source-port", .has_arg = true, .val = IP_SPORT },
|
||||
{ .name = "ip6-sport", .has_arg = true, .val = IP_SPORT },
|
||||
{ .name = "ip6-destination-port",.has_arg = true,.val = IP_DPORT },
|
||||
{ .name = "ip6-dport", .has_arg = true, .val = IP_DPORT },
|
||||
{ .name = "ip6-icmp-type", .has_arg = true, .val = IP_ICMP6 },
|
||||
XT_GETOPT_TABLEEND,
|
||||
};
|
||||
|
||||
static const struct xt_icmp_names icmpv6_codes[] = {
|
||||
{ "destination-unreachable", 1, 0, 0xFF },
|
||||
{ "no-route", 1, 0, 0 },
|
||||
{ "communication-prohibited", 1, 1, 1 },
|
||||
{ "address-unreachable", 1, 3, 3 },
|
||||
{ "port-unreachable", 1, 4, 4 },
|
||||
|
||||
{ "packet-too-big", 2, 0, 0xFF },
|
||||
|
||||
{ "time-exceeded", 3, 0, 0xFF },
|
||||
/* Alias */ { "ttl-exceeded", 3, 0, 0xFF },
|
||||
{ "ttl-zero-during-transit", 3, 0, 0 },
|
||||
{ "ttl-zero-during-reassembly", 3, 1, 1 },
|
||||
|
||||
{ "parameter-problem", 4, 0, 0xFF },
|
||||
{ "bad-header", 4, 0, 0 },
|
||||
{ "unknown-header-type", 4, 1, 1 },
|
||||
{ "unknown-option", 4, 2, 2 },
|
||||
|
||||
{ "echo-request", 128, 0, 0xFF },
|
||||
/* Alias */ { "ping", 128, 0, 0xFF },
|
||||
|
||||
{ "echo-reply", 129, 0, 0xFF },
|
||||
/* Alias */ { "pong", 129, 0, 0xFF },
|
||||
|
||||
{ "router-solicitation", 133, 0, 0xFF },
|
||||
|
||||
{ "router-advertisement", 134, 0, 0xFF },
|
||||
|
||||
{ "neighbour-solicitation", 135, 0, 0xFF },
|
||||
/* Alias */ { "neighbor-solicitation", 135, 0, 0xFF },
|
||||
|
||||
{ "neighbour-advertisement", 136, 0, 0xFF },
|
||||
/* Alias */ { "neighbor-advertisement", 136, 0, 0xFF },
|
||||
|
||||
{ "redirect", 137, 0, 0xFF },
|
||||
};
|
||||
|
||||
static void
|
||||
parse_port_range(const char *protocol, const char *portstring, uint16_t *ports)
|
||||
{
|
||||
char *buffer;
|
||||
char *cp;
|
||||
|
||||
buffer = strdup(portstring);
|
||||
if ((cp = strchr(buffer, ':')) == NULL)
|
||||
ports[0] = ports[1] = xtables_parse_port(buffer, NULL);
|
||||
else {
|
||||
*cp = '\0';
|
||||
cp++;
|
||||
|
||||
ports[0] = buffer[0] ? xtables_parse_port(buffer, NULL) : 0;
|
||||
ports[1] = cp[0] ? xtables_parse_port(cp, NULL) : 0xFFFF;
|
||||
|
||||
if (ports[0] > ports[1])
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"invalid portrange (min > max)");
|
||||
}
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
static char *parse_range(const char *str, unsigned int res[])
|
||||
{
|
||||
char *next;
|
||||
|
||||
if (!xtables_strtoui(str, &next, &res[0], 0, 255))
|
||||
return NULL;
|
||||
|
||||
res[1] = res[0];
|
||||
if (*next == ':') {
|
||||
str = next + 1;
|
||||
if (!xtables_strtoui(str, &next, &res[1], 0, 255))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_icmpv6(const char *icmpv6type, uint8_t type[], uint8_t code[])
|
||||
{
|
||||
static const unsigned int limit = ARRAY_SIZE(icmpv6_codes);
|
||||
unsigned int match = limit;
|
||||
unsigned int i, number[2];
|
||||
|
||||
for (i = 0; i < limit; i++) {
|
||||
if (strncasecmp(icmpv6_codes[i].name, icmpv6type, strlen(icmpv6type)))
|
||||
continue;
|
||||
if (match != limit)
|
||||
xtables_error(PARAMETER_PROBLEM, "Ambiguous ICMPv6 type `%s':"
|
||||
" `%s' or `%s'?",
|
||||
icmpv6type, icmpv6_codes[match].name,
|
||||
icmpv6_codes[i].name);
|
||||
match = i;
|
||||
}
|
||||
|
||||
if (match < limit) {
|
||||
type[0] = type[1] = icmpv6_codes[match].type;
|
||||
code[0] = icmpv6_codes[match].code_min;
|
||||
code[1] = icmpv6_codes[match].code_max;
|
||||
} else {
|
||||
char *next = parse_range(icmpv6type, number);
|
||||
if (!next) {
|
||||
xtables_error(PARAMETER_PROBLEM, "Unknown ICMPv6 type `%s'",
|
||||
icmpv6type);
|
||||
return -1;
|
||||
}
|
||||
type[0] = (uint8_t) number[0];
|
||||
type[1] = (uint8_t) number[1];
|
||||
switch (*next) {
|
||||
case 0:
|
||||
code[0] = 0;
|
||||
code[1] = 255;
|
||||
return 0;
|
||||
case '/':
|
||||
next = parse_range(next+1, number);
|
||||
code[0] = (uint8_t) number[0];
|
||||
code[1] = (uint8_t) number[1];
|
||||
if (next == NULL)
|
||||
return -1;
|
||||
if (next && *next == 0)
|
||||
return 0;
|
||||
/* fallthrough */
|
||||
default:
|
||||
xtables_error(PARAMETER_PROBLEM, "unknown character %c", *next);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_init(struct xt_entry_match *match)
|
||||
{
|
||||
struct ebt_ip6_info *ipinfo = (struct ebt_ip6_info *)match->data;
|
||||
|
||||
ipinfo->invflags = 0;
|
||||
ipinfo->bitmask = 0;
|
||||
memset(ipinfo->saddr.s6_addr, 0, sizeof(ipinfo->saddr.s6_addr));
|
||||
memset(ipinfo->smsk.s6_addr, 0, sizeof(ipinfo->smsk.s6_addr));
|
||||
memset(ipinfo->daddr.s6_addr, 0, sizeof(ipinfo->daddr.s6_addr));
|
||||
memset(ipinfo->dmsk.s6_addr, 0, sizeof(ipinfo->dmsk.s6_addr));
|
||||
}
|
||||
|
||||
static struct in6_addr *numeric_to_addr(const char *num)
|
||||
{
|
||||
static struct in6_addr ap;
|
||||
int err;
|
||||
|
||||
if ((err=inet_pton(AF_INET6, num, &ap)) == 1)
|
||||
return ≈
|
||||
return (struct in6_addr *)NULL;
|
||||
}
|
||||
|
||||
static struct in6_addr *parse_ip6_mask(char *mask)
|
||||
{
|
||||
static struct in6_addr maskaddr;
|
||||
struct in6_addr *addrp;
|
||||
unsigned int bits;
|
||||
|
||||
if (mask == NULL) {
|
||||
/* no mask at all defaults to 128 bits */
|
||||
memset(&maskaddr, 0xff, sizeof maskaddr);
|
||||
return &maskaddr;
|
||||
}
|
||||
if ((addrp = numeric_to_addr(mask)) != NULL)
|
||||
return addrp;
|
||||
if (!xtables_strtoui(mask, NULL, &bits, 0, 128))
|
||||
xtables_error(PARAMETER_PROBLEM, "Invalid IPv6 Mask '%s' specified", mask);
|
||||
if (bits != 0) {
|
||||
char *p = (char *)&maskaddr;
|
||||
memset(p, 0xff, bits / 8);
|
||||
memset(p + (bits / 8) + 1, 0, (128 - bits) / 8);
|
||||
p[bits / 8] = 0xff << (8 - (bits & 7));
|
||||
return &maskaddr;
|
||||
}
|
||||
|
||||
memset(&maskaddr, 0, sizeof maskaddr);
|
||||
return &maskaddr;
|
||||
}
|
||||
|
||||
/* Set the ipv6 mask and address. Callers should check ebt_errormsg[0].
|
||||
* The string pointed to by address can be altered. */
|
||||
static void ebt_parse_ip6_address(char *address, struct in6_addr *addr, struct in6_addr *msk)
|
||||
{
|
||||
struct in6_addr *tmp_addr;
|
||||
char buf[256];
|
||||
char *p;
|
||||
int i;
|
||||
int err;
|
||||
|
||||
strncpy(buf, address, sizeof(buf) - 1);
|
||||
/* first the mask */
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
if ((p = strrchr(buf, '/')) != NULL) {
|
||||
*p = '\0';
|
||||
tmp_addr = parse_ip6_mask(p + 1);
|
||||
} else
|
||||
tmp_addr = parse_ip6_mask(NULL);
|
||||
|
||||
*msk = *tmp_addr;
|
||||
|
||||
/* if a null mask is given, the name is ignored, like in "any/0" */
|
||||
if (!memcmp(msk, &in6addr_any, sizeof(in6addr_any)))
|
||||
strcpy(buf, "::");
|
||||
|
||||
if ((err=inet_pton(AF_INET6, buf, addr)) < 1) {
|
||||
xtables_error(PARAMETER_PROBLEM, "Invalid IPv6 Address '%s' specified", buf);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
addr->s6_addr32[i] &= msk->s6_addr32[i];
|
||||
}
|
||||
|
||||
#define OPT_SOURCE 0x01
|
||||
#define OPT_DEST 0x02
|
||||
#define OPT_TCLASS 0x04
|
||||
#define OPT_PROTO 0x08
|
||||
#define OPT_SPORT 0x10
|
||||
#define OPT_DPORT 0x20
|
||||
static int
|
||||
brip6_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct ebt_ip6_info *info = (struct ebt_ip6_info *)(*match)->data;
|
||||
unsigned int i;
|
||||
char *end;
|
||||
|
||||
switch (c) {
|
||||
case IP_SOURCE:
|
||||
if (invert)
|
||||
info->invflags |= EBT_IP6_SOURCE;
|
||||
ebt_parse_ip6_address(optarg, &info->saddr, &info->smsk);
|
||||
info->bitmask |= EBT_IP6_SOURCE;
|
||||
break;
|
||||
case IP_DEST:
|
||||
if (invert)
|
||||
info->invflags |= EBT_IP6_DEST;
|
||||
ebt_parse_ip6_address(optarg, &info->daddr, &info->dmsk);
|
||||
info->bitmask |= EBT_IP6_DEST;
|
||||
break;
|
||||
case IP_SPORT:
|
||||
if (invert)
|
||||
info->invflags |= EBT_IP6_SPORT;
|
||||
parse_port_range(NULL, optarg, info->sport);
|
||||
info->bitmask |= EBT_IP6_SPORT;
|
||||
break;
|
||||
case IP_DPORT:
|
||||
if (invert)
|
||||
info->invflags |= EBT_IP6_DPORT;
|
||||
parse_port_range(NULL, optarg, info->dport);
|
||||
info->bitmask |= EBT_IP6_DPORT;
|
||||
break;
|
||||
case IP_ICMP6:
|
||||
if (invert)
|
||||
info->invflags |= EBT_IP6_ICMP6;
|
||||
if (parse_icmpv6(optarg, info->icmpv6_type, info->icmpv6_code))
|
||||
return 0;
|
||||
info->bitmask |= EBT_IP6_ICMP6;
|
||||
break;
|
||||
case IP_TCLASS:
|
||||
if (invert)
|
||||
info->invflags |= EBT_IP6_TCLASS;
|
||||
if (!xtables_strtoui(optarg, &end, &i, 0, 255))
|
||||
xtables_error(PARAMETER_PROBLEM, "Problem with specified IPv6 traffic class '%s'", optarg);
|
||||
info->tclass = i;
|
||||
info->bitmask |= EBT_IP6_TCLASS;
|
||||
break;
|
||||
case IP_PROTO:
|
||||
if (invert)
|
||||
info->invflags |= EBT_IP6_PROTO;
|
||||
info->protocol = xtables_parse_protocol(optarg);
|
||||
info->bitmask |= EBT_IP6_PROTO;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
*flags |= info->bitmask;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void brip6_final_check(unsigned int flags)
|
||||
{
|
||||
if (!flags)
|
||||
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) {
|
||||
printf("--ip6-src ");
|
||||
if (ipinfo->invflags & EBT_IP6_SOURCE)
|
||||
printf("! ");
|
||||
printf("%s", xtables_ip6addr_to_numeric(&ipinfo->saddr));
|
||||
printf("%s ", xtables_ip6mask_to_numeric(&ipinfo->smsk));
|
||||
}
|
||||
if (ipinfo->bitmask & EBT_IP6_DEST) {
|
||||
printf("--ip6-dst ");
|
||||
if (ipinfo->invflags & EBT_IP6_DEST)
|
||||
printf("! ");
|
||||
printf("%s", xtables_ip6addr_to_numeric(&ipinfo->daddr));
|
||||
printf("%s ", xtables_ip6mask_to_numeric(&ipinfo->dmsk));
|
||||
}
|
||||
if (ipinfo->bitmask & EBT_IP6_TCLASS) {
|
||||
printf("--ip6-tclass ");
|
||||
if (ipinfo->invflags & EBT_IP6_TCLASS)
|
||||
printf("! ");
|
||||
printf("0x%02X ", ipinfo->tclass);
|
||||
}
|
||||
if (ipinfo->bitmask & EBT_IP6_PROTO) {
|
||||
struct protoent *pe;
|
||||
|
||||
printf("--ip6-proto ");
|
||||
if (ipinfo->invflags & EBT_IP6_PROTO)
|
||||
printf("! ");
|
||||
pe = getprotobynumber(ipinfo->protocol);
|
||||
if (pe == NULL) {
|
||||
printf("%d ", ipinfo->protocol);
|
||||
} else {
|
||||
printf("%s ", pe->p_name);
|
||||
}
|
||||
}
|
||||
if (ipinfo->bitmask & EBT_IP6_SPORT) {
|
||||
printf("--ip6-sport ");
|
||||
if (ipinfo->invflags & EBT_IP6_SPORT)
|
||||
printf("! ");
|
||||
print_port_range(ipinfo->sport);
|
||||
}
|
||||
if (ipinfo->bitmask & EBT_IP6_DPORT) {
|
||||
printf("--ip6-dport ");
|
||||
if (ipinfo->invflags & EBT_IP6_DPORT)
|
||||
printf("! ");
|
||||
print_port_range(ipinfo->dport);
|
||||
}
|
||||
if (ipinfo->bitmask & EBT_IP6_ICMP6) {
|
||||
printf("--ip6-icmp-type ");
|
||||
if (ipinfo->invflags & EBT_IP6_ICMP6)
|
||||
printf("! ");
|
||||
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)),
|
||||
.init = brip6_init,
|
||||
.help = brip6_print_help,
|
||||
.parse = brip6_parse,
|
||||
.final_check = brip6_final_check,
|
||||
.print = brip6_print,
|
||||
.xlate = brip6_xlate,
|
||||
.extra_opts = brip6_opts,
|
||||
};
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_match(&brip6_match);
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
: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-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 udp --ip6-sport 1024:65535;=;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 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
|
||||
@@ -1,29 +0,0 @@
|
||||
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
|
||||
@@ -1,8 +0,0 @@
|
||||
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
|
||||
@@ -1,217 +0,0 @@
|
||||
/*
|
||||
* 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 <getopt.h>
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter_bridge/ebt_log.h>
|
||||
|
||||
#define LOG_DEFAULT_LEVEL LOG_INFO
|
||||
|
||||
#define LOG_PREFIX '1'
|
||||
#define LOG_LEVEL '2'
|
||||
#define LOG_ARP '3'
|
||||
#define LOG_IP '4'
|
||||
#define LOG_LOG '5'
|
||||
#define LOG_IP6 '6'
|
||||
|
||||
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 }
|
||||
};
|
||||
|
||||
static int name_to_loglevel(const char *arg)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
if (!strcmp(arg, eight_priority[i].c_name))
|
||||
return eight_priority[i].c_val;
|
||||
|
||||
/* return bad loglevel */
|
||||
return 9;
|
||||
}
|
||||
|
||||
static const struct option brlog_opts[] = {
|
||||
{ .name = "log-prefix", .has_arg = true, .val = LOG_PREFIX },
|
||||
{ .name = "log-level", .has_arg = true, .val = LOG_LEVEL },
|
||||
{ .name = "log-arp", .has_arg = false, .val = LOG_ARP },
|
||||
{ .name = "log-ip", .has_arg = false, .val = LOG_IP },
|
||||
{ .name = "log", .has_arg = false, .val = LOG_LOG },
|
||||
{ .name = "log-ip6", .has_arg = false, .val = LOG_IP6 },
|
||||
XT_GETOPT_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->bitmask = 0;
|
||||
loginfo->prefix[0] = '\0';
|
||||
loginfo->loglevel = LOG_NOTICE;
|
||||
}
|
||||
|
||||
static unsigned int log_chk_inv(int inv, unsigned int bit, const char *suffix)
|
||||
{
|
||||
if (inv)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Unexpected `!' after --log%s", suffix);
|
||||
return bit;
|
||||
}
|
||||
|
||||
static int brlog_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct ebt_log_info *loginfo = (struct ebt_log_info *)(*target)->data;
|
||||
long int i;
|
||||
char *end;
|
||||
|
||||
switch (c) {
|
||||
case LOG_PREFIX:
|
||||
if (invert)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Unexpected `!` after --log-prefix");
|
||||
if (strlen(optarg) > sizeof(loginfo->prefix) - 1)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Prefix too long");
|
||||
if (strchr(optarg, '\"'))
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Use of \\\" is not allowed"
|
||||
" in the prefix");
|
||||
strcpy((char *)loginfo->prefix, (char *)optarg);
|
||||
break;
|
||||
case LOG_LEVEL:
|
||||
i = strtol(optarg, &end, 16);
|
||||
if (*end != '\0' || i < 0 || i > 7)
|
||||
loginfo->loglevel = name_to_loglevel(optarg);
|
||||
else
|
||||
loginfo->loglevel = i;
|
||||
|
||||
if (loginfo->loglevel == 9)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Problem with the log-level");
|
||||
break;
|
||||
case LOG_IP:
|
||||
loginfo->bitmask |= log_chk_inv(invert, EBT_LOG_IP, "-ip");
|
||||
break;
|
||||
case LOG_ARP:
|
||||
loginfo->bitmask |= log_chk_inv(invert, EBT_LOG_ARP, "-arp");
|
||||
break;
|
||||
case LOG_LOG:
|
||||
loginfo->bitmask |= log_chk_inv(invert, 0, "");
|
||||
break;
|
||||
case LOG_IP6:
|
||||
loginfo->bitmask |= log_chk_inv(invert, EBT_LOG_IP6, "-ip6");
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
*flags |= loginfo->bitmask;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void brlog_final_check(unsigned int flags)
|
||||
{
|
||||
}
|
||||
|
||||
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 --log-prefix \"%s\"",
|
||||
eight_priority[loginfo->loglevel].c_name,
|
||||
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]) {
|
||||
if (params->escape_quotes)
|
||||
xt_xlate_add(xl, " prefix \\\"%s\\\"", loginfo->prefix);
|
||||
else
|
||||
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);
|
||||
|
||||
xt_xlate_add(xl, " flags ether ");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct xtables_target brlog_target = {
|
||||
.name = "log",
|
||||
.revision = 0,
|
||||
.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,
|
||||
.parse = brlog_parse,
|
||||
.final_check = brlog_final_check,
|
||||
.print = brlog_print,
|
||||
.xlate = brlog_xlate,
|
||||
.extra_opts = brlog_opts,
|
||||
};
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_target(&brlog_target);
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
:INPUT,FORWARD,OUTPUT
|
||||
--log;=;OK
|
||||
--log-level crit;=;OK
|
||||
--log-level 1;--log-level alert --log-prefix "";OK
|
||||
--log-level emerg --log-ip --log-arp --log-ip6;--log-level emerg --log-prefix "" --log-ip --log-arp --log-ip6 -j CONTINUE;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
|
||||
@@ -1,15 +0,0 @@
|
||||
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
|
||||
|
||||
@@ -1,228 +0,0 @@
|
||||
/* 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 <getopt.h>
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter_bridge/ebt_mark_t.h>
|
||||
#include "iptables/nft.h"
|
||||
#include "iptables/nft-bridge.h"
|
||||
|
||||
#define MARK_TARGET '1'
|
||||
#define MARK_SETMARK '2'
|
||||
#define MARK_ORMARK '3'
|
||||
#define MARK_ANDMARK '4'
|
||||
#define MARK_XORMARK '5'
|
||||
static const struct option brmark_opts[] = {
|
||||
{ .name = "mark-target",.has_arg = true, .val = MARK_TARGET },
|
||||
/* an oldtime messup, we should have always used the scheme
|
||||
* <extension-name>-<option> */
|
||||
{ .name = "set-mark", .has_arg = true, .val = MARK_SETMARK },
|
||||
{ .name = "mark-set", .has_arg = true, .val = MARK_SETMARK },
|
||||
{ .name = "mark-or", .has_arg = true, .val = MARK_ORMARK },
|
||||
{ .name = "mark-and", .has_arg = true, .val = MARK_ANDMARK },
|
||||
{ .name = "mark-xor", .has_arg = true, .val = MARK_XORMARK },
|
||||
XT_GETOPT_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;
|
||||
}
|
||||
|
||||
#define OPT_MARK_TARGET 0x01
|
||||
#define OPT_MARK_SETMARK 0x02
|
||||
#define OPT_MARK_ORMARK 0x04
|
||||
#define OPT_MARK_ANDMARK 0x08
|
||||
#define OPT_MARK_XORMARK 0x10
|
||||
|
||||
static int
|
||||
brmark_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)
|
||||
(*target)->data;
|
||||
char *end;
|
||||
uint32_t mask;
|
||||
|
||||
switch (c) {
|
||||
case MARK_TARGET:
|
||||
{ unsigned int tmp;
|
||||
EBT_CHECK_OPTION(flags, OPT_MARK_TARGET);
|
||||
if (ebt_fill_target(optarg, &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 1;
|
||||
case MARK_SETMARK:
|
||||
EBT_CHECK_OPTION(flags, OPT_MARK_SETMARK);
|
||||
mask = (OPT_MARK_ORMARK|OPT_MARK_ANDMARK|OPT_MARK_XORMARK);
|
||||
if (*flags & mask)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"--mark-set cannot be used together with"
|
||||
" specific --mark option");
|
||||
info->target = (info->target & EBT_VERDICT_BITS) |
|
||||
MARK_SET_VALUE;
|
||||
break;
|
||||
case MARK_ORMARK:
|
||||
EBT_CHECK_OPTION(flags, OPT_MARK_ORMARK);
|
||||
mask = (OPT_MARK_SETMARK|OPT_MARK_ANDMARK|OPT_MARK_XORMARK);
|
||||
if (*flags & mask)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"--mark-or cannot be used together with"
|
||||
" specific --mark option");
|
||||
info->target = (info->target & EBT_VERDICT_BITS) |
|
||||
MARK_OR_VALUE;
|
||||
break;
|
||||
case MARK_ANDMARK:
|
||||
EBT_CHECK_OPTION(flags, OPT_MARK_ANDMARK);
|
||||
mask = (OPT_MARK_SETMARK|OPT_MARK_ORMARK|OPT_MARK_XORMARK);
|
||||
if (*flags & mask)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"--mark-and cannot be used together with"
|
||||
" specific --mark option");
|
||||
info->target = (info->target & EBT_VERDICT_BITS) |
|
||||
MARK_AND_VALUE;
|
||||
break;
|
||||
case MARK_XORMARK:
|
||||
EBT_CHECK_OPTION(flags, OPT_MARK_XORMARK);
|
||||
mask = (OPT_MARK_SETMARK|OPT_MARK_ANDMARK|OPT_MARK_ORMARK);
|
||||
if (*flags & mask)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"--mark-xor cannot be used together with"
|
||||
" specific --mark option");
|
||||
info->target = (info->target & EBT_VERDICT_BITS) |
|
||||
MARK_XOR_VALUE;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
/* mutual code */
|
||||
info->mark = strtoul(optarg, &end, 0);
|
||||
if (*end != '\0' || end == optarg)
|
||||
xtables_error(PARAMETER_PROBLEM, "Bad MARK value '%s'",
|
||||
optarg);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
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(unsigned int flags)
|
||||
{
|
||||
if (!flags)
|
||||
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,
|
||||
.parse = brmark_parse,
|
||||
.final_check = brmark_final_check,
|
||||
.print = brmark_print,
|
||||
.xlate = brmark_xlate,
|
||||
.extra_opts = brmark_opts,
|
||||
};
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_target(&brmark_target);
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
: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
|
||||
@@ -1,11 +0,0 @@
|
||||
ebtables-translate -A INPUT --mark-set 42
|
||||
nft add rule bridge filter INPUT mark set 0x2a counter
|
||||
|
||||
ebtables-translate -A INPUT --mark-or 42 --mark-target RETURN
|
||||
nft add rule bridge filter INPUT mark set mark or 0x2a counter return
|
||||
|
||||
ebtables-translate -A INPUT --mark-and 42 --mark-target ACCEPT
|
||||
nft add rule bridge filter INPUT mark set mark and 0x2a counter accept
|
||||
|
||||
ebtables-translate -A INPUT --mark-xor 42 --mark-target DROP
|
||||
nft add rule bridge filter INPUT mark set mark xor 0x2a counter drop
|
||||
@@ -1,143 +0,0 @@
|
||||
/* 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 <getopt.h>
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter_bridge/ebt_mark_m.h>
|
||||
|
||||
#define MARK '1'
|
||||
|
||||
static const struct option brmark_m_opts[] = {
|
||||
{ .name = "mark", .has_arg = true, .val = MARK },
|
||||
XT_GETOPT_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_init(struct xt_entry_match *match)
|
||||
{
|
||||
struct ebt_mark_m_info *info = (struct ebt_mark_m_info *)match->data;
|
||||
|
||||
info->mark = 0;
|
||||
info->mask = 0;
|
||||
info->invert = 0;
|
||||
info->bitmask = 0;
|
||||
}
|
||||
|
||||
#define OPT_MARK 0x01
|
||||
static int
|
||||
brmark_m_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct ebt_mark_m_info *info = (struct ebt_mark_m_info *)
|
||||
(*match)->data;
|
||||
char *end;
|
||||
|
||||
switch (c) {
|
||||
case MARK:
|
||||
if (invert)
|
||||
info->invert = 1;
|
||||
info->mark = strtoul(optarg, &end, 0);
|
||||
info->bitmask = EBT_MARK_AND;
|
||||
if (*end == '/') {
|
||||
if (end == optarg)
|
||||
info->bitmask = EBT_MARK_OR;
|
||||
info->mask = strtoul(end+1, &end, 0);
|
||||
} else {
|
||||
info->mask = 0xffffffff;
|
||||
}
|
||||
if (*end != '\0' || end == optarg)
|
||||
xtables_error(PARAMETER_PROBLEM, "Bad mark value '%s'",
|
||||
optarg);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
*flags |= info->bitmask;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void brmark_m_final_check(unsigned int flags)
|
||||
{
|
||||
if (!flags)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"You must specify proper arguments");
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
printf("--mark ");
|
||||
if (info->invert)
|
||||
printf("! ");
|
||||
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 != 0xffffffffU) {
|
||||
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)),
|
||||
.init = brmark_m_init,
|
||||
.help = brmark_m_print_help,
|
||||
.parse = brmark_m_parse,
|
||||
.final_check = brmark_m_final_check,
|
||||
.print = brmark_m_print,
|
||||
.xlate = brmark_m_xlate,
|
||||
.extra_opts = brmark_m_opts,
|
||||
};
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_match(&brmark_m_match);
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
: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
|
||||
@@ -1,14 +0,0 @@
|
||||
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
|
||||
@@ -1,168 +0,0 @@
|
||||
/* 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 <getopt.h>
|
||||
#include <xtables.h>
|
||||
#include "iptables/nft.h"
|
||||
#include "iptables/nft-bridge.h"
|
||||
#include <linux/netfilter_bridge/ebt_nflog.h>
|
||||
|
||||
enum {
|
||||
NFLOG_GROUP = 0x1,
|
||||
NFLOG_PREFIX = 0x2,
|
||||
NFLOG_RANGE = 0x4,
|
||||
NFLOG_THRESHOLD = 0x8,
|
||||
NFLOG_NFLOG = 0x16,
|
||||
};
|
||||
|
||||
static const struct option brnflog_opts[] = {
|
||||
{ .name = "nflog-group", .has_arg = true, .val = NFLOG_GROUP},
|
||||
{ .name = "nflog-prefix", .has_arg = true, .val = NFLOG_PREFIX},
|
||||
{ .name = "nflog-range", .has_arg = true, .val = NFLOG_RANGE},
|
||||
{ .name = "nflog-threshold", .has_arg = true, .val = NFLOG_THRESHOLD},
|
||||
{ .name = "nflog", .has_arg = false, .val = NFLOG_NFLOG},
|
||||
XT_GETOPT_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 int brnflog_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct ebt_nflog_info *info = (struct ebt_nflog_info *)(*target)->data;
|
||||
unsigned int i;
|
||||
|
||||
if (invert)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"The use of '!' makes no sense for the"
|
||||
" nflog watcher");
|
||||
|
||||
switch (c) {
|
||||
case NFLOG_PREFIX:
|
||||
EBT_CHECK_OPTION(flags, NFLOG_PREFIX);
|
||||
if (strlen(optarg) > EBT_NFLOG_PREFIX_SIZE - 1)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Prefix too long for nflog-prefix");
|
||||
strncpy(info->prefix, optarg, EBT_NFLOG_PREFIX_SIZE);
|
||||
break;
|
||||
case NFLOG_GROUP:
|
||||
EBT_CHECK_OPTION(flags, NFLOG_GROUP);
|
||||
if (!xtables_strtoui(optarg, NULL, &i, 1, UINT32_MAX))
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"--nflog-group must be a number!");
|
||||
info->group = i;
|
||||
break;
|
||||
case NFLOG_RANGE:
|
||||
EBT_CHECK_OPTION(flags, NFLOG_RANGE);
|
||||
if (!xtables_strtoui(optarg, NULL, &i, 1, UINT32_MAX))
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"--nflog-range must be a number!");
|
||||
info->len = i;
|
||||
break;
|
||||
case NFLOG_THRESHOLD:
|
||||
EBT_CHECK_OPTION(flags, NFLOG_THRESHOLD);
|
||||
if (!xtables_strtoui(optarg, NULL, &i, 1, UINT32_MAX))
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"--nflog-threshold must be a number!");
|
||||
info->threshold = i;
|
||||
break;
|
||||
case NFLOG_NFLOG:
|
||||
EBT_CHECK_OPTION(flags, NFLOG_NFLOG);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
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') {
|
||||
if (params->escape_quotes)
|
||||
xt_xlate_add(xl, "prefix \\\"%s\\\" ", info->prefix);
|
||||
else
|
||||
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,
|
||||
.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,
|
||||
.parse = brnflog_parse,
|
||||
.print = brnflog_print,
|
||||
.xlate = brnflog_xlate,
|
||||
.extra_opts = brnflog_opts,
|
||||
};
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_target(&brnflog_watcher);
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
:INPUT,FORWARD,OUTPUT
|
||||
--nflog;=;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
|
||||
@@ -1,11 +0,0 @@
|
||||
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
|
||||
@@ -1,119 +0,0 @@
|
||||
/* ebt_pkttype
|
||||
*
|
||||
* Authors:
|
||||
* Bart De Schuymer <bdschuym@pandora.be>
|
||||
*
|
||||
* April, 2003
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <getopt.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",
|
||||
};
|
||||
|
||||
static const struct option brpkttype_opts[] =
|
||||
{
|
||||
{ "pkttype-type" , required_argument, 0, '1' },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
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 int brpkttype_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct ebt_pkttype_info *ptinfo = (struct ebt_pkttype_info *)(*match)->data;
|
||||
char *end;
|
||||
long int i;
|
||||
|
||||
switch (c) {
|
||||
case '1':
|
||||
if (invert)
|
||||
ptinfo->invert = 1;
|
||||
i = strtol(optarg, &end, 16);
|
||||
if (*end != '\0') {
|
||||
for (i = 0; i < ARRAY_SIZE(classes); i++) {
|
||||
if (!strcasecmp(optarg, classes[i]))
|
||||
break;
|
||||
}
|
||||
if (i >= ARRAY_SIZE(classes))
|
||||
xtables_error(PARAMETER_PROBLEM, "Could not parse class '%s'", optarg);
|
||||
}
|
||||
if (i < 0 || i > 255)
|
||||
xtables_error(PARAMETER_PROBLEM, "Problem with specified pkttype class");
|
||||
ptinfo->pkt_type = (uint8_t)i;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
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("--pkttype-type %s", 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,
|
||||
.parse = brpkttype_parse,
|
||||
.print = brpkttype_print,
|
||||
.xlate = brpkttype_xlate,
|
||||
.extra_opts = brpkttype_opts,
|
||||
};
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_match(&brpkttype_match);
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
: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
|
||||
@@ -1,20 +0,0 @@
|
||||
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
|
||||
@@ -1,109 +0,0 @@
|
||||
/* ebt_redirect
|
||||
*
|
||||
* Authors:
|
||||
* Bart De Schuymer <bdschuym@pandora.be>
|
||||
*
|
||||
* April, 2002
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter_bridge/ebt_redirect.h>
|
||||
#include "iptables/nft.h"
|
||||
#include "iptables/nft-bridge.h"
|
||||
|
||||
#define REDIRECT_TARGET '1'
|
||||
static const struct option brredir_opts[] =
|
||||
{
|
||||
{ "redirect-target", required_argument, 0, REDIRECT_TARGET },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#define OPT_REDIRECT_TARGET 0x01
|
||||
static int brredir_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct ebt_redirect_info *redirectinfo =
|
||||
(struct ebt_redirect_info *)(*target)->data;
|
||||
|
||||
switch (c) {
|
||||
case REDIRECT_TARGET:
|
||||
EBT_CHECK_OPTION(flags, OPT_REDIRECT_TARGET);
|
||||
if (ebt_fill_target(optarg, (unsigned int *)&redirectinfo->target))
|
||||
xtables_error(PARAMETER_PROBLEM, "Illegal --redirect-target target");
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
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 set pkttype host");
|
||||
if (red->target != EBT_ACCEPT)
|
||||
xt_xlate_add(xl, " %s ", brredir_verdict(red->target));
|
||||
return 0;
|
||||
}
|
||||
|
||||
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,
|
||||
.parse = brredir_parse,
|
||||
.print = brredir_print,
|
||||
.xlate = brredir_xlate,
|
||||
.extra_opts = brredir_opts,
|
||||
};
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_target(&brredirect_target);
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
:PREROUTING
|
||||
*nat
|
||||
-j redirect;=;OK
|
||||
-j redirect --redirect-target RETURN;=;OK
|
||||
@@ -1,146 +0,0 @@
|
||||
/* ebt_nat
|
||||
*
|
||||
* Authors:
|
||||
* Bart De Schuymer <bdschuym@pandora.be>
|
||||
*
|
||||
* June, 2002
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <netinet/ether.h>
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter_bridge/ebt_nat.h>
|
||||
#include "iptables/nft.h"
|
||||
#include "iptables/nft-bridge.h"
|
||||
|
||||
#define NAT_S '1'
|
||||
#define NAT_S_TARGET '2'
|
||||
#define NAT_S_ARP '3'
|
||||
static const struct option brsnat_opts[] =
|
||||
{
|
||||
{ "to-source" , required_argument, 0, NAT_S },
|
||||
{ "to-src" , required_argument, 0, NAT_S },
|
||||
{ "snat-target" , required_argument, 0, NAT_S_TARGET },
|
||||
{ "snat-arp" , no_argument, 0, NAT_S_ARP },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#define OPT_SNAT 0x01
|
||||
#define OPT_SNAT_TARGET 0x02
|
||||
#define OPT_SNAT_ARP 0x04
|
||||
static int brsnat_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct ebt_nat_info *natinfo = (struct ebt_nat_info *)(*target)->data;
|
||||
struct ether_addr *addr;
|
||||
|
||||
switch (c) {
|
||||
case NAT_S:
|
||||
EBT_CHECK_OPTION(flags, OPT_SNAT);
|
||||
if (!(addr = ether_aton(optarg)))
|
||||
xtables_error(PARAMETER_PROBLEM, "Problem with specified --to-source mac");
|
||||
memcpy(natinfo->mac, addr, ETH_ALEN);
|
||||
break;
|
||||
case NAT_S_TARGET:
|
||||
{ unsigned int tmp;
|
||||
EBT_CHECK_OPTION(flags, OPT_SNAT_TARGET);
|
||||
if (ebt_fill_target(optarg, &tmp))
|
||||
xtables_error(PARAMETER_PROBLEM, "Illegal --snat-target target");
|
||||
natinfo->target = (natinfo->target & ~EBT_VERDICT_BITS) | (tmp & EBT_VERDICT_BITS);
|
||||
}
|
||||
break;
|
||||
case NAT_S_ARP:
|
||||
EBT_CHECK_OPTION(flags, OPT_SNAT_ARP);
|
||||
natinfo->target ^= NAT_ARP_BIT;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void brsnat_final_check(unsigned int flags)
|
||||
{
|
||||
if (!flags)
|
||||
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,
|
||||
.parse = brsnat_parse,
|
||||
.final_check = brsnat_final_check,
|
||||
.print = brsnat_print,
|
||||
.xlate = brsnat_xlate,
|
||||
.extra_opts = brsnat_opts,
|
||||
};
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_target(&brsnat_target);
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
: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
|
||||
@@ -1,5 +0,0 @@
|
||||
ebtables-translate -t nat -A POSTROUTING -s 0:0:0:0:0:0 -o someport+ --to-source de:ad:00:be:ee:ff
|
||||
nft add rule bridge nat POSTROUTING oifname "someport*" ether saddr 00:00:00:00:00:00 ether saddr set de:ad:0:be:ee:ff accept counter
|
||||
|
||||
ebtables-translate -t nat -A POSTROUTING -o someport --to-src de:ad:00:be:ee:ff --snat-target CONTINUE
|
||||
nft add rule bridge nat POSTROUTING oifname "someport" ether saddr set de:ad:0:be:ee:ff continue counter
|
||||
@@ -1,28 +0,0 @@
|
||||
: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 0 -j ACCEPT;=;FAIL
|
||||
-p ! 0 -j ACCEPT;=;FAIL
|
||||
:INPUT
|
||||
-i foobar;=;OK
|
||||
-o foobar;=;FAIL
|
||||
:FORWARD
|
||||
-i foobar;=;OK
|
||||
-o foobar;=;OK
|
||||
:OUTPUT
|
||||
-i foobar;=;FAIL
|
||||
-o foobar;=;OK
|
||||
:PREROUTING
|
||||
*nat
|
||||
-i foobar;=;OK
|
||||
-o foobar;=;FAIL
|
||||
:POSTROUTING
|
||||
*nat
|
||||
-i foobar;=;FAIL
|
||||
-o foobar;=;OK
|
||||
@@ -1,318 +0,0 @@
|
||||
/* ebt_stp
|
||||
*
|
||||
* Authors:
|
||||
* Bart De Schuymer <bdschuym@pandora.be>
|
||||
*
|
||||
* July, 2003
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <netinet/ether.h>
|
||||
#include <linux/netfilter_bridge/ebt_stp.h>
|
||||
#include <xtables.h>
|
||||
|
||||
#include "iptables/nft.h"
|
||||
#include "iptables/nft-bridge.h"
|
||||
|
||||
#define STP_TYPE 'a'
|
||||
#define STP_FLAGS 'b'
|
||||
#define STP_ROOTPRIO 'c'
|
||||
#define STP_ROOTADDR 'd'
|
||||
#define STP_ROOTCOST 'e'
|
||||
#define STP_SENDERPRIO 'f'
|
||||
#define STP_SENDERADDR 'g'
|
||||
#define STP_PORT 'h'
|
||||
#define STP_MSGAGE 'i'
|
||||
#define STP_MAXAGE 'j'
|
||||
#define STP_HELLOTIME 'k'
|
||||
#define STP_FWDD 'l'
|
||||
#define STP_NUMOPS 12
|
||||
|
||||
static const struct option brstp_opts[] =
|
||||
{
|
||||
{ "stp-type" , required_argument, 0, STP_TYPE},
|
||||
{ "stp-flags" , required_argument, 0, STP_FLAGS},
|
||||
{ "stp-root-prio" , required_argument, 0, STP_ROOTPRIO},
|
||||
{ "stp-root-addr" , required_argument, 0, STP_ROOTADDR},
|
||||
{ "stp-root-cost" , required_argument, 0, STP_ROOTCOST},
|
||||
{ "stp-sender-prio" , required_argument, 0, STP_SENDERPRIO},
|
||||
{ "stp-sender-addr" , required_argument, 0, STP_SENDERADDR},
|
||||
{ "stp-port" , required_argument, 0, STP_PORT},
|
||||
{ "stp-msg-age" , required_argument, 0, STP_MSGAGE},
|
||||
{ "stp-max-age" , required_argument, 0, STP_MAXAGE},
|
||||
{ "stp-hello-time" , required_argument, 0, STP_HELLOTIME},
|
||||
{ "stp-forward-delay", required_argument, 0, STP_FWDD},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
#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 int parse_range(const char *portstring, void *lower, void *upper,
|
||||
int bits, uint32_t min, uint32_t max)
|
||||
{
|
||||
char *buffer;
|
||||
char *cp, *end;
|
||||
uint32_t low_nr, upp_nr;
|
||||
int ret = 0;
|
||||
|
||||
buffer = strdup(portstring);
|
||||
if ((cp = strchr(buffer, ':')) == NULL) {
|
||||
low_nr = strtoul(buffer, &end, 10);
|
||||
if (*end || low_nr < min || low_nr > max) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
if (bits == 2) {
|
||||
*(uint16_t *)lower = low_nr;
|
||||
*(uint16_t *)upper = low_nr;
|
||||
} else {
|
||||
*(uint32_t *)lower = low_nr;
|
||||
*(uint32_t *)upper = low_nr;
|
||||
}
|
||||
} else {
|
||||
*cp = '\0';
|
||||
cp++;
|
||||
if (!*buffer)
|
||||
low_nr = min;
|
||||
else {
|
||||
low_nr = strtoul(buffer, &end, 10);
|
||||
if (*end || low_nr < min) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (!*cp)
|
||||
upp_nr = max;
|
||||
else {
|
||||
upp_nr = strtoul(cp, &end, 10);
|
||||
if (*end || upp_nr > max) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (upp_nr < low_nr) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
if (bits == 2) {
|
||||
*(uint16_t *)lower = low_nr;
|
||||
*(uint16_t *)upper = upp_nr;
|
||||
} else {
|
||||
*(uint32_t *)lower = low_nr;
|
||||
*(uint32_t *)upper = upp_nr;
|
||||
}
|
||||
}
|
||||
out:
|
||||
free(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void print_range(unsigned int l, unsigned int u)
|
||||
{
|
||||
if (l == u)
|
||||
printf("%u ", l);
|
||||
else
|
||||
printf("%u:%u ", l, u);
|
||||
}
|
||||
|
||||
static int
|
||||
brstp_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct ebt_stp_info *stpinfo = (struct ebt_stp_info *)(*match)->data;
|
||||
unsigned int flag;
|
||||
long int i;
|
||||
char *end = NULL;
|
||||
|
||||
if (c < 'a' || c > ('a' + STP_NUMOPS - 1))
|
||||
return 0;
|
||||
flag = 1 << (c - 'a');
|
||||
EBT_CHECK_OPTION(flags, flag);
|
||||
if (invert)
|
||||
stpinfo->invflags |= flag;
|
||||
stpinfo->bitmask |= flag;
|
||||
switch (flag) {
|
||||
case EBT_STP_TYPE:
|
||||
i = strtol(optarg, &end, 0);
|
||||
if (i < 0 || i > 255 || *end != '\0') {
|
||||
if (!strcasecmp(optarg, BPDU_TYPE_CONFIG_STRING))
|
||||
stpinfo->type = BPDU_TYPE_CONFIG;
|
||||
else if (!strcasecmp(optarg, BPDU_TYPE_TCN_STRING))
|
||||
stpinfo->type = BPDU_TYPE_TCN;
|
||||
else
|
||||
xtables_error(PARAMETER_PROBLEM, "Bad --stp-type argument");
|
||||
} else
|
||||
stpinfo->type = i;
|
||||
break;
|
||||
case EBT_STP_FLAGS:
|
||||
i = strtol(optarg, &end, 0);
|
||||
if (i < 0 || i > 255 || *end != '\0') {
|
||||
if (!strcasecmp(optarg, FLAG_TC_STRING))
|
||||
stpinfo->config.flags = FLAG_TC;
|
||||
else if (!strcasecmp(optarg, 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 EBT_STP_ROOTPRIO:
|
||||
if (parse_range(argv[optind-1], &(stpinfo->config.root_priol),
|
||||
&(stpinfo->config.root_priou), 2, 0, 0xffff))
|
||||
xtables_error(PARAMETER_PROBLEM, "Bad --stp-root-prio range");
|
||||
break;
|
||||
case EBT_STP_ROOTCOST:
|
||||
if (parse_range(argv[optind-1], &(stpinfo->config.root_costl),
|
||||
&(stpinfo->config.root_costu), 4, 0, 0xffffffff))
|
||||
xtables_error(PARAMETER_PROBLEM, "Bad --stp-root-cost range");
|
||||
break;
|
||||
case EBT_STP_SENDERPRIO:
|
||||
if (parse_range(argv[optind-1], &(stpinfo->config.sender_priol),
|
||||
&(stpinfo->config.sender_priou), 2, 0, 0xffff))
|
||||
xtables_error(PARAMETER_PROBLEM, "Bad --stp-sender-prio range");
|
||||
break;
|
||||
case EBT_STP_PORT:
|
||||
if (parse_range(argv[optind-1], &(stpinfo->config.portl),
|
||||
&(stpinfo->config.portu), 2, 0, 0xffff))
|
||||
xtables_error(PARAMETER_PROBLEM, "Bad --stp-port-range");
|
||||
break;
|
||||
case EBT_STP_MSGAGE:
|
||||
if (parse_range(argv[optind-1], &(stpinfo->config.msg_agel),
|
||||
&(stpinfo->config.msg_ageu), 2, 0, 0xffff))
|
||||
xtables_error(PARAMETER_PROBLEM, "Bad --stp-msg-age range");
|
||||
break;
|
||||
case EBT_STP_MAXAGE:
|
||||
if (parse_range(argv[optind-1], &(stpinfo->config.max_agel),
|
||||
&(stpinfo->config.max_ageu), 2, 0, 0xffff))
|
||||
xtables_error(PARAMETER_PROBLEM, "Bad --stp-max-age range");
|
||||
break;
|
||||
case EBT_STP_HELLOTIME:
|
||||
if (parse_range(argv[optind-1], &(stpinfo->config.hello_timel),
|
||||
&(stpinfo->config.hello_timeu), 2, 0, 0xffff))
|
||||
xtables_error(PARAMETER_PROBLEM, "Bad --stp-hello-time range");
|
||||
break;
|
||||
case EBT_STP_FWDD:
|
||||
if (parse_range(argv[optind-1], &(stpinfo->config.forward_delayl),
|
||||
&(stpinfo->config.forward_delayu), 2, 0, 0xffff))
|
||||
xtables_error(PARAMETER_PROBLEM, "Bad --stp-forward-delay range");
|
||||
break;
|
||||
case EBT_STP_ROOTADDR:
|
||||
if (xtables_parse_mac_and_mask(argv[optind-1],
|
||||
stpinfo->config.root_addr,
|
||||
stpinfo->config.root_addrmsk))
|
||||
xtables_error(PARAMETER_PROBLEM, "Bad --stp-root-addr address");
|
||||
break;
|
||||
case EBT_STP_SENDERADDR:
|
||||
if (xtables_parse_mac_and_mask(argv[optind-1],
|
||||
stpinfo->config.sender_addr,
|
||||
stpinfo->config.sender_addrmsk))
|
||||
xtables_error(PARAMETER_PROBLEM, "Bad --stp-sender-addr address");
|
||||
break;
|
||||
default:
|
||||
xtables_error(PARAMETER_PROBLEM, "Unknown stp option");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
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; i < STP_NUMOPS; i++) {
|
||||
if (!(stpinfo->bitmask & (1 << i)))
|
||||
continue;
|
||||
printf("--%s %s", brstp_opts[i].name,
|
||||
(stpinfo->invflags & (1 << i)) ? "! " : "");
|
||||
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,
|
||||
.parse = brstp_parse,
|
||||
.print = brstp_print,
|
||||
.extra_opts = brstp_opts,
|
||||
};
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_match(&brstp_match);
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
:INPUT,FORWARD,OUTPUT
|
||||
--stp-type 1;=;OK
|
||||
--stp-flags 0x1;--stp-flags topology-change -j CONTINUE;OK
|
||||
--stp-root-prio 1 -j ACCEPT;=;OK
|
||||
--stp-root-addr 0d:ea:d0:0b:ee:f0;=;OK
|
||||
--stp-root-cost 1;=;OK
|
||||
--stp-sender-prio 1;=;OK
|
||||
--stp-sender-addr de:ad:be:ef:00:00;=;OK
|
||||
--stp-port 1;=;OK
|
||||
--stp-msg-age 1;=;OK
|
||||
--stp-max-age 1;=;OK
|
||||
--stp-hello-time 1;=;OK
|
||||
--stp-forward-delay 1;=;OK
|
||||
@@ -1,156 +0,0 @@
|
||||
/* 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 <getopt.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"
|
||||
|
||||
#define NAME_VLAN_ID "id"
|
||||
#define NAME_VLAN_PRIO "prio"
|
||||
#define NAME_VLAN_ENCAP "encap"
|
||||
|
||||
#define VLAN_ID '1'
|
||||
#define VLAN_PRIO '2'
|
||||
#define VLAN_ENCAP '3'
|
||||
|
||||
static const struct option brvlan_opts[] = {
|
||||
{"vlan-id" , required_argument, NULL, VLAN_ID},
|
||||
{"vlan-prio" , required_argument, NULL, VLAN_PRIO},
|
||||
{"vlan-encap", required_argument, NULL, VLAN_ENCAP},
|
||||
XT_GETOPT_TABLEEND,
|
||||
};
|
||||
|
||||
/*
|
||||
* option inverse flags definition
|
||||
*/
|
||||
#define OPT_VLAN_ID 0x01
|
||||
#define OPT_VLAN_PRIO 0x02
|
||||
#define OPT_VLAN_ENCAP 0x04
|
||||
#define OPT_VLAN_FLAGS (OPT_VLAN_ID | OPT_VLAN_PRIO | OPT_VLAN_ENCAP)
|
||||
|
||||
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 int
|
||||
brvlan_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct ebt_vlan_info *vlaninfo = (struct ebt_vlan_info *) (*match)->data;
|
||||
struct xt_ethertypeent *ethent;
|
||||
char *end;
|
||||
struct ebt_vlan_info local;
|
||||
|
||||
switch (c) {
|
||||
case VLAN_ID:
|
||||
EBT_CHECK_OPTION(flags, OPT_VLAN_ID);
|
||||
if (invert)
|
||||
vlaninfo->invflags |= EBT_VLAN_ID;
|
||||
local.id = strtoul(optarg, &end, 10);
|
||||
if (local.id > 4094 || *end != '\0')
|
||||
xtables_error(PARAMETER_PROBLEM, "Invalid --vlan-id range ('%s')", optarg);
|
||||
vlaninfo->id = local.id;
|
||||
vlaninfo->bitmask |= EBT_VLAN_ID;
|
||||
break;
|
||||
case VLAN_PRIO:
|
||||
EBT_CHECK_OPTION(flags, OPT_VLAN_PRIO);
|
||||
if (invert)
|
||||
vlaninfo->invflags |= EBT_VLAN_PRIO;
|
||||
local.prio = strtoul(optarg, &end, 10);
|
||||
if (local.prio >= 8 || *end != '\0')
|
||||
xtables_error(PARAMETER_PROBLEM, "Invalid --vlan-prio range ('%s')", optarg);
|
||||
vlaninfo->prio = local.prio;
|
||||
vlaninfo->bitmask |= EBT_VLAN_PRIO;
|
||||
break;
|
||||
case VLAN_ENCAP:
|
||||
EBT_CHECK_OPTION(flags, OPT_VLAN_ENCAP);
|
||||
if (invert)
|
||||
vlaninfo->invflags |= EBT_VLAN_ENCAP;
|
||||
local.encap = strtoul(optarg, &end, 16);
|
||||
if (*end != '\0') {
|
||||
ethent = xtables_getethertypebyname(optarg);
|
||||
if (ethent == NULL)
|
||||
xtables_error(PARAMETER_PROBLEM, "Unknown --vlan-encap value ('%s')", optarg);
|
||||
local.encap = ethent->e_ethertype;
|
||||
}
|
||||
if (local.encap < ETH_ZLEN)
|
||||
xtables_error(PARAMETER_PROBLEM, "Invalid --vlan-encap range ('%s')", optarg);
|
||||
vlaninfo->encap = htons(local.encap);
|
||||
vlaninfo->bitmask |= EBT_VLAN_ENCAP;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
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("--vlan-id %s%d ", (vlaninfo->invflags & EBT_VLAN_ID) ? "! " : "", vlaninfo->id);
|
||||
}
|
||||
if (vlaninfo->bitmask & EBT_VLAN_PRIO) {
|
||||
printf("--vlan-prio %s%d ", (vlaninfo->invflags & EBT_VLAN_PRIO) ? "! " : "", vlaninfo->prio);
|
||||
}
|
||||
if (vlaninfo->bitmask & EBT_VLAN_ENCAP) {
|
||||
printf("--vlan-encap %s", (vlaninfo->invflags & EBT_VLAN_ENCAP) ? "! " : "");
|
||||
printf("%4.4X ", 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,
|
||||
.parse = brvlan_parse,
|
||||
.print = brvlan_print,
|
||||
.xlate = brvlan_xlate,
|
||||
.extra_opts = brvlan_opts,
|
||||
};
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_match(&brvlan_match);
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
: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
|
||||
@@ -1,11 +0,0 @@
|
||||
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
|
||||
@@ -1,411 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
|
||||
*
|
||||
* Based on Rusty Russell's IPv4 DNAT target. Development of IPv6 NAT
|
||||
* funded by Astaro.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <xtables.h>
|
||||
#include <iptables.h>
|
||||
#include <limits.h> /* INT_MAX in ip_tables.h */
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
#include <linux/netfilter/nf_nat.h>
|
||||
|
||||
enum {
|
||||
O_TO_DEST = 0,
|
||||
O_RANDOM,
|
||||
O_PERSISTENT,
|
||||
O_X_TO_DEST,
|
||||
F_TO_DEST = 1 << O_TO_DEST,
|
||||
F_RANDOM = 1 << O_RANDOM,
|
||||
F_X_TO_DEST = 1 << O_X_TO_DEST,
|
||||
};
|
||||
|
||||
static void DNAT_help(void)
|
||||
{
|
||||
printf(
|
||||
"DNAT target options:\n"
|
||||
" --to-destination [<ipaddr>[-<ipaddr>]][:port[-port]]\n"
|
||||
" Address to map destination to.\n"
|
||||
"[--random] [--persistent]\n");
|
||||
}
|
||||
|
||||
static void DNAT_help_v2(void)
|
||||
{
|
||||
printf(
|
||||
"DNAT target options:\n"
|
||||
" --to-destination [<ipaddr>[-<ipaddr>]][:port[-port[/port]]]\n"
|
||||
" Address to map destination to.\n"
|
||||
"[--random] [--persistent]\n");
|
||||
}
|
||||
|
||||
static const struct xt_option_entry DNAT_opts[] = {
|
||||
{.name = "to-destination", .id = O_TO_DEST, .type = XTTYPE_STRING,
|
||||
.flags = XTOPT_MAND | XTOPT_MULTI},
|
||||
{.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE},
|
||||
{.name = "persistent", .id = O_PERSISTENT, .type = XTTYPE_NONE},
|
||||
XTOPT_TABLEEND,
|
||||
};
|
||||
|
||||
/* Ranges expected in network order. */
|
||||
static void
|
||||
parse_to(const char *orig_arg, int portok, struct nf_nat_range2 *range, int rev)
|
||||
{
|
||||
char *arg, *start, *end = NULL, *colon = NULL, *dash, *error;
|
||||
const struct in6_addr *ip;
|
||||
|
||||
arg = strdup(orig_arg);
|
||||
if (arg == NULL)
|
||||
xtables_error(RESOURCE_PROBLEM, "strdup");
|
||||
|
||||
start = strchr(arg, '[');
|
||||
if (start == NULL) {
|
||||
start = arg;
|
||||
/* Lets assume one colon is port information. Otherwise its an IPv6 address */
|
||||
colon = strchr(arg, ':');
|
||||
if (colon && strchr(colon+1, ':'))
|
||||
colon = NULL;
|
||||
}
|
||||
else {
|
||||
start++;
|
||||
end = strchr(start, ']');
|
||||
if (end == NULL)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Invalid address format");
|
||||
|
||||
*end = '\0';
|
||||
colon = strchr(end + 1, ':');
|
||||
}
|
||||
|
||||
if (colon) {
|
||||
int port;
|
||||
|
||||
if (!portok)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Need TCP, UDP, SCTP or DCCP with port specification");
|
||||
|
||||
range->flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
|
||||
|
||||
port = atoi(colon+1);
|
||||
if (port <= 0 || port > 65535)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Port `%s' not valid\n", colon+1);
|
||||
|
||||
error = strchr(colon+1, ':');
|
||||
if (error)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Invalid port:port syntax - use dash\n");
|
||||
|
||||
dash = strchr(colon, '-');
|
||||
if (!dash) {
|
||||
range->min_proto.tcp.port
|
||||
= range->max_proto.tcp.port
|
||||
= htons(port);
|
||||
} else {
|
||||
int maxport;
|
||||
|
||||
maxport = atoi(dash + 1);
|
||||
if (maxport <= 0 || maxport > 65535)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Port `%s' not valid\n", dash+1);
|
||||
if (maxport < port)
|
||||
/* People are stupid. */
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Port range `%s' funky\n", colon+1);
|
||||
range->min_proto.tcp.port = htons(port);
|
||||
range->max_proto.tcp.port = htons(maxport);
|
||||
|
||||
if (rev >= 2) {
|
||||
char *slash = strchr(dash, '/');
|
||||
if (slash) {
|
||||
int baseport;
|
||||
|
||||
baseport = atoi(slash + 1);
|
||||
if (baseport <= 0 || baseport > 65535)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Port `%s' not valid\n", slash+1);
|
||||
range->flags |= NF_NAT_RANGE_PROTO_OFFSET;
|
||||
range->base_proto.tcp.port = htons(baseport);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Starts with colon or [] colon? No IP info...*/
|
||||
if (colon == arg || colon == arg+2) {
|
||||
free(arg);
|
||||
return;
|
||||
}
|
||||
*colon = '\0';
|
||||
}
|
||||
|
||||
range->flags |= NF_NAT_RANGE_MAP_IPS;
|
||||
dash = strchr(start, '-');
|
||||
if (colon && dash && dash > colon)
|
||||
dash = NULL;
|
||||
|
||||
if (dash)
|
||||
*dash = '\0';
|
||||
|
||||
ip = xtables_numeric_to_ip6addr(start);
|
||||
if (!ip)
|
||||
xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
|
||||
start);
|
||||
range->min_addr.in6 = *ip;
|
||||
if (dash) {
|
||||
ip = xtables_numeric_to_ip6addr(dash + 1);
|
||||
if (!ip)
|
||||
xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
|
||||
dash+1);
|
||||
range->max_addr.in6 = *ip;
|
||||
} else
|
||||
range->max_addr = range->min_addr;
|
||||
|
||||
free(arg);
|
||||
return;
|
||||
}
|
||||
|
||||
static void _DNAT_parse(struct xt_option_call *cb,
|
||||
struct nf_nat_range2 *range, int rev)
|
||||
{
|
||||
const struct ip6t_entry *entry = cb->xt_entry;
|
||||
int portok;
|
||||
|
||||
if (entry->ipv6.proto == IPPROTO_TCP ||
|
||||
entry->ipv6.proto == IPPROTO_UDP ||
|
||||
entry->ipv6.proto == IPPROTO_SCTP ||
|
||||
entry->ipv6.proto == IPPROTO_DCCP ||
|
||||
entry->ipv6.proto == IPPROTO_ICMP)
|
||||
portok = 1;
|
||||
else
|
||||
portok = 0;
|
||||
|
||||
xtables_option_parse(cb);
|
||||
switch (cb->entry->id) {
|
||||
case O_TO_DEST:
|
||||
if (cb->xflags & F_X_TO_DEST) {
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"DNAT: Multiple --to-destination not supported");
|
||||
}
|
||||
parse_to(cb->arg, portok, range, rev);
|
||||
cb->xflags |= F_X_TO_DEST;
|
||||
break;
|
||||
case O_PERSISTENT:
|
||||
range->flags |= NF_NAT_RANGE_PERSISTENT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void DNAT_parse(struct xt_option_call *cb)
|
||||
{
|
||||
struct nf_nat_range *range_v1 = (void *)cb->data;
|
||||
struct nf_nat_range2 range = {};
|
||||
|
||||
memcpy(&range, range_v1, sizeof(*range_v1));
|
||||
_DNAT_parse(cb, &range, 1);
|
||||
memcpy(range_v1, &range, sizeof(*range_v1));
|
||||
}
|
||||
|
||||
static void DNAT_parse_v2(struct xt_option_call *cb)
|
||||
{
|
||||
_DNAT_parse(cb, (struct nf_nat_range2 *)cb->data, 2);
|
||||
}
|
||||
|
||||
static void _DNAT_fcheck(struct xt_fcheck_call *cb, unsigned int *flags)
|
||||
{
|
||||
static const unsigned int f = F_TO_DEST | F_RANDOM;
|
||||
|
||||
if ((cb->xflags & f) == f)
|
||||
*flags |= NF_NAT_RANGE_PROTO_RANDOM;
|
||||
}
|
||||
|
||||
static void DNAT_fcheck(struct xt_fcheck_call *cb)
|
||||
{
|
||||
_DNAT_fcheck(cb, &((struct nf_nat_range *)cb->data)->flags);
|
||||
}
|
||||
|
||||
static void DNAT_fcheck_v2(struct xt_fcheck_call *cb)
|
||||
{
|
||||
_DNAT_fcheck(cb, &((struct nf_nat_range2 *)cb->data)->flags);
|
||||
}
|
||||
|
||||
static void print_range(const struct nf_nat_range2 *range, int rev)
|
||||
{
|
||||
if (range->flags & NF_NAT_RANGE_MAP_IPS) {
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED)
|
||||
printf("[");
|
||||
printf("%s", xtables_ip6addr_to_numeric(&range->min_addr.in6));
|
||||
if (memcmp(&range->min_addr, &range->max_addr,
|
||||
sizeof(range->min_addr)))
|
||||
printf("-%s", xtables_ip6addr_to_numeric(&range->max_addr.in6));
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED)
|
||||
printf("]");
|
||||
}
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
|
||||
printf(":");
|
||||
printf("%hu", ntohs(range->min_proto.tcp.port));
|
||||
if (range->max_proto.tcp.port != range->min_proto.tcp.port)
|
||||
printf("-%hu", ntohs(range->max_proto.tcp.port));
|
||||
if (rev >= 2 && (range->flags & NF_NAT_RANGE_PROTO_OFFSET))
|
||||
printf("/%hu", ntohs(range->base_proto.tcp.port));
|
||||
}
|
||||
}
|
||||
|
||||
static void _DNAT_print(const struct nf_nat_range2 *range, int rev)
|
||||
{
|
||||
printf(" to:");
|
||||
print_range(range, rev);
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
|
||||
printf(" random");
|
||||
if (range->flags & NF_NAT_RANGE_PERSISTENT)
|
||||
printf(" persistent");
|
||||
}
|
||||
|
||||
static void DNAT_print(const void *ip, const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
const struct nf_nat_range *range_v1 = (const void *)target->data;
|
||||
struct nf_nat_range2 range = {};
|
||||
|
||||
memcpy(&range, range_v1, sizeof(*range_v1));
|
||||
_DNAT_print(&range, 1);
|
||||
}
|
||||
|
||||
static void DNAT_print_v2(const void *ip, const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
_DNAT_print((const struct nf_nat_range2 *)target->data, 2);
|
||||
}
|
||||
|
||||
static void _DNAT_save(const struct nf_nat_range2 *range, int rev)
|
||||
{
|
||||
printf(" --to-destination ");
|
||||
print_range(range, rev);
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
|
||||
printf(" --random");
|
||||
if (range->flags & NF_NAT_RANGE_PERSISTENT)
|
||||
printf(" --persistent");
|
||||
}
|
||||
|
||||
static void DNAT_save(const void *ip, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct nf_nat_range *range_v1 = (const void *)target->data;
|
||||
struct nf_nat_range2 range = {};
|
||||
|
||||
memcpy(&range, range_v1, sizeof(*range_v1));
|
||||
_DNAT_save(&range, 1);
|
||||
}
|
||||
|
||||
static void DNAT_save_v2(const void *ip, const struct xt_entry_target *target)
|
||||
{
|
||||
_DNAT_save((const struct nf_nat_range2 *)target->data, 2);
|
||||
}
|
||||
|
||||
static void print_range_xlate(const struct nf_nat_range2 *range,
|
||||
struct xt_xlate *xl, int rev)
|
||||
{
|
||||
bool proto_specified = range->flags & NF_NAT_RANGE_PROTO_SPECIFIED;
|
||||
|
||||
if (range->flags & NF_NAT_RANGE_MAP_IPS) {
|
||||
xt_xlate_add(xl, "%s%s%s",
|
||||
proto_specified ? "[" : "",
|
||||
xtables_ip6addr_to_numeric(&range->min_addr.in6),
|
||||
proto_specified ? "]" : "");
|
||||
|
||||
if (memcmp(&range->min_addr, &range->max_addr,
|
||||
sizeof(range->min_addr))) {
|
||||
xt_xlate_add(xl, "-%s%s%s",
|
||||
proto_specified ? "[" : "",
|
||||
xtables_ip6addr_to_numeric(&range->max_addr.in6),
|
||||
proto_specified ? "]" : "");
|
||||
}
|
||||
}
|
||||
if (proto_specified) {
|
||||
xt_xlate_add(xl, ":%hu", ntohs(range->min_proto.tcp.port));
|
||||
|
||||
if (range->max_proto.tcp.port != range->min_proto.tcp.port)
|
||||
xt_xlate_add(xl, "-%hu",
|
||||
ntohs(range->max_proto.tcp.port));
|
||||
}
|
||||
}
|
||||
|
||||
static int _DNAT_xlate(struct xt_xlate *xl,
|
||||
const struct nf_nat_range2 *range, int rev)
|
||||
{
|
||||
bool sep_need = false;
|
||||
const char *sep = " ";
|
||||
|
||||
xt_xlate_add(xl, "dnat to ");
|
||||
print_range_xlate(range, xl, rev);
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_RANDOM) {
|
||||
xt_xlate_add(xl, " random");
|
||||
sep_need = true;
|
||||
}
|
||||
if (range->flags & NF_NAT_RANGE_PERSISTENT) {
|
||||
if (sep_need)
|
||||
sep = ",";
|
||||
xt_xlate_add(xl, "%spersistent", sep);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int DNAT_xlate(struct xt_xlate *xl,
|
||||
const struct xt_xlate_tg_params *params)
|
||||
{
|
||||
const struct nf_nat_range *range_v1 = (const void *)params->target->data;
|
||||
struct nf_nat_range2 range = {};
|
||||
|
||||
memcpy(&range, range_v1, sizeof(*range_v1));
|
||||
_DNAT_xlate(xl, &range, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int DNAT_xlate_v2(struct xt_xlate *xl,
|
||||
const struct xt_xlate_tg_params *params)
|
||||
{
|
||||
_DNAT_xlate(xl, (const struct nf_nat_range2 *)params->target->data, 2);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct xtables_target dnat_tg_reg[] = {
|
||||
{
|
||||
.name = "DNAT",
|
||||
.version = XTABLES_VERSION,
|
||||
.family = NFPROTO_IPV6,
|
||||
.revision = 1,
|
||||
.size = XT_ALIGN(sizeof(struct nf_nat_range)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct nf_nat_range)),
|
||||
.help = DNAT_help,
|
||||
.print = DNAT_print,
|
||||
.save = DNAT_save,
|
||||
.x6_parse = DNAT_parse,
|
||||
.x6_fcheck = DNAT_fcheck,
|
||||
.x6_options = DNAT_opts,
|
||||
.xlate = DNAT_xlate,
|
||||
},
|
||||
{
|
||||
.name = "DNAT",
|
||||
.version = XTABLES_VERSION,
|
||||
.family = NFPROTO_IPV6,
|
||||
.revision = 2,
|
||||
.size = XT_ALIGN(sizeof(struct nf_nat_range2)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct nf_nat_range2)),
|
||||
.help = DNAT_help_v2,
|
||||
.print = DNAT_print_v2,
|
||||
.save = DNAT_save_v2,
|
||||
.x6_parse = DNAT_parse_v2,
|
||||
.x6_fcheck = DNAT_fcheck_v2,
|
||||
.x6_options = DNAT_opts,
|
||||
.xlate = DNAT_xlate_v2,
|
||||
},
|
||||
};
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_targets(dnat_tg_reg, ARRAY_SIZE(dnat_tg_reg));
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
: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
|
||||
-j DNAT;;FAIL
|
||||
@@ -1,11 +0,0 @@
|
||||
ip6tables-translate -t nat -A prerouting -i eth1 -p tcp --dport 8080 -j DNAT --to-destination [fec0::1234]:80
|
||||
nft add rule ip6 nat prerouting iifname "eth1" tcp dport 8080 counter dnat to [fec0::1234]:80
|
||||
|
||||
ip6tables-translate -t nat -A prerouting -p tcp -j DNAT --to-destination [fec0::1234]:1-20
|
||||
nft add rule ip6 nat prerouting meta l4proto tcp counter dnat to [fec0::1234]:1-20
|
||||
|
||||
ip6tables-translate -t nat -A prerouting -p tcp -j DNAT --to-destination [fec0::1234]:80 --persistent
|
||||
nft add rule ip6 nat prerouting meta l4proto tcp counter dnat to [fec0::1234]:80 persistent
|
||||
|
||||
ip6tables-translate -t nat -A prerouting -p tcp -j DNAT --to-destination [fec0::1234]:80 --random --persistent
|
||||
nft add rule ip6 nat prerouting meta l4proto tcp counter dnat to [fec0::1234]:80 random,persistent
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
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.
|
||||
@@ -1,7 +0,0 @@
|
||||
: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
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
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.
|
||||
@@ -1,10 +0,0 @@
|
||||
: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
|
||||
@@ -1,250 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter_ipv6/ip6t_LOG.h>
|
||||
|
||||
#ifndef IP6T_LOG_UID /* Old kernel */
|
||||
#define IP6T_LOG_UID 0x08
|
||||
#undef IP6T_LOG_MASK
|
||||
#define IP6T_LOG_MASK 0x0f
|
||||
#endif
|
||||
|
||||
#define LOG_DEFAULT_LEVEL LOG_WARNING
|
||||
|
||||
enum {
|
||||
O_LOG_LEVEL = 0,
|
||||
O_LOG_PREFIX,
|
||||
O_LOG_TCPSEQ,
|
||||
O_LOG_TCPOPTS,
|
||||
O_LOG_IPOPTS,
|
||||
O_LOG_UID,
|
||||
O_LOG_MAC,
|
||||
};
|
||||
|
||||
static void LOG_help(void)
|
||||
{
|
||||
printf(
|
||||
"LOG target options:\n"
|
||||
" --log-level level Level of logging (numeric or see syslog.conf)\n"
|
||||
" --log-prefix prefix Prefix log messages with this prefix.\n"
|
||||
" --log-tcp-sequence Log TCP sequence numbers.\n"
|
||||
" --log-tcp-options Log TCP options.\n"
|
||||
" --log-ip-options Log IP options.\n"
|
||||
" --log-uid Log UID owning the local socket.\n"
|
||||
" --log-macdecode Decode MAC addresses and protocol.\n");
|
||||
}
|
||||
|
||||
#define s struct ip6t_log_info
|
||||
static const struct xt_option_entry LOG_opts[] = {
|
||||
{.name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL,
|
||||
.flags = XTOPT_PUT, XTOPT_POINTER(s, level)},
|
||||
{.name = "log-prefix", .id = O_LOG_PREFIX, .type = XTTYPE_STRING,
|
||||
.flags = XTOPT_PUT, XTOPT_POINTER(s, prefix), .min = 1},
|
||||
{.name = "log-tcp-sequence", .id = O_LOG_TCPSEQ, .type = XTTYPE_NONE},
|
||||
{.name = "log-tcp-options", .id = O_LOG_TCPOPTS, .type = XTTYPE_NONE},
|
||||
{.name = "log-ip-options", .id = O_LOG_IPOPTS, .type = XTTYPE_NONE},
|
||||
{.name = "log-uid", .id = O_LOG_UID, .type = XTTYPE_NONE},
|
||||
{.name = "log-macdecode", .id = O_LOG_MAC, .type = XTTYPE_NONE},
|
||||
XTOPT_TABLEEND,
|
||||
};
|
||||
#undef s
|
||||
|
||||
static void LOG_init(struct xt_entry_target *t)
|
||||
{
|
||||
struct ip6t_log_info *loginfo = (struct ip6t_log_info *)t->data;
|
||||
|
||||
loginfo->level = LOG_DEFAULT_LEVEL;
|
||||
|
||||
}
|
||||
|
||||
struct ip6t_log_names {
|
||||
const char *name;
|
||||
unsigned int level;
|
||||
};
|
||||
|
||||
struct ip6t_log_xlate {
|
||||
const char *name;
|
||||
unsigned int level;
|
||||
};
|
||||
|
||||
static const struct ip6t_log_names ip6t_log_names[]
|
||||
= { { .name = "alert", .level = LOG_ALERT },
|
||||
{ .name = "crit", .level = LOG_CRIT },
|
||||
{ .name = "debug", .level = LOG_DEBUG },
|
||||
{ .name = "emerg", .level = LOG_EMERG },
|
||||
{ .name = "error", .level = LOG_ERR }, /* DEPRECATED */
|
||||
{ .name = "info", .level = LOG_INFO },
|
||||
{ .name = "notice", .level = LOG_NOTICE },
|
||||
{ .name = "panic", .level = LOG_EMERG }, /* DEPRECATED */
|
||||
{ .name = "warning", .level = LOG_WARNING }
|
||||
};
|
||||
|
||||
static void LOG_parse(struct xt_option_call *cb)
|
||||
{
|
||||
struct ip6t_log_info *info = cb->data;
|
||||
|
||||
xtables_option_parse(cb);
|
||||
switch (cb->entry->id) {
|
||||
case O_LOG_PREFIX:
|
||||
if (strchr(cb->arg, '\n') != NULL)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Newlines not allowed in --log-prefix");
|
||||
break;
|
||||
case O_LOG_TCPSEQ:
|
||||
info->logflags |= IP6T_LOG_TCPSEQ;
|
||||
break;
|
||||
case O_LOG_TCPOPTS:
|
||||
info->logflags |= IP6T_LOG_TCPOPT;
|
||||
break;
|
||||
case O_LOG_IPOPTS:
|
||||
info->logflags |= IP6T_LOG_IPOPT;
|
||||
break;
|
||||
case O_LOG_UID:
|
||||
info->logflags |= IP6T_LOG_UID;
|
||||
break;
|
||||
case O_LOG_MAC:
|
||||
info->logflags |= IP6T_LOG_MACDECODE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void LOG_print(const void *ip, const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
const struct ip6t_log_info *loginfo
|
||||
= (const struct ip6t_log_info *)target->data;
|
||||
unsigned int i = 0;
|
||||
|
||||
printf(" LOG");
|
||||
if (numeric)
|
||||
printf(" flags %u level %u",
|
||||
loginfo->logflags, loginfo->level);
|
||||
else {
|
||||
for (i = 0; i < ARRAY_SIZE(ip6t_log_names); ++i)
|
||||
if (loginfo->level == ip6t_log_names[i].level) {
|
||||
printf(" level %s", ip6t_log_names[i].name);
|
||||
break;
|
||||
}
|
||||
if (i == ARRAY_SIZE(ip6t_log_names))
|
||||
printf(" UNKNOWN level %u", loginfo->level);
|
||||
if (loginfo->logflags & IP6T_LOG_TCPSEQ)
|
||||
printf(" tcp-sequence");
|
||||
if (loginfo->logflags & IP6T_LOG_TCPOPT)
|
||||
printf(" tcp-options");
|
||||
if (loginfo->logflags & IP6T_LOG_IPOPT)
|
||||
printf(" ip-options");
|
||||
if (loginfo->logflags & IP6T_LOG_UID)
|
||||
printf(" uid");
|
||||
if (loginfo->logflags & IP6T_LOG_MACDECODE)
|
||||
printf(" macdecode");
|
||||
if (loginfo->logflags & ~(IP6T_LOG_MASK))
|
||||
printf(" unknown-flags");
|
||||
}
|
||||
|
||||
if (strcmp(loginfo->prefix, "") != 0)
|
||||
printf(" prefix \"%s\"", loginfo->prefix);
|
||||
}
|
||||
|
||||
static void LOG_save(const void *ip, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct ip6t_log_info *loginfo
|
||||
= (const struct ip6t_log_info *)target->data;
|
||||
|
||||
if (strcmp(loginfo->prefix, "") != 0) {
|
||||
printf(" --log-prefix");
|
||||
xtables_save_string(loginfo->prefix);
|
||||
}
|
||||
|
||||
if (loginfo->level != LOG_DEFAULT_LEVEL)
|
||||
printf(" --log-level %d", loginfo->level);
|
||||
|
||||
if (loginfo->logflags & IP6T_LOG_TCPSEQ)
|
||||
printf(" --log-tcp-sequence");
|
||||
if (loginfo->logflags & IP6T_LOG_TCPOPT)
|
||||
printf(" --log-tcp-options");
|
||||
if (loginfo->logflags & IP6T_LOG_IPOPT)
|
||||
printf(" --log-ip-options");
|
||||
if (loginfo->logflags & IP6T_LOG_UID)
|
||||
printf(" --log-uid");
|
||||
if (loginfo->logflags & IP6T_LOG_MACDECODE)
|
||||
printf(" --log-macdecode");
|
||||
}
|
||||
|
||||
static const struct ip6t_log_xlate ip6t_log_xlate_names[] = {
|
||||
{"alert", LOG_ALERT },
|
||||
{"crit", LOG_CRIT },
|
||||
{"debug", LOG_DEBUG },
|
||||
{"emerg", LOG_EMERG },
|
||||
{"err", LOG_ERR },
|
||||
{"info", LOG_INFO },
|
||||
{"notice", LOG_NOTICE },
|
||||
{"warn", LOG_WARNING }
|
||||
};
|
||||
|
||||
static int LOG_xlate(struct xt_xlate *xl,
|
||||
const struct xt_xlate_tg_params *params)
|
||||
{
|
||||
const struct ip6t_log_info *loginfo =
|
||||
(const struct ip6t_log_info *)params->target->data;
|
||||
unsigned int i = 0;
|
||||
|
||||
xt_xlate_add(xl, "log");
|
||||
if (strcmp(loginfo->prefix, "") != 0) {
|
||||
if (params->escape_quotes)
|
||||
xt_xlate_add(xl, " prefix \\\"%s\\\"", loginfo->prefix);
|
||||
else
|
||||
xt_xlate_add(xl, " prefix \"%s\"", loginfo->prefix);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ip6t_log_xlate_names); ++i)
|
||||
if (loginfo->level == ip6t_log_xlate_names[i].level &&
|
||||
loginfo->level != LOG_DEFAULT_LEVEL) {
|
||||
xt_xlate_add(xl, " level %s",
|
||||
ip6t_log_xlate_names[i].name);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((loginfo->logflags & IP6T_LOG_MASK) == IP6T_LOG_MASK) {
|
||||
xt_xlate_add(xl, " flags all");
|
||||
} else {
|
||||
if (loginfo->logflags & (IP6T_LOG_TCPSEQ | IP6T_LOG_TCPOPT)) {
|
||||
const char *delim = " ";
|
||||
|
||||
xt_xlate_add(xl, " flags tcp");
|
||||
if (loginfo->logflags & IP6T_LOG_TCPSEQ) {
|
||||
xt_xlate_add(xl, " sequence");
|
||||
delim = ",";
|
||||
}
|
||||
if (loginfo->logflags & IP6T_LOG_TCPOPT)
|
||||
xt_xlate_add(xl, "%soptions", delim);
|
||||
}
|
||||
if (loginfo->logflags & IP6T_LOG_IPOPT)
|
||||
xt_xlate_add(xl, " flags ip options");
|
||||
if (loginfo->logflags & IP6T_LOG_UID)
|
||||
xt_xlate_add(xl, " flags skuid");
|
||||
if (loginfo->logflags & IP6T_LOG_MACDECODE)
|
||||
xt_xlate_add(xl, " flags ether");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
static struct xtables_target log_tg6_reg = {
|
||||
.name = "LOG",
|
||||
.version = XTABLES_VERSION,
|
||||
.family = NFPROTO_IPV6,
|
||||
.size = XT_ALIGN(sizeof(struct ip6t_log_info)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct ip6t_log_info)),
|
||||
.help = LOG_help,
|
||||
.init = LOG_init,
|
||||
.print = LOG_print,
|
||||
.save = LOG_save,
|
||||
.x6_parse = LOG_parse,
|
||||
.x6_options = LOG_opts,
|
||||
.xlate = LOG_xlate,
|
||||
};
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_target(&log_tg6_reg);
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
: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
|
||||
@@ -1,8 +0,0 @@
|
||||
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\"
|
||||
@@ -1,188 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
|
||||
*
|
||||
* Based on Rusty Russell's IPv4 MASQUERADE 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 <limits.h> /* INT_MAX in ip_tables.h */
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
#include <linux/netfilter/nf_nat.h>
|
||||
|
||||
enum {
|
||||
O_TO_PORTS = 0,
|
||||
O_RANDOM,
|
||||
O_RANDOM_FULLY,
|
||||
};
|
||||
|
||||
static void MASQUERADE_help(void)
|
||||
{
|
||||
printf(
|
||||
"MASQUERADE target options:\n"
|
||||
" --to-ports <port>[-<port>]\n"
|
||||
" Port (range) to map to.\n"
|
||||
" --random\n"
|
||||
" Randomize source port.\n"
|
||||
" --random-fully\n"
|
||||
" Fully randomize source port.\n");
|
||||
}
|
||||
|
||||
static const struct xt_option_entry MASQUERADE_opts[] = {
|
||||
{.name = "to-ports", .id = O_TO_PORTS, .type = XTTYPE_STRING},
|
||||
{.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE},
|
||||
{.name = "random-fully", .id = O_RANDOM_FULLY, .type = XTTYPE_NONE},
|
||||
XTOPT_TABLEEND,
|
||||
};
|
||||
|
||||
/* Parses ports */
|
||||
static void
|
||||
parse_ports(const char *arg, struct nf_nat_range *r)
|
||||
{
|
||||
char *end;
|
||||
unsigned int port, maxport;
|
||||
|
||||
r->flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
|
||||
|
||||
if (!xtables_strtoui(arg, &end, &port, 0, UINT16_MAX))
|
||||
xtables_param_act(XTF_BAD_VALUE, "MASQUERADE", "--to-ports", arg);
|
||||
|
||||
switch (*end) {
|
||||
case '\0':
|
||||
r->min_proto.tcp.port
|
||||
= r->max_proto.tcp.port
|
||||
= htons(port);
|
||||
return;
|
||||
case '-':
|
||||
if (!xtables_strtoui(end + 1, NULL, &maxport, 0, UINT16_MAX))
|
||||
break;
|
||||
|
||||
if (maxport < port)
|
||||
break;
|
||||
|
||||
r->min_proto.tcp.port = htons(port);
|
||||
r->max_proto.tcp.port = htons(maxport);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
xtables_param_act(XTF_BAD_VALUE, "MASQUERADE", "--to-ports", arg);
|
||||
}
|
||||
|
||||
static void MASQUERADE_parse(struct xt_option_call *cb)
|
||||
{
|
||||
const struct ip6t_entry *entry = cb->xt_entry;
|
||||
struct nf_nat_range *r = cb->data;
|
||||
int portok;
|
||||
|
||||
if (entry->ipv6.proto == IPPROTO_TCP ||
|
||||
entry->ipv6.proto == IPPROTO_UDP ||
|
||||
entry->ipv6.proto == IPPROTO_SCTP ||
|
||||
entry->ipv6.proto == IPPROTO_DCCP ||
|
||||
entry->ipv6.proto == IPPROTO_ICMP)
|
||||
portok = 1;
|
||||
else
|
||||
portok = 0;
|
||||
|
||||
xtables_option_parse(cb);
|
||||
switch (cb->entry->id) {
|
||||
case O_TO_PORTS:
|
||||
if (!portok)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Need TCP, UDP, SCTP or DCCP with port specification");
|
||||
parse_ports(cb->arg, r);
|
||||
break;
|
||||
case O_RANDOM:
|
||||
r->flags |= NF_NAT_RANGE_PROTO_RANDOM;
|
||||
break;
|
||||
case O_RANDOM_FULLY:
|
||||
r->flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
MASQUERADE_print(const void *ip, const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
const struct nf_nat_range *r = (const void *)target->data;
|
||||
|
||||
if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
|
||||
printf(" masq ports: ");
|
||||
printf("%hu", ntohs(r->min_proto.tcp.port));
|
||||
if (r->max_proto.tcp.port != r->min_proto.tcp.port)
|
||||
printf("-%hu", ntohs(r->max_proto.tcp.port));
|
||||
}
|
||||
|
||||
if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
|
||||
printf(" random");
|
||||
|
||||
if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
|
||||
printf(" random-fully");
|
||||
}
|
||||
|
||||
static void
|
||||
MASQUERADE_save(const void *ip, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct nf_nat_range *r = (const void *)target->data;
|
||||
|
||||
if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
|
||||
printf(" --to-ports %hu", ntohs(r->min_proto.tcp.port));
|
||||
if (r->max_proto.tcp.port != r->min_proto.tcp.port)
|
||||
printf("-%hu", ntohs(r->max_proto.tcp.port));
|
||||
}
|
||||
|
||||
if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
|
||||
printf(" --random");
|
||||
|
||||
if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
|
||||
printf(" --random-fully");
|
||||
}
|
||||
|
||||
static int MASQUERADE_xlate(struct xt_xlate *xl,
|
||||
const struct xt_xlate_tg_params *params)
|
||||
{
|
||||
const struct nf_nat_range *r = (const void *)params->target->data;
|
||||
|
||||
xt_xlate_add(xl, "masquerade");
|
||||
|
||||
if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
|
||||
xt_xlate_add(xl, " to :%hu", ntohs(r->min_proto.tcp.port));
|
||||
if (r->max_proto.tcp.port != r->min_proto.tcp.port)
|
||||
xt_xlate_add(xl, "-%hu", ntohs(r->max_proto.tcp.port));
|
||||
}
|
||||
|
||||
xt_xlate_add(xl, " ");
|
||||
if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
|
||||
xt_xlate_add(xl, "random ");
|
||||
|
||||
xt_xlate_add(xl, " ");
|
||||
if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
|
||||
xt_xlate_add(xl, "random-fully ");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct xtables_target masquerade_tg_reg = {
|
||||
.name = "MASQUERADE",
|
||||
.version = XTABLES_VERSION,
|
||||
.family = NFPROTO_IPV6,
|
||||
.size = XT_ALIGN(sizeof(struct nf_nat_range)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct nf_nat_range)),
|
||||
.help = MASQUERADE_help,
|
||||
.x6_parse = MASQUERADE_parse,
|
||||
.print = MASQUERADE_print,
|
||||
.save = MASQUERADE_save,
|
||||
.x6_options = MASQUERADE_opts,
|
||||
.xlate = MASQUERADE_xlate,
|
||||
};
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_target(&masquerade_tg_reg);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
: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
|
||||
@@ -1,8 +0,0 @@
|
||||
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
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
:PREROUTING,INPUT,OUTPUT,POSTROUTING
|
||||
*nat
|
||||
-j NETMAP --to dead::/64;=;OK
|
||||
-j NETMAP --to dead::beef;=;OK
|
||||
@@ -1,170 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
|
||||
*
|
||||
* Based on Rusty Russell's IPv4 REDIRECT target. Development of IPv6 NAT
|
||||
* funded by Astaro.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <xtables.h>
|
||||
#include <limits.h> /* INT_MAX in ip_tables.h */
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
#include <linux/netfilter/nf_nat.h>
|
||||
|
||||
enum {
|
||||
O_TO_PORTS = 0,
|
||||
O_RANDOM,
|
||||
F_TO_PORTS = 1 << O_TO_PORTS,
|
||||
F_RANDOM = 1 << O_RANDOM,
|
||||
};
|
||||
|
||||
static void REDIRECT_help(void)
|
||||
{
|
||||
printf(
|
||||
"REDIRECT target options:\n"
|
||||
" --to-ports <port>[-<port>]\n"
|
||||
" Port (range) to map to.\n"
|
||||
" [--random]\n");
|
||||
}
|
||||
|
||||
static const struct xt_option_entry REDIRECT_opts[] = {
|
||||
{.name = "to-ports", .id = O_TO_PORTS, .type = XTTYPE_STRING},
|
||||
{.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE},
|
||||
XTOPT_TABLEEND,
|
||||
};
|
||||
|
||||
/* Parses ports */
|
||||
static void
|
||||
parse_ports(const char *arg, struct nf_nat_range *range)
|
||||
{
|
||||
char *end = "";
|
||||
unsigned int port, maxport;
|
||||
|
||||
range->flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
|
||||
|
||||
if (!xtables_strtoui(arg, &end, &port, 0, UINT16_MAX) &&
|
||||
(port = xtables_service_to_port(arg, NULL)) == (unsigned)-1)
|
||||
xtables_param_act(XTF_BAD_VALUE, "REDIRECT", "--to-ports", arg);
|
||||
|
||||
switch (*end) {
|
||||
case '\0':
|
||||
range->min_proto.tcp.port
|
||||
= range->max_proto.tcp.port
|
||||
= htons(port);
|
||||
return;
|
||||
case '-':
|
||||
if (!xtables_strtoui(end + 1, NULL, &maxport, 0, UINT16_MAX) &&
|
||||
(maxport = xtables_service_to_port(end + 1, NULL)) == (unsigned)-1)
|
||||
break;
|
||||
|
||||
if (maxport < port)
|
||||
break;
|
||||
|
||||
range->min_proto.tcp.port = htons(port);
|
||||
range->max_proto.tcp.port = htons(maxport);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
xtables_param_act(XTF_BAD_VALUE, "REDIRECT", "--to-ports", arg);
|
||||
}
|
||||
|
||||
static void REDIRECT_parse(struct xt_option_call *cb)
|
||||
{
|
||||
const struct ip6t_entry *entry = cb->xt_entry;
|
||||
struct nf_nat_range *range = (void *)(*cb->target)->data;
|
||||
int portok;
|
||||
|
||||
if (entry->ipv6.proto == IPPROTO_TCP
|
||||
|| entry->ipv6.proto == IPPROTO_UDP
|
||||
|| entry->ipv6.proto == IPPROTO_SCTP
|
||||
|| entry->ipv6.proto == IPPROTO_DCCP
|
||||
|| entry->ipv6.proto == IPPROTO_ICMP)
|
||||
portok = 1;
|
||||
else
|
||||
portok = 0;
|
||||
|
||||
xtables_option_parse(cb);
|
||||
switch (cb->entry->id) {
|
||||
case O_TO_PORTS:
|
||||
if (!portok)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Need TCP, UDP, SCTP or DCCP with port specification");
|
||||
parse_ports(cb->arg, range);
|
||||
if (cb->xflags & F_RANDOM)
|
||||
range->flags |= NF_NAT_RANGE_PROTO_RANDOM;
|
||||
break;
|
||||
case O_RANDOM:
|
||||
if (cb->xflags & F_TO_PORTS)
|
||||
range->flags |= NF_NAT_RANGE_PROTO_RANDOM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void REDIRECT_print(const void *ip, const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
const struct nf_nat_range *range = (const void *)target->data;
|
||||
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
|
||||
printf(" redir ports ");
|
||||
printf("%hu", ntohs(range->min_proto.tcp.port));
|
||||
if (range->max_proto.tcp.port != range->min_proto.tcp.port)
|
||||
printf("-%hu", ntohs(range->max_proto.tcp.port));
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
|
||||
printf(" random");
|
||||
}
|
||||
}
|
||||
|
||||
static void REDIRECT_save(const void *ip, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct nf_nat_range *range = (const void *)target->data;
|
||||
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
|
||||
printf(" --to-ports ");
|
||||
printf("%hu", ntohs(range->min_proto.tcp.port));
|
||||
if (range->max_proto.tcp.port != range->min_proto.tcp.port)
|
||||
printf("-%hu", ntohs(range->max_proto.tcp.port));
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
|
||||
printf(" --random");
|
||||
}
|
||||
}
|
||||
|
||||
static int REDIRECT_xlate(struct xt_xlate *xl,
|
||||
const struct xt_xlate_tg_params *params)
|
||||
{
|
||||
const struct nf_nat_range *range = (const void *)params->target->data;
|
||||
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
|
||||
xt_xlate_add(xl, "redirect to :%hu",
|
||||
ntohs(range->min_proto.tcp.port));
|
||||
if (range->max_proto.tcp.port != range->min_proto.tcp.port)
|
||||
xt_xlate_add(xl, "-%hu ",
|
||||
ntohs(range->max_proto.tcp.port));
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
|
||||
xt_xlate_add(xl, " random ");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct xtables_target redirect_tg_reg = {
|
||||
.name = "REDIRECT",
|
||||
.version = XTABLES_VERSION,
|
||||
.family = NFPROTO_IPV6,
|
||||
.size = XT_ALIGN(sizeof(struct nf_nat_range)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct nf_nat_range)),
|
||||
.help = REDIRECT_help,
|
||||
.x6_parse = REDIRECT_parse,
|
||||
.print = REDIRECT_print,
|
||||
.save = REDIRECT_save,
|
||||
.x6_options = REDIRECT_opts,
|
||||
.xlate = REDIRECT_xlate,
|
||||
};
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_target(&redirect_tg_reg);
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
:PREROUTING,OUTPUT
|
||||
*nat
|
||||
-p tcp -j REDIRECT --to-ports 42;=;OK
|
||||
-p udp -j REDIRECT --to-ports 42-1234;=;OK
|
||||
-p tcp -j REDIRECT --to-ports 42-1234 --random;=;OK
|
||||
-j REDIRECT --to-ports 42;;FAIL
|
||||
@@ -1,5 +0,0 @@
|
||||
ip6tables-translate -t nat -A prerouting -p tcp --dport 80 -j REDIRECT --to-ports 8080
|
||||
nft add rule ip6 nat prerouting tcp dport 80 counter redirect to :8080
|
||||
|
||||
ip6tables-translate -t nat -A prerouting -p tcp --dport 80 -j REDIRECT --to-ports 8080 --random
|
||||
nft add rule ip6 nat prerouting tcp dport 80 counter redirect to :8080 random
|
||||
@@ -1,185 +0,0 @@
|
||||
/* 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);
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
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
|
||||
-A INPUT ... -j REJECT
|
||||
@@ -1,11 +0,0 @@
|
||||
:INPUT,FORWARD,OUTPUT
|
||||
-j REJECT;=;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
|
||||
@@ -1,8 +0,0 @@
|
||||
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
|
||||
@@ -1,317 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
|
||||
*
|
||||
* Based on Rusty Russell's IPv4 SNAT target. Development of IPv6 NAT
|
||||
* funded by Astaro.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <xtables.h>
|
||||
#include <iptables.h>
|
||||
#include <limits.h> /* INT_MAX in ip_tables.h */
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
#include <linux/netfilter/nf_nat.h>
|
||||
|
||||
enum {
|
||||
O_TO_SRC = 0,
|
||||
O_RANDOM,
|
||||
O_RANDOM_FULLY,
|
||||
O_PERSISTENT,
|
||||
O_X_TO_SRC,
|
||||
F_TO_SRC = 1 << O_TO_SRC,
|
||||
F_RANDOM = 1 << O_RANDOM,
|
||||
F_RANDOM_FULLY = 1 << O_RANDOM_FULLY,
|
||||
F_X_TO_SRC = 1 << O_X_TO_SRC,
|
||||
};
|
||||
|
||||
static void SNAT_help(void)
|
||||
{
|
||||
printf(
|
||||
"SNAT target options:\n"
|
||||
" --to-source [<ipaddr>[-<ipaddr>]][:port[-port]]\n"
|
||||
" Address to map source to.\n"
|
||||
"[--random] [--random-fully] [--persistent]\n");
|
||||
}
|
||||
|
||||
static const struct xt_option_entry SNAT_opts[] = {
|
||||
{.name = "to-source", .id = O_TO_SRC, .type = XTTYPE_STRING,
|
||||
.flags = XTOPT_MAND | XTOPT_MULTI},
|
||||
{.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE},
|
||||
{.name = "random-fully", .id = O_RANDOM_FULLY, .type = XTTYPE_NONE},
|
||||
{.name = "persistent", .id = O_PERSISTENT, .type = XTTYPE_NONE},
|
||||
XTOPT_TABLEEND,
|
||||
};
|
||||
|
||||
/* Ranges expected in network order. */
|
||||
static void
|
||||
parse_to(const char *orig_arg, int portok, struct nf_nat_range *range)
|
||||
{
|
||||
char *arg, *start, *end = NULL, *colon = NULL, *dash, *error;
|
||||
const struct in6_addr *ip;
|
||||
|
||||
arg = strdup(orig_arg);
|
||||
if (arg == NULL)
|
||||
xtables_error(RESOURCE_PROBLEM, "strdup");
|
||||
|
||||
start = strchr(arg, '[');
|
||||
if (start == NULL) {
|
||||
start = arg;
|
||||
/* Lets assume one colon is port information. Otherwise its an IPv6 address */
|
||||
colon = strchr(arg, ':');
|
||||
if (colon && strchr(colon+1, ':'))
|
||||
colon = NULL;
|
||||
}
|
||||
else {
|
||||
start++;
|
||||
end = strchr(start, ']');
|
||||
if (end == NULL)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Invalid address format");
|
||||
|
||||
*end = '\0';
|
||||
colon = strchr(end + 1, ':');
|
||||
}
|
||||
|
||||
if (colon) {
|
||||
int port;
|
||||
|
||||
if (!portok)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Need TCP, UDP, SCTP or DCCP with port specification");
|
||||
|
||||
range->flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
|
||||
|
||||
port = atoi(colon+1);
|
||||
if (port <= 0 || port > 65535)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Port `%s' not valid\n", colon+1);
|
||||
|
||||
error = strchr(colon+1, ':');
|
||||
if (error)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Invalid port:port syntax - use dash\n");
|
||||
|
||||
dash = strchr(colon, '-');
|
||||
if (!dash) {
|
||||
range->min_proto.tcp.port
|
||||
= range->max_proto.tcp.port
|
||||
= htons(port);
|
||||
} else {
|
||||
int maxport;
|
||||
|
||||
maxport = atoi(dash + 1);
|
||||
if (maxport <= 0 || maxport > 65535)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Port `%s' not valid\n", dash+1);
|
||||
if (maxport < port)
|
||||
/* People are stupid. */
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Port range `%s' funky\n", colon+1);
|
||||
range->min_proto.tcp.port = htons(port);
|
||||
range->max_proto.tcp.port = htons(maxport);
|
||||
}
|
||||
/* Starts with colon or [] colon? No IP info...*/
|
||||
if (colon == arg || colon == arg+2) {
|
||||
free(arg);
|
||||
return;
|
||||
}
|
||||
*colon = '\0';
|
||||
}
|
||||
|
||||
range->flags |= NF_NAT_RANGE_MAP_IPS;
|
||||
dash = strchr(start, '-');
|
||||
if (colon && dash && dash > colon)
|
||||
dash = NULL;
|
||||
|
||||
if (dash)
|
||||
*dash = '\0';
|
||||
|
||||
ip = xtables_numeric_to_ip6addr(start);
|
||||
if (!ip)
|
||||
xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
|
||||
start);
|
||||
range->min_addr.in6 = *ip;
|
||||
if (dash) {
|
||||
ip = xtables_numeric_to_ip6addr(dash + 1);
|
||||
if (!ip)
|
||||
xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
|
||||
dash+1);
|
||||
range->max_addr.in6 = *ip;
|
||||
} else
|
||||
range->max_addr = range->min_addr;
|
||||
|
||||
free(arg);
|
||||
return;
|
||||
}
|
||||
|
||||
static void SNAT_parse(struct xt_option_call *cb)
|
||||
{
|
||||
const struct ip6t_entry *entry = cb->xt_entry;
|
||||
struct nf_nat_range *range = cb->data;
|
||||
int portok;
|
||||
|
||||
if (entry->ipv6.proto == IPPROTO_TCP ||
|
||||
entry->ipv6.proto == IPPROTO_UDP ||
|
||||
entry->ipv6.proto == IPPROTO_SCTP ||
|
||||
entry->ipv6.proto == IPPROTO_DCCP ||
|
||||
entry->ipv6.proto == IPPROTO_ICMP)
|
||||
portok = 1;
|
||||
else
|
||||
portok = 0;
|
||||
|
||||
xtables_option_parse(cb);
|
||||
switch (cb->entry->id) {
|
||||
case O_TO_SRC:
|
||||
if (cb->xflags & F_X_TO_SRC) {
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"SNAT: Multiple --to-source not supported");
|
||||
}
|
||||
parse_to(cb->arg, portok, range);
|
||||
cb->xflags |= F_X_TO_SRC;
|
||||
break;
|
||||
case O_PERSISTENT:
|
||||
range->flags |= NF_NAT_RANGE_PERSISTENT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void SNAT_fcheck(struct xt_fcheck_call *cb)
|
||||
{
|
||||
static const unsigned int f = F_TO_SRC | F_RANDOM;
|
||||
static const unsigned int r = F_TO_SRC | F_RANDOM_FULLY;
|
||||
struct nf_nat_range *range = cb->data;
|
||||
|
||||
if ((cb->xflags & f) == f)
|
||||
range->flags |= NF_NAT_RANGE_PROTO_RANDOM;
|
||||
if ((cb->xflags & r) == r)
|
||||
range->flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY;
|
||||
}
|
||||
|
||||
static void print_range(const struct nf_nat_range *range)
|
||||
{
|
||||
if (range->flags & NF_NAT_RANGE_MAP_IPS) {
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED)
|
||||
printf("[");
|
||||
printf("%s", xtables_ip6addr_to_numeric(&range->min_addr.in6));
|
||||
if (memcmp(&range->min_addr, &range->max_addr,
|
||||
sizeof(range->min_addr)))
|
||||
printf("-%s", xtables_ip6addr_to_numeric(&range->max_addr.in6));
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED)
|
||||
printf("]");
|
||||
}
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
|
||||
printf(":");
|
||||
printf("%hu", ntohs(range->min_proto.tcp.port));
|
||||
if (range->max_proto.tcp.port != range->min_proto.tcp.port)
|
||||
printf("-%hu", ntohs(range->max_proto.tcp.port));
|
||||
}
|
||||
}
|
||||
|
||||
static void SNAT_print(const void *ip, const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
const struct nf_nat_range *range = (const void *)target->data;
|
||||
|
||||
printf(" to:");
|
||||
print_range(range);
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
|
||||
printf(" random");
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
|
||||
printf(" random-fully");
|
||||
if (range->flags & NF_NAT_RANGE_PERSISTENT)
|
||||
printf(" persistent");
|
||||
}
|
||||
|
||||
static void SNAT_save(const void *ip, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct nf_nat_range *range = (const void *)target->data;
|
||||
|
||||
printf(" --to-source ");
|
||||
print_range(range);
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
|
||||
printf(" --random");
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
|
||||
printf(" --random-fully");
|
||||
if (range->flags & NF_NAT_RANGE_PERSISTENT)
|
||||
printf(" --persistent");
|
||||
}
|
||||
|
||||
static void print_range_xlate(const struct nf_nat_range *range,
|
||||
struct xt_xlate *xl)
|
||||
{
|
||||
bool proto_specified = range->flags & NF_NAT_RANGE_PROTO_SPECIFIED;
|
||||
|
||||
if (range->flags & NF_NAT_RANGE_MAP_IPS) {
|
||||
xt_xlate_add(xl, "%s%s%s",
|
||||
proto_specified ? "[" : "",
|
||||
xtables_ip6addr_to_numeric(&range->min_addr.in6),
|
||||
proto_specified ? "]" : "");
|
||||
|
||||
if (memcmp(&range->min_addr, &range->max_addr,
|
||||
sizeof(range->min_addr))) {
|
||||
xt_xlate_add(xl, "-%s%s%s",
|
||||
proto_specified ? "[" : "",
|
||||
xtables_ip6addr_to_numeric(&range->max_addr.in6),
|
||||
proto_specified ? "]" : "");
|
||||
}
|
||||
}
|
||||
if (proto_specified) {
|
||||
xt_xlate_add(xl, ":%hu", ntohs(range->min_proto.tcp.port));
|
||||
|
||||
if (range->max_proto.tcp.port != range->min_proto.tcp.port)
|
||||
xt_xlate_add(xl, "-%hu",
|
||||
ntohs(range->max_proto.tcp.port));
|
||||
}
|
||||
}
|
||||
|
||||
static int SNAT_xlate(struct xt_xlate *xl,
|
||||
const struct xt_xlate_tg_params *params)
|
||||
{
|
||||
const struct nf_nat_range *range = (const void *)params->target->data;
|
||||
bool sep_need = false;
|
||||
const char *sep = " ";
|
||||
|
||||
xt_xlate_add(xl, "snat to ");
|
||||
print_range_xlate(range, xl);
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_RANDOM) {
|
||||
xt_xlate_add(xl, " random");
|
||||
sep_need = true;
|
||||
}
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) {
|
||||
if (sep_need)
|
||||
sep = ",";
|
||||
xt_xlate_add(xl, "%sfully-random", sep);
|
||||
sep_need = true;
|
||||
}
|
||||
if (range->flags & NF_NAT_RANGE_PERSISTENT) {
|
||||
if (sep_need)
|
||||
sep = ",";
|
||||
xt_xlate_add(xl, "%spersistent", sep);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct xtables_target snat_tg_reg = {
|
||||
.name = "SNAT",
|
||||
.version = XTABLES_VERSION,
|
||||
.family = NFPROTO_IPV6,
|
||||
.revision = 1,
|
||||
.size = XT_ALIGN(sizeof(struct nf_nat_range)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct nf_nat_range)),
|
||||
.help = SNAT_help,
|
||||
.x6_parse = SNAT_parse,
|
||||
.x6_fcheck = SNAT_fcheck,
|
||||
.print = SNAT_print,
|
||||
.save = SNAT_save,
|
||||
.x6_options = SNAT_opts,
|
||||
.xlate = SNAT_xlate,
|
||||
};
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_target(&snat_tg_reg);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
: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
|
||||
-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
|
||||
@@ -1,11 +0,0 @@
|
||||
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
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
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.
|
||||
@@ -1,7 +0,0 @@
|
||||
: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
|
||||
@@ -1,185 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter_ipv6/ip6t_ah.h>
|
||||
|
||||
enum {
|
||||
O_AHSPI = 0,
|
||||
O_AHLEN,
|
||||
O_AHRES,
|
||||
};
|
||||
|
||||
static void ah_help(void)
|
||||
{
|
||||
printf(
|
||||
"ah match options:\n"
|
||||
"[!] --ahspi spi[:spi] match spi (range)\n"
|
||||
"[!] --ahlen length total length of this header\n"
|
||||
" --ahres check the reserved field too\n");
|
||||
}
|
||||
|
||||
#define s struct ip6t_ah
|
||||
static const struct xt_option_entry ah_opts[] = {
|
||||
{.name = "ahspi", .id = O_AHSPI, .type = XTTYPE_UINT32RC,
|
||||
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, spis)},
|
||||
{.name = "ahlen", .id = O_AHLEN, .type = XTTYPE_UINT32,
|
||||
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hdrlen)},
|
||||
{.name = "ahres", .id = O_AHRES, .type = XTTYPE_NONE},
|
||||
XTOPT_TABLEEND,
|
||||
};
|
||||
#undef s
|
||||
|
||||
static void ah_init(struct xt_entry_match *m)
|
||||
{
|
||||
struct ip6t_ah *ahinfo = (void *)m->data;
|
||||
|
||||
/* Defaults for when no --ahspi is used at all */
|
||||
ahinfo->spis[1] = ~0U;
|
||||
}
|
||||
|
||||
static void ah_parse(struct xt_option_call *cb)
|
||||
{
|
||||
struct ip6t_ah *ahinfo = cb->data;
|
||||
|
||||
xtables_option_parse(cb);
|
||||
switch (cb->entry->id) {
|
||||
case O_AHSPI:
|
||||
if (cb->nvals == 1)
|
||||
ahinfo->spis[1] = ahinfo->spis[0];
|
||||
if (cb->invert)
|
||||
ahinfo->invflags |= IP6T_AH_INV_SPI;
|
||||
break;
|
||||
case O_AHLEN:
|
||||
if (cb->invert)
|
||||
ahinfo->invflags |= IP6T_AH_INV_LEN;
|
||||
break;
|
||||
case O_AHRES:
|
||||
ahinfo->hdrres = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_spis(const char *name, uint32_t min, uint32_t max,
|
||||
int invert)
|
||||
{
|
||||
const char *inv = invert ? "!" : "";
|
||||
|
||||
if (min != 0 || max != 0xFFFFFFFF || invert) {
|
||||
if (min == max)
|
||||
printf("%s:%s%u", name, inv, min);
|
||||
else
|
||||
printf("%ss:%s%u:%u", name, inv, min, max);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_len(const char *name, uint32_t len, int invert)
|
||||
{
|
||||
const char *inv = invert ? "!" : "";
|
||||
|
||||
if (len != 0 || invert)
|
||||
printf("%s:%s%u", name, inv, len);
|
||||
}
|
||||
|
||||
static void ah_print(const void *ip, const struct xt_entry_match *match,
|
||||
int numeric)
|
||||
{
|
||||
const struct ip6t_ah *ah = (struct ip6t_ah *)match->data;
|
||||
|
||||
printf(" ah ");
|
||||
print_spis("spi", ah->spis[0], ah->spis[1],
|
||||
ah->invflags & IP6T_AH_INV_SPI);
|
||||
print_len("length", ah->hdrlen,
|
||||
ah->invflags & IP6T_AH_INV_LEN);
|
||||
|
||||
if (ah->hdrres)
|
||||
printf(" reserved");
|
||||
|
||||
if (ah->invflags & ~IP6T_AH_INV_MASK)
|
||||
printf(" Unknown invflags: 0x%X",
|
||||
ah->invflags & ~IP6T_AH_INV_MASK);
|
||||
}
|
||||
|
||||
static void ah_save(const void *ip, const struct xt_entry_match *match)
|
||||
{
|
||||
const struct ip6t_ah *ahinfo = (struct ip6t_ah *)match->data;
|
||||
|
||||
if (!(ahinfo->spis[0] == 0
|
||||
&& ahinfo->spis[1] == 0xFFFFFFFF)) {
|
||||
printf("%s --ahspi ",
|
||||
(ahinfo->invflags & IP6T_AH_INV_SPI) ? " !" : "");
|
||||
if (ahinfo->spis[0]
|
||||
!= ahinfo->spis[1])
|
||||
printf("%u:%u",
|
||||
ahinfo->spis[0],
|
||||
ahinfo->spis[1]);
|
||||
else
|
||||
printf("%u",
|
||||
ahinfo->spis[0]);
|
||||
}
|
||||
|
||||
if (ahinfo->hdrlen != 0 || (ahinfo->invflags & IP6T_AH_INV_LEN) ) {
|
||||
printf("%s --ahlen %u",
|
||||
(ahinfo->invflags & IP6T_AH_INV_LEN) ? " !" : "",
|
||||
ahinfo->hdrlen);
|
||||
}
|
||||
|
||||
if (ahinfo->hdrres != 0 )
|
||||
printf(" --ahres");
|
||||
}
|
||||
|
||||
static int ah_xlate(struct xt_xlate *xl,
|
||||
const struct xt_xlate_mt_params *params)
|
||||
{
|
||||
const struct ip6t_ah *ahinfo = (struct ip6t_ah *)params->match->data;
|
||||
char *space = "";
|
||||
|
||||
if (!(ahinfo->spis[0] == 0 && ahinfo->spis[1] == 0xFFFFFFFF)) {
|
||||
xt_xlate_add(xl, "ah spi%s ",
|
||||
(ahinfo->invflags & IP6T_AH_INV_SPI) ? " !=" : "");
|
||||
if (ahinfo->spis[0] != ahinfo->spis[1])
|
||||
xt_xlate_add(xl, "%u-%u", ahinfo->spis[0],
|
||||
ahinfo->spis[1]);
|
||||
else
|
||||
xt_xlate_add(xl, "%u", ahinfo->spis[0]);
|
||||
space = " ";
|
||||
}
|
||||
|
||||
if (ahinfo->hdrlen != 0 || (ahinfo->invflags & IP6T_AH_INV_LEN)) {
|
||||
xt_xlate_add(xl, "%sah hdrlength%s %u", space,
|
||||
(ahinfo->invflags & IP6T_AH_INV_LEN) ? " !=" : "",
|
||||
ahinfo->hdrlen);
|
||||
space = " ";
|
||||
}
|
||||
|
||||
if (ahinfo->hdrres != 0) {
|
||||
xt_xlate_add(xl, "%sah reserved %u", space, ahinfo->hdrres);
|
||||
space = " ";
|
||||
}
|
||||
|
||||
if (!space[0]) /* plain '-m ah' */
|
||||
xt_xlate_add(xl, "meta l4proto ah");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct xtables_match ah_mt6_reg = {
|
||||
.name = "ah",
|
||||
.version = XTABLES_VERSION,
|
||||
.family = NFPROTO_IPV6,
|
||||
.size = XT_ALIGN(sizeof(struct ip6t_ah)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct ip6t_ah)),
|
||||
.help = ah_help,
|
||||
.init = ah_init,
|
||||
.print = ah_print,
|
||||
.save = ah_save,
|
||||
.x6_parse = ah_parse,
|
||||
.x6_options = ah_opts,
|
||||
.xlate = ah_xlate,
|
||||
};
|
||||
|
||||
void
|
||||
_init(void)
|
||||
{
|
||||
xtables_register_match(&ah_mt6_reg);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user