Commit c2d7e04a authored by Arturo Borrero Gonzalez's avatar Arturo Borrero Gonzalez
Browse files

Update upstream source from tag 'upstream/1.8.1'

Update to upstream version '1.8.1'
with Debian dir f7eefdbc289bc01f3d8a1522cd469a3564de9051
parents 698f2511 dab1e98e
#!/bin/bash
set -e
#set -x
# ensure verbose output is identical between legacy and nft tools
RULE1='-i eth2 -o eth3 -s feed:babe::1 -d feed:babe::2 -j ACCEPT'
VOUT1='ACCEPT all opt in eth2 out eth3 feed:babe::1 -> feed:babe::2'
RULE2='-i eth2 -o eth3 -s feed:babe::4 -d feed:babe::5 -j ACCEPT'
VOUT2='ACCEPT all opt in eth2 out eth3 feed:babe::4 -> feed:babe::5'
diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI ip6tables -v -A FORWARD $RULE1)
diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI ip6tables -v -I FORWARD 2 $RULE2)
diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI ip6tables -v -C FORWARD $RULE1)
diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI ip6tables -v -C FORWARD $RULE2)
EXPECT='Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all eth2 eth3 feed:babe::1 feed:babe::2
0 0 ACCEPT all eth2 eth3 feed:babe::4 feed:babe::5
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination'
diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI ip6tables -v -n -L)
diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI ip6tables -v -D FORWARD $RULE1)
diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI ip6tables -v -D FORWARD $RULE2)
EXPECT="Flushing chain \`INPUT'
Flushing chain \`FORWARD'
Flushing chain \`OUTPUT'"
diff -u <(echo -e "$EXPECT") <($XT_MULTI ip6tables -v -F)
EXPECT="Zeroing chain \`INPUT'
Zeroing chain \`FORWARD'
Zeroing chain \`OUTPUT'"
diff -u <(echo -e "$EXPECT") <($XT_MULTI ip6tables -v -Z)
diff -u <(echo "Flushing chain \`OUTPUT'") <($XT_MULTI ip6tables -v -F OUTPUT)
diff -u <(echo "Zeroing chain \`OUTPUT'") <($XT_MULTI ip6tables -v -Z OUTPUT)
$XT_MULTI ip6tables -N foo
diff -u <(echo "Deleting chain \`foo'") <($XT_MULTI ip6tables -v -X foo)
#!/bin/bash
set -e
$XT_MULTI ip6tables -N foo
$XT_MULTI ip6tables -A FORWARD -i eth23 -o eth42 -j ACCEPT
$XT_MULTI ip6tables -A FORWARD -i eth42 -o eth23 -g foo
$XT_MULTI ip6tables -t nat -A OUTPUT -o eth123 -m mark --mark 0x42 -j ACCEPT
EXPECT='-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N foo
-A FORWARD -i eth23 -o eth42 -j ACCEPT
-A FORWARD -i eth42 -o eth23 -g foo'
diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI ip6tables -S)
EXPECT='-P INPUT ACCEPT -c 0 0
-P FORWARD ACCEPT -c 0 0
-P OUTPUT ACCEPT -c 0 0
-N foo
-A FORWARD -i eth23 -o eth42 -c 0 0 -j ACCEPT
-A FORWARD -i eth42 -o eth23 -c 0 0 -g foo'
diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI ip6tables -v -S)
EXPECT='-P FORWARD ACCEPT
-A FORWARD -i eth23 -o eth42 -j ACCEPT
-A FORWARD -i eth42 -o eth23 -g foo'
diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI ip6tables -S FORWARD)
EXPECT='-P FORWARD ACCEPT -c 0 0
-A FORWARD -i eth23 -o eth42 -c 0 0 -j ACCEPT
-A FORWARD -i eth42 -o eth23 -c 0 0 -g foo'
diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI ip6tables -v -S FORWARD)
EXPECT='-P OUTPUT ACCEPT
-A OUTPUT -o eth123 -m mark --mark 0x42 -j ACCEPT'
diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI ip6tables -t nat -S OUTPUT)
EXPECT='-P OUTPUT ACCEPT -c 0 0
-A OUTPUT -o eth123 -m mark --mark 0x42 -c 0 0 -j ACCEPT'
diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI ip6tables -v -t nat -S OUTPUT)
# some of the following commands are supposed to fail
set +e
$XT_MULTI ip6tables -S nonexistent && {
echo "list-rules in non-existent chain should fail"
exit 1
}
$XT_MULTI ip6tables -S nonexistent 23 && {
echo "list-rules in non-existent chain with given rule number should fail"
exit 1
}
$XT_MULTI ip6tables -S FORWARD 234 || {
echo "list-rules in existent chain with invalid rule number should succeed"
exit 1
}
#!/bin/sh
# make sure error return codes are as expected useful cases
# (e.g. commands to check ruleset state)
global_rc=0
cmd() { # (rc, cmd, [args ...])
rc_exp=$1; shift
$XT_MULTI "$@"
rc=$?
[ $rc -eq $rc_exp ] || {
echo "---> expected $rc_exp, got $rc for command '$@'"
global_rc=1
}
}
# test chain creation
cmd 0 ip6tables -N foo
cmd 1 ip6tables -N foo
# iptables-nft allows this - bug or feature?
#cmd 2 ip6tables -N "invalid name"
# test rule adding
cmd 0 ip6tables -A INPUT -j ACCEPT
cmd 1 ip6tables -A noexist -j ACCEPT
# test rule checking
cmd 0 ip6tables -C INPUT -j ACCEPT
cmd 1 ip6tables -C FORWARD -j ACCEPT
cmd 1 ip6tables -C nonexist -j ACCEPT
cmd 2 ip6tables -C INPUT -j foobar
cmd 2 ip6tables -C INPUT -m foobar -j ACCEPT
cmd 3 ip6tables -t foobar -C INPUT -j ACCEPT
exit $global_rc
#!/bin/bash
RET=0
tmpfile=""
set -x
clean_tempfile()
{
if [ -n "${tmpfile}" ]; then
rm -f "${tmpfile}"
fi
}
trap clean_tempfile EXIT
tmpfile=$(mktemp) || exit 1
do_simple()
{
iptables="${1}"
table="${2}"
dumpfile="$(dirname "${0}")/dumps/${iptables}.dump"
"$XT_MULTI" "${iptables}-restore" --table="${table}" <"${dumpfile}"; rv=$?
if [ "${rv}" -ne 0 ]; then
RET=1
fi
}
do_simple "iptables" "filter"
do_simple "iptables" "mangle"
do_simple "iptables" "raw"
do_simple "iptables" "nat"
do_simple "ip6tables" "filter"
do_simple "ip6tables" "mangle"
do_simple "ip6tables" "raw"
do_simple "ip6tables" "nat"
exit "${RET}"
#!/bin/sh
set -e
# make sure wait and wait-interval options are accepted
clean_tempfile()
{
if [ -n "${tmpfile}" ]; then
rm -f "${tmpfile}"
fi
}
trap clean_tempfile EXIT
tmpfile=$(mktemp) || exit 1
$XT_MULTI iptables-save -f $tmpfile
$XT_MULTI iptables-restore $tmpfile
$XT_MULTI iptables-restore -w 5 $tmpfile
$XT_MULTI iptables-restore -w 5 -W 1 $tmpfile
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [8:656]
:POSTROUTING ACCEPT [8:656]
COMMIT
*mangle
:PREROUTING ACCEPT [794:190738]
:INPUT ACCEPT [794:190738]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [991:170303]
:POSTROUTING ACCEPT [991:170303]
COMMIT
*raw
:PREROUTING ACCEPT [794:190738]
:OUTPUT ACCEPT [991:170303]
COMMIT
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [991:170303]
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p ipv6-icmp -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 137 -j REJECT --reject-with icmp6-port-unreachable
-A OUTPUT -p udp -m udp --dport 137 -j REJECT --reject-with icmp6-port-unreachable
COMMIT
*nat
:PREROUTING ACCEPT [1:89]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [351:24945]
:POSTROUTING ACCEPT [351:24945]
COMMIT
*mangle
:PREROUTING ACCEPT [3270:1513114]
:INPUT ACCEPT [3270:1513114]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [3528:1087907]
:POSTROUTING ACCEPT [3546:1090751]
COMMIT
*raw
:PREROUTING ACCEPT [3270:1513114]
:OUTPUT ACCEPT [3528:1087907]
COMMIT
*filter
:INPUT DROP [37:4057]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [3528:1087907]
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 137 -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -p udp -m udp --dport 137 -j REJECT --reject-with icmp-port-unreachable
COMMIT
#!/bin/bash
tmpfile=""
tmpfile1=""
set -x
clean_tmpfile()
{
if [ ! -z "$tmpfile" ];then
rm -f "$tmpfile"
fi
if [ ! -z "$tmpfile1" ];then
rm -f "$tmpfile1"
fi
}
trap clean_tmpfile EXIT
tmpfile=$(mktemp) || exit 1
tmpfile1=$(mktemp) || exit 1
do_diff()
{
diff -u "$1" "$2"
if [ $? -ne 0 ]; then
echo "iptables configuration is not restored" 1>&2
exit 1
else
exit 0
fi
}
$XT_MULTI iptables -N FOO || exit 1
$XT_MULTI iptables -I INPUT || exit 1
$XT_MULTI iptables -I FOO || exit 1
$XT_MULTI iptables -I FOO || exit 1
$XT_MULTI iptables-save | grep -v "^#" > "$tmpfile" || exit 1
$XT_MULTI iptables-restore < "$tmpfile" || exit 1
$XT_MULTI iptables -N BAR || exit 1
$XT_MULTI iptables -A BAR || exit 1
$XT_MULTI iptables-restore < "$tmpfile" || exit 1
$XT_MULTI iptables-save | grep -v "^#" > "$tmpfile1" || exit 1
do_diff $tmpfile1 "$tmpfile"
#!/bin/bash
set -e
tmpfile1=$(mktemp)
tmpfile2=$(mktemp)
clean_tmpfile()
{
rm -f "$tmpfile1" "$tmpfile2"
}
trap clean_tmpfile EXIT
cat > $tmpfile1<<EOF
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N FOO
-A FOO -j DROP
EOF
$XT_MULTI iptables -N FOO
$XT_MULTI iptables -A FOO -j DROP
$XT_MULTI iptables -S > $tmpfile2
diff -u $tmpfile1 $tmpfile2
rm -f $tmpfile1 $tmpfile2
#!/bin/bash
# make sure rules are not counted in references of iptables output
set -e
$XT_MULTI iptables -N foo
$XT_MULTI iptables -L | grep 'Chain foo (0 references)'
$XT_MULTI iptables -A foo -j ACCEPT
$XT_MULTI iptables -L | grep 'Chain foo (0 references)'
$XT_MULTI iptables -A FORWARD -j foo
$XT_MULTI iptables -L | grep 'Chain foo (1 references)'
#!/bin/bash
set -e
#set -x
# ensure verbose output is identical between legacy and nft tools
RULE1='-i eth2 -o eth3 -s 10.0.0.1 -d 10.0.0.2 -j ACCEPT'
VOUT1='ACCEPT all opt -- in eth2 out eth3 10.0.0.1 -> 10.0.0.2'
RULE2='-i eth2 -o eth3 -s 10.0.0.4 -d 10.0.0.5 -j ACCEPT'
VOUT2='ACCEPT all opt -- in eth2 out eth3 10.0.0.4 -> 10.0.0.5'
diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI iptables -v -A FORWARD $RULE1)
diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI iptables -v -I FORWARD 2 $RULE2)
diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI iptables -v -C FORWARD $RULE1)
diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI iptables -v -C FORWARD $RULE2)
EXPECT='Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- eth2 eth3 10.0.0.1 10.0.0.2
0 0 ACCEPT all -- eth2 eth3 10.0.0.4 10.0.0.5
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination'
diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -v -n -L)
diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI iptables -v -D FORWARD $RULE1)
diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI iptables -v -D FORWARD $RULE2)
EXPECT="Flushing chain \`INPUT'
Flushing chain \`FORWARD'
Flushing chain \`OUTPUT'"
diff -u <(echo -e "$EXPECT") <($XT_MULTI iptables -v -F)
EXPECT="Zeroing chain \`INPUT'
Zeroing chain \`FORWARD'
Zeroing chain \`OUTPUT'"
diff -u <(echo -e "$EXPECT") <($XT_MULTI iptables -v -Z)
diff -u <(echo "Flushing chain \`OUTPUT'") <($XT_MULTI iptables -v -F OUTPUT)
diff -u <(echo "Zeroing chain \`OUTPUT'") <($XT_MULTI iptables -v -Z OUTPUT)
$XT_MULTI iptables -N foo
diff -u <(echo "Deleting chain \`foo'") <($XT_MULTI iptables -v -X foo)
#!/bin/bash
set -e
$XT_MULTI iptables -N foo
$XT_MULTI iptables -A FORWARD -i eth23 -o eth42 -j ACCEPT
$XT_MULTI iptables -A FORWARD -i eth42 -o eth23 -g foo
$XT_MULTI iptables -t nat -A OUTPUT -o eth123 -m mark --mark 0x42 -j ACCEPT
EXPECT='-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N foo
-A FORWARD -i eth23 -o eth42 -j ACCEPT
-A FORWARD -i eth42 -o eth23 -g foo'
diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -S)
EXPECT='-P INPUT ACCEPT -c 0 0
-P FORWARD ACCEPT -c 0 0
-P OUTPUT ACCEPT -c 0 0
-N foo
-A FORWARD -i eth23 -o eth42 -c 0 0 -j ACCEPT
-A FORWARD -i eth42 -o eth23 -c 0 0 -g foo'
diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -v -S)
EXPECT='-P FORWARD ACCEPT
-A FORWARD -i eth23 -o eth42 -j ACCEPT
-A FORWARD -i eth42 -o eth23 -g foo'
diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -S FORWARD)
EXPECT='-P FORWARD ACCEPT -c 0 0
-A FORWARD -i eth23 -o eth42 -c 0 0 -j ACCEPT
-A FORWARD -i eth42 -o eth23 -c 0 0 -g foo'
diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -v -S FORWARD)
EXPECT='-P OUTPUT ACCEPT
-A OUTPUT -o eth123 -m mark --mark 0x42 -j ACCEPT'
diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -t nat -S OUTPUT)
EXPECT='-P OUTPUT ACCEPT -c 0 0
-A OUTPUT -o eth123 -m mark --mark 0x42 -c 0 0 -j ACCEPT'
diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -v -t nat -S OUTPUT)
# some of the following commands are supposed to fail
set +e
$XT_MULTI iptables -S nonexistent && {
echo "list-rules in non-existent chain should fail"
exit 1
}
$XT_MULTI iptables -S nonexistent 23 && {
echo "list-rules in non-existent chain with given rule number should fail"
exit 1
}
$XT_MULTI iptables -S FORWARD 234 || {
echo "list-rules in existent chain with invalid rule number should succeed"
exit 1
}
#!/bin/sh
# make sure error return codes are as expected useful cases
# (e.g. commands to check ruleset state)
global_rc=0
cmd() { # (rc, cmd, [args ...])
rc_exp=$1; shift
$XT_MULTI "$@"
rc=$?
[ $rc -eq $rc_exp ] || {
echo "---> expected $rc_exp, got $rc for command '$@'"
global_rc=1
}
}
# test chain creation
cmd 0 iptables -N foo
cmd 1 iptables -N foo
# iptables-nft allows this - bug or feature?
#cmd 2 iptables -N "invalid name"
# test rule adding
cmd 0 iptables -A INPUT -j ACCEPT
cmd 1 iptables -A noexist -j ACCEPT
# test rule checking
cmd 0 iptables -C INPUT -j ACCEPT
cmd 1 iptables -C FORWARD -j ACCEPT
cmd 1 iptables -C nonexist -j ACCEPT
cmd 2 iptables -C INPUT -j foobar
cmd 2 iptables -C INPUT -m foobar -j ACCEPT
cmd 3 iptables -t foobar -C INPUT -j ACCEPT
exit $global_rc
#!/bin/sh
# test case for bug fixed in
# commit 873c5d5d293991ee3c06aed2b1dfc5764872582f (HEAD -> master)
# xtables: avoid bogus 'is incompatible' warning
case "$XT_MULTI" in
*/xtables-nft-multi)
nft -v >/dev/null || exit 0
nft 'add table ip nft-test; add chain ip nft-test foobar { type filter hook forward priority 42; }' || exit 1
nft 'add table ip6 nft-test; add chain ip6 nft-test foobar { type filter hook forward priority 42; }' || exit 1
$XT_MULTI iptables -L -t filter || exit 1
$XT_MULTI ip6tables -L -t filter || exit 1
;;
*)
echo skip $XT_MULTI
;;
esac
exit 0
#!/bin/sh
set -e
[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; }
$XT_MULTI iptables -A INPUT -p tcp --dport 53 ! -s 192.168.0.1 -j ACCEPT
$XT_MULTI ip6tables -A INPUT -p tcp --dport 53 ! -s feed:babe::1 -j ACCEPT
$XT_MULTI ebtables -A INPUT -p IPv4 --ip-src 10.0.0.1 ! -i lo -j ACCEPT
#!/bin/bash
set -e
[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; }
comment1="foo bar"
comment2="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
for ipt in iptables ip6tables; do
for comment in "$comment1" "$comment2"; do
$XT_MULTI $ipt -A INPUT -m comment --comment "$comment" -j ACCEPT
$XT_MULTI $ipt -D INPUT -m comment --comment "$comment" -j ACCEPT
done
done
#include <config.h> #include <config.h>
#include <ctype.h>
#include <getopt.h> #include <getopt.h>
#include <errno.h> #include <errno.h>
#include <libgen.h> #include <libgen.h>
...@@ -359,9 +360,337 @@ void parse_wait_interval(int argc, char *argv[], struct timeval *wait_interval) ...@@ -359,9 +360,337 @@ void parse_wait_interval(int argc, char *argv[], struct timeval *wait_interval)
xtables_error(PARAMETER_PROBLEM, "wait interval not numeric"); xtables_error(PARAMETER_PROBLEM, "wait interval not numeric");
} }
int parse_counters(const char *string, struct xt_counters *ctr)
{
int ret;
if (!string)
return 0;
ret = sscanf(string, "[%llu:%llu]",
(unsigned long long *)&ctr->pcnt,
(unsigned long long *)&ctr->bcnt);
return ret == 2;
}
inline bool xs_has_arg(int argc, char *argv[]) inline bool xs_has_arg(int argc, char *argv[])
{ {
return optind < argc && return optind < argc &&
argv[optind][0] != '-' && argv[optind][0] != '-' &&
argv[optind][0] != '!'; argv[optind][0] != '!';
} }
/* global new argv and argc */
char *newargv[255];
int newargc = 0;
/* saved newargv and newargc from save_argv() */
char *oldargv[255];
int oldargc = 0;
/* arg meta data, were they quoted, frinstance */
int newargvattr[255];
/* function adding one argument to newargv, updating newargc
* returns true if argument added, false otherwise */
int add_argv(const char *what, int quoted)
{
DEBUGP("add_argv: %s\n", what);
if (what && newargc + 1 < ARRAY_SIZE(newargv)) {
newargv[newargc] = strdup(what);
newargvattr[newargc] = quoted;
newargv[++newargc] = NULL;
return 1;
} else {
xtables_error(PARAMETER_PROBLEM,
"Parser cannot handle more arguments\n");
}
}
void free_argv(void)
{
while (newargc)
free(newargv[--newargc]);
while (oldargc)
free(oldargv[--oldargc]);
}
/* Save parsed rule for comparison with next rule to perform action aggregation
* on duplicate conditions.
*/
void save_argv(void)
{
unsigned int i;
while (oldargc)
free(oldargv[--oldargc]);
oldargc = newargc;
newargc = 0;
for (i = 0; i < oldargc; i++) {
oldargv[i] = newargv[i];
}
}
void add_param_to_argv(char *parsestart, int line)
{
int quote_open = 0, escaped = 0, param_len = 0;
char param_buffer[1024], *curchar;
/* After fighting with strtok enough, here's now
* a 'real' parser. According to Rusty I'm now no
* longer a real hacker, but I can live with that */
for (curchar = parsestart; *curchar; curchar++) {
if (quote_open) {
if (escaped) {
param_buffer[param_len++] = *curchar;
escaped = 0;
continue;
} else if (*curchar == '\\') {
escaped = 1;
continue;
} else if (*curchar == '"') {
quote_open = 0;
*curchar = '"';
} else {
param_buffer[param_len++] = *curchar;
continue;
}
} else {
if (*curchar == '"') {
quote_open = 1;
continue;
}
}
switch (*curchar) {
case '"':
break;
case ' ':
case '\t':
case '\n':
if (!param_len) {
/* two spaces? */
continue;
}
break;
default:
/* regular character, copy to buffer */
param_buffer[param_len++] = *curchar;
if (param_len >= sizeof(param_buffer))
xtables_error(PARAMETER_PROBLEM,
"Parameter too long!");
continue;
}
param_buffer[param_len] = '\0';
/* check if table name specified */
if ((param_buffer[0] == '-' &&
param_buffer[1] != '-' &&
strchr(param_buffer, 't')) ||
(!strncmp(param_buffer, "--t", 3) &&
!strncmp(param_buffer, "--table", strlen(param_buffer)))) {
xtables_error(PARAMETER_PROBLEM,
"The -t option (seen in line %u) cannot be used in %s.\n",
line, xt_params->program_name);
}
add_argv(param_buffer, 0);
param_len = 0;
}
}
static const char *ipv4_addr_to_string(const struct in_addr *addr,
const struct in_addr *mask,
unsigned int format)
{
static char buf[BUFSIZ];
if (!mask->s_addr && !(format & FMT_NUMERIC))
return "anywhere";
if (format & FMT_NUMERIC)
strncpy(buf, xtables_ipaddr_to_numeric(addr), BUFSIZ - 1);
else
strncpy(buf, xtables_ipaddr_to_anyname(addr), BUFSIZ - 1);
buf[BUFSIZ - 1] = '\0';
strncat(buf, xtables_ipmask_to_numeric(mask),
BUFSIZ - strlen(buf) - 1);
return buf;
}
void print_ipv4_addresses(const struct ipt_entry *fw, unsigned int format)
{
fputc(fw->ip.invflags & IPT_INV_SRCIP ? '!' : ' ', stdout);
printf(FMT("%-19s ", "%s "),
ipv4_addr_to_string(&fw->ip.src, &fw->ip.smsk, format));
fputc(fw->ip.invflags & IPT_INV_DSTIP ? '!' : ' ', stdout);
printf(FMT("%-19s ", "-> %s"),
ipv4_addr_to_string(&fw->ip.dst, &fw->ip.dmsk, format));
}
static const char *ipv6_addr_to_string(const struct in6_addr *addr,
const struct in6_addr *mask,
unsigned int format)
{
static char buf[BUFSIZ];
if (IN6_IS_ADDR_UNSPECIFIED(addr) && !(format & FMT_NUMERIC))
return "anywhere";
if (format & FMT_NUMERIC)
strncpy(buf, xtables_ip6addr_to_numeric(addr), BUFSIZ - 1);
else
strncpy(buf, xtables_ip6addr_to_anyname(addr), BUFSIZ - 1);
buf[BUFSIZ - 1] = '\0';
strncat(buf, xtables_ip6mask_to_numeric(mask),
BUFSIZ - strlen(buf) - 1);
return buf;
}
void print_ipv6_addresses(const struct ip6t_entry *fw6, unsigned int format)
{
fputc(fw6->ipv6.invflags & IP6T_INV_SRCIP ? '!' : ' ', stdout);
printf(FMT("%-19s ", "%s "),
ipv6_addr_to_string(&fw6->ipv6.src,
&fw6->ipv6.smsk, format));
fputc(fw6->ipv6.invflags & IP6T_INV_DSTIP ? '!' : ' ', stdout);
printf(FMT("%-19s ", "-> %s"),
ipv6_addr_to_string(&fw6->ipv6.dst,
&fw6->ipv6.dmsk, format));
}
/* Luckily, IPT_INV_VIA_IN and IPT_INV_VIA_OUT
* have the same values as IP6T_INV_VIA_IN and IP6T_INV_VIA_OUT
* so this function serves for both iptables and ip6tables */
void print_ifaces(const char *iniface, const char *outiface, uint8_t invflags,
unsigned int format)
{
const char *anyname = format & FMT_NUMERIC ? "*" : "any";
char iface[IFNAMSIZ + 2];
if (!(format & FMT_VIA))
return;
snprintf(iface, IFNAMSIZ + 2, "%s%s",
invflags & IPT_INV_VIA_IN ? "!" : "",
iniface[0] != '\0' ? iniface : anyname);
printf(FMT(" %-6s ", "in %s "), iface);
snprintf(iface, IFNAMSIZ + 2, "%s%s",
invflags & IPT_INV_VIA_OUT ? "!" : "",
outiface[0] != '\0' ? outiface : anyname);
printf(FMT("%-6s ", "out %s "), iface);
}
void command_match(struct iptables_command_state *cs)
{
struct option *opts = xt_params->opts;
struct xtables_match *m;
size_t size;
if (cs->invert)
xtables_error(PARAMETER_PROBLEM,
"unexpected ! flag before --match");
m = xtables_find_match(optarg, XTF_LOAD_MUST_SUCCEED, &cs->matches);
size = XT_ALIGN(sizeof(struct xt_entry_match)) + m->size;
m->m = xtables_calloc(1, size);
m->m->u.match_size = size;
if (m->real_name == NULL) {
strcpy(m->m->u.user.name, m->name);
} else {
strcpy(m->m->u.user.name, m->real_name);
if (!(m->ext_flags & XTABLES_EXT_ALIAS))
fprintf(stderr, "Notice: the %s match is converted into %s match "
"in rule listing and saving.\n", m->name, m->real_name);
}
m->m->u.user.revision = m->revision;
xs_init_match(m);
if (m == m->next)
return;
/* Merge options for non-cloned matches */
if (m->x6_options != NULL)
opts = xtables_options_xfrm(xt_params->orig_opts, opts,
m->x6_options, &m->option_offset);
else if (m->extra_opts != NULL)
opts = xtables_merge_options(xt_params->orig_opts, opts,
m->extra_opts, &m->option_offset);
if (opts == NULL)
xtables_error(OTHER_PROBLEM, "can't alloc memory!");
xt_params->opts = opts;
}
const char *xt_parse_target(const char *targetname)
{
const char *ptr;
if (strlen(targetname) < 1)
xtables_error(PARAMETER_PROBLEM,
"Invalid target name (too short)");
if (strlen(targetname) >= XT_EXTENSION_MAXNAMELEN)
xtables_error(PARAMETER_PROBLEM,
"Invalid target name `%s' (%u chars max)",
targetname, XT_EXTENSION_MAXNAMELEN - 1);
for (ptr = targetname; *ptr; ptr++)
if (isspace(*ptr))
xtables_error(PARAMETER_PROBLEM,
"Invalid target name `%s'", targetname);
return targetname;
}
void command_jump(struct iptables_command_state *cs)
{
struct option *opts = xt_params->opts;
size_t size;
cs->jumpto = xt_parse_target(optarg);
/* TRY_LOAD (may be chain name) */
cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
if (cs->target == NULL)
return;
size = XT_ALIGN(sizeof(struct xt_entry_target)) + cs->target->size;
cs->target->t = xtables_calloc(1, size);
cs->target->t->u.target_size = size;
if (cs->target->real_name == NULL) {
strcpy(cs->target->t->u.user.name, cs->jumpto);
} else {
/* Alias support for userspace side */
strcpy(cs->target->t->u.user.name, cs->target->real_name);
if (!(cs->target->ext_flags & XTABLES_EXT_ALIAS))
fprintf(stderr, "Notice: The %s target is converted into %s target "
"in rule listing and saving.\n",
cs->jumpto, cs->target->real_name);
}
cs->target->t->u.user.revision = cs->target->revision;
xs_init_target(cs->target);
if (cs->target->x6_options != NULL)
opts = xtables_options_xfrm(xt_params->orig_opts, opts,
cs->target->x6_options,
&cs->target->option_offset);
else
opts = xtables_merge_options(xt_params->orig_opts, opts,
cs->target->extra_opts,
&cs->target->option_offset);
if (opts == NULL)
xtables_error(OTHER_PROBLEM, "can't alloc memory!");
xt_params->opts = opts;
}
...@@ -6,9 +6,16 @@ ...@@ -6,9 +6,16 @@
#include <stdint.h> #include <stdint.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <net/if.h> #include <net/if.h>
#include <linux/netfilter_arp/arp_tables.h>
#include <linux/netfilter_ipv4/ip_tables.h> #include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h> #include <linux/netfilter_ipv6/ip6_tables.h>
#ifdef DEBUG
#define DEBUGP(x, args...) fprintf(stdout, x, ## args)
#else
#define DEBUGP(x, args...)
#endif
enum { enum {
OPT_NONE = 0, OPT_NONE = 0,
OPT_NUMERIC = 1 << 0, OPT_NUMERIC = 1 << 0,
...@@ -83,6 +90,7 @@ struct iptables_command_state { ...@@ -83,6 +90,7 @@ struct iptables_command_state {
struct ebt_entry eb; struct ebt_entry eb;
struct ipt_entry fw; struct ipt_entry fw;
struct ip6t_entry fw6; struct ip6t_entry fw6;
struct arpt_entry arp;
}; };
int invert; int invert;
int c; int c;
...@@ -142,8 +150,32 @@ extern int xtables_lock_or_exit(int wait, struct timeval *tv); ...@@ -142,8 +150,32 @@ extern int xtables_lock_or_exit(int wait, struct timeval *tv);
int parse_wait_time(int argc, char *argv[]); int parse_wait_time(int argc, char *argv[]);
void parse_wait_interval(int argc, char *argv[], struct timeval *wait_interval); void parse_wait_interval(int argc, char *argv[], struct timeval *wait_interval);
int parse_counters(const char *string, struct xt_counters *ctr);
bool xs_has_arg(int argc, char *argv[]); bool xs_has_arg(int argc, char *argv[]);
extern const struct xtables_afinfo *afinfo; extern const struct xtables_afinfo *afinfo;
extern char *newargv[];
extern int newargc;
extern char *oldargv[];
extern int oldargc;
extern int newargvattr[];
int add_argv(const char *what, int quoted);
void free_argv(void);
void save_argv(void);
void add_param_to_argv(char *parsestart, int line);
void print_ipv4_addresses(const struct ipt_entry *fw, unsigned int format);
void print_ipv6_addresses(const struct ip6t_entry *fw6, unsigned int format);
void print_ifaces(const char *iniface, const char *outiface, uint8_t invflags,
unsigned int format);
void command_match(struct iptables_command_state *cs);
const char *xt_parse_target(const char *targetname);
void command_jump(struct iptables_command_state *cs);
#endif /* IPTABLES_XSHARED_H */ #endif /* IPTABLES_XSHARED_H */
...@@ -47,24 +47,11 @@ int xtables_arp_main(int argc, char *argv[]) ...@@ -47,24 +47,11 @@ int xtables_arp_main(int argc, char *argv[])
{ {
int ret; int ret;
char *table = "filter"; char *table = "filter";
struct nft_handle h = { struct nft_handle h;
.family = NFPROTO_ARP,
};
arptables_globals.program_name = "arptables"; nft_init_arp(&h, "arptables");
ret = xtables_init_all(&arptables_globals, NFPROTO_ARP);
if (ret < 0) {
fprintf(stderr, "%s/%s Failed to initialize arptables-compat\n",
arptables_globals.program_name,
arptables_globals.program_version);
exit(1);
}
#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS) ret = do_commandarp(&h, argc, argv, &table, false);
init_extensionsa();
#endif
ret = do_commandarp(&h, argc, argv, &table);
if (ret) if (ret)
ret = nft_commit(&h); ret = nft_commit(&h);
......
...@@ -149,8 +149,7 @@ static struct option original_opts[] = { ...@@ -149,8 +149,7 @@ static struct option original_opts[] = {
int RUNTIME_NF_ARP_NUMHOOKS = 3; int RUNTIME_NF_ARP_NUMHOOKS = 3;
static struct option *opts = original_opts; #define opts xt_params->opts
static unsigned int global_option_offset;
extern void xtables_exit_error(enum xtables_exittype status, const char *msg, ...) __attribute__((noreturn, format(printf,2,3))); extern void xtables_exit_error(enum xtables_exittype status, const char *msg, ...) __attribute__((noreturn, format(printf,2,3)));
struct xtables_globals arptables_globals = { struct xtables_globals arptables_globals = {
...@@ -588,16 +587,15 @@ static struct in_addr * ...@@ -588,16 +587,15 @@ static struct in_addr *
host_to_addr(const char *name, unsigned int *naddr) host_to_addr(const char *name, unsigned int *naddr)
{ {
struct in_addr *addr; struct in_addr *addr;
struct addrinfo hints; struct addrinfo hints = {
.ai_flags = AI_CANONNAME,
.ai_family = AF_INET,
.ai_socktype = SOCK_RAW,
};;
struct addrinfo *res, *p; struct addrinfo *res, *p;
int err; int err;
unsigned int i; unsigned int i;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_RAW;
*naddr = 0; *naddr = 0;
err = getaddrinfo(name, NULL, &hints, &res); err = getaddrinfo(name, NULL, &hints, &res);
if (err != 0) if (err != 0)
...@@ -757,27 +755,6 @@ parse_rulenumber(const char *rule) ...@@ -757,27 +755,6 @@ parse_rulenumber(const char *rule)
return rulenum; return rulenum;
} }
static const char *
parse_target(const char *targetname)
{
const char *ptr;
if (strlen(targetname) < 1)
xtables_error(PARAMETER_PROBLEM,
"Invalid target name (too short)");
if (strlen(targetname)+1 > sizeof(arpt_chainlabel))
xtables_error(PARAMETER_PROBLEM,
"Invalid target name `%s' (%zu chars max)",
targetname, sizeof(arpt_chainlabel)-1);
for (ptr = targetname; *ptr; ptr++)
if (isspace(*ptr))
xtables_error(PARAMETER_PROBLEM,
"Invalid target name `%s'", targetname);
return targetname;
}
static void static void
set_option(unsigned int *options, unsigned int option, u_int16_t *invflg, set_option(unsigned int *options, unsigned int option, u_int16_t *invflg,
int invert) int invert)
...@@ -824,46 +801,11 @@ list_entries(struct nft_handle *h, const char *chain, const char *table, ...@@ -824,46 +801,11 @@ list_entries(struct nft_handle *h, const char *chain, const char *table,
return nft_rule_list(h, chain, table, rulenum, format); return nft_rule_list(h, chain, table, rulenum, format);
} }
static struct xtables_target *command_jump(struct arpt_entry *fw,
const char *jumpto)
{
struct xtables_target *target;
size_t size;
/* XTF_TRY_LOAD (may be chain name) */
target = xtables_find_target(jumpto, XTF_TRY_LOAD);
if (!target)
return NULL;
size = XT_ALIGN(sizeof(struct xt_entry_target))
+ target->size;
target->t = xtables_calloc(1, size);
target->t->u.target_size = size;
strncpy(target->t->u.user.name, jumpto, sizeof(target->t->u.user.name) - 1);
target->t->u.user.name[sizeof(target->t->u.user.name)-1] = '\0';
target->t->u.user.revision = target->revision;
xs_init_target(target);
if (target->x6_options != NULL)
opts = xtables_options_xfrm(arptables_globals.orig_opts,
opts, target->x6_options,
&target->option_offset);
else
opts = xtables_merge_options(arptables_globals.orig_opts,
opts, target->extra_opts,
&target->option_offset);
return target;
}
static int static int
append_entry(struct nft_handle *h, append_entry(struct nft_handle *h,
const char *chain, const char *chain,
const char *table, const char *table,
struct arptables_command_state *cs, struct iptables_command_state *cs,
int rulenum, int rulenum,
unsigned int nsaddrs, unsigned int nsaddrs,
const struct in_addr saddrs[], const struct in_addr saddrs[],
...@@ -875,9 +817,9 @@ append_entry(struct nft_handle *h, ...@@ -875,9 +817,9 @@ append_entry(struct nft_handle *h,
int ret = 1; int ret = 1;
for (i = 0; i < nsaddrs; i++) { for (i = 0; i < nsaddrs; i++) {
cs->fw.arp.src.s_addr = saddrs[i].s_addr; cs->arp.arp.src.s_addr = saddrs[i].s_addr;
for (j = 0; j < ndaddrs; j++) { for (j = 0; j < ndaddrs; j++) {
cs->fw.arp.tgt.s_addr = daddrs[j].s_addr; cs->arp.arp.tgt.s_addr = daddrs[j].s_addr;
if (append) { if (append) {
ret = nft_rule_append(h, chain, table, cs, 0, ret = nft_rule_append(h, chain, table, cs, 0,
verbose); verbose);
...@@ -894,14 +836,14 @@ append_entry(struct nft_handle *h, ...@@ -894,14 +836,14 @@ append_entry(struct nft_handle *h,
static int static int
replace_entry(const char *chain, replace_entry(const char *chain,
const char *table, const char *table,
struct arptables_command_state *cs, struct iptables_command_state *cs,
unsigned int rulenum, unsigned int rulenum,
const struct in_addr *saddr, const struct in_addr *saddr,
const struct in_addr *daddr, const struct in_addr *daddr,
bool verbose, struct nft_handle *h) bool verbose, struct nft_handle *h)
{ {
cs->fw.arp.src.s_addr = saddr->s_addr; cs->arp.arp.src.s_addr = saddr->s_addr;
cs->fw.arp.tgt.s_addr = daddr->s_addr; cs->arp.arp.tgt.s_addr = daddr->s_addr;
return nft_rule_replace(h, chain, table, cs, rulenum, verbose); return nft_rule_replace(h, chain, table, cs, rulenum, verbose);
} }
...@@ -909,7 +851,7 @@ replace_entry(const char *chain, ...@@ -909,7 +851,7 @@ replace_entry(const char *chain,
static int static int
delete_entry(const char *chain, delete_entry(const char *chain,
const char *table, const char *table,
struct arptables_command_state *cs, struct iptables_command_state *cs,
unsigned int nsaddrs, unsigned int nsaddrs,
const struct in_addr saddrs[], const struct in_addr saddrs[],
unsigned int ndaddrs, unsigned int ndaddrs,
...@@ -920,9 +862,9 @@ delete_entry(const char *chain, ...@@ -920,9 +862,9 @@ delete_entry(const char *chain,
int ret = 1; int ret = 1;
for (i = 0; i < nsaddrs; i++) { for (i = 0; i < nsaddrs; i++) {
cs->fw.arp.src.s_addr = saddrs[i].s_addr; cs->arp.arp.src.s_addr = saddrs[i].s_addr;
for (j = 0; j < ndaddrs; j++) { for (j = 0; j < ndaddrs; j++) {
cs->fw.arp.tgt.s_addr = daddrs[j].s_addr; cs->arp.arp.tgt.s_addr = daddrs[j].s_addr;
ret = nft_rule_delete(h, chain, table, cs, verbose); ret = nft_rule_delete(h, chain, table, cs, verbose);
} }
} }
...@@ -930,9 +872,40 @@ delete_entry(const char *chain, ...@@ -930,9 +872,40 @@ delete_entry(const char *chain,
return ret; return ret;
} }
int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table) int nft_init_arp(struct nft_handle *h, const char *pname)
{
arptables_globals.program_name = pname;
if (xtables_init_all(&arptables_globals, NFPROTO_ARP) < 0) {
fprintf(stderr, "%s/%s Failed to initialize arptables-compat\n",
arptables_globals.program_name,
arptables_globals.program_version);
exit(1);
}
#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
init_extensionsa();
#endif
memset(h, 0, sizeof(*h));
h->family = NFPROTO_ARP;
if (nft_init(h, xtables_arp) < 0)
xtables_error(OTHER_PROBLEM,
"Could not initialize nftables layer.");
h->ops = nft_family_ops_lookup(h->family);
if (h->ops == NULL)
xtables_error(PARAMETER_PROBLEM, "Unknown family");
return 0;
}
int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
bool restore)
{ {
struct arptables_command_state cs; struct iptables_command_state cs = {
.jumpto = "",
};
int invert = 0; int invert = 0;
unsigned int nsaddrs = 0, ndaddrs = 0; unsigned int nsaddrs = 0, ndaddrs = 0;
struct in_addr *saddrs = NULL, *daddrs = NULL; struct in_addr *saddrs = NULL, *daddrs = NULL;
...@@ -946,14 +919,6 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table) ...@@ -946,14 +919,6 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
int ret = 1; int ret = 1;
struct xtables_target *t; struct xtables_target *t;
memset(&cs, 0, sizeof(cs));
cs.jumpto = "";
opts = original_opts;
global_option_offset = 0;
xtables_globals.orig_opts = original_opts;
/* re-set optind to 0 in case do_command gets called /* re-set optind to 0 in case do_command gets called
* a second time */ * a second time */
optind = 0; optind = 0;
...@@ -967,6 +932,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table) ...@@ -967,6 +932,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
demand-load a protocol. */ demand-load a protocol. */
opterr = 0; opterr = 0;
opts = xt_params->orig_opts;
while ((c = getopt_long(argc, argv, while ((c = getopt_long(argc, argv,
"-A:D:R:I:L::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:l:i:vnt:m:c:", "-A:D:R:I:L::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:l:i:vnt:m:c:",
opts, NULL)) != -1) { opts, NULL)) != -1) {
...@@ -1090,47 +1056,47 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table) ...@@ -1090,47 +1056,47 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
break; break;
case 's': case 's':
check_inverse(optarg, &invert, &optind, argc); check_inverse(optarg, &invert, &optind, argc);
set_option(&options, OPT_S_IP, &cs.fw.arp.invflags, set_option(&options, OPT_S_IP, &cs.arp.arp.invflags,
invert); invert);
shostnetworkmask = argv[optind-1]; shostnetworkmask = argv[optind-1];
break; break;
case 'd': case 'd':
check_inverse(optarg, &invert, &optind, argc); check_inverse(optarg, &invert, &optind, argc);
set_option(&options, OPT_D_IP, &cs.fw.arp.invflags, set_option(&options, OPT_D_IP, &cs.arp.arp.invflags,
invert); invert);
dhostnetworkmask = argv[optind-1]; dhostnetworkmask = argv[optind-1];
break; break;
case 2:/* src-mac */ case 2:/* src-mac */
check_inverse(optarg, &invert, &optind, argc); check_inverse(optarg, &invert, &optind, argc);
set_option(&options, OPT_S_MAC, &cs.fw.arp.invflags, set_option(&options, OPT_S_MAC, &cs.arp.arp.invflags,
invert); invert);
if (getmac_and_mask(argv[optind - 1], if (getmac_and_mask(argv[optind - 1],
cs.fw.arp.src_devaddr.addr, cs.fw.arp.src_devaddr.mask)) cs.arp.arp.src_devaddr.addr, cs.arp.arp.src_devaddr.mask))
xtables_error(PARAMETER_PROBLEM, "Problem with specified " xtables_error(PARAMETER_PROBLEM, "Problem with specified "
"source mac"); "source mac");
break; break;
case 3:/* dst-mac */ case 3:/* dst-mac */
check_inverse(optarg, &invert, &optind, argc); check_inverse(optarg, &invert, &optind, argc);
set_option(&options, OPT_D_MAC, &cs.fw.arp.invflags, set_option(&options, OPT_D_MAC, &cs.arp.arp.invflags,
invert); invert);
if (getmac_and_mask(argv[optind - 1], if (getmac_and_mask(argv[optind - 1],
cs.fw.arp.tgt_devaddr.addr, cs.fw.arp.tgt_devaddr.mask)) cs.arp.arp.tgt_devaddr.addr, cs.arp.arp.tgt_devaddr.mask))
xtables_error(PARAMETER_PROBLEM, "Problem with specified " xtables_error(PARAMETER_PROBLEM, "Problem with specified "
"destination mac"); "destination mac");
break; break;
case 'l':/* hardware length */ case 'l':/* hardware length */
check_inverse(optarg, &invert, &optind, argc); check_inverse(optarg, &invert, &optind, argc);
set_option(&options, OPT_H_LENGTH, &cs.fw.arp.invflags, set_option(&options, OPT_H_LENGTH, &cs.arp.arp.invflags,
invert); invert);
getlength_and_mask(argv[optind - 1], &cs.fw.arp.arhln, getlength_and_mask(argv[optind - 1], &cs.arp.arp.arhln,
&cs.fw.arp.arhln_mask); &cs.arp.arp.arhln_mask);
if (cs.fw.arp.arhln != 6) { if (cs.arp.arp.arhln != 6) {
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"Only harware address length of" "Only harware address length of"
" 6 is supported currently."); " 6 is supported currently.");
...@@ -1142,20 +1108,20 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table) ...@@ -1142,20 +1108,20 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
xtables_error(PARAMETER_PROBLEM, "not supported"); xtables_error(PARAMETER_PROBLEM, "not supported");
/* /*
check_inverse(optarg, &invert, &optind, argc); check_inverse(optarg, &invert, &optind, argc);
set_option(&options, OPT_P_LENGTH, &cs.fw.arp.invflags, set_option(&options, OPT_P_LENGTH, &cs.arp.arp.invflags,
invert); invert);
getlength_and_mask(argv[optind - 1], &cs.fw.arp.arpln, getlength_and_mask(argv[optind - 1], &cs.arp.arp.arpln,
&cs.fw.arp.arpln_mask); &cs.arp.arp.arpln_mask);
break; break;
*/ */
case 4:/* opcode */ case 4:/* opcode */
check_inverse(optarg, &invert, &optind, argc); check_inverse(optarg, &invert, &optind, argc);
set_option(&options, OPT_OPCODE, &cs.fw.arp.invflags, set_option(&options, OPT_OPCODE, &cs.arp.arp.invflags,
invert); invert);
if (get16_and_mask(argv[optind - 1], &cs.fw.arp.arpop, if (get16_and_mask(argv[optind - 1], &cs.arp.arp.arpop,
&cs.fw.arp.arpop_mask, 10)) { &cs.arp.arp.arpop_mask, 10)) {
int i; int i;
for (i = 0; i < NUMOPCODES; i++) for (i = 0; i < NUMOPCODES; i++)
...@@ -1163,65 +1129,64 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table) ...@@ -1163,65 +1129,64 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
break; break;
if (i == NUMOPCODES) if (i == NUMOPCODES)
xtables_error(PARAMETER_PROBLEM, "Problem with specified opcode"); xtables_error(PARAMETER_PROBLEM, "Problem with specified opcode");
cs.fw.arp.arpop = htons(i+1); cs.arp.arp.arpop = htons(i+1);
} }
break; break;
case 5:/* h-type */ case 5:/* h-type */
check_inverse(optarg, &invert, &optind, argc); check_inverse(optarg, &invert, &optind, argc);
set_option(&options, OPT_H_TYPE, &cs.fw.arp.invflags, set_option(&options, OPT_H_TYPE, &cs.arp.arp.invflags,
invert); invert);
if (get16_and_mask(argv[optind - 1], &cs.fw.arp.arhrd, if (get16_and_mask(argv[optind - 1], &cs.arp.arp.arhrd,
&cs.fw.arp.arhrd_mask, 16)) { &cs.arp.arp.arhrd_mask, 16)) {
if (strcasecmp(argv[optind-1], "Ethernet")) if (strcasecmp(argv[optind-1], "Ethernet"))
xtables_error(PARAMETER_PROBLEM, "Problem with specified hardware type"); xtables_error(PARAMETER_PROBLEM, "Problem with specified hardware type");
cs.fw.arp.arhrd = htons(1); cs.arp.arp.arhrd = htons(1);
} }
break; break;
case 6:/* proto-type */ case 6:/* proto-type */
check_inverse(optarg, &invert, &optind, argc); check_inverse(optarg, &invert, &optind, argc);
set_option(&options, OPT_P_TYPE, &cs.fw.arp.invflags, set_option(&options, OPT_P_TYPE, &cs.arp.arp.invflags,
invert); invert);
if (get16_and_mask(argv[optind - 1], &cs.fw.arp.arpro, if (get16_and_mask(argv[optind - 1], &cs.arp.arp.arpro,
&cs.fw.arp.arpro_mask, 0)) { &cs.arp.arp.arpro_mask, 0)) {
if (strcasecmp(argv[optind-1], "ipv4")) if (strcasecmp(argv[optind-1], "ipv4"))
xtables_error(PARAMETER_PROBLEM, "Problem with specified protocol type"); xtables_error(PARAMETER_PROBLEM, "Problem with specified protocol type");
cs.fw.arp.arpro = htons(0x800); cs.arp.arp.arpro = htons(0x800);
} }
break; break;
case 'j': case 'j':
set_option(&options, OPT_JUMP, &cs.fw.arp.invflags, set_option(&options, OPT_JUMP, &cs.arp.arp.invflags,
invert); invert);
cs.jumpto = parse_target(optarg); command_jump(&cs);
cs.target = command_jump(&cs.fw, cs.jumpto);
break; break;
case 'i': case 'i':
check_inverse(optarg, &invert, &optind, argc); check_inverse(optarg, &invert, &optind, argc);
set_option(&options, OPT_VIANAMEIN, &cs.fw.arp.invflags, set_option(&options, OPT_VIANAMEIN, &cs.arp.arp.invflags,
invert); invert);
parse_interface(argv[optind-1], parse_interface(argv[optind-1],
cs.fw.arp.iniface, cs.arp.arp.iniface,
cs.fw.arp.iniface_mask); cs.arp.arp.iniface_mask);
/* cs.fw.nfcache |= NFC_IP_IF_IN; */ /* cs.arp.nfcache |= NFC_IP_IF_IN; */
break; break;
case 'o': case 'o':
check_inverse(optarg, &invert, &optind, argc); check_inverse(optarg, &invert, &optind, argc);
set_option(&options, OPT_VIANAMEOUT, &cs.fw.arp.invflags, set_option(&options, OPT_VIANAMEOUT, &cs.arp.arp.invflags,
invert); invert);
parse_interface(argv[optind-1], parse_interface(argv[optind-1],
cs.fw.arp.outiface, cs.arp.arp.outiface,
cs.fw.arp.outiface_mask); cs.arp.arp.outiface_mask);
/* cs.fw.nfcache |= NFC_IP_IF_OUT; */ /* cs.arp.nfcache |= NFC_IP_IF_OUT; */
break; break;
case 'v': case 'v':
if (!verbose) if (!verbose)
set_option(&options, OPT_VERBOSE, set_option(&options, OPT_VERBOSE,
&cs.fw.arp.invflags, invert); &cs.arp.arp.invflags, invert);
verbose++; verbose++;
break; break;
...@@ -1244,7 +1209,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table) ...@@ -1244,7 +1209,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
break; break;
case 'n': case 'n':
set_option(&options, OPT_NUMERIC, &cs.fw.arp.invflags, set_option(&options, OPT_NUMERIC, &cs.arp.arp.invflags,
invert); invert);
break; break;
...@@ -1264,7 +1229,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table) ...@@ -1264,7 +1229,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
exit(0); exit(0);
case '0': case '0':
set_option(&options, OPT_LINENUMBERS, &cs.fw.arp.invflags, set_option(&options, OPT_LINENUMBERS, &cs.arp.arp.invflags,
invert); invert);
break; break;
...@@ -1274,7 +1239,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table) ...@@ -1274,7 +1239,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
case 'c': case 'c':
set_option(&options, OPT_COUNTERS, &cs.fw.arp.invflags, set_option(&options, OPT_COUNTERS, &cs.arp.arp.invflags,
invert); invert);
pcnt = optarg; pcnt = optarg;
if (xs_has_arg(argc, argv)) if (xs_has_arg(argc, argv))
...@@ -1284,12 +1249,12 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table) ...@@ -1284,12 +1249,12 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
"-%c requires packet and byte counter", "-%c requires packet and byte counter",
opt2char(OPT_COUNTERS)); opt2char(OPT_COUNTERS));
if (sscanf(pcnt, "%llu", &cs.fw.counters.pcnt) != 1) if (sscanf(pcnt, "%llu", &cs.arp.counters.pcnt) != 1)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"-%c packet counter not numeric", "-%c packet counter not numeric",
opt2char(OPT_COUNTERS)); opt2char(OPT_COUNTERS));
if (sscanf(bcnt, "%llu", &cs.fw.counters.bcnt) != 1) if (sscanf(bcnt, "%llu", &cs.arp.counters.bcnt) != 1)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"-%c byte counter not numeric", "-%c byte counter not numeric",
opt2char(OPT_COUNTERS)); opt2char(OPT_COUNTERS));
...@@ -1313,7 +1278,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table) ...@@ -1313,7 +1278,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
default: default:
if (cs.target) { if (cs.target) {
xtables_option_tpcall(c, argv, xtables_option_tpcall(c, argv,
invert, cs.target, &cs.fw); invert, cs.target, &cs.arp);
} }
break; break;
} }
...@@ -1341,14 +1306,14 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table) ...@@ -1341,14 +1306,14 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
if (shostnetworkmask) if (shostnetworkmask)
parse_hostnetworkmask(shostnetworkmask, &saddrs, parse_hostnetworkmask(shostnetworkmask, &saddrs,
&(cs.fw.arp.smsk), &nsaddrs); &(cs.arp.arp.smsk), &nsaddrs);
if (dhostnetworkmask) if (dhostnetworkmask)
parse_hostnetworkmask(dhostnetworkmask, &daddrs, parse_hostnetworkmask(dhostnetworkmask, &daddrs,
&(cs.fw.arp.tmsk), &ndaddrs); &(cs.arp.arp.tmsk), &ndaddrs);
if ((nsaddrs > 1 || ndaddrs > 1) && if ((nsaddrs > 1 || ndaddrs > 1) &&
(cs.fw.arp.invflags & (ARPT_INV_SRCIP | ARPT_INV_TGTIP))) (cs.arp.arp.invflags & (ARPT_INV_SRCIP | ARPT_INV_TGTIP)))
xtables_error(PARAMETER_PROBLEM, "! not allowed with multiple" xtables_error(PARAMETER_PROBLEM, "! not allowed with multiple"
" source or destination IP addresses"); " source or destination IP addresses");
...@@ -1363,14 +1328,6 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table) ...@@ -1363,14 +1328,6 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
"chain name `%s' too long (must be under %i chars)", "chain name `%s' too long (must be under %i chars)",
chain, ARPT_FUNCTION_MAXNAMELEN); chain, ARPT_FUNCTION_MAXNAMELEN);
if (nft_init(h, xtables_arp) < 0)
xtables_error(OTHER_PROBLEM,
"Could not initialize nftables layer.");
h->ops = nft_family_ops_lookup(h->family);
if (h->ops == NULL)
xtables_error(PARAMETER_PROBLEM, "Unknown family");
if (command == CMD_APPEND if (command == CMD_APPEND
|| command == CMD_DELETE || command == CMD_DELETE
|| command == CMD_INSERT || command == CMD_INSERT
...@@ -1394,17 +1351,6 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table) ...@@ -1394,17 +1351,6 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
opt2char(OPT_VIANAMEIN), opt2char(OPT_VIANAMEIN),
chain); chain);
} }
if (!cs.target && strlen(cs.jumpto) != 0) {
size_t size;
cs.target = xtables_find_target(XT_STANDARD_TARGET,
XTF_LOAD_MUST_SUCCEED);
size = sizeof(struct arpt_entry_target) + cs.target->size;
cs.target->t = xtables_calloc(1, size);
cs.target->t->u.target_size = size;
strcpy(cs.target->t->u.user.name, cs.jumpto);
}
} }
switch (command) { switch (command) {
...@@ -1439,10 +1385,11 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table) ...@@ -1439,10 +1385,11 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
options&OPT_LINENUMBERS); options&OPT_LINENUMBERS);
break; break;
case CMD_FLUSH: case CMD_FLUSH:
ret = nft_rule_flush(h, chain, *table); ret = nft_rule_flush(h, chain, *table, options & OPT_VERBOSE);
break; break;
case CMD_ZERO: case CMD_ZERO:
ret = nft_chain_zero_counters(h, chain, *table); ret = nft_chain_zero_counters(h, chain, *table,
options & OPT_VERBOSE);
break; break;
case CMD_LIST|CMD_ZERO: case CMD_LIST|CMD_ZERO:
ret = list_entries(h, chain, *table, rulenum, ret = list_entries(h, chain, *table, rulenum,
...@@ -1451,13 +1398,15 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table) ...@@ -1451,13 +1398,15 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
/*options&OPT_EXPANDED*/0, /*options&OPT_EXPANDED*/0,
options&OPT_LINENUMBERS); options&OPT_LINENUMBERS);
if (ret) if (ret)
ret = nft_chain_zero_counters(h, chain, *table); ret = nft_chain_zero_counters(h, chain, *table,
options & OPT_VERBOSE);
break; break;
case CMD_NEW_CHAIN: case CMD_NEW_CHAIN:
ret = nft_chain_user_add(h, chain, *table); ret = nft_chain_user_add(h, chain, *table);
break; break;
case CMD_DELETE_CHAIN: case CMD_DELETE_CHAIN:
ret = nft_chain_user_del(h, chain, *table); ret = nft_chain_user_del(h, chain, *table,
options & OPT_VERBOSE);
break; break;
case CMD_RENAME_CHAIN: case CMD_RENAME_CHAIN:
ret = nft_chain_user_rename(h, chain, *table, newname); ret = nft_chain_user_rename(h, chain, *table, newname);
...@@ -1473,6 +1422,16 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table) ...@@ -1473,6 +1422,16 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
exit_tryhelp(2); exit_tryhelp(2);
} }
if (nsaddrs)
free(saddrs);
if (ndaddrs)
free(daddrs);
if (cs.target)
free(cs.target->t);
xtables_free_opts(1);
/* if (verbose > 1) /* if (verbose > 1)
dump_entries(*handle);*/ dump_entries(*handle);*/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment