#!/bin/sh
# wanrouter	WAN Router Initialization Script.
#
# Debian: renamed to "wanpipe"
#
# copyright	(c) 1999, Sangoma Technologies Inc.
#
#		This program is free software; you can redistribute it and/or
#		modify it under the terms of the GNU General Public License
#		as published by the Free Software Foundation; either version
#		2 of the License, or (at your option) any later version.
# ============================================================================
# Nov 09, 1999  Nenad Corbic    o Updated for v2.1.1
#                               o Enabled starting and stoping
#                                 each wanpipe device separately.
# Nov 09, 1999  Nenad Corbic    Updated for v2.1.1
# Oct 04, 1999  Nenad Corbic    Updated for v2.1.0
# Aug 04, 1999  Nenad Corbic    Updated for v2.0.5
# Oct 15, 1998	Jaspreet Singh	Updated for v2.0.4
# Dec 09, 1997	Jaspreet Singh	Updated for v2.0.2
# Nov 28, 1997	Jaspreet Singh	Updated for v2.0.1
# Nov 06, 1997	Jaspreet Singh	Updated for v2.0.0
# Jul 28, 1997	Jaspreet Singh	Updated for v1.0.5
# Jul 10, 1997	Jaspreet Singh	Updated for v1.0.4
# Dec 15, 1996	Gene Kozin	Initial version based on Sangoma's WANPIPE(tm)
# ============================================================================
#
# Debian patches by <tmancill@debian.org>
# 20000115/tm	modified default rc filename

####### FUNCTION DEFINITIONS #################################################

