#! /bin/sh
# 
#pragma ident "%W 96/10/24"
#
# SKIP interface management utility

os_release=`uname -r | sed 's/\..*//g'`
os_name=`uname`

if [ $os_release = 5 ]; then
	SKIP_BIN=/opt/SUNWicg/bin
	SKIP_ETC=/etc/opt/SUNWicg/skip
	ECHO=/bin/echo
	TAB="\t"
	ECHO_NONL=$ECHO
	NO_NL="\c"
else
	SKIP_BIN=/usr/skip/bin
	SKIP_ETC=/etc/skip
	ECHO=echo
	TAB="        "
	ECHO_NONL="echo -n"
fi

PATH=/bin:/usr/bin:/usr/sbin:/usr/ucb:/etc:$SKIP_BIN

if [ $os_name != SunOS ]
then
	PATH=/sbin:$PATH
fi
export PATH

SKIPHOST=$SKIP_BIN/skiphost

SKIP_REBOOT="skipif: please reboot your system for changes to take effect"
SKIP_ADDIF="skipif: SKIP added on network interface "
SKIP_DELIF="skipif: SKIP deleted from network interface "
SKIP_NOACL="Warning: ACL file not found for network interface "
SKIP_NOTPRESENT="SKIP not present on network interface "
SKIP_SAVE="skipif: saving configuration to $SKIP_ETC/acl."
SKIP_NOSKIPIF="skipif: no SKIP interface found"


# Get the list of the network interfaces -eclude loopback interfaces
#
get_if_list()
{

iflist=`netstat -i |grep -v Name|grep -v Kernel |grep -v Iface| \
		sed -e "s/ \(.*\)//"|grep -v lo0|grep -v lo|uniq`
}

# List all the network interfaces status
#
if_list()
{
$ECHO "Network interface list:"
for i in $iflist
do
	$SKIPHOST -i $i >/dev/null 2>&1
	if [ $? -ne 0 ]
	then
		if [ -f $SKIP_ETC/acl.$i ]
		then
			$ECHO "${TAB}$i [skip] [need reboot]"
		else
			$ECHO "${TAB}$i"
		fi
	else
		if [ -s $SKIP_ETC/acl.$i ]
		then
			$SKIPHOST -i $i -P |sort >/tmp/skip.acl.$i
			cat $SKIP_ETC/acl.$i |sort >/tmp/etc.acl.$i
			diff /tmp/skip.acl.$i /tmp/etc.acl.$i >/dev/null 2>&1
			if [ $? -eq 0 ]
			then
				$ECHO "${TAB}$i [skip]"
			else
				$ECHO "${TAB}$i [skip] [acl not saved]"
			fi
			rm /tmp/skip.acl.$i /tmp/etc.acl.$i
			if [ $verbose = "yes" ]
			then
				$ECHO "${TAB}Active configuration for $i:"
				$SKIPHOST -i $i | sed -e "s/^/        /"
				$ECHO
			fi
		else
			$ECHO "${TAB}$i [skip] [acl not saved]"
		fi
	fi
done
}

