#! /bin/bash
#
# Split access
#
# Route to multiple ISPs via available links
# Sets TOS on links to choose routing ...
#
VERSION='$Id: split-access,v 1.39 2007/01/10 05:58:14 andrewm Exp $'
# 

# Priorities
PRIOTEST=108
PRIOOVERRIDE=109
PRIOBYSOURCE=32800
PRIOZONES=32910
PRIODEFAULT=32980
PRIOBALANCE=33000
PRIOOLDROUTES=42000
# Tables
TABLETEST=108
TABLEOVERRIDE=109
TABLEALLROUTES=33
TABLEOLDROUTES=42
TABLEZONE0=10
TABLEDEFAULT=90
TABLEINTERFACE0=100
# Hack it ...
TOSHACK=1

# Only run one of these thingies at a time, unless it's taking really long
LOCKFILE=/var/lock/split-access.lock
if ! lockfile -r 60 -10 -l 10800 $LOCKFILE ; then
        echo 1>&2 "Forcing lock $LOCKFILE pid `cat $LOCKFILE`"
        rm $LOCKFILE
fi
echo $$ > $LOCKFILE
trap '
    rm -f $LOCKFILE;
    ip route flush table $TABLETEST' EXIT


iptables=iptables
CMiptables=iptables  # true means don't use CONNMARK

# Where is the 'interfaces' file stored
VARRUN=/var/run/split-access
SCRIPT=$VARRUN/script
SCRIPTiptables=$VARRUN/script-iptables
INTERFACESFILE=$VARRUN/interfaces

touch $SCRIPT
cp $SCRIPT $SCRIPT.old
> $SCRIPT
> $SCRIPTiptables

# "true" means don't make connection marks
ETC=/etc/split-access
[ -d $ETC ] || ETC=.
#

# Build the file
function BUILD()
{
	echo "$@" >> $SCRIPT
}

# Build the file that gets run no matter what (iptables part)
function BUILDiptables()
{
	echo "$@" >> $SCRIPTiptables
}

function runBUILD()
{
	echo "## Applying iptables rules :: $SCRIPTiptables"
	source $SCRIPTiptables
	echo "## Applying routing rules :: $SCRIPT"
	source $SCRIPT
	echo "## Done"
}

# Note: Order of numbers: $TABLEINTERFACE0 < $PRIORITY < $TABLEOVERRIDE <
# $FWMARK < $TABLEALLROUTES
function getipforinterface()
{
  ifconfig $1 2>/dev/null | 
    sed '/inet addr:/ { s/.*inet addr:\([0-9.]*\).*/\1/ ; p } ; d' 
}

# Since we saved the default gw, or we have not yet fiddled it ..
function getdefaultgateway()
{
  {
  ip route ls ; 
  ip route ls table $TABLEALLROUTES 2>/dev/null
  # default via $IP dev $DEV
  } | 
  awk '($1 == "default" && $5 == "'$1'") { print $3; exit; }'
}

# Get the ptp for an interface
function getpointtopointpartner()
{
  ifconfig $1 2>/dev/null | sed '/P-t-P:/     { s/.*P-t-P:\([0-9.]*\).*/\1/ ;     p } ; d' 
}

# Guess the destination network - for P_NET preferred destination
function guessdestnetwork()
{
  echo "$1" | sed 's:[0-9]\+$:0/24:'
}

# remove_rules 100: remove all rules referring to table 100
function remove_rules()
{
  BUILD "# remove_rules $@"
  ip rule ls |
	  sed '/lookup '$1'/ {
	  	s/:// ;
		s/from all//;
		s/lookup/table/ ;
		p ;
		} ; d;'  |
	  while read rmRULE ; do BUILD ip rule del prio $rmRULE ; done
}

