#! /bin/sh
# 
#pragma ident "%W 99/07/15"
#
# SKIP interface management utility

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

if [ $os_release = 5 ]; then
	SKIP_BIN=/usr/sbin
	SKIP_ETC=/etc/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
CATGETS=/usr/lib/skip/catgets

set_num=19	#  SI_admin
LS()		# localize a string
{
	msg_num=$1; shift
	if [ -x ${CATGETS} ]
	then ${CATGETS} $set_num $msg_num "$*"
	else echo "$*"
	fi
}

SKIP_REBOOT=`LS 100 "skipif: please reboot your system for changes to take effect"`
SKIP_ADDIF=`LS 101 "skipif: SKIP added on network interface "`
SKIP_DELIF=`LS 102 "skipif: SKIP deleted from network interface "`
SKIP_NOACL=`LS 103 "Warning: ACL file not found for network interface "`
SKIP_NOTPRESENT=`LS 104 "SKIP not present on network interface "`
SKIP_SAVE=`LS 105 "skipif: saving configuration to "`
SKIP_NOSKIPIF=`LS 106 "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 `LS 125 "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 " `LS 126 "[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]" `LS 108 "[acl not saved]"`
			fi
			rm /tmp/skip.acl.$i /tmp/etc.acl.$i
			if [ $verbose = "yes" ]
			then
				$ECHO ${TAB} $i `LS 109 ": Active configuration:"`
				$SKIPHOST -i $i | sed -e "s/^/        /"
				$ECHO
			fi
		else
			$ECHO "${TAB}$i [skip]" `LS 108 "[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 `LS 110 "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 `LS 110 "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 `LS 112 ": interface not present: "` $ifname
	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"$SKIP_ETC/acl.$i..."$NO_NL
			$SKIPHOST -i $i -P >$SKIP_ETC/acl.$i
			if [ $? -eq 0 ]
			then
				$ECHO `LS 113 "done."`
			else
				$ECHO `LS 114 "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_NOTPRESENT $ifname
		else
			$ECHO_NONL $SKIP_SAVE"$SKIP_ETC/acl.$ifname..."$NO_NL
			$SKIPHOST -i $ifname -P >$SKIP_ETC/acl.$ifname
			if [ $? -eq 0 ]
			then
				$ECHO `LS 113 "done."`
			else
				$ECHO `LS 114 "failed."`
			fi
		fi
	else
		$ECHO $0 `LS 112 ": interface not present: "` $ifname
	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 `LS 112 ": interface not present: "` $ifname
	fi
fi
}

# Display skipif usage
#
usage()
{
  	cmd=`basename $0`
	$ECHO `LS 117 "usage:"`
	$ECHO ${TAB}${cmd} `LS 118 "[-i <ifname|all>] -a"`
	$ECHO ${TAB}${cmd} `LS 119 "[-i <ifname|all>] -d"`
	$ECHO ${TAB}${cmd} `LS 120 "[-i <ifname|all>] -s"`
	$ECHO ${TAB}${cmd} `LS 121 "-l [-v]"`
	$ECHO ${TAB}${cmd} `LS 122 "-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 `LS 123 ": 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 `LS 124 ": Unknown action:"` $action; usage; exit 1;;
esac

exit 0