# Add SKIP (plumb) onto an interface
#
add_skip()
{
need_boot=no
if [ $ifname = "all" ]
then
	# Walk thru all the interfaces
	#
	for i in $iflist
	do
		if ( [ -f /dev/skip_key ] && 
			$SKIPHOST -i $i >/dev/null 2>&1 ) ||
							[ -f $SKIP_ETC/acl.$i ]
		then
			$ECHO "SKIP is already present on $i"
		else
			$ECHO "skiphost -i $i -p" >/tmp/acl.$$
			$ECHO "skiphost -i $i -o off" >>/tmp/acl.$$
			mv /tmp/acl.$$ $SKIP_ETC/acl.$i
			$ECHO $SKIP_ADDIF $i
			need_boot=yes
		fi
	done
	if [ $need_boot = "yes" ]
	then
		$ECHO $SKIP_REBOOT
	fi
else
	# Check if this interface exists
	#
	if ifconfig $ifname >/dev/null 2>&1
	then
		#
		# Check if SKIP is already plumbed
		#
		if ( [ -f /dev/skip_key ] && 
			$SKIPHOST -i $ifname >/dev/null 2>&1 ) ||
						[ -f $SKIP_ETC/acl.$ifname ]
		then
			$ECHO "SKIP is already present on $ifname"
		else
			$ECHO "skiphost -i $ifname -p" >/tmp/acl.$$
			$ECHO "skiphost -i $ifname -o off" >>/tmp/acl.$$
			mv /tmp/acl.$$ $SKIP_ETC/acl.$ifname
			$ECHO $SKIP_ADDIF $ifname
			$ECHO $SKIP_REBOOT
		fi
	else
		$ECHO "$0: interface \"$ifname\" not present"
	fi
fi
}

# Save SKIP interface state (produce the ACL file)
#
save_skip()
{
if [ $ifname = "all" ]
then
	has_done=no	
	# Walk thru all the interfaces
	#
	for i in $iflist
	do
		$SKIPHOST -i $i >/dev/null 2>&1
		if [ $? -eq 0 ]
		then
			has_done=yes	
			$ECHO_NONL $SKIP_SAVE"$i..."$NO_NL
			$SKIPHOST -i $i -P >$SKIP_ETC/acl.$i
			if [ $? -eq 0 ]
			then
				$ECHO "done."
			else
				$ECHO "failed."
			fi
		fi
	done
	if [ $has_done = "no" ]
	then
		$ECHO $SKIP_NOSKIPIF
	fi
else
	# Check if this interface exists
	#
	if ifconfig $ifname >/dev/null 2>&1
	then
		#
		# Check if SKIP is already plumbed
		#
		$SKIPHOST -i $ifname >/dev/null 2>&1
		if [ $? -ne 0 ]
		then
			$ECHO "SKIP not present on $ifname"
		else
			$ECHO_NONL $SKIP_SAVE"$ifname..."$NO_NL
			$SKIPHOST -i $ifname -P >$SKIP_ETC/acl.$ifname
			if [ $? -eq 0 ]
			then
				$ECHO "done."
			else
				$ECHO "failed."
			fi
		fi
	else
		$ECHO "$0: interface \"$ifname\" not present"
	fi
fi
}


# Delete SKIP interface(s) state (remove ACL file and unplumb SKIP)
#
delete_skip()
{
need_boot=no
if [ $ifname = "all" ]
then
	# Walk thru all the interfaces
	#
	for i in $iflist
	do
		$SKIPHOST -i $i >/dev/null 2>&1
		if [ $? -eq 0 ]
		then
			# Remove SKIP (un-plumb) from the interface
			#
			$SKIPHOST -i $i -u >/dev/null 2>&1

			# Check if the ACL file exists
			#
			if [ -f $SKIP_ETC/acl.$i ]
			then
				rm $SKIP_ETC/acl.$i
			else
				$ECHO $SKIP_NOACL $i
			fi
			need_boot=yes
		else
			# Remove the ACL file any way
			#
			if [ -f $SKIP_ETC/acl.$i ]
			then
				rm $SKIP_ETC/acl.$i
				need_boot=yes
			fi
		fi
	done
	if [ $need_boot = "yes" ]
	then
		$ECHO $SKIP_DELIF $i
		$ECHO $SKIP_REBOOT
	else
		$ECHO $SKIP_NOSKIPIF
	fi
else
	# Check if this interface exists
	#
	if ifconfig $ifname >/dev/null 2>&1
	then
		$SKIPHOST -i $ifname >/dev/null 2>&1
		if [ $? -eq 0 ]
		then
			# Remove SKIP (un-plumb) from the interface
			#
			$SKIPHOST -i $ifname -u >/dev/null 2>&1
			$ECHO $SKIP_DELIF $ifname
	
			# Check if the ACL file exists
			#
			if [ -f $SKIP_ETC/acl.$ifname ]
			then
				rm $SKIP_ETC/acl.$ifname
			else
				$ECHO $SKIP_NOACL $ifname
			fi

			$ECHO $SKIP_REBOOT
		else
			# Remove the ACL file any way
			#
			if [ -f $SKIP_ETC/acl.$ifname ]
			then
				rm $SKIP_ETC/acl.$ifname
				$ECHO $SKIP_DELIF $ifname
				$ECHO $SKIP_REBOOT
			else
				$ECHO $SKIP_NOTPRESENT $ifname
			fi
		fi

	else
		$ECHO "$0: interface \"$ifname\" not present"
	fi
fi
}