# remove_all_custom_rules -- drop all rules except main, local and default
function remove_all_custom_rules()
{
  BUILD "# remove_all_custom_rules $@"
  ip rule ls |
	sed '/\(main\|local\|default\)/ d;
		s/:// ;
		s/from all//;
		s/lookup/table/ ;'  |
	while read rmRULE ; do
		case "$rmRULE" in 
			*local) true ;;
			*main) true ;;
			*default) true ;;
			*) BUILD ip rule del prio $rmRULE
		esac
	done
}
# copy the 'main' routing table to the named routing table, but not its
# "default" route
function removedefaultsfrommaintable()
{
  ip route ls table main |
	sed '/^default / p; d ; '  |
	while read clROUTE ; do
		BUILD ip route add table $1 $clROUTE ;
		BUILD ip route del table main $clROUTE ;
	done
}

# "copytable 42000 main" adds rules from table 42000 to table main
# -- it doesn't work for multi-line routes (nexthop)
function copytable()
{
  ip route ls table $1 |
	while read clROUTE ; do
		BUILD ip route add table $2 $clROUTE ;
	done
}


# Stop the firewall
function stopit()
{
copytable $TABLEOLDROUTES main
# Revert to no configuration ...
for table in $TABLEOVERRIDE $TABLEALLROUTES $TABLEOLDROUTES; do
	BUILD ip route flush table $table
done
# unlink rules
remove_all_custom_rules

# FIXME: We should make our own table ...
BUILDiptables $iptables -t mangle -F splitpre
BUILDiptables $iptables -t mangle -F splitpos
BUILDiptables $iptables -t nat -F split

TABLE=$TABLEINTERFACE0
for CONFFILE in $ETC/*.conf extra anotherextra ; do
        let TABLE=TABLE+1
	# Remove old rules and routing info
	BUILD ip route flush table $TABLE
	remove_rules $TABLE
done
# remove 
ZONETABLE=$TABLEZONE0
for ZONEFILE in $ETC/*.zone $VARRUN/default.zone extra spare ; do
    remove_rules $ZONETABLE
    let ZONETABLE=ZONETABLE+1
done
BUILD ip route flush table cache

}

# Start the whole show -- flush all rules and make new ones.
# New rules for old!  New rules for old!
function startit()
{

mkdir -p $VARRUN
> $INTERFACESFILE

# Revert to no configuration ...
remove_rules $TABLEOVERRIDE
remove_rules $TABLEALLROUTES
remove_rules $TABLEOLDROUTES
BUILD ip route flush table $TABLEOVERRIDE
BUILD ip route flush table $TABLEALLROUTES
removedefaultsfrommaintable $TABLEOLDROUTES
BUILD ip rule add prio $PRIOOLDROUTES table $TABLEOLDROUTES

# FIXME: We should make our own table ...
BUILDiptables $iptables -t mangle -F split     "2>/dev/null"
BUILDiptables $iptables -t mangle -F splitpost "2>/dev/null"
BUILDiptables $iptables -t mangle -N split     "2>/dev/null"
BUILDiptables $iptables -t mangle -N splitpost "2>/dev/null"
BUILDiptables $iptables -t mangle -F splitpre  "2>/dev/null"
BUILDiptables $iptables -t mangle -F splitpos  "2>/dev/null"
BUILDiptables $iptables -t mangle -N splitpre  "2>/dev/null"
BUILDiptables $iptables -t mangle -N splitpos  "2>/dev/null"

BUILDiptables $iptables -t mangle -D PREROUTING  -j splitpre "2> /dev/null"
BUILDiptables $iptables -t mangle -I PREROUTING  -j splitpre
BUILDiptables $iptables -t mangle -D POSTROUTING -j splitpos "2> /dev/null"
BUILDiptables $iptables -t mangle -I POSTROUTING -j splitpos

#BUILDiptables $iptables -t mangle -D OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j CONNMARK --restore-mark
#BUILDiptables $iptables -t mangle -I OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j CONNMARK --restore-mark

BUILDiptables $iptables -t nat -F split "2>/dev/null"
BUILDiptables $iptables -t nat -N split "2> /dev/null"
BUILDiptables $iptables -t nat -D POSTROUTING -j split "2> /dev/null"
BUILDiptables $iptables -t nat -I POSTROUTING -j split

BUILDiptables $iptables -t mangle -A splitpre -j CONNMARK --restore-mark
# Clear all TOS before we start thinking about using it for routing
if [ $TOSHACK ] ; then
    BUILDiptables $iptables -t mangle -A splitpre -j TOS --set-tos 0
fi
# BUILDiptables $iptables -t mangle -A splitpre -m mark ! --mark 0 -j ACCEPT
# BUILDiptables $iptables -t mangle -A splitpos -m mark --mark 0 -j CONNMARK --restore-mark

#ip rule del prio $PRIOOVERRIDE table $TABLEOVERRIDE 2> /dev/null
#ip rule del prio $PRIOOVERRIDE table $TABLEOVERRIDE 2> /dev/null

BUILD ip rule add prio $PRIOOVERRIDE from all table $TABLEOVERRIDE
BUILD ip rule add prio $PRIOBALANCE from all table $TABLEALLROUTES

# Add ip rules for the various destinations
rm -f $VARRUN/*.knownzone
> $VARRUN/zones
ZONETABLE=$TABLEZONE0
echo 0.0.0.0/0 > $VARRUN/default.zone
for ZONEFILE in $ETC/*.zone $VARRUN/default.zone ; do
    ZONENAME=${ZONEFILE/*\//}   
    ZONENAME=${ZONENAME/.zone/} 
    [ "$ZONENAME" = "*" ] && continue
    if [ "$ZONENAME" = default ] ; then
        DESTPRIO=$PRIODEFAULT
        ZONETABLE=$TABLEDEFAULT
    else
        let DESTPRIO=$PRIOZONES+$ZONETABLE-$TABLEZONE0
    fi
    # Clear out previous rules ...
    remove_rules $ZONETABLE
    # We'll refer to this later ...  ('
    echo "$ZONENAME" >> $VARRUN/zones
    echo "$ZONETABLE" > $VARRUN/$ZONENAME.table
    true > $VARRUN/$ZONENAME.nexthops
    BUILD ip route flush table $ZONETABLE
    while read NETWORK COMMENT ; do
        case "$NETWORK" in
            [0-9]*)
                BUILD ip rule add prio $DESTPRIO from all to $NETWORK table $ZONETABLE
                ;;
            ""|"#"*)
                continue
                ;;
            *)
                echo 1>&2 "Warning: $ZONEFILE says $NETWORK $COMMENT"
                ;;
        esac
    done < $ZONEFILE
    let ZONETABLE=ZONETABLE+1
done

NEXTHOP=""
NEXTHOPTEMP=$VARRUN/lastresort.nexthops
> $NEXTHOPTEMP

# 32800
PRIORITY=$PRIOBYSOURCE
TABLE=$TABLEINTERFACE0
TOS=1
MARK=$TABLE
COUNTER=1
for CONFFILE in $ETC/*.conf ; do
	ZONES=default
	SHARED=
	P_NET=
	DESTS=
	PRIO=
        DNAT=
        ALLOWEDUSERS=
	source $CONFFILE
	# Here's what goes in the config files split*.conf:
	# PRIO TOS IF IP GW NET WEIGHT DESTS
	# PRIO: a number for this link 101-108
	# TOS: a fwmark number for incoming connections over this link 
	# IF: interface name (e.g. eth0)
	# IP: ip address of interface or "-"
	# GW: gateway to use "-" means use pointopoint, or default gw for eth0
	# NET: network that this links to, "-" means guess /24
	# WEIGHT: weighting of this link
	# DESTS: za: preferred bidder for .za traffic
	#   net1/mask net2/mask: route specific destinations only 

        IFNAME=$IF
        for IFTEST in $IF ; do
            case "$IFTEST" in
                eth*) continue;;  # exception! 'eth' can come up in ppp command lines!
                wlan*) continue;;
            esac
            # This means you can say IF=telkom3523541@telkomdsl.512net.net
            # and you'll get the interface that uses that account.
            IFCMDLINE=$(
                    fgrep -l "$IFTEST" $VARRUN/cmdline-* 2>/dev/null |
                    sed 's:.*cmdline-:: ; q'
                )
            [ "$IFCMDLINE" ] && IFNAME="${IFCMDLINE/ */}"  # select the first 
            # This means you can say IF=dsl-provider::
            [ -r $VARRUN/peer-ifname-$IFTEST ] && IFNAME=$(cat $VARRUN/peer-ifname-$IFTEST)
            BUILD "# echo 1>&2 'IFTEST=$IFTEST, IFCMDLINE=$IFCMDLINE IFNAME=$IFNAME '"
            echo "$IFNAME" > $VARRUN/linkname-$IFTEST
        done

	[ "$IP"    = "-" ] && IP=""
	[ "$GW"    = "-" ] && GW=""
	[ "$P_NET" = "-" ] && P_NET=""

	[ "$IP" = "" ]     && IP="$( getipforinterface $IFNAME )"

	[ "$GW" = "" ]     && GW="$( getpointtopointpartner $IFNAME )"
	[ "$GW" = "" ]     && GW="$( getdefaultgateway $IFNAME )"
	[ "$GW" = "" ]     && GW="$( getdefaultgateway $IFNAME )"

	# [ "$P_NET" = "" ] && P_NET="$(guessdestnetwork $GW)"

        # Auto priority and stuff 

        let PRIORITY=PRIORITY+1
        let TABLE=TABLE+1

	# Remove old rules and routing info
	BUILD ip route flush table $TABLE
	remove_rules $TABLE

	# Of course, if the interface isn't there, let's not use it
	[ "$IP" ] || continue

        let MARK=MARK+1
        let TOS=TOS*2
        let COUNTER=COUNTER+1

	# If the gateway is not arpable, then don't use the route either
        # Actually, ping
	if [ "$TEST" ] ; then
            #fping_s="fping -u -S"
            #if ! type -p fping >& /dev/null ; then
            #    echo 1>&2 "WARNING: cannot TEST= properly without fping - assuming OK"
            fping_s="ping -w 3 -c 1 -I"
            #fi

	    # This doesn't affect ppp connections
	    PING="$TEST"
	    [ "$TEST" = 1 ] && PING=$GW

            # There's a bit of a gotcha here ... if we ping something we have a
            # cached-and-invalid route to, then that's not going to work very
            # well...  don't ping the same thing for all routes!
            ip rule add prio $PRIOTEST from all table $TABLETEST
            ip route flush table $TABLETEST
            echo "## Testing to $TEST from $IP on dev $IFNAME via gw $GW"
            ip route add "$TEST" via "$GW" dev "$IFNAME" \
                src "$IP" table "$TABLETEST"
            PINGFAILED=
            $fping_s $IP $PING || PINGFAILED=1
            ip rule del prio $PRIOTEST from all table $TABLETEST
            ip route flush table $TABLETEST

            [ "$PINGFAILED" ] && {
	    	echo "## Failed to reach $TEST on dev $IFNAME via gw $GW"
	    	continue;
	    }
	    sleep 1
            # If there's an incomplete arp entry, then give up already
	    if arp -an | grep "($PING) at.*incomplete" ; then
	    	# this network is not up
	    	continue
	    fi
	fi

	# This interface is active
	echo "$IFNAME" >> $INTERFACESFILE
        echo 0 > /proc/sys/net/ipv4/conf/$IFNAME/rp_filter 

	# Routing for outgoing interface
