#!/bin/bash

#	Copyright (c) 2014 Brocade Communications Systems, Inc.
#	All rights reserved.

#	Ethernet Port Monitor - ethif - Use this CLI to display or set the link operating modes.

STS_OK=0
STS_ERR=255

TOTAL_ARGS=0

ETHIF_OPT="help"

INTERFACE=0
AN_VALUE=0
SPEED_VALUE=0
CAP_VALUE=0

SWBD=`/sbin/sin | /bin/sed -n -e 's/^.\+\(SWBD\)\([[:digit:]]\{1,\}\).\+$/\2/gp' 2> /dev/null`

display_usage() {
	echo
	echo "Please enter the following options."
	echo
	echo "To display the link attributes."
	echo "ethif --show interface"
	echo
	echo "To set the attributes."
	echo "ethif --set interface -auto-negotiate | -an [on|off] -speed [10|100|1000] -duplex [half|full]"
	echo
	echo "Usage."
	echo "ethif --help."
	echo
}

process_args() {

	argc=$#
	argv=("$@")
	TOTAL_ARGS=$argc

	for ((i=0;i<$argc;i=$((i+2))))
	do

		opt=${argv[$i]}
		value=${argv[$i+1]}

		if [ $i -eq 0 ]; then

			# Make sure that the first argument is only "show" or "set" or "help"

			if [ "$opt" == "--show" ]; then
				ETHIF_OPT="show"
				INTERFACE=$value
			elif [ "$opt" == "--set" ]; then
				ETHIF_OPT="set"
				INTERFACE=$value
			elif [ "$opt" == "--help" ]; then
				ETHIF_OPT="help"
			else
				echo "Unsupported option."
				return $STS_ERR
	        fi
			continue

		fi

		if [ "$opt" == "-auto-negotiate" -o "$opt" == "-an" ]; then
			AN_VALUE=$value
		elif [ "$opt" == "-speed" ]; then
			SPEED_VALUE="$value"
		elif [ "$opt" == "-duplex" ]; then
			CAP_VALUE="$value"
		else
			return $STS_ERR
		fi

	done

	return $STS_OK
}

validate_args() {

	if [ $TOTAL_ARGS -eq 0 -o $ETHIF_OPT = "help" -a $TOTAL_ARGS -eq 1 ]; then
		return $STS_OK
	fi

	if [ $ETHIF_OPT = "help" -a $TOTAL_ARGS -gt 1 ]; then
		# Make sure that help is not followed by any attributes."
		echo "Unsuppported options for the help command."
		return $STS_ERR
	fi

	if [ $ETHIF_OPT = "show" -a $TOTAL_ARGS -gt 2 ]; then
		# Make sure that show is not followed by any attributes other than interface."
		echo "Unsupported options for the show command."
		return $STS_ERR
	fi

	if [ $SWBD = 62 -o $SWBD = 77 -o $SWBD = 141 -o $SWBD = 142 ]; then
		if [ $ETHIF_OPT = "show" ]; then
			if [ "$INTERFACE" == "" -o "$INTERFACE" != "eth0" -a "$INTERFACE" != "eth3" -a "$INTERFACE" != "bond0" ]; then
				echo "Interface can only be eth0, eth3 or bond0."
				return $STS_ERR
			fi
		else
			if [ "$INTERFACE" == "" -o "$INTERFACE" != "eth0" -a "$INTERFACE" != "eth3" ]; then
				echo "Interface can only be eth0 or eth3."
				return $STS_ERR
			fi
		fi
	else
		if [ "$INTERFACE" != "eth0" ]; then
			echo "Interface can only be eth0."
			return $STS_ERR
		fi
	fi

	if [ $ETHIF_OPT = "help" -o $ETHIF_OPT = "show" ]; then
		# Return as we have completed the validation for help or show.
		return $STS_OK
	fi

	if [ "$AN_VALUE" == "" -o "$AN_VALUE" != "ON" -a "$AN_VALUE" != "OFF" -a "$AN_VALUE" != "on" -a "$AN_VALUE" != "off" ] ; then
		echo "Unknown or invalid value for \"an\"."
		return $STS_ERR
	fi

	if [ "$SPEED_VALUE" == "" -o "$SPEED_VALUE" != "1000" -a "$SPEED_VALUE" != "100" -a "$SPEED_VALUE" != "10" ] ; then
		echo "Unknown or invalid value for \"speed\"."
		return $STS_ERR
	fi

	if [ "$CAP_VALUE" == "" -o "$CAP_VALUE" != "FULL" -a "$CAP_VALUE" != "HALF" -a "$CAP_VALUE" != "full" -a "$CAP_VALUE" != "half" ] ; then
		echo "Unknown or invalid value for \"cap\"."
		return $STS_ERR
    fi

	return $STS_OK
}

ethif_show() {

	echo "$INTERFACE interface:"
	echo

	if [ $INTERFACE = "bond0" ]; then

		# Read the entire output of bond0 and display the slave interfaces
		echo -n "bond0 includes physical interfaces:"
		/bin/cat /proc/net/bonding/bond0 | /bin/grep -i "Slave Interface" |
		while read LINE; do
			INTF=${LINE##*: }
			echo -n " $INTF"
		done

		echo
		ACT_INTF=`/bin/cat /proc/net/bonding/bond0 | /bin/grep -i "Currently Active Slave"`
		ACT_INTF=${ACT_INTF##*: }
		echo "Currently Active Interface: $ACT_INTF"

		# Read the entire output of bond0 and display the interfaces other than Active
		echo -n "Currently Slave Interface:"
		/bin/cat /proc/net/bonding/bond0 | /bin/grep -i "Slave Interface" |
		while read LINE; do
			INTF=${LINE##*: }
			if [ $INTF != $ACT_INTF ]; then
				echo -n " $INTF "
			fi
		done

		echo

		# Display the link mode and mac address of curent active interface
		/fabos/cliexec/ifmodeshow $ACT_INTF

	else

		/fabos/cliexec/ifmodeshow $INTERFACE

	fi

	echo

	/sbin/ifconfig $INTERFACE

	return $STS_OK
}

ethif_set() {

	/fabos/cliexec/ifmodeset $INTERFACE -an $AN_VALUE -speed $SPEED_VALUE -cap $CAP_VALUE

	return $STS_OK
}

# First perform the rbac check to see whether the command is supported.
/fabos/libexec/rbac_check `/bin/basename $0`
ret=$?
if [ $ret -ne 0 -a $ret -ne 2 ]; then
	exit $STS_ERR
fi

# Now process the args to perform the rbac check for options.
process_args $@
#if [ $? -ne $STS_OK ];then
#	display_usage
#	exit $STS_ERR
#fi

# Perform the rbac check for the options.
/fabos/libexec/rbac_check -opt `/bin/basename $0` $ETHIF_OPT
ret=$?
if [ $ret -ne 0 -a $ret -ne 2 ];then
	exit $STS_ERR
fi

# Validate the args.
validate_args
if [ $? -ne $STS_OK ]; then
	display_usage
	exit $STS_ERR
fi

if [ $ETHIF_OPT = "help" ]; then
	display_usage
elif [ $ETHIF_OPT = "show" ]; then
	ethif_show
elif [ $ETHIF_OPT = "set" ]; then
	ethif_set
else
	echo "Unknown option."
	display_usage
fi

exit $STS_OK
