#!/bin/sh
RCDLINKS="2,S41 3,S41 6,K41"
#
#     The Shoreline Firewal (Shorewall) Packet Filtering Firewall - V1.0 4/15/2001
#
#     This program is under GPL [http://www.gnu.org/copyleft/gpl.htm]         
#
#     (c) 1999,2000,2001 - Tom Eastep (teastep@evergo.net)
#
#	On most distributions, this file should be called:
#	/etc/rc.d/init.d/wall or /etc/init.d/wall
#
#       Complete documentation is available at http://shorewall.sourceforge.net
#
#       This program is free software; you can redistribute it and/or modify
#       it under the terms of Version 2 of the GNU General Public License 
#       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., 675 Mass Ave, Cambridge, MA 02139, USA
#
#       If an error occurs while starting or restarting the firewall, the
#       wall is automatically stopped.
#
#       Commands are:
#
#          shorewall start                        Starts the firewall 
#          shorewall restart                      Restarts the firewall
#          shorewall stop                         Stops the firewall
#          shorewall status                       Displays firewall status              
#          shorewall reset                        Resets iptabless packet and
#                                                 byte counts
#          shorewall clear                        Remove all Shorewall chains and
#                                                 rules/policies.
#
# chkconfig: 2345 25 90
# description: Packet filtering firewall
#
# Run all utility programs using the C locale                                   
#
# Thanks to Vincent Planchenault for this tip #
    