#	ip route add $P_NET dev $IFNAME src $IP table $TABLE
	BUILD ip route add default via $GW dev $IFNAME  proto static  src $IP table $TABLE
	# Don't fall off ..
	# ip route append prohibit default table 20 metric 1 proto static
        # I don't think this is important 2006-07-07
        # BUILD ip route append prohibit default table $TABLE metric 1 proto static

#	ip route add default via $GW table $PRIORITY
	# Priority route for directly attached networks 
	[ "$P_NET" ] && {
	    for NET in $P_NET ; do
	        BUILD ip route add $NET dev $IFNAME via $GW src $IP table $TABLEOVERRIDE
	    done
	}
	# Add a rule to select this routing table for outgoing packets
	BUILD ip rule add prio $PRIORITY from $IP table $TABLE
	# Add rules for internal DNAT targets to use this for reply packets
	for anIP in $DNAT ; do
            BUILD ip rule add prio $PRIORITY from $anIP table $TABLE
	done
	for anIP in $ALLOWEDUSERS ; do
            BUILD ip rule add prio $((PRIODEFAULT-COUNTER)) from $anIP table $TABLE
	done
	# A rule for this packet's fwmark
        if [ $TOSHACK ] ; then
            BUILD ip rule add prio $((PRIORITY+10)) tos $TOS table $TABLE
        else
            BUILD ip rule add prio $((PRIORITY+10)) fwmark $MARK table $TABLE
        fi
	# BUILD ip rule add prio $TOS fwmark $TOS table $TABLE
	# If it's new, and it's coming in at this interface, then mark it - we
	# may be able to use the mark
	# First draft:
	# $CMiptables -t mangle -A split -i $IFNAME -d $IP -m mark --mark 0   -j MARK --set-mark $TOS

        # https://lists.netfilter.org/pipermail/netfilter/2006-March/065005.html
        iptables -t mangle -A splitpost -o $IFNAME -s $IP -m conntrack --ctstate NEW -j CONNMARK --set-mark $MARK

        # Use the correct gateway for reply packets from local connections

	# Second draft:
#        if [ $SHARED ] ; then
#            BUILDiptables $CMiptables -t mangle -A split -i $IFNAME -m state --state NEW      -j MARK --set-mark $MARK
#        fi

	# just in case
        [ $SHARED ] || {
            # Mark incoming new connections
            if [ $TOSHACK ] ; then
                BUILDiptables $CMiptables -t mangle -A splitpre -i ! $IFNAME -m mark --mark $MARK -j TOS --set-tos $TOS
            fi
            #BUILDiptables $CMiptables -t mangle -A splitpre -i $IFNAME -m mark --mark 0 -m conntrack --ctstate NEW  -d $IP -j MARK --set-mark $MARK
            #BUILDiptables $CMiptables -t mangle -A splitpos -o $IFNAME -m mark --mark 0 -m conntrack --ctstate NEW         -j MARK --set-mark $MARK
            BUILDiptables $CMiptables -t mangle -A splitpre -i $IFNAME -m mark --mark 0 -m conntrack --ctstate NEW  -d $IP -j MARK --set-mark $MARK
            BUILDiptables $CMiptables -t mangle -A splitpos -o $IFNAME -j MARK --set-mark $MARK
	}
	BUILD ip route add 127.0.0.0/8 dev lo table $TABLE

	#NEXTHOP="$NEXTHOP nexthop via $GW dev $IFNAME weight $WEIGHT"
	if [ "$DESTS" ] ; then
		for NET in $DESTS ; do 
			# 164.146.0.0/15 via 165.165.80.1 dev ppp0
			BUILD ip route add table $TABLEALLROUTES $NET via $GW dev $IFNAME
		done
	else
                [ "$WEIGHT" = 0 ] ||
		NEXTHOP="nexthop via $GW dev $IFNAME weight $WEIGHT"
		echo "$NEXTHOP" >> $NEXTHOPTEMP
                for ZONE in $ZONES ; do
                    [ "$ZONE" ] || continue;
                    [ -f $VARRUN/$ZONE.table ] || { echo 1>&2 "Warning: undefined zone $ZONE in $CONFFILE" ; }
                    echo "$NEXTHOP" >> $VARRUN/$ZONE.nexthops
                done
	fi
	# iptables -t nat -A split -o $IFNAME -j SNAT --to $IP
	BUILDiptables $iptables -t nat -A split -o $IFNAME -m mark --mark $MARK -j SNAT --to $IP

        if [ ! "$SHARED" ] ; then
            BUILDiptables $iptables -t nat -A split -o $IFNAME -j SNAT --to $IP
        fi
        for anIP in $DNAT ; do
            BUILDiptables $iptables -t nat -A split -o $IFNAME -s $anIP -j SNAT --to $IP
        done
