#! /bin/sh
#
# ident	"%Z%%M%	%I%	%E% SMI"
#
# *****************************************************************
# *                                                               *
# *    Copyright (c) Essential Communications Corp, 1998          *
# *                                                               *
# *   All Rights Reserved.  Unpublished rights  reserved  under   *
# *   the copyright laws of the United States.                    *
# *                                                               *
# *   RESTRICTED RIGHTS LEGEND   Use, duplication, or disclosure  *
# *   by the U.S. Government is subject to restrictions  as  set  *
# *   forth in Subparagraph (c)(1)(ii)  of  DFARS  252.227-7013,  *
# *   or  in  FAR 52.227-19, as applicable.                       *
# *                                                               *
# *****************************************************************

echo "\n\t$0 - SunHiPPI Administration Tool\n
"
WHOAMI=`id|sed 's/^[^(]*.\([^)]*\).*/\1/'`
if [ "$WHOAMI" != "root" ] ; then
	echo "You must be logged on as root to use $0"
	exit 1
fi


# get installation base for package
basedir=`/usr/bin/pkginfo -r SUNWhip 2>/dev/null`/etc/opt/SUNWconn/hippi
if [ ! -r "${basedir}" ]
then
	echo "SUNWhip package doesn't appear to be installed."
	echo "Please install the package before continuing."
	exit 1
fi

# get number of NICs in system
nbhip=`${basedir}/bin/hippi cards 2>/dev/null`

# does user want to update NICs EEPROM?
upgradeeeprom=0
getopts u c
case $c in
'u') 
	# user wants to upgrade NIC EEPROM
	upgradeeeprom=1
	;;
esac

# check number of NICs available in system 
if [ "${nbhip}" -eq 0 ] ; then
        echo "No HiPPI NIC present"
	if [ ${upgradeeeprom} -eq 1 ] ; then
	    echo ""
	    echo "Cannot upgrade HiPPI NIC(s) EEPROM, no HiPPI NIC currently"
	    echo "present in system."
	    echo ""
	    exit 1
	fi
	nbhip=`ckrange -l1 -u4 -d1 \
	-p "How many HiPPI interfaces do you want to configure"` || exit $?
	nbinstalled=0
else
	echo "Detected ${nbhip} HiPPI NIC(s) present"
	nbinstalled=$nbhip
fi

isno()
{
	case $1 in
	n | no | nO | N | No | NO)
		return 0
		;;
	*)
		return 1
		;;
	esac
}

#
# returns 0 if the first argument contains blanks, non-zero otherwise.
#
arg_contains_blanks()
{
	set -- $1
	test $# -gt 1
}

#
# usage: find_etc_hosts_entry <hostname>
# Returns ipaddr if all goes well,
#         status 0 on error
# Writes "<ip-address> <hostname>" to the standard output.
#
find_etc_hosts_entry()
{
	hn=$1
	if arg_contains_blanks "$hn" ; then
		return 0
	fi

	if he=`awk -F# '{print $1}' /etc/hosts | grep -w $hn` ; then
		set -- $he
		for i in $* ; do
			if [ $i = $hn ] ; then
				return $1
			fi
		done
	fi
	return 0
}

#
# returns 1 if $1 is a number and within 1-255, 0 otherwise
#
valid_field()
{
	nonNum=`echo "$1" | sed "s/[1-9][0-9]*//g"`
	if [ -n "$nonNum" ] ; then
		return 0
	fi
	if [ $1 -gt 255 -o $1 -lt 0 ] ; then
		return 0
	fi
	return 1
}

#
# returns 0 if $1-4 comprise a valid IP address
#
validate_addr_wrong()
{
	if [ $1 -lt 127 -a  $1 -gt 0 ] ; then   	# Class A address
		for n in $2 $3 $4 ; do
			if valid_field $n ; then
				return 0
			fi
		done
	else
		if [ $1 -gt 127 -a $1 -lt 192 ] ; then 	# Class B address
			for n in $3 $4 ; do
				if valid_field $n ; then
					return 0
				fi
			done
		else					# Class C address
			if [ $1 -ge 192 -a $1 -lt 224 ] ; then
				if valid_field $4 ; then
					return 0
				fi
			fi
		fi
	fi
	return 1
}