LC_ALL=C
#
# Determine if a chain exists
#
havechain() # $1 = name of chain
{
    qt iptables -L $1 -n
}
#
# Delete a chain if it exists
#
deletechain() # $1 = name of chain
{
    havechain $1 && iptables -F $1 && iptables -X $1
}
#
# Set a standard chain's policy and flush its rules
#
setpolicy() # $1 = name of chain, $2 = policy
{
    run_iptables -P $1 $2
    run_iptables -F $1
}
#
# Set a standard chain's policy and immediately enable established connections
#
setpolicycontinue() # $1 = name of chain, $2 = policy
{
    setpolicy $1 $2
    run_iptables -A $1 -m state --state ESTABLISHED -j ACCEPT
}
#
# Flush one of the NAT table chains
#
flushnat() # $1 = name of chain
{
    run_iptables -t nat -F $1
}
#
# Find interfaces to a given zone
#
find_interfaces() # $1 = interface zone
{
    while read z interface subnet options; do
	[ "x$z" = "x$1" ] && echo $interface
    done < /etc/shorewall/interfaces
}
#
# Determine the interfaces on the firewall and generate report
#
determine_interfaces()
{
    for zone in $zones; do
	interfaces=`find_interfaces $zone`
	interfaces=`echo $interfaces` # Remove extra trash
	eval ${zone}_interfaces="\$interfaces"

	[ -n "$interfaces" ] && { eval display=\$${zone}_display; display_list "$display interfaces:" $interfaces; }
    done
}
#
# Find broadcast addresses corresponding to an interface to a given zone
#
find_broadcast() # $1 = zone
{
    while read z interface subnet options; do
	if [ "x$z" = "x$1" -a -n "$subnet" ]; then
	    if [ "$subnet" = "detect" ]; then
		addr="`run_ip addr show $interface 2> /dev/null`"
		if ! echo "$addr" | qt grep -i "P-t-P"; then
		    addr="`echo "$addr" | grep "inet " | sed 's/   inet.*brd //;s/scope.*//'`"
		    echo $addr | cut -d' ' -f 1
                fi
	    elif [ "x${subnet}" != "x-" ]; then
		echo $subnet
	    fi
	fi
    done < /etc/shorewall/interfaces
}
#
# Find interfaces with the passed option
#
find_interfaces_by_option() # $1 = option
{
    mygrep "$zonepattern" /etc/shorewall/interfaces | while read ignore interface subnet options; do
	echo "$options" | qt grep $1 && echo $interface
    done
}
#
# Determine if there are interfaces of the given zone and option
#
have_interfaces_in_zone_with_option() # $1 = zone, $2 = option
{
    while read z interface broadcast options; do
	[ "x$z" = "x$1" ] && [ -n "`echo $options | grep $2`" ] && return 0
    done < /etc/shorewall/interfaces
    return 1
}
#
# Stop the Firewall - 
#
stop_firewall()
{
    stopping="Yes"

    deletechain shorewall

    [ -f /etc/shorewall/stop ] && . /etc/shorewall/stop

    delete_nat
    delete_proxy_arp

    setpolicy INPUT DROP
    setpolicy OUTPUT DROP
    setpolicy FORWARD DROP

    chains="`iptables -L -n | mygrep ^Chain | cut -d' ' -f2`"
    chains="`echo $chains`"

    for chain in $chains; do
	iptables -F $chain
    done

    for chain in $chains; do
	case $chain in
	INPUT|OUTPUT|FORWARD)
	    ;;
	*)
	    iptables -X $chain
	    ;;
        esac
    done

    deletechain common
    deletechain rfc1918
    deletechain icmp-def

    interfaces="`find_interfaces_by_option routestopped`"

    for interface in $interfaces; do
	iptables -A INPUT  -i $interface -j ACCEPT
	iptables -A OUTPUT -o $interface -j ACCEPT
	
	for interface1 in $interfaces; do
	    [ "$interface" != "$interface1" ] && iptables -A FORWARD -i $interface -o $interface1 -j ACCEPT
	done
    done

    iptables -A INPUT  -i lo -j ACCEPT
    iptables -A OUTPUT -o lo -j ACCEPT

    mygrep "$zonepattern" /etc/shorewall/interfaces | while read ignore interface subnet options; do
	if echo "$options" | qt grep dhcp ; then
	    iptables -A INPUT  -p udp -i $interface --dport 67:68 -j ACCEPT
	    iptables -A OUTPUT -p udp -o $interface --dport 67:68 -j ACCEPT
	fi
    done
    
    logger "Shorewall Stopped"
	
}
#
# Remove all rules and remove all user-defined chains
#
clear_firewall()
{
    stop_firewall
	
    setpolicy INPUT ACCEPT
    setpolicy FORWARD ACCEPT
    setpolicy OUTPUT ACCEPT

    [ -f /etc/shorewall/clear ] && . /etc/shorewall/clear
    
    logger "Shorewall Cleared"
}
#
# Run iptables and if an error occurs, stop the firewall and quit
#
run_iptables()
{
    if ! iptables $*; then
	[ -z "$stopping" ] && { stop_firewall; exit 2; }
    fi
}
#
# Run ip and if an error occurs, stop the firewall and quit
#
run_ip()
{
    if ! ip $* ; then
	stop_firewall
	exit 2
    fi
}
#
# Set ipsec tunnels
#
setup_tunnels()
{
    options="-mstate --state NEW -j ACCEPT"

    while read kind z gateway nomasq; do
	case $kind in
	    \#*)
		;;
	    ipsec)
		run_iptables -A ${z}2fw -p 50 -s $gateway $options
		run_iptables -A ${z}2fw -p 51 -s $gateway $options
		run_iptables -A fw2${z} -p 50 -d $gateway $options
		run_iptables -A fw2${z} -p 51 -d $gateway $options
		run_iptables -A ${z}2fw -p udp -s $gateway --sport 500 --dport 500 $options 
		run_iptables -A fw2${z} -p udp -d $gateway --dport 500 --sport 500 $options 
		echo "   IPSEC tunnel to $gateway defined.".
		;;
            *)  if [ -n "$kind" ]; then
		    echo "Tunnels of type $kind are not supported" >&2
		    stop_firewall
		    exit 2
                fi
	    ;;
	esac
    done < /etc/shorewall/tunnels
}
#
# Delete Tunnel Routes
#
delete_tunnel_routes()
{
    if [ -f ${STATEDIR}/routes ]; then
	while read host nomasq; do
	    if [ -n "$useip" ]; then
		qt ip route del $nomasq
	    else
		qt route del -net $nomasq gw $host
	    fi
	done < ${STATEDIR}/routes
	    
	rm -f ${STATEDIR}/routes
    fi

    [ -d ${STATEDIR} ] && touch ${STATEDIR}/routes
}
#
#
# Setup Proxy ARP
#
setup_proxy_arp()
{
    > ${STATEDIR}/proxyarp

    [ -f /etc/shorewall/proxyarp ] && while read address interface external; do
	[ -n "$address" ] && case "$address" in
	    \#*)
		;;
	    *)
		if [ -n "$address" ]; then
		    run_ip route add $address dev $interface
			
		    qt arp -Ds $address $external pub
			
		    echo 1 > /proc/sys/net/ipv4/conf/$interface/proxy_arp
		    echo 0 > /proc/sys/net/ipv4/conf/$external/proxy_arp
			
		    echo $address $interface $external >> ${STATEDIR}/proxyarp

		    echo "   Host $address connected to $internal added to ARP on $external" 
		fi
		;;
	esac
    done < /etc/shorewall/proxyarp
}
#
# Delete existing Proxy ARP
#
delete_proxy_arp()
{
    if [ -f ${STATEDIR}/proxyarp ]; then
	while read address interface external; do
	    qt arp -i $external -d $address pub
	    qt ip route del $address dev $interface
	    
	    echo 0 > /proc/sys/net/ipv4/conf/$external/proxy_arp
	    echo 0 > /proc/sys/net/ipv4/conf/$interface/proxy_arp
       done < ${STATEDIR}/proxyarp

    rm -f ${STATEDIR}/proxyarp
    fi

    [ -d ${STATEDIR} ] && touch ${STATEDIR}/proxyarp
}	    
#
# Setup Static Network Address Translation (NAT)
#
setup_nat()
{
    #
    # At this point, we're just interested in the network translation
    #
    > ${STATEDIR}/nat

    while read external interface internal; do
	[ -n "$external" ] && case "$external" in
	    \#*)
		;;
	    *)
		qt ip addr del $external dev $interface
		run_iptables -t nat -A PREROUTING  -d $external -j DNAT --to-destination $internal
		run_iptables -t nat -A POSTROUTING -s $internal -j SNAT --to-source $external
		run_ip addr add $external dev $interface
		echo "$external $interface" >> ${STATEDIR}/nat
		echo "   Host $internal NAT $external on $interface"
		;;
        esac
    done < /etc/shorewall/nat
}
#
# Delete existing Static NAT and Port Forwarding
#
delete_nat()
{
    run_iptables -t nat -F PREROUTING
    run_iptables -t nat -F POSTROUTING
    run_iptables -t nat -F OUTPUT

    [ -f ${STATEDIR}/nat ] && while read external interface; do
	qt ip addr del $external dev $interface
    done < ${STATEDIR}/nat
}
#
# Create a chain if it doesn't exist -- otherwise flush the chain
# 
# Add a rule to the chain allowing packets that are part of an
# established connection or that are related to an
# established connection.
#
createchain() # $1 = chain name
{
    havechain $1 && run_iptables -F $1 || run_iptables -N $1
    [ "$1" = "common" ] || [ "$1" = "icmp-def" ] || [ "$1" = "shorewall" ] || [ "$1" = "rfc1918" ] || run_iptables -A $1 -m state --state ESTABLISHED,RELATED -j ACCEPT
    echo "   Chain $1 created."
}
#
# Process a record from the rules file
#
process_rule() 
{
    rule="`echo $target $client $server $protocol $port $cport $address`"

    if echo $target | qt grep ':' ; then
	loglevel="`echo $target | cut -d':' -f2`"
	target="`echo $target | cut -d':' -f1`"
    else
	loglevel=
    fi

    if echo $client | qt grep ':'; then
	clientzone="`echo $client | cut -d':' -f1`"
	client="`echo $client | cut -d':' -f2`"
    else
	clientzone="$client"
	client=
    fi

    source=

    for zone in $zones fw; do
	[ "$zone" = "$clientzone" ] && source="$zone" && break
    done

    [ -z "$source" ] && { echo "Warning: Undefined Client Zone - rule \"$rule\" ignored" >&2; return; }

    [ $source = fw ] && source_interfaces= || eval source_interfaces=\$${source}_interfaces

    [ -n "$client" ] && case "$client" in
	[0-9]*)
	    #
	    # IP Address or subnet
	    #
	    client="-s $client"
	    ;;
	*)
	    #
	    # Assume that this is a device name
	    #
	    client="-i $client"
	    ;;
    esac

    dest_interface=
    
    if echo $server | qt grep ':' ; then
	serverzone="`echo $server | cut -d':' -f1`"
	serverport="`echo $server | cut -d':' -f3`"
	server="`echo $server | cut -d':' -f2`"
	
	[ -n "$server" ] && case "$server" in
	    [0-9]*)
		;;
	    *)
		dest_interface="-o $server"
		server=
		;;
        esac
    else
	serverzone="$server"
	server=
	serverport=
    fi

    dest=

    for zone in $zones fw; do
	[ "$zone" = "$serverzone" ] && dest="$zone" && break
    done
	   
    [ -z "$dest" ] && { echo "Warning: Undefined Server Zone - rule \"$rule\" ignored" >&2; return; }

    chain=${source}2${dest}
    #
    # Be sure chain exists
    #
    if ! havechain $chain; then
	echo "Warning: Chain $chain doesn't exist - Rule \"$rule\" ignored" >&2
	return
    fi

    cports=""
    dports=""
    state=""

    case $protocol in 
	tcp|udp)
	    [ -n "$port" ] && dports="--dport $port"
	    [ -n "$cport" ] && [ "x${cport}" != "x-" ] && cports="--sport $cport"
	    state="-m state --state NEW"
	    ;;
	icmp)
	    [ -n "$port" ] && dports="--icmp-type $port"
	    ;;
        *)
	    state="-m state --state NEW"
	    ;;
    esac
    
    if [ -n "${server}${serverport}" ]; then
	#
	# Specific Server 
	#
	if [ -n "$address" -a "$address" != "$server" ]; then
	    #
	    # Must use Prerouting DNAT
	    #
	    if [ "$target" != "ACCEPT" ]; then
		echo "Warning - Negative rule may not specify port mapping; rule \"$rule\" ignored" >&2
		return
            fi

	    [ "$address" = "all" ] && address= || address="-d $address"

	    if [ -n "$server" ]; then
		[ -n "$serverport" ] && serverport=":$serverport"
		target1="DNAT --to-destination ${server}${serverport}"
	    else
		target1="REDIRECT --to-port $serverport"
	    fi

	    if [ -n "$client" ]; then
		run_iptables -t nat -A PREROUTING -p $protocol $client $cports $address $dports -j $target1
	    else
	        for source_interface in $source_interfaces; do
		    run_iptables -t nat -A PREROUTING -i $source_interface -p $protocol $cports $address $dports -j $target1
		done
	    fi
        fi
		
	[ -n "$loglevel" ] && run_iptables -A $chain -p $protocol $state $client $cports -d $server $dports -j LOG --log-prefix "Shorewall:$chain:" --log-level $loglevel
	run_iptables -A $chain -p $protocol $state $client $cports -d $server $dports -j $target
    else
	#
	# Destination is just a location or an interface
	#
	[ -n "$loglevel" ] && run_iptables -A $chain -p $protocol $dest_interface $state $client $cports $dports -j LOG --log-prefix "Shorewall:$chain:" --log-level $loglevel
	run_iptables -A $chain -p $protocol $dest_interface $state $client $cports $dports -j $target
    fi
    
    echo "   Rule \"$rule\" added."
}
#
# Process the rules file
#
process_rules() 
{
    mygrep '^ACCEPT\|^DROP\|^REJECT' /etc/shorewall/rules | while read target client server protocol port cport address; do
	process_rule
    done
}
#
# Load a Module
#
loadmodule() # $1 = module name
{    
    modulename=$modulesdir/${1}.o

    [ -f $modulename ] && ! lsmod | qt grep $1 && insmod $modulename
}

