#!/bin/ksh -p
#
# ident "@(#)utdhcpnet.ksh	1.8 05/01/18 SMI"
#
# Copyright 2004-5 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#

CORONA_NAME="SunRay";
VARDIR=/var/opt/SUNWut
TMPDIR="$VARDIR"/tmp
GREP=/usr/xpg4/bin/grep
NETWORKS="/etc/inet/networks";
DHTADM_P="${TMPDIR}/dhtadm-P.$$"

ProcessAdd() {
	BEGAN=false

	while read input
	do
		case $input in
		(begin*)
			COMMAND=${input#begin }
			if [[ $COMMAND != "subnet" && $COMMAND != "interface" ]]; then
				print -u2 "Error: Invalid block type.  Please try again."
				exit 1
			else
				BEGAN=true
			fi		
			;;
		(end)
			break
			;;
		(*)
			if ! $BEGAN ; then
				print -u2 "Error: Input must start with a \"begin\" statement"
				exit 1
			else
				ConvertKeyToLower "$input"
                        	input="$_RETURN_VAL"
				if [[ $COMMAND = "subnet" ]]; then
					case $input in
                                        (network*)
                                                SUBNET=${input#network=}
						grep "${CORONA_NAME}-${SUBNET}" $DHTADM_P >/dev/null 2>&1
						if [[ $? = "0" ]]; then
							print -u2 "DHCP subnet configuration for $SUBNET already exists."
                                                        exit 1
                                                fi
					esac
					SourceSubnet "$input"
				elif [[ $COMMAND = "interface" ]]; then
					case $input in
                                        (interface*)
                                                INT=${input#interface=}
						grep "${CORONA_NAME}-${INT}" $DHTADM_P >/dev/null 2>&1
						if [[ $? = "0" ]]; then
                                                 	print -u2 "DHCP interface configuration for $INT already exists."
                                                        exit 1
						fi
						;;
					(network*)
                                                SUBNET=${input#network=}
						fgrep "${SUBNET}" ${TMPDIR}/allSRnets.$$ >/dev/null
                                                if [[ $? = "0" ]]; then
                                                        print -u2 "DHCP subnet configuration for $SUBNET already exists."
                                                        exit 1
                                                fi
						;;
                                        esac
					SourceInterface "$input"
				fi
			fi
			;;
		esac
	done
	AddConfig
	exit 0
}

AddConfig() {
	# set a default MTU only if we are responding to DHCPREQUEST
	if [[ -z $UT_DHCP_MTU && -n $UT_DHCP_RANGE ]]; then
		UT_DHCP_MTU="1500"
	fi
	if [[ $COMMAND = "subnet" ]]; then
		ValidateSubnetBlock
		if [[ $? != 0 ]]; then
			print -u2 "Error: Invalid subnet block"
			exit 1
		else
			INTF_NETNAME=${CORONA_NAME}-${UT_DHCP_NETWORK}
			NET_MACRO=":Include=${INTF_NETNAME}:\
Subnet=${UT_DHCP_NETMASK}:FWSrvr=${UT_DHCP_FIRMWARESRVR}"
		fi
	elif [[ $COMMAND = "interface" ]]; then
		ValidateInterfaceBlock
		if [[ $? != 0 ]]; then
			print -u2 "Error: Invalid interface block"
			exit 1
		else
			INTF_NETNAME=${CORONA_NAME}-${UT_DHCP_INTERFACE}
			NET_MACRO=":Include=${INTF_NETNAME}:\
Subnet=${UT_DHCP_NETMASK}:\
FWSrvr=${UT_DHCP_FIRMWARESRVR}:Intf=\"${UT_DHCP_INTERFACE}\"";
		fi
	fi
	if [ "${UT_DHCP_BROADCAST}" != "" ]; then
		NET_MACRO="${NET_MACRO}:Broadcst=${UT_DHCP_BROADCAST}"
	fi
	if [ "${UT_DHCP_MTU}" != "" ]; then
		NET_MACRO="${NET_MACRO}:MTU=${UT_DHCP_MTU}"
	fi
	if [ "${UT_DHCP_ROUTERS}" != "" ]; then
		NET_MACRO="${NET_MACRO}:Router=${UT_DHCP_ROUTERS}"
	fi
	ConstructOptionsMacro
	NET_MACRO=${NET_MACRO}${CORONA_MACRO}
	# add server macro for each interface
	# (includes the sunray macro and contains auth server ipa and port,
	#  loghost, logkern/net/usb/vid/appl)
	AUTH_SRVR="AuthSrvr=${UT_DHCP_AUTHSRVR}";
	if [ "${UT_DHCP_ALTAUTHLIST}" != "" ]; then
		AUTH_SRVR="${AUTH_SRVR}:AltAuth=${UT_DHCP_ALTAUTHLIST}"
	fi
        SRV_MACRO=":Include=${CORONA_NAME}:${AUTH_SRVR}:";
	dhtadm -A -m ${INTF_NETNAME} -d "${SRV_MACRO}" 2> ${TMPDIR}/Err.$$;
	if [ ${?} -ne 0 ]; then
		print -u2 "Error:  cannot add interface macro \"${INTF_NETNAME}\" to dhcptab:\n	   `cat ${TMPDIR}/Err.$$`"
           	rm -f ${TMPDIR}/Err.$$;
		return 1;
	else
        		rm -f ${TMPDIR}/Err.$$;
	fi
        typeset MULTINET=N
	typeset TMPMULTIFILE=${TMPDIR}/pntadm-multi.$$

	rm -f ${TMPMULTIFILE} 2> /dev/null
	pntadm -P ${UT_DHCP_NETWORK} 2>/dev/null | sed -e '1,2d' > ${TMPMULTIFILE}
	# check for MULTINET by looking into the network table, not the networks file
	if $GREP -q -s -v "${INTF_NETNAME}" ${TMPMULTIFILE}; then
		MULTINET=Y
	fi
	if [ "${MULTINET}" = "N" ]; then
        	dhtadm -A -m ${UT_DHCP_NETWORK} -d "${NET_MACRO}" 2> ${TMPDIR}/Err.$$;
                if [ ${?} -ne 0 ]; then
 			print -u2 "Error:  cannot add network macro \"${UT_DHCP_NETWORK}\" to dhcptab:\n `cat ${TMPDIR}/Err.$$`"
                        rm -f ${TMPDIR}/Err.$$;
                        return 1;
                else
                        rm -f ${TMPDIR}/Err.$$;
                fi
	fi
	BuildNetworkTables $COMMAND
}

ProcessDelete() {
	BEGAN=false
	INTSET=false
	NETSET=false

	while read input
	do
          	case $input in
		(begin*)
                        COMMAND=${input#begin }
                        if [[ $COMMAND != "subnet" && $COMMAND != "interface" ]]; then
                                print -u2 "Error: Invalid block type.  Please try again."
				exit 1
			else
				BEGAN=true
                        fi
                        ;;
		(interface*)
			if $BEGAN; then
				if [[ $COMMAND = "subnet" ]]; then
					print -u2 "Error: Invalid block."
					exit 1
				elif [[ $COMMAND = "interface" ]]; then
					INT=${input#interface=}
					grep "${CORONA_NAME}-${INT}" $DHTADM_P >/dev/null 2>&1
					if [[ $? != "0" ]]; then
						print -u2 "Configuration for DHCP interface $INT does not exist."
                                                exit 1
					fi
					INTF_NETNAME=${CORONA_NAME}-${INT}
					# not defined in the networks file, try checking in dhtadm
					INTF_NET=`$GREP -s ":Include=${INTF_NETNAME}:" $DHTADM_P | awk '{print $1}'`
					if [ -z "${INTF_NET}" ]; then
						print -u2 "Error: Cannot translate interface \"${INT}\" to a network number"
						return 1
					fi
					INTSET=true
				fi
			else
				print -u2 "Error: Input must start with a \"begin\" statement"
				exit 1
			fi
			;;	
		(network*)
			if $BEGAN; then
				if [[ $COMMAND = "interface" ]]; then
					print -u2 "Error: Invalid block."
                                        exit 1
				elif [[ $COMMAND = "subnet" ]]; then
					SUBNET=${input#network=}
					grep "${CORONA_NAME}-${SUBNET}" $DHTADM_P >/dev/null 2>&1
                                        if [[ $? != "0" ]]; then
						print -u2 "Configuration for DHCP subnet $SUBNET does not exist."
                                                exit 1
                                        fi
					INTF_NETNAME=${CORONA_NAME}-${SUBNET}
					INTF_NET=${SUBNET}
					NETSET=true
				fi
			else
				print -u2 "Error: Input must start with a \"begin\" statement"	
				exit 1
			fi
                        ;;
		(end)
			if $NETSET || $INTSET; then
                     		break
			else
				print -u2 "Error: Must specify either an subnet or interface."
				exit 1
			fi
			;;
		(*)
			if $BEGAN; then
				print -u2 "Error: Invalid argument."
				exit 1
			else
				print -u2 "Error: Must specify a valid block."
				exit 1
			fi
			;;
		esac
	done
	DeleteConfig
	if [[ $? != 0 ]]; then
		print -u2 "Error:  failed to remove dhcp network configuration."
	fi
}

DeleteConfig() {
	typeset MULTINET=N

	typeset TMPMULTIFILE=${TMPDIR}/pntadm-multi.$$
	typeset pntstat

	rm -f ${TMPMULTIFILE} 2> /dev/null
	pntadm -P ${INTF_NET} | sed -e '1,2d' > ${TMPMULTIFILE}
	pntstat=${?}
	# check for MULTINET by looking into the network table, not the networks file
	if $GREP -q -s -v "${INTF_NETNAME}" ${TMPMULTIFILE}; then
		MULTINET=Y
	fi
	if [ $MULTINET = "N" ]; then
		dhtadm -D -m "${INTF_NET}";
		if [[ $pntstat -eq  0 ]]; then
			# remove the network table.
			 pntadm -R "${INTF_NET}"
		fi
	else
		typeset TMPBATCH=${TMPDIR}/pntadm-rm-batch.$$
		rm -f $TMPBATCH 2> /dev/null
		awk "/${INTF_NETNAME}/ { print \"pntadm -D \" \$3 \" ${INTF_NET}\" }" ${TMPMULTIFILE} \
		> $TMPBATCH
		if [[ -s $TMPBATCH ]]; then
			# CR 6217989 - dhtadm -B errors on Solaris x86
			DoDhcpBatch pntadm $TMPBATCH 2> ${TMPDIR}/Err.$$;
			if [[ ${?} != 0 ]]; then
                       		print -u2 "Error:  failed to remove the entries for subnetwork \"${INTF_NET}\":\n\
					`cat ${TMPDIR}/Err.$$`"
					# even when it failed, continue with the removal
                        fi
			 rm -f $TMPBATCH ${TMPDIR}/Err.$$ 2> /dev/null
		fi
	fi
	rm -f ${TMPMULTIFILE}
	if ! dhtadm -D -m ${INTF_NETNAME}; then
		return 1
	fi
	return 0
}

ProcessChange() {
	STARTED=false
	INTSET=false
	NETSET=false

        while read input
        do
                case $input in
		(begin*)
                        COMMAND=${input#begin }
                        if [[ $COMMAND != "subnet" && $COMMAND != "interface" ]]; then
                                print -u2 "Error: Invalid block type.  Please try again."
				exit 1
			else
				STARTED=true
                        fi
                        ;;
		(interface*)
			if $STARTED; then
				if [[ $COMMAND = "subnet" ]]; then
					print -u2 "Error: Invalid block."
                                        exit 1
				fi						
				INTSET=true
				INT=${input#interface=}
				grep "${CORONA_NAME}-${INT}" $DHTADM_P >/dev/null 2>&1
				if [[ $? != "0" ]]; then
					print -u2 "Configuration for DHCP interface $INT does not exist."
					exit 1
				fi
				INTF_NETNAME=${CORONA_NAME}-${INT}
				INTF_NET=`$GREP -s ":Include=${INTF_NETNAME}:" $DHTADM_P | awk '{print $1}'`
				if [ -z "${INTF_NET}" ]; then
					print -u2 "Error: Cannot translate interface \"${INT}\" to a network number"
					return 1
				fi
				TranslateDhtadmP 
				InitDHCPBlockParser $UTDHCPFILE
				while GetNextDHCPBlock interface
				do
					if [[ $UT_DHCP_INTERFACE = $INT ]]; then
						break
					fi
				done
			else
				print -u2 "Error: Input must start with a \"begin\" statement"
                                exit 1
			fi
			;;
                (network*)
			if $STARTED; then
				if [[ $COMMAND = "interface" ]]; then
					if ! $INTSET; then
                                		print -u2 "Error: Missing Interface definition"
						exit 1
                        		else
                                		ConvertKeyToLower "$input"
                                		input="$_RETURN_VAL"
                                		SourceInterface "$input" 
                        		fi
				elif [[ $COMMAND = "subnet" ]]; then
                        		SUBNET=${input#network=}
					grep "${CORONA_NAME}-${SUBNET}" $DHTADM_P >/dev/null 2>&1
                                        if [[ $? != "0" ]]; then
                                                print -u2 "Configuration for DHCP subnet $SUBNET does not exist."
                                                exit 1
                                        fi
					INTF_NETNAME=${CORONA_NAME}-${SUBNET}
                                        INTF_NET=${SUBNET}
					NETSET=true
					TranslateDhtadmP 
					InitDHCPBlockParser $UTDHCPFILE
					while GetNextDHCPBlock subnet
					do
						if [[ $UT_DHCP_NETWORK = $SUBNET ]]; then
							break
						fi
					done
				fi
			else
				print -u2 "Error: Input must start with a \"begin\" statement"
                                exit 1
                        fi
                        ;;
                (end)
                        break
                        ;;
                (*)
			if $INTSET; then
				ConvertKeyToLower "$input"
				input="$_RETURN_VAL"
				SourceInterface "$input"
			elif $NETSET; then
				ConvertKeyToLower "$input"
                        	input="$_RETURN_VAL"
                        	SourceSubnet "$input" 
			else
				print -u2 "Error: Missing DHCP block definition"
                                exit 1
			fi
                        ;;
                esac
        done
	DeleteConfig
	AddConfig
        exit 0
}

ListSubnetBlocks() {
	TranslateDhtadmP 
	if [[ $? != 0 ]]; then
                return 0
        fi
	InitDHCPBlockParser $UTDHCPFILE
	if [[ $? != 0 ]]; then
                return 0
        fi
	while GetNextDHCPBlock subnet
        do
                CreateDHCPBlock subnet
	done	
	DestroyDHCPBlockParser
	rm -f $UTDHCPFILE 2>/dev/null
}

ListInterfaceBlocks() {
	TranslateDhtadmP 
	if [[ $? != 0 ]]; then
		return 0
	fi
	InitDHCPBlockParser $UTDHCPFILE
	if [[ $? != 0 ]]; then
		return 0
	fi
	while GetNextDHCPBlock interface
	do
          	CreateDHCPBlock interface
	done
	DestroyDHCPBlockParser
	rm -f $UTDHCPFILE 2>/dev/null
}

# main

trap "rm -rf ${TMPDIR}/*.$$; exit" 0 1 2 3 14 15

ETC_OPT_UT="/etc/opt/SUNWut"
UT_DHCP_BASEDIR=`(cd ${ETC_OPT_UT}/dhcp ; /bin/pwd)`
. ${UT_DHCP_BASEDIR}/dhcp_config_solaris
. ${UT_DHCP_BASEDIR}/../../support_lib/dhcp_config

GetCurrentCfg;

if [[ $# = 0 ]]; then
	ANYINTFSFOUND=false
	ListSubnetBlocks
	if $ANYINTFSFOUND; then
		ListInterfaceBlocks
	fi
	exit 0
fi	

case $1 in
(add)
	ProcessAdd 
	;;
(change)
	ProcessChange 
	;;
(delete)
	ProcessDelete 
	;;
(list)
	if [[ $# = 1 ]]; then
		ANYINTFSFOUND=false
		ListSubnetBlocks
		if $ANYINTFSFOUND; then
			ListInterfaceBlocks
		fi
		exit 0
	fi
	if [[ $2 = "subnet" ]]; then
		ListSubnetBlocks
		exit 0
	elif [[ $2 = "interface" ]]; then
		ListInterfaceBlocks
		exit 0
	else
		print -u2 "Must specify either interface or subnet."
		exit 1
	fi
	;;
(*)
	exit 1
esac