done

BUILD ip route add default scope global table $TABLEALLROUTES $(cat $NEXTHOPTEMP)
cat $VARRUN/zones | while read ZONE ; do
    BUILD ip route add default scope global table $(cat $VARRUN/$ZONE.table) $(cat $VARRUN/$ZONE.nexthops)
done

#BUILDiptables $CMiptables -t mangle -A splitpre -m mark ! --mark 0 -j CONNMARK --save-mark
#BUILDiptables $CMiptables -t mangle -A splitpos -m mark ! --mark 0 -j CONNMARK --save-mark
BUILDiptables $CMiptables -t mangle -A splitpre -j CONNMARK --save-mark
BUILDiptables $CMiptables -t mangle -A splitpos -j CONNMARK --save-mark


# za route:
# 
# birdie:~ # ip route ls table main | head
# 127.0.0.0/8 dev lo  scope link
#
# 196.41.11.0/25 via 165.165.80.1 dev ppp0
# 196.41.11.128/25 via 165.165.80.1 dev ppp0
# 168.210.133.128/25 via 165.165.80.1 dev ppp0
# 196.4.160.0/24 via 165.165.80.1 dev ppp0
# 196.13.232.0/24 via 165.165.80.1 dev ppp0
# 196.4.161.0/24 via 165.165.80.1 dev ppp0
# 196.4.162.0/24 via 165.165.80.1 dev ppp0
#
# birdie:~ # ip route ls table main | tail
# 196.30.0.0/15 via 165.165.80.1 dev ppp0
# 163.198.0.0/15 via 165.165.80.1 dev ppp0
# 196.34.0.0/15 via 165.165.80.1 dev ppp0
# 165.144.0.0/15 via 165.165.80.1 dev ppp0
# 137.214.0.0/15 via 165.165.80.1 dev ppp0
# 163.202.0.0/15 via 165.165.80.1 dev ppp0
# 164.146.0.0/15 via 165.165.80.1 dev ppp0
# 164.148.0.0/14 via 165.165.80.1 dev ppp0
# default via 165.146.0.1 dev ppp1
BUILD ip route flush cache
}