#
# Display elements of a list with leading white space
#
display_list() # $1 = List Title, rest of $* = list to display
{
    [ $# -gt 1 ] && echo $*
}
#
# Silently drop packets addressed to any of the passed addresses
#
drop_broadcasts() # $* = broadcast addresses
{
    while [ $# -gt 0 ]; do
	run_iptables -A common -d $1 -j DROP
	shift
    done
}
#
# Generate default policy & log level rules for the passed client & server zones
#
default_policy() # $1 = client $2 = server
{
    local chain="${1}2${2}"
    local policy=
    local loglevel=

    apply_common()
    {
	run_iptables -A $chain -j common
    }

    apply_default()
    {
	[ "$policy" != "ACCEPT" ] && apply_common
	[ -n "$loglevel" ] && run_iptables -A $chain -j LOG --log-prefix "Shorewall:$chain:" --log-level $loglevel
	run_iptables -A $chain -m state --state NEW -j $policy
	echo "   Policy $policy for $1 to $2."
    }

    while read client server policy loglevel ; do
	case "$client" in
	\#*)
	    ;;
	all)
	    [ "$server" = "$2" -o "$server" = "all" ] && { apply_default $1 $2; return; }
	    ;;
	*)  
	    if [ "$client" = "all" -o "$client" = "$1" ] && [ "$server" = "all" -o "$server" = "$2" ]; then
		apply_default $1 $2
		return
            fi
	    ;;
        esac
    done < /tmp/shorewallpolicy-$$

    [ -n "$exists" ] && apply_common
}
#
# Set up Dynamic NAT (Masquerading)
#
setup_masq()
{
    echo "Masqueraded Subnets and Hosts:"

    while read interface subnet; do
	case "$interface" in
	    \#*)
		;;
            *)
		case $subnet in
		    [0-9]*)
			;;
		    *)
			subnet="`run_ip addr show $subnet | grep "inet " | sed s/"    "// | cut -d' ' -f2`"
			[ -z "`echo "$subnet" | grep '/'`" ] && subnet="${subnet}/32"
			;;
		esac
		    
		iptables -t nat -A POSTROUTING -s $subnet -o $interface -j MASQUERADE
		echo "   $subnet through interface $interface"
		;;
	esac
    done < /etc/shorewall/masq
}
#
# Setup Intrazone chain if appropriate
#
setup_intrazone() # $1 = zone
{
    eval interfaces=\$${1}_interfaces

    if echo -n "$interfaces" | qt grep ' ' || have_interfaces_in_zone_with_option $1 multi; then
	createchain ${1}2${1}
    else
	deletechain ${1}2${1}
    fi
}
#
# Start/Restart the Firewall
#
define_firewall() # $1 = Command (Start or Restart)
{
    echo "${1}ing Shorewall..."

    osversion=`uname -r`
    
    case $osversion in
    2.4.*|2.5.*)
	;;
    *)
	echo "Shorewall version $version does not work with kernel version $osversion"
	exit 2
	;;
    esac

    modulesdir=/lib/modules/$osversion/kernel/net/ipv4/netfilter

    if [ -d $moduledir ]; then
	echo "Loading Modules..."
	loadmodule ip_tables
	loadmodule ip_conntrack
	loadmodule ip_conntrack_ftp
	loadmodule ip_nat_ftp
    fi

    echo "Initializing..."

    deletechain shorewall
        
    qt mkdir -p ${STATEDIR}

    delete_nat
    
    delete_proxy_arp

    setpolicycontinue INPUT   DROP
    setpolicycontinue OUTPUT  DROP
    setpolicycontinue FORWARD DROP

    echo "Determining Zones..."

    determine_zones

    [ -z "$zones" ] && echo "ERROR: No Zones Defined" >&2 && exit 2

    display_list "Zones:" $zones

    echo "Determining interfaces..."

    determine_interfaces

    echo "Creating user chains..."

    for zone in $zones; do
	eval source_interfaces=\$${zone}_interfaces

	if [ -n "$source_interfaces" ]; then
	    createchain ${zone}2fw
	    createchain fw2${zone}

	    setup_intrazone $zone

	    for zone1 in $zones ; do
		if [ $zone != $zone1 ]; then
		    eval dest_interfaces=\$${zone1}_interfaces

		    [ -n "$dest_interfaces" ] && createchain ${zone}2${zone1} || deletechain ${zone}2${zone1}
                fi
            done
	else
	    for zone1 in $zones ; do
		deletechain ${zone}2${zone1}
            done
        fi
    done

    createchain icmp-def
    createchain common
    
    echo "Configuring Proxy ARP and NAT"

    setup_proxy_arp
    setup_nat

    echo "Adding Common Rules"

    run_iptables -A icmp-def -p ICMP --icmp-type echo-reply              -j ACCEPT
    run_iptables -A icmp-def -p ICMP --icmp-type source-quench           -j ACCEPT
    run_iptables -A icmp-def -p ICMP --icmp-type destination-unreachable -j ACCEPT
    run_iptables -A icmp-def -p ICMP --icmp-type time-exceeded           -j ACCEPT
    run_iptables -A icmp-def -p ICMP --icmp-type parameter-problem       -j ACCEPT

    # Common rules in each chain

    run_iptables -A common -p icmp -j icmp-def

    # accept ACKs and RSTs that aren't related to any session so that the protocol stack can handle them

    run_iptables -A common -p tcp --tcp-flags ACK ACK -j ACCEPT
    run_iptables -A common -p tcp --tcp-flags RST RST -j ACCEPT

    # NETBIOS chatter

    run_iptables -A common -p udp --dport 137:139     -j DROP
    run_iptables -A common -p udp --dport 445         -j DROP

    # BROADCASTS

    run_iptables -A common -d 255.255.255.255 -j DROP
    run_iptables -A common -d 224.0.0.0/4 -j DROP

    for zone in $zones; do
	eval interfaces=\$${zone}_interfaces

	[ -n "$interfaces" ] && drop_broadcasts `find_broadcast $zone`
    done

    norfc1918_interfaces="`find_interfaces_by_option norfc1918`"

    if [ -n "$norfc1918_interfaces" ]; then
	echo "Enabling IP Spoof Protection"

	createchain rfc1918
	
	for subnet in '10.0.0.0/8' '192.168.0.0/16' '172.16.0.0/12' ; do 
	    run_iptables -A rfc1918 -s $subnet -j LOG --log-prefix "Shorewall:rfc1918 " --log-level info
	    run_iptables -A rfc1918 -s $subnet -j DROP
	done

	for interface in $norfc1918_interfaces; do
	    run_iptables -A INPUT   -i $interface -j rfc1918
	    run_iptables -A FORWARD -i $interface -j rfc1918
        done
    else
	deletechain rfc1918
    fi

    # Enable the Loopback interface

    run_iptables -A INPUT   -i lo -j ACCEPT
    run_iptables -A OUTPUT  -o lo -j ACCEPT

    # Enable icmp output

    run_iptables -A OUTPUT -p icmp -j ACCEPT
    
    noping_interfaces="`find_interfaces_by_option noping`"

    for zone in $zones; do
	eval interfaces=\$${zone}_interfaces
    
	for interface in $interfaces; do
	    echo $noping_interfaces | qt grep $interface && target=DROP || target=ACCEPT
	    run_iptables -A ${zone}2fw -i $interface -p icmp --icmp-type echo-request -j $target
	done
    done

    [ -f /etc/shorewall/tunnels ] && echo "Processing /etc/shorewall/tunnels..." && setup_tunnels

    echo "Processing /etc/shorewall/rules..."
    
    process_rules

    echo "Adding rules for DHCP"
    
    mygrep "$zonepattern" /etc/shorewall/interfaces | while read zone interface subnet options; do
	if echo "$options" | qt grep dhcp ; then
	    run_iptables -A ${zone}2fw -p udp -i $interface --dport 67:68 -j ACCEPT
	    run_iptables -A fw2${zone} -p udp -o $interface --dport 67:68 -j ACCEPT
	fi
    done
    
    echo "Processing /etc/shorewall/policy..."

    mygrep "${zonepattern}\|^fw\|^all" /etc/shorewall/policy > /tmp/shorewallpolicy-$$

    for zone in fw $zones; do
	for zone1 in fw $zones; do
	    chain=${zone}2${zone1}
	    if havechain $chain ; then
		[ -f /etc/shorewall/$chain ] && . /etc/shorewall/$chain
		default_policy $zone $zone1
            fi
	done
    done

    rm -f /tmp/shorewallpolicy-$$

    [ -f /etc/shorewall/masq ] && setup_masq

    echo "Activating Rules..."

    for zone in $zones; do
	eval source_interfaces=\$${zone}_interfaces

	for interface in $source_interfaces; do
	    run_iptables -A INPUT -i $interface -j ${zone}2fw
	    run_iptables -A OUTPUT -o $interface -j fw2${zone}
        done
	
	for zone1 in $zones; do
	    eval dest_interfaces=\$${zone1}_interfaces
		
	    for interface in $source_interfaces; do
		for interface1 in $dest_interfaces; do
		    [ $interface = $interface1 ] || run_iptables -A FORWARD -i $interface -o $interface1 -j ${zone}2${zone1}
		done
	    done
	done
    done

    while read zone interface broadcast options; do
	for z in $zones; do
	    [ "x$z" = "x$zone" ] && echo "$options" | qt grep multi && run_iptables -A FORWARD -i $interface -o $interface -j ${zone}2${zone}
        done
    done < /etc/shorewall/interfaces
    
    for chain in INPUT OUTPUT FORWARD; do
	[ -f /etc/shorewall/$chain ] && . /etc/shorewall/$chain
	iptables -A $chain -j LOG --log-prefix "Shorewall:$chain " --log-level info
    done

    run_iptables -D INPUT 1
    run_iptables -D OUTPUT 1
    run_iptables -D FORWARD 1

    createchain shorewall
    
    echo "Shorewall ${1}ed"

    logger "Shorewall ${1}ed"
}    
#
# Give Usage Information
#
usage()
{
    echo "Usage: $0 {start|stop|reset|restart|status]}"
    exit 1
}
#
# Execution begins here
#
[ $# -gt 1 ] && [ "$1" = "debug" ] && { set -x ; shift ; }
[ $# -ne 1 ] && usage

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
#
# Clear all configuration variables
#
version=
LOCKFILE=
STATEDIR=

[ -f /etc/shorewall/version ] && version=`cat /etc/shorewall/version`
    
[ -f /etc/shorewall/shorewall.conf ] && . /etc/shorewall/shorewall.conf

[ -f /etc/shorewall/functions ] && . /etc/shorewall/functions || { echo "/etc/shorewall/functions does not exist!" ; exit 2; }

[ -n "${STATEDIR}" ] && STATEDIR=/var/state/shorewall

case "$1" in
    stop)
	echo -n "Stopping Shorewall..."
	determine_zones
	stop_firewall
        [ -n "$LOCKFILE" ] && rm -f $LOCKFILE
	echo "done."
	;;
    start)
	if havechain shorewall ; then
	    [ -n "$LOCKFILE" ] && touch $LOCKFILE
	    echo "Shorewall Already Started"
	    exit 0;
	fi 

	define_firewall "Start" && [ -n "$LOCKFILE" ] && touch $LOCKFILE
	;;
    restart)
	if havechain shorewall ; then
	    define_firewall "Restart"
	else
	    echo "Shorewall Not Currently Running"
	    define_firewall "Start"
	fi

	[ $? -eq 0 ] && [ -n "$LOCKFILE" ] && touch $LOCKFILE
	;;
    status)
	echo -e "Shorewall-$version Status at $HOSTNAME - `date`\\n"
	iptables -L -n -v
	;;
    reset)
	iptables -L -n -Z -v
	echo "Shorewall Counters Reset"
	logger "Shorewall Counters Reset"
	;;
    clear)
	echo -n "Clearing Shorewall..."
	determine_zones
	clear_firewall
        [ -n "$LOCKFILE" ] && rm -f $LOCKFILE
	echo "done."
	;;
    *)
	usage
	;;
esac 
