####################################################################################
# Functions imported from /usr/share/shorewall/prog.functions
####################################################################################
#
# Clear Proxy Arp
#
delete_proxyarp() {
    if [ -f ${VARDIR}/proxyarp ]; then
	while read address interface external haveroute; do
	    qt arp -i $external -d $address pub
	    [ -z "${haveroute}${NOROUTES}" ] && qt $IP -4 route del $address dev $interface
	    f=/proc/sys/net/ipv4/conf/$interface/proxy_arp
	    [ -f $f ] && echo 0 > $f
	done < ${VARDIR}/proxyarp
    fi

    rm -f ${VARDIR}/proxyarp
}

#
# Remove all Shorewall-added rules
#
clear_firewall() {
    stop_firewall

    setpolicy INPUT ACCEPT
    setpolicy FORWARD ACCEPT
    setpolicy OUTPUT ACCEPT

    run_iptables -F

    echo 1 > /proc/sys/net/ipv4/ip_forward

    if [ -n "$DISABLE_IPV6" ]; then
	if qt mywhich ip6tables; then
	    ip6tables -P INPUT   ACCEPT 2> /dev/null
	    ip6tables -P OUTPUT  ACCEPT 2> /dev/null
	    ip6tables -P FORWARD ACCEPT 2> /dev/null
	fi
    fi

    run_clear_exit

    set_state "Cleared"

    logger -p kern.info "$PRODUCT Cleared"
}

#
# Issue a message and stop/restore the firewall
#
fatal_error()
{
    echo "   ERROR: $@" >&2

    if [ $LOG_VERBOSE -gt 1 ]; then
        timestamp="$(date +'%_b %d %T') "
        echo "${timestamp}  ERROR: $@" >> $STARTUP_LOG
    fi

    stop_firewall
    [ -n "$TEMPFILE" ] && rm -f $TEMPFILE
    exit 2
}

#
# Issue a message and stop
#
startup_error() # $* = Error Message
{
    echo "   ERROR: $@: Firewall state not changed" >&2
    case $COMMAND in
        start)
	    logger -p kern.err "ERROR:$PRODUCT start failed:Firewall state not changed"
	    ;;
	restart)
	    logger -p kern.err "ERROR:$PRODUCT restart failed:Firewall state not changed"
	    ;;
	restore)
	    logger -p kern.err "ERROR:$PRODUCT restore failed:Firewall state not changed"
	    ;;
    esac

    if [ $LOG_VERBOSE -gt 1 ]; then
        timestamp="$(date +'%_b %d %T') "

	case $COMMAND in
	    start)
		echo "${timestamp}  ERROR:$PRODUCT start failed:Firewall state not changed" >> $STARTUP_LOG
		;;
	    restart)
		echo "${timestamp}  ERROR:$PRODUCT restart failed:Firewall state not changed" >> $STARTUP_LOG
		;;
	    restore)
		echo "${timestamp}  ERROR:$PRODUCT restore failed:Firewall state not changed" >> $STARTUP_LOG
		;;
	esac
    fi

    kill $$
    exit 2
}

#
# Run iptables and if an error occurs, stop/restore the firewall
#
run_iptables()
{
    local status

    while [ 1 ]; do
	$IPTABLES $@
	status=$?
	[ $status -ne 4 ] && break
    done

    if [ $status -ne 0 ]; then
        error_message "ERROR: Command \"$IPTABLES $@\" Failed"
	stop_firewall
        exit 2
    fi
}

#
# Run iptables retrying exit status 4
#
do_iptables()
{
    local status

    while [ 1 ]; do
	$IPTABLES $@
	status=$?
	[ $status -ne 4 ] && return $status;
    done
}

#
# Run iptables and if an error occurs, stop/restore the firewall
#
run_ip()
{
    if ! $IP -4 $@; then
	error_message "ERROR: Command \"$IP -4 $@\" Failed"
	stop_firewall
	exit 2
    fi
}

#
# Run tc and if an error occurs, stop/restore the firewall
#
run_tc() {
    if ! $TC $@ ; then
	error_message "ERROR: Command \"$TC $@\" Failed"
	stop_firewall
	exit 2
    fi
}

#
# Restore the rules generated by 'drop','reject','logdrop', etc.
#
restore_dynamic_rules() {
    if [ -f ${VARDIR}/save ]; then
	progress_message2 "Setting up dynamic rules..."
	rangematch='source IP range'
	while read target ignore1 ignore2 address ignore3 rest; do
	    case $target in
		DROP|reject|logdrop|logreject)
		    case $rest in
			$rangematch*)
			    run_iptables -A dynamic -m iprange --src-range ${rest#source IP range} -j $target
			    ;;
			*)
			    if [ -z "$rest" ]; then
				run_iptables -A dynamic -s $address -j $target
			    else
				error_message "WARNING: Unable to restore dynamic rule \"$target $ignore1 $ignore2 $address $ignore3 $rest\""
			    fi
			    ;;
		    esac
		    ;;
	    esac
	done < ${VARDIR}/save
    fi
}

#
# Get a list of all configured broadcast addresses on the system
#
get_all_bcasts()
{
    $IP -f inet addr show 2> /dev/null | grep 'inet.*brd' | sed 's/inet.*brd //; s/scope.*//;' | sort -u
}

#
# Run the .iptables_restore_input as a set of discrete iptables commands
#
debug_restore_input() {
    local first second rest table chain
    #
    # Clear the ruleset 
    #
    qt1 $IPTABLES -t mangle -F
    qt1 $IPTABLES -t mangle -X

    for chain in PREROUTING INPUT FORWARD POSTROUTING; do
	qt1 $IPTABLES -t mangle -P $chain ACCEPT
    done

    qt1 $IPTABLES -t raw    -F
    qt1 $IPTABLES -t raw    -X

    for chain in PREROUTING OUTPUT; do
	qt1 $IPTABLES -t raw -P $chain ACCEPT
    done

    run_iptables -t nat -F
    run_iptables -t nat -X

    for chain in PREROUTING POSTROUTING OUTPUT; do
	qt1 $IPTABLES -t nat -P $chain ACCEPT
    done

    qt1 $IPTABLES -t filter -F
    qt1 $IPTABLES -t filter -X

    for chain in INPUT FORWARD OUTPUT; do
	qt1 $IPTABLES -t filter -P $chain -P ACCEPT
    done

    while read first second rest; do
	case $first in
	    -*)
		#
		# We can't call run_iptables() here because the rules may contain quoted strings
		#
		eval $IPTABLES -t $table $first $second $rest

		if [ $? -ne 0 ]; then
		    error_message "ERROR: Command \"$IPTABLES $first $second $rest\" Failed"
		    stop_firewall
		    exit 2
		fi
		;;
	    :*)
		chain=${first#:}

		if [ "x$second" = x- ]; then
		    do_iptables -t $table -N $chain
		else
		    do_iptables -t $table -P $chain $second
		fi

		if [ $? -ne 0 ]; then
		    error_message "ERROR: Command \"$IPTABLES $first $second $rest\" Failed"
		    stop_firewall
		    exit 2
		fi
		;;
	    #
	    # This grotesque hack with the table names works around a bug/feature with ash
	    #
	    '*'raw)
		table=raw
		;;
	    '*'mangle)
		table=mangle
		;;
	    '*'nat)
		table=nat
		;;
	    '*'filter)
		table=filter
		;;
	esac
    done
}
####################################################################################
# End of functions imported from /usr/share/shorewall/prog.functions
####################################################################################