function autoconfig()
{
	FWMARK=110

	for IFNAME in eth0 ppp0 ppp1 ; do
		FWMARK=$((FWMARK+1))
		[ -e $IFNAME.conf ] ||
		cat > $IFNAME.conf << EOF
# Configuration file for split-ppp*

# IF: interface name (e.g. eth0)
# You can also specify the name of a ppp peer.  If you are using "pppd call
# dsl-provider" to start the connection, or "pon dsl-provider" then you can
# say "IF=dsl-provider" here.  You can also specify a list of peers that may
# provide this connection, IF="provider1 provider2":
IF=$IFNAME

# IP: ip address of interface or "-"
IP=-

# GW: gateway to use "-" means use pointopoint, or default gw for eth0
GW=-

# NET: network that this links to, "-" means guess /24
NET=-

# WEIGHT: weighting of this link
WEIGHT=1

# P_NET: Destinations which this route used for - peer network.
# i.e. your ISP's mail server
P_NET=

# DESTS: If this route is used *only* for specific hosts, then list those
#   hosts here.  This means that the route is not balanced with other routes.
#   e.g. \$(cat za.dests) : preferred bidder for .za traffic
#   net1/mask net2/mask: route specific destinations only 
DESTS=

# DNAT: Destinations *inside* which are are DNATed from the outside.
# If you have 5 ISPs delivering mail, you need to DNAT to five different
# internal IP's - one for each external interface.  The IP address of reply
# packets (before un-NAT) is used to determine which outgoing interface is
# selected.
DNAT=10.10.10.$FWMARK

# ALLOWEDUSERS: Destinations inside your network which are allowed to use this
# link -- if they don't find another non-default link first.
ALLOWEDUSERS=

# TEST: Set TEST=1 if the interface should be tested for connectivity
TEST=

# SHARED subnet: If there is more than one gateway on this subnet, then
# we can't use the fact that we're going out here as a reason to SNAT.
SHARED=

# ZONES: what *.zone file lists IP addresses this link is good for
ZONES=default

EOF
	done
}

