#!/bin/sh
: ${IPTABLES:=sbin_iptables}
: ${fwh_state:=/var/run/fwrules-helper.state}
: ${tmpl_dir:=/etc/fwrules.tmpl}
: ${ext_dir:=/etc/rc.d}
: ${ipset_next:=/var/run/ipset-next}
fw_tmp=/tmp/fwrules-helper.$$
iptables_dynrules=/var/run/iptables.dynrules
iptables_dynrules_idx=/var/run/iptables.dynrules.next
iptables_rules=/var/run/iptables.rules
dummy_rule="127.0.0.1/8 !127.0.0.1/8 ACCEPT"
create_next_dynrule()
{
phidx=$(cat $iptables_dynrules_idx)
echo $((phidx+1)) > $iptables_dynrules_idx
dummy_comment="(PLACEHOLDER:$phidx)"
comment="$comment $dummy_comment"
cat <<-EOF > $iptables_dynrules/$phidx.rule
dyn_ips="$dyn_ips"
table=$orig_table
chain=$orig_chain
rule="$full_rule"
comment="$comment"
dummy_rule="$dummy_rule"
dummy_comment="$dummy_comment"
EOF
}
get_next_rule_index()
{
table=$1
chain=$2
file=$iptables_rules/$table/$chain.next
if [ ! -f $file ]
then
echo 1
else
echo $(($(cat $file)+1))
fi
}
iptables_rules_added=0
reset_rules_added ()
{
iptables_rules_added=0
}
get_rules_added ()
{
eval $1=$iptables_rules_added
}
set_rules_added ()
{
iptables_rules_added=$1
}
create_next_ipset ()
{
if grep -q "^${ip#@} " /var/run/ipset.list
then
res="$(sed -n "/^${ip#@} /s/^[^ ]\+ *\(.*\)$/\1/p" /var/run/ipset.list)"
else
next=$(cat $ipset_next)
echo $((next+1)) > $ipset_next
res="dns${next}-"
echo "${ip#@} $res" >> /var/run/ipset.list
ipset create "${res}4" hash:ip family inet timeout 0
ipset create "${res}6" hash:ip family inet6 timeout 0
fi
}
sbin_iptables ()
{
if ! /sbin/iptables "$@" > $fw_tmp 2>&1
then
log_error "Error executing iptables $@"
log_error < $fw_tmp
rc=1
else
iptables_rules_added=`expr $iptables_rules_added + 1`
rc=0
fi
rm -f $fw_tmp
[ "$op" = R ] && op=I
[ "$op" = I ] && position=$((position+1))
return $rc
}
[ "$IP_NET_N" ] || . /var/run/ip_net.conf
for i in $ext_dir/fwrules-*.ext
do
if [ -f $i ]
then
if sh -c ". $i" > $fw_tmp 2>&1
then
. $i
else
log_error "Error parsing extension $i, rules with this extension in them will fail."
log_error < $fw_tmp
fi
rm -f $fw_tmp
fi
done
assert_empty ()
{
case x$2 in
x) ;;
*) set_error "$1: to many subexpressions after translation" ;;
esac
}
get_limit()
{
limit=
case x"$1" in
x | xnone) ;;
*) set -- `echo $1 | sed -e 's/:/ /'`
case x$2 in
x) limit="-m limit --limit $1" ;;
*) limit="-m limit --limit $1 --limit-burst $2" ;;
esac
;;
esac
}
normalize_network ()
{
res=$1
case $res in
*/*) res=`netcalc canonicalize $res` ;;
esac
}
mangle_params ()
{
echo $1 | sed -e "s/:/ /g;s/\([0-9]\+\)-\([0-9]\+\)/\1:\2/g;"
}
do_recent_param ()
{
eval `echo $recent_param | sed -e 's/^\([a-z]*\)=\(.*\)/recent_tok=\1;recent_val=\2/'`
recent_opt="$recent_opt --$recent_tok $recent_val"
}
do_recent ()
{
recent_opt=
set -- `echo $1 | sed -e 's/,/ /g'`
while [ "$1" ]; do
case $1 in
\!*) recent_param=`echo $1 | sed -e 's/^!//'`
recent_neg='!'
;;
*) recent_param="$1"
recent_neg=
;;
esac
case $recent_param in
name=* | seconds=* | hitcount=*)
do_recent_param $recent_param
;;
set | update | rcheck | remove)
recent_opt="$recent_opt $recent_neg --$recent_param"
;;
rttl | rsource | rdest)
recent_opt="$recent_opt --$recent_param"
;;
*)
set_error "recent: unknown option $recent_param"
;;
esac
shift
done
match_opt="$match_opt -m recent $recent_opt"
}
mangle_ip_params ()
{
param=$1
keepslash=$2
nomap=$3
case $param in
*:*)
set -- `echo $param | sed -e 's/:/ /'`
ip=$1
port=$2
tcp_udp_needed='yes'
;;
*)
if echo $param | grep -q '^[-,0-9]\+$'
then
ip=0.0.0.0/0
port=$param
tcp_udp_needed='yes'
else
ip=$param
port=''
fi
;;
esac
get_negation $ip
ip=$param
ip_neg_opt="$neg_opt"
get_negation $port
port=$param
port_neg_opt="$neg_opt"
eval $(grep "^OPT_DNS=" /etc/rc.cfg)
if [ ! "$nomap" -a "${ip#@}" != "$ip" -a "$OPT_DNS" = "yes" ] &&
! lookup_name "${ip#@}"
then
create_next_ipset
res="${res}4"
else
if can_translate_ip_net $ip || [ "${ip#@}" != "$ip" ]
then
translate_ip_net $ip || set_error
normalize_network $res
ip=$res
[ -n "$potentially_dynamic" ] && dynamic=1
else
dyn_ips="$dyn_ips $ip"
dynamic=1
fi
fi
[ "$port" -a ! "$keepslash" ] && port="`echo $port | sed -e 's/-/:/'`"
}
get_negation ()
{
case $1 in
!*)
param=`echo $1 | sed -e 's/^!//g'`
neg_opt='! '
;;
*)
param=$1
neg_opt=''
;;
esac
}
recent_p=yes
prot_p=yes
state_p=yes
length_p=yes
limit_p=yes
mark_p=yes
if_p=yes
mac_p=yes
do_prot ()
{
set -- `mangle_params $1`
proto=$1
opt=$2
case $proto in
icmp) assert_empty "do_prot $*" "$3" ;;
*) assert_empty "do_prot $*" "$2" ;;
esac
get_negation $proto
case $param in
any) ;;
icmp)
prot_opt="${neg_opt}-p icmp"
case x$opt in
x) ;;
*)
get_negation $opt
prot_opt="$prot_opt ${neg_opt}--icmp-type $param"
;;
esac
;;
*)
prot_opt="${neg_opt}-p $param" ;;
esac
}
do_mark ()
{
get_negation $1
match_opt="$match_opt -m mark ${neg_opt}--mark $param"
}
do_state ()
{
get_negation $1
match_opt="$match_opt -m conntrack ${neg_opt}--ctstate $param"
}
do_length ()
{
param=`mangle_params $1`
get_negation $param
match_opt="$match_opt -m length ${neg_opt}--length $param"
}
do_limit ()
{
get_limit $1
match_opt="$match_opt $limit"
}
do_mac ()
{
get_negation $1
match_opt="$match_opt -m mac ${neg_opt}--mac-source $param"
}
do_if_opt ()
{
translate_ip_dev $3 real_if 1
if is_error; then
real_if=lo
log_error "setting interfaces to 'lo'"
fi
[ "$real_if" != "any" ] && if_opt="$if_opt $1$2 $real_if"
}
do_if ()
{
set -- `mangle_params $1`
assert_empty "do_if $*" "$3"
get_negation $1
if_in=$param
if_in_negopt="$neg_opt"
get_negation $2
if_out=$param
if_out_negopt="$neg_opt"
do_if_opt "$if_in_negopt" -i $if_in
do_if_opt "$if_out_negopt" -o $if_out
}
do_default ()
{
rule="$*"
full_rule_suffix=
case "$rule" in
*BIDIRECTIONAL*)
rule=`echo $rule | sed -e 's#\(.*\)BIDIRECTIONAL\(.*\)#\1\2#'`
bidirectional='yes'
full_rule_suffix="$full_rule_suffix BIDIRECTIONAL"
;;
esac
case "$rule" in
*DROP*|*REJECT*|*ACCEPT*|*SNAT*|*DNAT*|*NETMAP*|*MASQUERADE*|*REDIRECT*|*HELPER*)
case "$rule" in
*NOLOG*)
rule=`echo $rule | sed -e 's#\(.*\)NOLOG[^[:space:]]*\(.*\)#\1\2#'`
full_rule_suffix="$full_rule_suffix NOLOG"
log_opt='no'
;;
*LOG*)
log_prefix="`echo $rule | sed -e 's#.*LOG:\?\([^[:space:]]*\).*#\1#'`"
log_opt='yes'
rule=`echo $rule | sed -e 's#\(.*\)LOG[^[:space:]]*\(.*\)#\1\2#'`
full_rule_suffix="$full_rule_suffix LOG"
[ -n "$log_prefix" ] && full_rule_suffix="${full_rule_suffix}:$log_prefix"
;;
esac
;;
esac
set -- $rule
case "$#" in
3)
src=$1
dst=$2
action=$3
;;
2)
case $1 in
*:* | dynamic*)
dst=$1
action=$2
;;
*.*.*.* | any | IP_* | ip_* | @* )
src=$1
action=$2
;;
*)
dst=$1
action=$2
;;
esac
;;
1)
action=$1
;;
*)
set_error "*** Error in rule $rule ***"
;;
esac
mangle_ip_params $src "" nomap
if is_error
then
set_error "$rule: error while processing source '$src'"
return 1
fi
src_unmapped=$src
src_unmapped_neg=$src_neg
case "$ip" in
@*)
match_opt="$match_opt -m set ${ip_neg_opt}--match-set $res src"
src=0.0.0.0/0
src_neg=
;;
*)
src="$ip"
src_neg="$ip_neg_opt"
;;
esac
case "x$port" in
x) ;;
*,*) src_port_opt="-m multiport ${port_neg_opt}--source-ports $port" ;;
*) src_port_opt="${port_neg_opt}--source-port $port" ;;
esac
if [ -z "$in_template" ]
then
full_src="$ip_neg_opt$ip"
[ -n "$port" ] && full_src="$full_src:$(echo $port | sed 's/:/-/')"
fi
mangle_ip_params $dst
if is_error
then
set_error "$rule: error while processing destination '$dst'"
return 1
fi
dst_unmapped=$dst
dst_unmapped_neg=$dst_neg
case "$ip" in
@*)
match_opt="$match_opt -m set ${ip_neg_opt}--match-set $res dst"
dst=0.0.0.0/0
dst_neg=
;;
*)
dst="$ip"
dst_neg="$ip_neg_opt"
;;
esac
[ -n "$port" ] && dport=$port
case "x$port" in
x) ;;
*,*) dst_port_opt="-m multiport ${port_neg_opt}--destination-ports $port" ;;
*) dst_port_opt="${port_neg_opt}--destination-port $port" ;;
esac
if [ -z "$in_template" ]
then
full_dst="$ip_neg_opt$ip"
[ -n "$dport" ] && full_dst="$full_dst:$(echo $dport | sed 's/:/-/')"
full_rule="$full_rule $full_src $full_dst $action $full_rule_suffix"
fi
action_opt=
case $action in
NONE) ;;
DROP)
case x$log_prefix in
x) action_opt="$drop";;
*) action_opt="$action";;
esac
;;
REJECT)
case x$log_prefix in
x) action_opt="$reject";;
*) action_opt="$action";;
esac
;;
MARK:*)
val=`echo $action | sed -e 's/MARK://'`
action_opt="MARK --set-mark $val"
;;
MASQUERADE:*)
mangle_ip_params `echo $action | sed -e 's/MASQUERADE://'` keepslash nomap
action_opt="MASQUERADE"
[ "$port" ] && action_opt="$action_opt --to-ports $port"
;;
SNAT:*)
mangle_ip_params `echo $action | sed -e 's/SNAT://'` keepslash nomap
action_opt="SNAT --to-source ${ip}"
[ "$port" ] && action_opt="$action_opt:$port"
;;
NETMAP:*)
mangle_ip_params `echo $action | sed -e 's/NETMAP://'` keepslash nomap
action_opt="NETMAP --to ${ip}"
;;
DNAT:*)
mangle_ip_params `echo $action | sed -e 's/DNAT://'` keepslash nomap
action_opt="DNAT --to-destination ${ip}"
[ "$port" ] && action_opt="$action_opt:$port"
;;
REDIRECT:*)
mangle_ip_params `echo $action | sed -e 's/REDIRECT://'` keepslash nomap
: ${port:=$dport}
action_opt="REDIRECT --to-ports $port"
;;
HELPER:*)
helper=`echo $action | sed -e 's/HELPER://'`
action_opt="CT --helper $helper"
if ! do_modprobe_if_exists kernel/net/netfilter nf_nat_$helper ||
! do_modprobe_if_exists kernel/net/ipv4/netfilter nf_nat_$helper
then
log_error "NAT helper module for protocol $helper failed to load, NAT traversal will not work"
fi
;;
LOG:*)
log_prefix="`echo $action | sed -e 's/LOG://'`"
action_opt=LOG
;;
*)
action_opt="$action"
;;
esac
}
execute_log_statement ()
{
case x$log_prefix in
x) $IPTABLES -t $table -$op $chain $position $1 -m comment --comment "$comment" -j LOG $log_level ;;
*) $IPTABLES -t $table -$op $chain $position $1 -m comment --comment "$comment" -j LOG --log-prefix "$log_prefix " $log_level ;;
esac
}
really_execute_iptables ()
{
do_action=$2
do_log=''
case $do_action in
*drp-log | *rej-log)
if [ "$log_opt" = 'no' ]
then
do_action=`echo $do_action | sed -e 's#^\(.*\)-log#\1#'`
fi
;;
*drp | *rej)
if [ "$log_opt" = 'yes' ]
then
do_action=${do_action}-log
fi
;;
*)
do_log="$log_opt"
;;
esac
case "$do_log" in
yes)
execute_log_statement "$1"
$IPTABLES -t $table -$op $chain $position $1 -m comment --comment "$comment" -j $do_action
;;
*)
case $do_action in
LOG) execute_log_statement "$1" ;;
*) $IPTABLES -t $table -$op $chain $position $1 -m comment --comment "$comment" -j $do_action ;;
esac
;;
esac
}
exec_iptables ()
{
table=$1
chain=$2
case $op in
I|R) ;;
*) position= ;;
esac
opts="$if_opt $match_opt ${src_neg}-s $src $src_port_opt ${dst_neg}-d $dst $dst_port_opt"
if [ -z "$fw_rule_error" ]
then
if [ -z "$tcp_udp_needed" -o "$prot_opt" ]
then
really_execute_iptables "$prot_opt $opts" "$action_opt"
else
really_execute_iptables "-p tcp $opts" "$action_opt"
really_execute_iptables "-p udp $opts" "$action_opt"
fi
fi
}
init_options ()
{
table=$1
chain=$2
op=$3
comment=$4
if_opt=''
match_opt=''
prot_opt=''
src='any'
src_neg=''
src_port_opt=''
src_unmapped='any'
src_unmapped_neg=''
dst='any'
dst_neg=''
dst_port_opt=''
dst_unmapped='any'
dst_unmapped_neg=''
dport=
action_opt=''
tcp_udp_needed=''
bidirectional=''
log_opt=''
log_prefix=''
log_target='LOG'
fw_rule_error=''
dynamic=
dyn_ips=
full_rule=
if [ -f $fwh_state.$chain ]
then
. $fwh_state.$chain
else
drop=DROP
reject=REJECT
fi
}
parse_rule ()
{
parse_rule_param="$1"
while true
do
set -- $parse_rule_param
eval `echo $1 | sed -e 's/^[[:space:]]*/#/;s/^#\([a-z][[:alnum:]]\+\):\([^[:space:]]*\).*/present=\$\1_p;ext=\1;val=\2/;s/^#.*/ext=;/;s/.*ext=any.*/ext=/'`
case x$ext in
x|xdynamic)
do_default $*
return $?
;;
*)
shift
parse_rule_param="$*"
case $present in
yes)
full_rule="$full_rule $ext:$val"
eval do_$ext $val
;;
*)
log_error "invalid match $ext:"
;;
esac
;;
esac
done
}
exec_rule ()
{
if [ -n "$dynamic" ] && ! echo "$comment" | grep -q "(PLACEHOLDER:[0-9]\+)$"
then
case $orig_op in
A|I|R)
create_next_dynrule
;;
*)
;;
esac
fi
if [ -n "$dyn_ips" ]
then
save_full_rule="$full_rule"
do_rule "$orig_table" "$orig_chain" "$orig_op" "$dummy_rule" "$position" exec_rule "$comment"
rc=$?
full_rule="$save_full_rule"
return $rc
else
$pre_exec
if [ "$bidirectional" = 'yes' ]
then
exec_iptables $table $chain
swp=$src
swp_neg=$src_neg
swp_port_opt=$src_port_opt
src=$dst
src_neg=$dst_neg
src_port_opt=$(echo $dst_port_opt | sed 's/--destination-port/--source-port/')
dst=$swp
dst_neg=$swp_neg
dst_port_opt=$(echo $swp_port_opt | sed 's/--source-port/--destination-port/')
if_opt=`echo $if_opt | sed -e 's#-i #-x #' -e 's#-o #-i #' -e 's#-x #-o #'`
fi
exec_iptables $table $chain
fi
}
exec_access_rule()
{
rule="$full_rule"
new_rule=
while true
do
set -- $rule
eval `echo $1 | sed -e 's/^[[:space:]]*/#/;s/^#\([a-z][[:alnum:]]\+\):\([^[:space:]]*\).*/present=\$\1_p;ext=\1;val=\2/;s/^#.*/ext=;/;s/.*ext=any.*/ext=/'`
case x$ext in
x|xdynamic)
break
;;
*)
new_rule="$new_rule $1"
shift
rule="$*"
;;
esac
done
set -- $rule
src=$1
dst=$2
action=$3
shift 3
rule_tail="$*"
set -- $(echo $dst | sed 's/:/ /')
dst=$1
dport=$2
case $action in
DNAT:*)
chain=PORTFWACCESS
set -- $(echo $action | sed 's/^DNAT://;s/:/ /')
dst=$1
[ -n "$2" ] && dport=$2
;;
REDIRECT:*)
chain=PORTREDIRACCESS
set -- $(echo $action | sed 's/^REDIRECT://')
dport=$1
;;
*)
return ;;
esac
new_rule="$new_rule $src $dst"
[ -n "$dport" ] && new_rule="$new_rule:$dport"
new_rule="$new_rule ACCEPT $rule_tail"
do_rule filter $chain "$orig_op" "$new_rule" "$position" exec_rule "$comment"
}
exec_prerouting_rule()
{
exec_rule || return $?
get_rules_added saved_rules_added
exec_access_rule
local rc=$?
set_rules_added $saved_rules_added
return $rc
}
read_tmpl ()
{
local tmpl_name=$1
{
if [ -e $tmpl_dir/$tmpl_name ]
then
cat $tmpl_dir/$tmpl_name
else
tmpl_name=$(echo $tmpl_name | tr "A-Z" "a-z")
sed -n "s/^$tmpl_name[[:space:]]\+//p" $tmpl_dir/templates
fi
} | sed -e "s/#.*//;/^[[:space:]]*$/d"
}
do_rule ()
{
case x$FWRULES_DO_DEBUG in x) set +x ;; esac
local orig_table=$1
local orig_chain=$2
local orig_op=$3
local orig_rule="$4"
local full_orig_rule="$4"
local position=$5
local method="$6"
local orig_comment="$7"
: ${method:=exec_rule}
: ${orig_comment:="$orig_rule"}
reset_rules_added
case "$orig_rule" in
*tmpl:*)
eval set -- `echo "$orig_rule" | sed -e "s#\(.*\)[[:space:]:]*tmpl:\([^[:space:]]*\)\(.*\)#'\1' '\2' '\3'#"`
rule_head="$1"
rule_tail="$3"
orig_rule="$rule_head $rule_tail"
local orig_tmpl_name=$2
local orig_position=$position
: ${orig_position:=1}
tmpl_rules="`read_tmpl $2`"
if [ -n "$tmpl_rules" ]
then
while read tmpl_rule
do
init_options $orig_table $orig_chain $orig_op "$orig_comment"
in_template=yes
parse_rule "$tmpl_rule DROP"
in_template=
parse_rule "$orig_rule"
if ! is_error
then
if [ -n "$bidirectional" ]
then
set_error "$full_orig_rule: using templates and BIDIRECTIONAL simultaneously is not allowed"
else
$method
fi
fi
get_rules_added rules_added
position=`expr $orig_position + $rules_added`
done <<EOF
$tmpl_rules
EOF
else
set_error "can't find packetfilter template '$orig_tmpl_name'"
fi
;;
*)
init_options $orig_table $orig_chain $orig_op "$orig_comment"
parse_rule "$orig_rule"
is_error || $method
esac
case x$tmp_debug in xyes) set -x; ;; esac
case x$debug_active in xyes) set -x; ;; esac
}
add_rule_to_file()
{
mkdir -p $(dirname $pf_file)
echo "$pf_rule %%% $comment" >> $pf_file
if [ ! -f $pf_file.next ]
then
echo 1 > $pf_file.next
else
local next=$(($(cat $pf_file.next)+1))
echo $next > $pf_file.next
fi
}
del_rule_from_file()
{
local pf_rule="$(echo $pf_rule | sed 's,/,\\/,g;s/\[/\\[/g')"
local pf_comment="$(echo $comment | sed 's,/,\\/,g;s/\[/\\[/g')"
sed -i "/^[[:space:]]*$pf_rule %%% $pf_comment[[:space:]]*$/d" $pf_file 2>/dev/null
}
add_rule ()
{
local pf_file=$iptables_rules/$1/$2
local pf_rule="$3"
do_rule $1 $2 A "$3" '' "$5" "$4"
if is_error
then
set_error
else
add_rule_to_file
fi
}
del_rule ()
{
local pf_file=$iptables_rules/$1/$2
local pf_rule="$3"
do_rule $1 $2 D "$3" '' "$5" "$4"
if is_error
then
set_error
else
del_rule_from_file
fi
}
ins_rule ()
{
local pf_file=$iptables_rules/$1/$2
local pf_rule="$3"
do_rule $1 $2 I "$3" "$4" "$6" "$5"
if is_error
then
set_error
else
add_rule_to_file
fi
}
do_pre_exec ()
{
chain=test-chain
}
do_check_rule ()
{
dcr_res=0
pre_exec=do_pre_exec
base_colecho=true
base_log_file=/tmp/check_rule.$$
cons_boot=yes
rm -f $base_log_file
if ! iptables -t $1 -L test-chain > /dev/null 2>&1; then
do_chain $1 test-chain N add-test-chain
fi
do_rule $1 $2 A "$3" '' "$4" "$3"
if [ -f $base_log_file ]; then
echo "Invalid rule '$3'"
cat $base_log_file
rm -f $base_log_file
dcr_res=1
else
do_rule $1 $2 D "$3" '' "$4" "$3"
fi
unset pre_exec
unset base_colecho
unset base_log_file
return $dcr_res
}
check_rule ()
{
: ${SCRIPT:=check_rule}
do_check_rule filter foo "$1" ''
}
setup_logging ()
{
enabled=$1
chain=$2
prefix="$3"
log_limit="$4"
rej_limit="$5"
udp_rej_limit="$6"
log_level=$7
get_limit "$log_limit"
log_limit="$limit"
get_limit "$rej_limit"
rej_limit="$limit"
get_limit "$udp_rej_limit"
udp_rej_limit="$limit"
case $chain in
FORWARD)
drop="fw-drp"
reject="fw-rej"
;;
INPUT)
drop="in-drp"
reject="in-rej"
;;
OUTPUT)
drop="out-drp"
reject="out-rej"
;;
*)
log_error "setup_loggig: unknown chain $chain"
drop="un-drp"
reject="un-rej"
;;
esac
cat <<-EOF > $fwh_state.$chain
        drop_name=$drop
        reject_name=$reject
