#!/bin/bash

# Check the WAN and 3G connections to see if they work.
# Re-configure the networking if they don't work.
# Restart the VPN if we change anything significant pertaining to the network

LOCKFILE=/tmp/wanmanager

if [ -f $LOCKFILE ] ; then
 exit
fi

touch $LOCKFILE

WAN=eth1
WANBAD=/tmp/eth1badgateway
WANGW=/tmp/eth1gateway
WANOK=0
GATEWAY=undefined

WWAN=3g-3G
WWANOK=0

TESTSERVER1=`cat /etc/testserver1`
TESTSERVER2=`cat /etc/testserver2`
TESTSERVER3=`cat /etc/testserver3`


# store default gateway in $WANGW if not already there
netstat -rn | grep ^0\. | grep $WAN 1>/dev/null 2>/dev/null && {
   # we have a gateway too

   GATEWAY=`netstat -rn | grep ^0\. | grep $WAN | awk '{print $2}'`
   echo $GATEWAY > $WANGW 

   # If there is no WAN link then clearly WAN is not OK and we should not use it as a default route
   /usr/bin/wanlink || { 
	route del default gw $GATEWAY
	WANOK=-1
   }

echo test 1 >> $LOCKFILE
# end checking default gateway
}

/usr/bin/wanlink && {
# we have an ethernet link
echo "test 2 - WANLINK returned true" >> $LOCKFILE

 # Maybe there was a gateway existed but we deleted it in a previous run
 #  (due to no ethernet link, or unreachable MSI servers)

 if [ "$GATEWAY" == "undefined" ] ; then {
  echo "test 2.5"  >> $LOCKFILE
  if [ -f $WANGW ] ; then GATEWAY=`cat $WANGW` 
  elif [ -f $WANBAD ] ; then GATEWAY=`cat $WANBAD`
  fi

 }
 fi

echo "test 3" >> $LOCKFILE

 if [ "$GATEWAY" != "undefined" ] ; then
   echo test 3.2 >> $LOCKFILE

   # Check if we can ARP for the existing or previous gateway. If not then ethernet is not working OK.
   arping -q -c 3 -f -I $WAN $GATEWAY || {
      echo $GATEWAY > $WANBAD
      WANOK=-1
   }
   arping -q -c 3 -f -I $WAN $GATEWAY && {
      echo "test 3.5 - gateway responds to ARP" >> $LOCKFILE

      # The gateway is ARPable, let's try adding it as a default route and see if it works now
      netstat -rn | grep ^0\. | grep $WAN 1>/dev/null 2>/dev/null || {
	echo "No default gateway - adding $GATEWAY"  >> $LOCKFILE
	logger -t wanmanager "SETTING DEFAULT WAN GATEWAY TO ETHERNET"
	route add default gw $GATEWAY
	/etc/init.d/openvpn restart 1>/dev/null 2>/dev/null
      }

      WANOK=0
   }

 fi

echo test 4 >> $LOCKFILE

 # If we have link and the gateway is ARPable, then proceed with network testing
 # Check if we can reach any our test servers with ICMP. Even one response is success.

 netstat -rn | grep ^0\. | grep $WAN 1>/dev/null 2>/dev/null || {
 # OMG there's no default gateway.
 # Re-add the default gateway if there isn't one, so this test has a chance at working.
 # It will get deleted again and hopefully nothing of value will be lost if the ping tests don't pass.

 # The network will be in a nonfunctional state for 6 seconds if we add a non-working default gateway.
  echo "No default gateway - adding $GATEWAY" >> $LOCKFILE
  logger -t wanmanager "SETTING DEFAULT WAN GATEWAY TO ETHERNET"
  route add default gw $GATEWAY
  /etc/init.d/openvpn restart 1>/dev/null 2>/dev/null
 }

 TESTIF=$WAN

 if [ "$WANOK" == "0" ] ; then ping -q -c 3 -W 4 -I $TESTIF -n $TESTSERVER1 | grep -i rtt 1>/dev/null 2>/dev/null && WANOK=1 ; fi
 if [ "$WANOK" == "0" ] ; then ping -q -c 3 -W 4 -I $TESTIF -n $TESTSERVER2 | grep -i rtt 1>/dev/null 2>/dev/null && WANOK=1 ; fi
 if [ "$WANOK" == "0" ] ; then ping -q -c 3 -W 4 -I $TESTIF -n $TESTSERVER3 | grep -i rtt 1>/dev/null 2>/dev/null && WANOK=1 ; fi

 # if WANOK != 1 then delete the default route on ethernet because it doesn't seem to work
 if [ "$WANOK" != "1" ] ; then {
	netstat -rn | grep ^0\. | grep $WAN 1>/dev/null 2>/dev/null && {
	route del default gw $GATEWAY
	}
 }
 fi

# end if we have ethernet link on $WAN
}