valid_hex_digit()
{
	case $1 in 
	0|1|2|3|4|5|6|7|8|9|a|A|b|B|c|C|d|D|e|E|f|F)
		return 0
		;;
	*)
		return 1
		;;
	esac
}
valid_hex_num()
{
	tmp=$1
	len=0
	while [ -n "$tmp" ] ; do
		if valid_hex_digit `echo $tmp|cut -c1` ; then
			tmp=`echo $tmp|cut -c2-32`
		else
			return 1
		fi
		len=`expr ${len} + 1`
	done
	[ ${len} -eq 8 ]
}
valid_hex_sw()
{
	tmp=$1
	len=0
	while [ -n "$tmp" ] ; do
		if valid_hex_digit `echo $tmp|cut -c1` ; then
			tmp=`echo $tmp|cut -c2-32`
		else
			return 1
		fi
		len=`expr ${len} + 1`
	done
	[ ${len} -lt 4 ]
}

#
# returns 0 if $1 comprises a valid netmask
#
valid_mask()
{
	case $1 in 
	0x*)
		if valid_hex_num `echo $1|cut -c3-32` ; then
			return 0
		else
			return 1
		fi
		;;
	*)
		echo "netmask should be of the form 0xffffff00"
		return 1
		;;
	esac
	return 0
}

#
# returns 0 if $1 comprises a valid logical address
#
valid_swaddr()
{
	case $1 in
	0x*)
		if valid_hex_sw `echo $1|cut -c3-` ; then
		    return 0
		else
		    return 1
		fi
		;;
	*)
		echo "Logical address should be of the form 0xfff"
		return 1
		;;
	esac
	return 0
}

#
# update EEPROM of specified HiPPI NIC
#
update_eeprom()
{
	# get pci state register value according to architecture
	if [ "`uname -i`" = SUNW,Ultra-5_10 ] ; then
		pcistate=0x54
	else
		pcistate=0x90
	fi

	# store tuning parameters into EEPROM
	echo "setting tuning parameters into ${hipname} EEPROM"
	${basedir}/bin/hippi off $1 2>&1 >/dev/null
	${basedir}/bin/hippitune -D $1 -e -x 0x500000 -r 0x200000 \
		    -s 20000000 -h ${pcistate} -i 0x120 -w 0x80 -d 0x80 \
		    2>&1 >/dev/null

	# download firmware
	echo "downloading firmware into ${hipname} EEPROM"
	${basedir}/bin/hippidnld -D $1 -r ${basedir}/runcode.nic 2>&1 >/dev/null
}