EOF
case x$log_level in
x) ;;
*)
log_level="--log-level $log_level"
echo "log_level='$log_level'" >> $fwh_state.$chain
;;
esac
$IPTABLES -N ${drop}
$IPTABLES -N ${drop}-log
$IPTABLES -N ${reject}
$IPTABLES -N ${reject}-log
$IPTABLES -N ${reject}-fin
$IPTABLES -A ${drop}-log $log_limit -j LOG --log-prefix "${prefix}-drop " $log_level
$IPTABLES -A ${drop}-log -j DROP
$IPTABLES -A ${drop} -j DROP
$IPTABLES -A ${reject}-log $log_limit -j LOG --log-prefix "${prefix}-reject " $log_level
$IPTABLES -A ${reject}-log -j ${reject}
$IPTABLES -A ${reject} -p udp $udp_rej_limit -j ${reject}-fin
$IPTABLES -A ${reject} ! -p udp $rej_limit -j ${reject}-fin
$IPTABLES -A ${reject} -j DROP
case $reject in
*in*)
$IPTABLES -A ${reject}-fin -p tcp -j REJECT --reject-with tcp-reset
$IPTABLES -A ${reject}-fin -p udp -j REJECT --reject-with port-unreach
$IPTABLES -A ${reject}-fin ! -p icmp -j REJECT --reject-with proto-unreach
$IPTABLES -A ${reject}-fin -j DROP
;;
*)
$IPTABLES -A ${reject}-fin ! -p icmp -j REJECT --reject-with admin-prohib
$IPTABLES -A ${reject}-fin -j DROP
;;
esac
case $enabled in
yes)
drop="${drop}-log"
reject="${reject}-log"
;;
*)
drop=DROP
;;
esac
cat <<-EOF >> $fwh_state.$chain
        drop=$drop
        reject=$reject