function version()
{
	VERSION="${VERSION/*,v /}"
	VERSION="${VERSION/ */}"
	echo "$0 $VERSION"
}

# MAIN ------------------
# If we are run in /etc/ppp/ip-up.d/
pppBASENAME=${0##*/}
pppINTERFACE=$1
pppDEVICE=$2
pppSPEED=$3
pppLOCALIP=$4
pppREMOTEIP=$5
pppIPPARAM=$6

# Automatic behaviour for ppp0
if [ "$pppLOCALIP" ] ; then
        # record that 'pppd call fooxey' brought up interface ppp13

        # this works from pppd-2.4.4
        [ "$CALL_FILE" ] && echo $IFNAME > $VARRUN/peer-ifname-$CALL_FILE

        # Capture the PPPD command line so we can grep it later to figure out
        # which of our many ppp accounts is running on this interface
        ps wwwp $PPPD_PID | tail -1 > $VARRUN/cmdline-$IFNAME
        # Usually that's going to store something like "1231 root 1 R 00:01
        # pppd call foobar"

	PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11
	export PATH

        # just in case we are running caching local server, and it needs to
        # re-bind to new addresses:
        rndc reload

	version
	startit
	runBUILD
	# And now do a DDDNS update, since things have changed a little
	dddns "$@"
	exit
fi

case "$1" in 
	status)
		version
		echo "ip rule ls rules ##"
		ip rule ls
		ip rule ls | sed 's/.*lookup //' | uniq |
		while read x; do
			echo ; echo "ip route ls table $x ##"
			ip route ls table $x ;
		done
		;;
	stop)
		version
		stopit
		runBUILD
		;;
	debug)
		version
		echo "# Building script..."
		startit
		echo "# NOT applying routing rules..."
		;;

	start)
		version
		echo "# Building script..."
		startit
		echo "# Applying routing rules..."
		runBUILD
		# And now do a DDDNS update, since things have changed a little
		dddns
		;;

	trouble)
		*conf
		;;
	reload)
		removedefaultsfrommaintable $TABLEOLDROUTES
		;;
	autoconfig)
		autoconfig;;
	install)
		cp $0 /usr/local/bin/split-access
		mkdir -p /etc/split-access
		autoconfig

		DIR=/etc/ppp/ip-up.d
		[ -d $DIR ] && ln -s /usr/local/bin/split-access $DIR/split-access

		DIR=/etc/ppp/ip-down.d
		[ -d $DIR ] && ln -s /usr/local/bin/split-access $DIR/split-access

		if [ -d /etc/shorewall ] ; then
			grep -q split-access /etc/shorewall/start || echo "/usr/local/bin/split-access start" >> /etc/shorewall/start
		fi
		;;
	*)
		version
		echo "$0 [start|stop|status]"
		echo "  start     set up split rules"
		echo "  stop      revert to vanilla routing"
		echo "  debug     create rules in $VARRUN"
		echo "  trouble   tcpdump interfaces for non-snat packets"
		echo "  status    show ip rules"
		echo "  install   write blank configs for eth0, ppp0-2 in /etc/split-access"
		echo "            and trigger in /etc/ppp/ip-up.d and /etc/ppp/ip-down.d/"
		echo ""
		echo "Although you are welcome to ask questions, the code is"
		echo "the only documentation at the moment"
		;;
esac