# Display skipif usage
#
usage()
{
	$ECHO "usage:"
	$ECHO "${TAB}`basename $0` [-i <ifname|all>] -a"
	$ECHO "${TAB}`basename $0` [-i <ifname|all>] -d"
	$ECHO "${TAB}`basename $0` [-i <ifname|all>] -s"
	$ECHO "${TAB}`basename $0` -l [-v]"
	$ECHO "${TAB}`basename $0` -h"
	exit 1
}

# Main Entry - Parse command line options
#
sedfunc()
{
	echo "$1" | sed "s/'/'\\\\''/g"
}

exitcode_=0
while getopts hasdlvi: c_
do
	case $c_ in
	\?)
		exitcode_=1
		break;;
	*)	if [ "$OPTARG" ]
		then
			optarg_=`sedfunc "$OPTARG"`
			arg_="$arg_ -$c_ '$optarg_'"
		else
			arg_="$arg_ -$c_"
		fi;;
	esac
done
shift `expr $OPTIND - 1`
arg_="$arg_ --"
for i_ in "$@"
do
	optarg_=`sedfunc "$i_"`
	arg_="$arg_ '$optarg_'"
done
eval set -- "$arg_"
test  $exitcode_ = 0 ;

if [ $? != 0 ]
then
	usage
fi

action=""
ifname=""
verbose=no
iflist=""

for i in $*
do
	case $i in
	-a)
		if [ a$action != a"" ]
		then
			usage
		fi
		action=add; shift;;
	-s)
		if [ a$action != a"" ]
		then
			usage
		fi
		action=save; shift;;
	-d)
		if [ a$action != a"" ]
		then
			usage
		fi
		action=delete; shift;;
	-r)
		if [ a$action != a"" ]
		then
			usage
		fi
		action=remove; shift;;
	-l)
		if [ a$action != a"" ]
		then
			usage
		fi
		action=list; export action; shift;;
	-v)
		verbose=yes; shift;;
	-i)
		ifname=$2; export ifname; shift 2;;
	-h)	
		usage;;
	--)
		shift; break;;
	esac
done

if [ a$1 != a"" ] || [ a$action = a"" ]
then
	usage
fi

if [ $verbose  = "yes" ] && [ $action != list ]
then
	usage
fi

if [ a$ifname != a"" ] && [ ${action} = "list" ]
then
	usage
fi

if [ a$ifname = a"" ] && [ $action != list ]
then
	# Try to find the default interface
	#
	ifname=`$SKIPHOST -i default 2>/dev/null`
	if [ $? -ne 0 ]
	then
		$ECHO "$0: failed to get default network interface"
		exit 1
	fi
	if [ a$ifname  = a"" ]
	then
		usage
	fi
fi

get_if_list
export ifname iflist

# Dispatching...
#
case $action in
	# Add SKIP to an interface
	#
	add) add_skip;;

	# Save the current SKIP interface state into the acl file
	#
	save) save_skip;;

	# Delete the SKIP acl startup file
	#
	delete) delete_skip;;

	# List interfaces
	#
	list) if_list;;

	# Unsupported action
	#
	*) $ECHO "$0: Unknown action <$action>"; usage; exit 1;;
esac

exit 0