EOF
}
get_defaults ()
{
. $fwh_state.$1
}
close_chain ()
{
. $fwh_state.$1
case "$2" in
DROP)
$IPTABLES -A $1 -j $drop
;;
REJECT)
$IPTABLES -A $1 -j $reject
;;
ACCEPT)
$IPTABLES -P $1 ACCEPT
;;
esac
}
do_chain ()
{
local table=$1
local chain=$2
local op=$3
local name=$4
if ! $IPTABLES -t $table -$op $chain
then
log_error "${name}_chain $chain failed..."
fi
}
chain_present ()
{
local table=$2
: ${table:=filter}
iptables -t $table -L $1 > /dev/null 2>&1
}
nat_chain_present ()
{
chain_present $1 nat
}
add_chain ()
{
do_chain filter $1 N add
}
add_nat_chain ()
{
do_chain nat $1 N add
}
flush_chain ()
{
do_chain filter $1 F flush
}
flush_nat_chain ()
{
do_chain nat $1 F flush
}
del_chain ()
{
do_chain filter $1 X del
}
del_nat_chain ()
{
do_chain nat $1 X del
}
set_count ()
{
echo 1 > /var/run/$1_def_end
iptables -nL $1 --line-numbers | \
 while read num tail
do
case $num in
[0-9]*)
echo `expr $num + 1` > /var/run/$1_def_end
;;
esac
done
}
get_count ()
{
res=`cat /var/run/$1_def_end`
}