echo test 5 >> $LOCKFILE

if [ "$WANOK" == "1" ] ; then {
# If WANOK=1 then stop here. We prefer the WAN connection over ethernet, so no 3G testing.

  # delete the 3G default route if ethernet works OK
  netstat -rn | grep ^0\. | grep $WWAN 1>/dev/null 2>/dev/null && {
  route del default dev $WWAN
  }

  rm -f $LOCKFILE
  exit 0
 }
fi

# If we get to this point, then WAN is not OK and we should try to use 3G.

echo test 6 >> $LOCKFILE

# This wanmanager script switches between ethernet and WAN.
# See what we have for 3G interface. It might be down, up, or connecting.

ifconfig 3g-3G | grep "UP POINTOPOINT" 1>/dev/null 2>/dev/null && {
# We have a WWAN connection, make sure it works.

 netstat -rn | grep ^0\. | grep $WWAN 1>/dev/null 2>/dev/null || {
 # OMG there's no default gateway.
  logger -t wanmanager "SETTING DEFAULT WAN GATEWAY TO 3G"
  echo "No default gateway - adding $WWAN" >> $LOCKFILE
  route add default dev $WWAN
  /etc/init.d/openvpn restart 1>/dev/null 2>/dev/null

 }

echo test 7 >> $LOCKFILE

 TESTIF=$WWAN

 if [ "$WWANOK" == "0" ] ; then ping -q -c 3 -W 4 -I $TESTIF -n $TESTSERVER1 | grep -i rtt 1>/dev/null 2>/dev/null && WWANOK=1 ; fi
 if [ "$WWANOK" == "0" ] ; then ping -q -c 3 -W 4 -I $TESTIF -n $TESTSERVER2 | grep -i rtt 1>/dev/null 2>/dev/null && WWANOK=1 ; fi
 if [ "$WWANOK" == "0" ] ; then ping -q -c 3 -W 4 -I $TESTIF -n $TESTSERVER3 | grep -i rtt 1>/dev/null 2>/dev/null && WWANOK=1 ; fi

 # if WWANOK != 1 then delete the default route because it doesn't seem to work anyway
 if [ "$WWANOK" != "1" ] ; then {
	netstat -rn | grep ^0\. | grep $WWAN 1>/dev/null 2>/dev/null && {
	route del default dev $WWAN
	}
 }
 fi

# end if 3g-3G is up
}

echo test 8 >> $LOCKFILE

if [ "$WWANOK" == "1" ] ; then {
# If WWANOK=1 then stop here. No further 3G testing or switching if it works OK.

  rm -f $LOCKFILE
  exit 0
 }
fi

echo test 9 >> $LOCKFILE

# If we get here then something is wrong and neither WANOK or WWANOK are set. :(

if [ ! -f /tmp/changingproviders ] ; then
 # only do this if the /tmp/changingproviders mutex/lockfile does not exist
 # If that file DOES exist then that means the user has specified a 3G provider
 #  change and the change is in progress.

 touch /tmp/changingproviders

 echo test 9.4 - changing 3G providers >> $LOCKFILE
 
 grep automatic /etc/config/preferredprovider 1>/dev/null 2>/dev/null && {
 # If wanpreferred is set to automatic then we can try the other WWAN connection.

  /usr/bin/isverizon && ln -sf /etc/config/network.att /etc/config/network || ln -sf /etc/config/network.verizon /etc/config/network
  logger -t wanmanager "UNABLE TO ESTABLISH WAN CONNECTION; CHANGING PROVIDERS & RESTARTING 3G"
  echo "Trying to switch 3G providers... wait 60 seconds" >> $LOCKFILE
  ifdown 3G 1>/dev/null 2>/dev/null
  sleep 2
  ifup 3G 1>/dev/null 2>/dev/null

  # If we down the 3G connection we shouldn't rerun this script while it's trying to
  #  redial, so give it a minute to try to connect.  This sleep 60 is just a guess at
  #  the timing required for this to be reliable.
  sleep 60
  /etc/init.d/openvpn restart 1>/dev/null 2>/dev/null

 # end automatic preferred provider
 } 

 # release the mutex
 rm -f /tmp/changingproviders

fi 

# Clean up and exit
rm -f $LOCKFILE
