#!/bin/bash

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

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

PATH=/fabos/link_bin:/bin:/usr/bin:/sbin:/usr/sbin:/fabos/link_abin:/fabos/link_sbin:/fabos/link_rbin:/fabos/factory:/fabos/xtool
STS_OK=0
STS_ERR=255

TOTAL_ARGS=0

ETHIF_OPT="help"

INTERFACE=0
value=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`
LINUX_VER=`/bin/uname -r | /usr/bin/cut -c1-6` 
chassis_info=`/bin/getchassisconfig`

ischassis=`echo $chassis_info | \
        sed -n -e 's/.*Chassis based system: //gp' | \
        sed -n -e 's/ .*//gp'`


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 [full]"
		echo
		if [ $LINUX_VER = 2.6.34 ]; then
			echo "To clear the error counters."
                	echo "ethif --reseterror interface"
                	echo
		fi
		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" == "--reseterror" ]; then
				ETHIF_OPT="reseterror"
				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 [ "$ischassis" = "Yes" ]; 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 [ $ETHIF_OPT != "reseterror" ]; then
			if [ "$INTERFACE" != "eth0" ]; then
				echo "Interface can only be eth0."
				return $STS_ERR
			fi	
		fi
	fi
	
	if [ $ETHIF_OPT = "reseterror" -a $LINUX_VER != 2.6.34 ]; then
                echo "Unsupported options for the command."
                return $STS_ERR
        fi
	

	if [ $ETHIF_OPT = "reseterror" -a $TOTAL_ARGS -gt 2 ]; then
                echo "Unsupported options for the command."
                return $STS_ERR
        fi
	
	if [ $ETHIF_OPT = "reseterror" ]; then 	
		if [ "$ischassis" = "Yes" ]; then
			if [ "$INTERFACE" == "" -o "$INTERFACE" != "eth0" -a "$INTERFACE" != "eth3" ]; then
                                echo "Interface can only be eth0 or eth3."
                                return $STS_ERR
                        fi
		else
			if [ "$INTERFACE" != "eth0" ]; then
                                echo "Interface can only be eth0."
                                return $STS_ERR
			fi
		fi
	fi	

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

	if [ $ETHIF_OPT = "set" -a $TOTAL_ARGS -eq 2 ]; then
		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" != "full" ] ; 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/rbin/ifmodeshow $ACT_INTF -support

	else

		/fabos/rbin/ifmodeshow $INTERFACE -support

	fi

	echo

	/sbin/ifconfig $INTERFACE

	return $STS_OK
}

ethif_set() {
	if [ $ETHIF_OPT = "set" -a $TOTAL_ARGS -eq 2 ]; then
		/fabos/rbin/ifmodeset $INTERFACE -support
	else
		/fabos/rbin/ifmodeset $INTERFACE -an $AN_VALUE -speed $SPEED_VALUE -cap $CAP_VALUE -support
	fi

	return $STS_OK
}

#check half duplex support
ethif_duplex_support() {
        for bd in 148 171 141 142 157 158 165 166; do
                if [ $SWBD == "$bd" ]; then
                        return $STS_ERR
                fi
        done
        return $STS_OK
}

ethif_clear() {

        echo "Statistics cleared for $INTERFACE"

        echo $INTERFACE > /proc/net/clear-statistics

        #record a raslog for reesterror counters
        /fabos/cliexec/errlogtest -i SWCH-1031 -a $INTERFACE

        return $STS_OK
}

ethif_clear() {
	
	echo "Statistics cleared for $INTERFACE"

	echo $INTERFACE > /proc/net/clear-statistics
	
	#record a raslog for reesterror counters
        /fabos/cliexec/errlogtest -i SWCH-1032 -a $INTERFACE
	
	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
elif [ $ETHIF_OPT = "reseterror" ]; then
	ethif_clear
else
	echo "Unknown option."
	display_usage
fi

exit $STS_OK