#
# main()
#
curhip=0
while [ "${curhip}" -ne "${nbhip}" ] ; do
	# get current NIC name
	hipname="hip${curhip}"
	confname="${basedir}/${hipname}.conf"
	hipipname="hipip${curhip}"

	# has the NIC been configured already?
	if [ ! -r ${confname} ] ; then
		#
		# ask user for NIC IP configuration
		#

		fdone=0
		msg="Illegal IP address... Try again"
		while [ ${fdone} -eq 0 ] ; do
			hostname=`ckstr -Q \
		-p "Enter the IP {hostname} or address for ${hipipname}" \
		-h "4 octet network address in dotted decimal notation or hostname" `

			nonNum=`echo "${hostname}" | \
			    sed "s/[.][0-9]*[0-9]/X/g" | \
			    sed "s/[1-9][0-9]*X\{3\}//g"`
			if [ -n "$nonNum" ] ; then
				#
				# we have a hostname, convert to IP address
				#
				getent_res=`getent hosts ${hostname}`
				if [ $? -ge 1 ] ; then
					echo "I can't find an IP address for ${hostname}"
					continue
				else
					ip_addr=`echo "${getent_res}" | awk '{ print $1 }'`
				fi
			else
				ip_addr="${hostname}"
			fi

			case ${ip_addr} in
			127.1 | 127.0.1 | 127.0.0.1 | 127.01)
				echo ${msg}
				;;
			*)
				if [ -z "$ip_addr" ]
				then    # NULL Address
					echo ${msg}

				else	# I need 4 fields separated by dots
			nfields=`echo $ip_addr|awk -F. '{printf("%d", NF)}'`
					if [ $nfields != "4" ] ; then
						echo ${msg}
					else   # they must be numeric and < 255
						
						wrongField=0
						IFS_save=$IFS
						IFS="$IFS."
						set `echo ${ip_addr}`
						IFS=$IFS_save
						for n in $1 $2 $3 $4 ; do
						    if valid_field $n ; then
							wrongField=1
							break
						    fi
						done
						if validate_addr_wrong $1 $2 $3 $4
						then
							wrongField=1
						fi

						if [ $wrongField -eq 0 ] ; then
							fdone=1
						else
							echo ${msg}
						fi
						
					fi
				fi
				;;
			esac
		done

		#
		# get the interface netmask
		#
		fdone=0
		while [ ${fdone} -eq 0 ] ; do
			answermask=`ckstr -Q \
				-p "Enter the netmask for ${hipipname}" \
				-h "4 octet network mask in hex notation." \
				-d "0xffffff00"`

			if valid_mask ${answermask} ; then
				fdone=1
			else
				echo "Please enter the mask in hex notation -"
				echo "0xffffff00"
			fi
		done

		#
		# get the HiPPI switch address
		#

		fdone=0
		while [ ${fdone} -eq 0 ] ; do
		        answersw=`ckstr -Q \
			    -p "Enter the HIPPI logical address for ${hipipname} in hex notation" \
			    -h "12 bit number in hex notation, e.g. 0xa3f."`
		        if valid_swaddr ${answersw} ; then
				fdone=1
			else
				echo "Please enter the logical address in hex notation, e.g. 0xa3f."
			fi
		done


		echo "\nsaving configuration to ${confname}"
		echo "${ip_addr} ${answermask} ${answersw}" > ${confname}
		chmod 644 "${confname}"
	fi


	if [ ${nbinstalled} -eq 0 ] ; then
	    echo "\n   NOTE: After installing the HiPPI NIC(s) in your system,"
	    echo "   run $0 -u to update the NIC(s) EEPROM contents."
	else
	    update_eeprom ${hipname}
	fi

	# proceed with next device
        curhip=`expr $curhip + 1`
done

if [ ${upgradeeeprom} -eq 1 ] ; then
	# only updating EEPROM contents
	exit 0
fi	

answer=`ckyorn -Q -d "y" -p \
	"Do you wish to patch the global network tunables for increased network throughput? [y] "`
isno $answer
if [ $? -eq 1 ] ; then
# setting TCP for large window support
cat >> /etc/init.d/inetinit <<HIP_END1
/usr/sbin/ndd -set /dev/tcp tcp_recv_hiwat 1048576	#SUNWhip
/usr/sbin/ndd -set /dev/tcp tcp_xmit_hiwat 1048576	#SUNWhip
/usr/sbin/ndd -set /dev/tcp tcp_wscale_always 1		#SUNWhip
/usr/sbin/ndd -set /dev/tcp tcp_cwnd_max 1048576	#SUNWhip
HIP_END1
# also run the commands here so that new values are in effect without reboot
/usr/sbin/ndd -set /dev/tcp tcp_recv_hiwat 1048576	#SUNWhip
/usr/sbin/ndd -set /dev/tcp tcp_xmit_hiwat 1048576	#SUNWhip
/usr/sbin/ndd -set /dev/tcp tcp_wscale_always 1		#SUNWhip
/usr/sbin/ndd -set /dev/tcp tcp_cwnd_max 1048576	#SUNWhip
fi

echo ""
echo "You will need to update the HiPPI ARP configuration file:"
echo "  ${basedir}/hippiarp.conf"
echo "in order to be able to communicate with other HiPPI hosts on"
echo "your network using the IP protocol."
echo ""


exit 0