# ----------------------------------------------------------------------------
# Check to see if a value belongs to the list.
# Return:	0 - yes
#		1 - no
# ----------------------------------------------------------------------------
check_list()
{
	[ $# -lt 2 ] && return 1

	val=$1
	shift
	for i in $*
	do [ "$val" = "$i" ] && return 0
	done
	return 1
}

# ----------------------------------------------------------------------------
# Display error message.
# ----------------------------------------------------------------------------
error() {
	echo -e "$SCRIPT: $*!"
	[ -f "$ROUTER_LOG" ] && echo -e "$*!" >> $ROUTER_LOG
	return 0
}

# ----------------------------------------------------------------------------
# Configure network interface.
# This routine performs TCP/IP-level interface configuration.  Interface name
# is given as an argument. It reads a configuration file with the same name in
# and calls ifconfig and route to do the job.
#
# Configuration file is actually a shell script containing only variables:
#
#	ONBOOT=yes			if not 'yes' then skip this file
#	IPADDR=xxx.xxx.xxx.xxx		IP address of this interface
#	NETMASK=xxx.xxx.xxx.xxx		Network mask for this interface
#	NETWORK=xxx.xxx.xxx.xxx		Network address
#	BROADCAST=xxx.xxx.xxx.xxx	Broadcast address
#	POINTOPOINT=xxx.xxx.xxx.xxx	Point-to-point address
#	GATEWAY=xxx.xxx.xxx.xxx		Gateway address
# ----------------------------------------------------------------------------
interface_up()
{
	# Clear variables and read the definitions file in
	ONBOOT=
	IPADDR=
	NETMASK=
	NETWORK=
	BROADCAST=
	POINTOPOINT=
	GATEWAY=
	. $1

	[ "${ONBOOT}" != "yes" -o -z "$IPADDR" ] && { 
		echo -e "\n\nERROR in $IFCONF_DIR/$1 interface file !!!"
		echo -e "  ONBOOT is not equal to LOWERCAP yes. OR" 
	        echo -e "  Local IP address is not set\n"
		echo -e "  wanpipe start failed !!!\n"
		return 0
      	}

	# Configure interface.
	[ "$IPADDR" ] && {
		# Prepare ifconfig options.
		OPTIONS=
		[ "$NETMASK" ] && OPTIONS="$OPTIONS netmask $NETMASK"
		[ "$BROADCAST" ] && OPTIONS="$OPTIONS broadcast $BROADCAST"
		[ "$POINTOPOINT" ] && OPTIONS="$OPTIONS pointopoint $POINTOPOINT"

		ifconfig $1 $IPADDR $OPTIONS
	}

	# Update routing table.
	uname -r | grep "2.0.*" > /dev/null
	if [ $? -eq 0 ] 
	then
		[ "$POINTOPOINT" ] && route add -host $POINTOPOINT
	fi

	[ "$NETWORK" ] && {
		OPTIONS="-net $NETWORK"
		[ "$NETWORK" != 0 ] && {
		[ "$NETMASK" ] && OPTIONS="$OPTIONS netmask $NETMASK"
		}
		[ "$GATEWAY" ] && OPTIONS="$OPTIONS gw $GATEWAY"
		route add $OPTIONS $1
	}
	return 0
}

# ----------------------------------------------------------------------------
# Start WAN wanrouter.
#	o create log file
#	o check configuration file presence
#	o load WAN drivers (using modprobe)
#	o configure drivers
#	o configure interfaces
# ----------------------------------------------------------------------------
router_load()
{

	echo "Starting WAN Router..."
	echo "`date`: starting WAN router" > $ROUTER_LOG

	[ -f "$MOD1" ] || {
		mod_error $MOD1
		return 1
	}
		
        [ -f "$MOD2" ] || {
		mod_error $MOD2 
                return 1
        }           
        [ -f "$MOD3" ] || {
		mod_error $MOD3 
                return 1
        }          

#	[ -f "$ROUTER_CONF" ] || {
#		error "Configuration file $ROUTER_CONF not found"
#		return 1
#	}

	[ "$ROUTER_BOOT" = "NO" -o -z "$WAN_DRIVERS" ] && { 

		echo -e "\n\nERROR in $WANPIPE_CONF_DIR/router.rc file !!!" 
		echo -e "   ROUTER_BOOT is set to NO, OR" 
		echo -e "   WAN_DRIVERS must be set to wanpipe\n"
		echo -e "   wanpipe start failed !!!\n" 
		return 1
  	}

	echo -n "Loading WAN drivers: "
	for i in $WAN_DRIVERS
	do
		lsmod | grep -wq $i && continue
		echo -n "$i "
		echo -n "Loading driver $i ... " >> $ROUTER_LOG
		if modprobe $i
		then echo "ok" >> $ROUTER_LOG
		else echo "fail" >> $ROUTER_LOG
		fi
	done
	echo "done."
	return 0
}

router_config()
{
	# Configure router.
	# $1 = /etc/wanpipe#.conf  where # is an integer
	wanconfig -v -f $1 >> $ROUTER_LOG
	return 
}

interf_config()
{
	local device=$1
	local ROUTER_CONF=$2
	local int_file
	local INTERFACES

	# Configure network interfaces.
	[ -d "$IFCONF_DIR" ] || {
		error "Directory $IFCONF_DIR not found"
		return 1
	}
	cd $IFCONF_DIR
	INTERFACES=`grep ".*=.*$device" -i $ROUTER_CONF | cut -d' ' -f1`
	[ -z "$INTERFACES" ] && {
		error "No interface definitions found in $ROUTER_CONF"
		return 1
	}
	echo -n "Configuring interfaces: "
	for i in $INTERFACES
	do      
		int_file=${i%%=*}
		if [ -s $int_file ]; then
			cat /proc/net/dev | grep -wq $int_file || continue
			echo -n "$int_file "
			interface_up $int_file || {
				error "Failed to configure interface $int_file"
				continue
			}
		else
			echo "Error Interface File $int_file not found"
			return 1;
		fi
	done
	echo "done."

	return 0
}

# ----------------------------------------------------------------------------
# Stop WAN router.
#	o shut down interfaces
#	o unload WAN drivers
#	o remove lock file
# ----------------------------------------------------------------------------
interf_down()
{
	local device=$1
	local ROUTER_CONF=$2
	local int_file
	local INTERFACES

	# Shut down network interfaces.
	[ -d "$IFCONF_DIR" ] && {
		cd $IFCONF_DIR
		INTERFACES=`grep ".*=.*$device" -i $ROUTER_CONF | cut -d' ' -f1`
		for i in $INTERFACES
		do
			int_file=${i%%=*}
			cat /proc/net/dev | grep -wq $int_file || continue
			echo "Shutting down $device interface: $int_file"
			ifconfig $int_file down
		done
	}
}

router_unconfig()
{
	wanconfig -v -d $1 >> $ROUTER_LOG
	# Unload WAN drivers.
}

router_unload()
{
	for i in $WAN_DRIVERS
	do lsmod | grep -wq $i && {
		modprobe -r $i
	}
	done
	rm -f $ROUTER_LOCK 2> /dev/null
}

mod_error()
{
	echo -e "\n"
        error "Wanpipe Module: $1 not found !!!"
        echo -e "        WANPIPE drivers must be compiled as modules"
        echo -e "        Check kernel configuration in /usr/src/linux/.config: "
        echo -e "             CONFIG_WAN_ROUTER=m"
        echo -e "             CONFIG_VENDOR_SANGOMA=m\n"               
}

get_distrib()
{
	grep -i "red *hat" "/etc/issue" > /dev/null 
	if [ $? -eq 0 ]
	then
		return 1; #RedHat Found
	else
		return 0;
	fi

}

check_config()
{
	for dev in $WAN_DEVICES; do
		check_file "$WANPIPE_CONF_DIR/$dev.conf" || {
				echo -e "\n$SCRIPT: Error, $WANPIPE_CONF_DIR/$dev.conf not found!\n";
				return 1;
				}
	done
	return 0;
}

check_file()
{
	local file=$1

	[ ! -f "$file" ] && {
			if [ ! -z $file ]; 
			then
				echo -e "ERROR: Wanpipe configuration file not found: $file\n"
			else
				echo -e "ERROR: Wanpipe configuration file not found in $WANPIPE_CONF_DIR\n"
			fi
			return 1;
	}
	return 0;
}

print_active_devices()
{
	local ac_list;
	local ac_wan;

	echo -en "\t" 

	#If /proc directory doesn't exist nothing
        #to print, thus exit
	[ ! -d "$ROUTER_PROC" ] && return 0 

	cd $ROUTER_PROC
	ac_list=`ls wanpipe*`;
	for ac_wan in $ac_list; do
		res=`grep "Device is not configured" $ROUTER_PROC/$ac_wan`
		[ -z "$res" ] && {
			echo -n "$ac_wan "
		}
	done		
	echo -e "\n" 

	cd $ROUTER_HOME

	return 0
}

check_running ()
{

	local device=$1
	local res

	
	[ ! -d "$ROUTER_PROC" ] && return 1  #Device not running

	cd $ROUTER_PROC
	
	res=`grep "Device is not configured" $ROUTER_PROC/$device`
	[ -z "$res" ] && {
			#Device running
			return 0
		}
	
	#Device not running
	return 1;
}

check_and_print_still_running ()
{
	local WAN_LIST
	local res
	local wan

	cd $ROUTER_PROC
	WAN_LIST=`ls wanpipe*`	
	for wan in $WAN_LIST; do
		res=`grep "Device is not configured" $ROUTER_PROC/$wan`
		[ -z "$res" ] && {
			echo "Devices still running:"
			print_active_devices;
			return 0
		}
	done		
	cd $ROUTER_HOME

	return 1
}

####### MAIN #################################################################
# set -x

export PATH=/sbin:/bin:/usr/sbin:/usr/bin
ROUTER_VERSION=2.1.1
ROUTER_RC=/etc/wanpipe/router.rc
ROUTER_HOME=/etc/wanpipe
IFCONF_DIR=$ROUTER_HOME/interfaces
SCRIPT=wanpipe
REDHAT=/usr/src/redhat
ROUTER_PROC=/proc/net/wanrouter
WAN_DRIVERS=wanpipe
MOD1=/lib/modules/$(uname -r)/misc/wanrouter.o
MOD2=/lib/modules/$(uname -r)/net/wanpipe.o
MOD3=/lib/modules/$(uname -r)/net/sdladrv.o

# Ignore interrupt signals.
trap '' 2

# Read meta-configuration file.
if [ -f $ROUTER_RC ]
then . $ROUTER_RC
else echo "$SCRIPT: WARNING: $ROUTER_RC not found! Using defaults."
fi

# Set default configuration.
ROUTER_BOOT=${ROUTER_BOOT:=YES}
WANPIPE_CONF_DIR=${WANPIPE_CONF_DIR:=/etc/wanpipe}
ROUTER_LOG=${ROUTER_LOG:=/var/log/wanpipe}
ROUTER_LOCK=${ROUTER_LOCK:=/var/lock/wanpipe}
WAN_DEVICES=${WAN_DEVICES:="wanpipe1"}

#
# what's the point in this? (tm)
#
#get_distrib || { 
#
#     if [ $ROUTER_LOCK != "/var/lock/subsys/wanrouter" ] 
#     then 
#	 echo -e "\nREDHAT Detected changing ROUTER_LOCK location"
#         echo -e "to /var/lock/subsys/wanrouter"
#	 echo -e "To avoid this message change the ROUTER_LOCK directory"
#         echo -e "in $WANPIPE_CONF_DIR/router.rc to /var/lock/subsys/wanrouter\n"
#	 ROUTER_LOCK=/var/lock/subsys/wanrouter
#     fi 
#}

echo
# See how we were called.
case "$1" in
	start)	
		# ROUTER START
		if [ -z $2 ]; then	

			check_config || exit 1

			[ -f "$ROUTER_LOCK" ] && {
				echo -e "Router is already running. Stop it first!\n"
				exit 1
			}
			router_load && touch $ROUTER_LOCK

			for dev in $WAN_DEVICES; do
				[ ! -e "$ROUTER_PROC/$dev" ] && {
					echo -e "Error: Device $dev is not supported by kernel\n"
					exit 1
				}
				ROUTER_CONF=$WANPIPE_CONF_DIR/$dev.conf
				echo "Starting up device: $dev"
				echo "Starting up device: $dev" >> $ROUTER_LOG
				router_config $ROUTER_CONF
			done
			
			for dev in $WAN_DEVICES; do
				ROUTER_CONF=$WANPIPE_CONF_DIR/$dev.conf
				interf_config $dev $ROUTER_CONF
			done

		else
		#ROUTER START WANPIPE

			dev=$2
			ROUTER_CONF=$WANPIPE_CONF_DIR/$dev.conf

			check_file $ROUTER_CONF || exit 1

			[ ! -f "$ROUTER_LOCK" ] && {
				router_load && touch $ROUTER_LOCK
			}	

			res=`grep "Device is not configured" $ROUTER_PROC/$dev`
			[ -z "$res" ] && {
				echo "Device $dev is still running"
				echo -e "Run wanpipe stop $dev first\n"
				exit 1
			}
		
			#Configure a separate WANPIPE device
			echo "Starting up device: $dev"
			echo "Starting up device: $dev" >> $ROUTER_LOG
			router_config $ROUTER_CONF
			interf_config $dev $ROUTER_CONF
		fi
		;;
	stop)	
		
		#ROUTER STOP
		if [ -z $2 ]; then

			#Check that all wanpipe#.conf file defined in 
			# WAN_DEVICES exist
			check_config || exit 1

			[ ! -f "$ROUTER_LOCK" -o ! -d "$ROUTER_PROC" ] && {
				echo -e "Router is already stopped !\n"
				exit 1
			}

			#Stop all interfaces, but check whether 
                        #device is running first
			for dev in $WAN_DEVICES; do
				ROUTER_CONF=$WANPIPE_CONF_DIR/$dev.conf
				check_running $dev || continue
				interf_down $dev $ROUTER_CONF
			done

			#Stop all routers but check if device
			#is running first
			for dev in $WAN_DEVICES; do
				check_running $dev || continue
				ROUTER_CONF=$WANPIPE_CONF_DIR/$dev.conf
				echo "Shutting down device: $dev"
				echo "Shutting down device: $dev" >> $ROUTER_LOG
				router_unconfig $ROUTER_CONF
			done


			#Check if any devices are still running
			#  If YES: don't unload the modules, just printout
			#	   the list of active devices
			#  If NO:  unload modules
			check_and_print_still_running && exit 0

			echo -e "No devices running, Unloading Modules"
			router_unload

		else
		#ROUTER STOP WANPIPE

			dev=$2
			ROUTER_CONF=$WANPIPE_CONF_DIR/$dev.conf

			#Check that all configuration files exist
			check_file $ROUTER_CONF || exit 1

			#Check that modules are up and running
			[ ! -f "$ROUTER_LOCK" -o ! -d "$ROUTER_PROC" ] && {
				echo -e "Router is already stopped !\n";
				exit 1;
			}


			#Check that device is running first
			check_running $dev || {
					echo -e "Device $dev is already stopped\n"
					exit 0;
					}

			#Bring down the interface and router
			interf_down $dev $ROUTER_CONF
			echo "Shutting down device: $dev"
			echo "Shutting down device: $dev" >> $ROUTER_LOG
			router_unconfig $ROUTER_CONF
			

			#Check if any devices are still running
			#  If YES: don't unload the modules, just printout
			#	   the list of active devices
			#  If NO:  unload modules
	
			check_and_print_still_running && exit 0

			cd $ROUTER_HOME
			echo -e "No devices running, Unloading Modules"
			router_unload

		fi			
		;;
	list)
		
		[ -f "$ROUTER_LOCK" ] || {
				echo -e "Router is stopped !\n";
				exit 1;
		}
		
		echo -e "Devices currently active:"
		print_active_devices;
		exit 1;

		;;
	*)	echo -e "\nWAN Router startup script"
		echo -e "Usage: $SCRIPT: {start|stop} <wanpipe#> optional\n"
		echo -e "       wanpipe start : Starts all devices specified in"
		echo -e "                      $WANPIPE_CONF_DIR/router.rc WAN_DEVICES\n"
		echo -e "       wanpipe stop  : Stops all devices specified in"
		echo -e "                      $WANPIPE_CONF_DIR/router.rc WAN_DEVICES\n"
		echo -e "       wanpipe start wanpipe# : Starts only device wanpipe#\n"
		echo -e "       wanpipe stop wanpipe#  : Stops only device wanpipe#" 
		echo -e "                               (# can range from 1 to 16)\n"
		echo -e " 	wanpipe list	: List all active devices\n"
		exit 1
esac
echo
exit 0

