#!/bin/ksh -p
#
# ident "@(#)dhcp_config.ksh	1.11 04/09/28 SMI"
#
# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#

VARDIR=/var/opt/SUNWut
ETCDIR=/etc/opt/SUNWut
TMPDIR="$VARDIR"/tmp
TMPDHCPDIR="$TMPDIR"/dhcp.$$
CLEANUPLIST="${TMPDIR}/*.$$"

trap "rm -rf ${CLEANUPLIST}; exit" 0 

ConvertKeyToLower() {
	keyvalue="$1"

	typeset -l key=${keyvalue%%=*}
	value=${keyvalue#*=}
	if [[ $key == $keyvalue || "$value" == $keyvalue ]]; then
		keyvalue="invalid"
	else
		keyvalue="$key=$value"
	fi
	_RETURN_VAL=$keyvalue
}

#
# Normalize Ethernet address for use with DHCP
#
function normalizeEther {
	NETHER=
	# Some people will insist on entering the colons
	case "$ETHER" in
	*[0-9A-Fa-f]:[0-9A-Fa-f]*)
			# Get rid of colons
		SAVEIFS=$IFS
		IFS=:			# colon is separator
		for BYTE in $ETHER
		do
	          	case $BYTE in
				?)
	                  	# single digit gets leading zero
					NETHER=${NETHER}0$BYTE
				;;
			*)
	                  	NETHER=${NETHER}$BYTE
					;;
			esac
		done
		IFS=$SAVEIFS
		ETHER=$NETHER
		;;
	esac
	case $ETHER in
	[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f])
#ok, exactly 12 hex characters
         	;;
	*)
	 	print -u2 "Error: Invalid ethernet address: \"$ETHER\""
         	exit 1
                ;;
	esac
}

AddEtherColon () {
	case "$UT_DHCP_MACADDRESS" in
	[0-9A-Fa-f]*)
		ETHERCOLON=
		NEXT=${UT_DHCP_MACADDRESS%??????????}
		REST=${UT_DHCP_MACADDRESS#??}
		ETHERCOLON=${NEXT}:
		NEXT=${REST%????????}
		REST=${REST#??}
		ETHERCOLON=${ETHERCOLON}${NEXT}:
		NEXT=${REST%??????}
                REST=${REST#??}
                ETHERCOLON=${ETHERCOLON}${NEXT}:
		NEXT=${REST%????}
                REST=${REST#??}
                ETHERCOLON=${ETHERCOLON}${NEXT}:
		NEXT=${REST%??}
                REST=${REST#??}
                ETHERCOLON=${ETHERCOLON}${NEXT}:
		ETHERCOLON=${ETHERCOLON}${REST}
	esac
}

#
# lock a file in preparation for updating it
#  usage:  StartFileUpdate <path>
#  first tries to lock the file and if it succeeds, it makes a copy
# of the given file, which is to be used to modify the file.
#  the EndFileUpdate function is called after changes have been made
# to the file and it is ready to be put back in operation.
#
function StartFileUpdate {
  # generate a tmp copy of the new file
  cp -f $1 $1.$$
  CLEANUPLIST="$CLEANUPLIST $1.$$"
  if [ ${?} -ne 0 ]; then
    print -u2 "Error:  unable to make tmp file"
    exit 1;
  fi
  chmod 600 $1.$$;
}


#
# end the update of a file
#  usage:  EndFileUpdate <path>
#  this is called after StartFileUpdate is called and atomically
# updates the given file and unlocks it
#
function EndFileUpdate {
  # save a copy of the original file
  rm -f $1.bak
  cp -p -f $1 $1.bak
  if [ ${?} -ne 0 ]; then
    print -u2 "Error:  unable to make backup file \"$1.bak\""
    exit 1;
  fi

  # Copy over the original, preserving ownership, links, and permissions
  cp -f $1.$$ $1
  rm -f $1.$$
}

#
# restore a file to it's non-newt state (handle both NEWT and SUNRAY)
#
function RestoreFile {
  rm -f ${TMPDIR}/tmpfile.$$;
  typeset __AWK=$(whence nawk)
  if [[ -z $__AWK ]] ; then
    __AWK=$(whence gawk)
    if [[ -z $__AWK ]] ; then
      print -u2 'Fatal: No recognized awk implementation found on this host'
      exit 1
    fi
  fi
  $__AWK 'BEGIN { omit = 0 }
                /^# SUNRAY DEL / {
                  sub("# SUNRAY DEL  *", "", $0)
                  print $0
                  next;
                };
                /^# NEWT DEL / {
                  sub("# NEWT DEL  *", "", $0)
                  print $0
                  next;
                };
                /# SUNRAY ADD/ {
                  next;
                };
                /# NEWT ADD/ {
                  next;
                };
                /^# SUNRAY BEGIN/ { omit = 1 };
                /^# NEWT BEGIN/ { omit = 1 };
                (omit == 0) { print $0 };
                /^# SUNRAY END/ { omit = 0 };
                /^# NEWT END/ { omit = 0 };
                END { }' $1 > ${TMPDIR}/tmpfile.$$;
  cp -f ${TMPDIR}/tmpfile.$$ $1;
  rm -f ${TMPDIR}/tmpfile.$$;
}

#
# Add dotted network and undotted host number together
# Parameters:
#	$1 network number
#	$2 host number
#	$3 max host number
# Sets:
#	IP - a dotted IP address
#
function NetPlusHost {
  if [[ $2 -ge $3 ]] || [[ $2 -eq 0 ]]; then
     # invalid host number
     print -u2 "Host number $2 is invalid for $1 subnet"
     IP="BadAdd"
     return 1
  fi
  IP=`print "$1 $2" | awk '{
                        split($1, a, ".")
                        dot = ""
                        out = ""
                        b = $2
                        for (i = 4; i >= 1; i--) {
                                c =  (a[i] + b) % 256
                                b -= (b % 256)
                                b /= 256
                                out = c dot out
                                dot = "."
                        }
                        printf "%s\n", out
                }'`
  return 0;
}

#
# Return the maximum host number for a given netmask
# Parameters:
#	$1 netmask
# Sets:
#	H - the maximum host number
#
function MaxHostNum {
  H=`print "$1" | awk '{
                        split($1, m, ".")
                        out = 0
                        for (i = 1; i <= 4; i++) {
                                out *= 256
                                for (j = 1; j <= 256; j *= 2) {
                                        if ((m[i] + j) == 256) {
                                                out += j - 1
                                                break
                                        } else if ((m[i] + j) > 256) {
                                                print "BadMask"
                                                exit
                                        }
                                }
                        }
                        printf "%d\n", out
                }'`
  if [ $H = "BadMask" ]; then
    return 1;
  fi
  return 0;
}

#
# Get undotted host number from IP address
# Parameters:
#	$1 IP address
#	$2 netmask
# Sets:
#	H - host number
#
function IP2Host {
  H=`print "$1 $2" | awk '{
                        split($1, a, ".")
			split($2, m, ".")
			dot = ""
			out = 0
			for (i = 1; i <= 4; i++) {
				out *= 256
				for (j = 1; j <= 256; j *= 2) {
                                        if ((m[i] + j) == 256) {
                                                out += a[i] % j
                                                break
                                        } else if ((m[i] + j) > 256) {
                                                print "BadMask"
                                                exit
                                        }
				}
			}
                        printf "%d\n", out
		}'`
  if [ $H = "BadMask" ]; then
    return 1;
  fi
  return 0;
}

InitDHCPBlockParser() {
	FILE=$1
	typeset -i i=0
	BEGAN=false
	TMPFILE="$TMPDHCPDIR"/tmpfile.$$

	rm -rf $TMPDHCPDIR 2>/dev/null
	if [[ ! -f $FILE ]]; then
		return 1
	fi
	mkdir -p $TMPDHCPDIR 

	while read line
	do
		case $line in
                (begin*)
			if $BEGAN; then
				rm -rf $TMPDHCPDIR
				return 2
			fi
			BEGAN=true
			rm -f $TMPFILE 2>/dev/null
			touch $TMPFILE
                        SUFFIX=${line#begin }
                        ;;
		(end)
			if ! $BEGAN; then
				rm -rf $TMPDHCPDIR
				return 2
			fi
			echo $line >> $TMPFILE
			BEGAN=false
			mv $TMPFILE $TMPDHCPDIR/$i.$SUFFIX
			i=i+1	
			;;	
		esac
		if $BEGAN; then
			print $line >> $TMPFILE
		fi
	done < $FILE
}

DestroyDHCPBlockParser() {
	rm -rf $TMPDHCPDIR 2>/dev/null
	return 0
}

InitOptionsBlock() {
	UT_DHCP_AUTHPORT=""
  	UT_DHCP_NEWTVER=""
  	UT_DHCP_LOGHOST=""
  	UT_DHCP_LOGKERNEL=""
  	UT_DHCP_LOGNET=""
  	UT_DHCP_LOGUSB=""
  	UT_DHCP_LOGVIDEO=""
  	UT_DHCP_LOGAPPLICATION=""
  	UT_DHCP_NEWTBANDWIDTH=""
  	UT_DHCP_BARRIERLEVEL=""
  	UT_DHCP_NEWTFLAGS=""
  	UT_DHCP_NEWTDISPINDEX=""
	return 0
}

SourceOptionsBlock() {
	INFILE=$1

	while read oline
        do
		SourceOptions "$oline"
	done < $INFILE
}

SourceOptions() {
	INARG=$1
	case $INARG in
		(authport=*)
			UT_DHCP_AUTHPORT=${INARG#authport=}	
			;;
		(newtver=*)
			UT_DHCP_NEWTVER=${INARG#newtver=}
			# strip imbedded quotes if any
			UT_DHCP_NEWTVER=${UT_DHCP_NEWTVER#\"}
			UT_DHCP_NEWTVER=${UT_DHCP_NEWTVER%\"}
			;;
		(loghost=*)
                        UT_DHCP_LOGHOST=${INARG#loghost=}
                        ;;
		(logkernel=*)
                        UT_DHCP_LOGKERNEL=${INARG#logkernel=}
                        ;;	
		(lognet=*)
                        UT_DHCP_LOGNET=${INARG#lognet=}
                        ;;
		(logusb=*)
                        UT_DHCP_LOGUSB=${INARG#logusb=}
                        ;;
		(logvideo=*)
                        UT_DHCP_LOGVIDEO=${INARG#logvideo=}
                        ;;
		(logapplication=*)
                        UT_DHCP_LOGAPPLICATION=${INARG#logapplication=}
                        ;;
		(newtbandwidth=*)
                        UT_DHCP_NEWTBANDWIDTH=${INARG#newtbandwidth=}
                        ;;
		(barrierlevel=*)
                        UT_DHCP_BARRIERLEVEL=${INARG#barrierlevel=}
                        ;;
		(newtflags=*)
                        UT_DHCP_NEWTFLAGS=${INARG#newtflags=}
                        ;;
		(newtdispindex=*)
                        UT_DHCP_NEWTDISPINDEX=${INARG#newtdispindex=}
                        ;;
	esac
}

GenerateOptionsBlock() {
	print "begin options" 
	GenerateOptions
	print "end" 
}

GenerateOptions() {
	if [[ -n $UT_DHCP_AUTHPORT ]]; then
                print "authport=$UT_DHCP_AUTHPORT" 
        fi
        if [[ -n $UT_DHCP_NEWTVER ]]; then
                print "newtver=$UT_DHCP_NEWTVER" 
        fi
        if [[ -n $UT_DHCP_LOGHOST ]]; then
                print "loghost=$UT_DHCP_LOGHOST" 
        fi
        if [[ -n $UT_DHCP_LOGKERNEL ]]; then
                print "logkernel=$UT_DHCP_LOGKERNEL" 
        fi
        if [[ -n $UT_DHCP_LOGNET ]]; then
                print "lognet=$UT_DHCP_LOGNET" 
        fi
        if [[ -n $UT_DHCP_LOGUSB ]]; then
                print "logusb=$UT_DHCP_LOGUSB" 
        fi
        if [[ -n $UT_DHCP_LOGVIDEO ]]; then
                print "logvideo=$UT_DHCP_LOGVIDEO" 
        fi
        if [[ -n $UT_DHCP_LOGAPPLICATION ]]; then
                print "logapplication=$UT_DHCP_LOGAPPLICATION" 
        fi
        if [[ -n $UT_DHCP_NEWTBANDWIDTH ]]; then
                print "newtbandwidth=$UT_DHCP_NEWTBANDWIDTH" 
        fi
        if [[ -n $UT_DHCP_BARRIERLEVEL ]]; then
                print "barrierlevel=$UT_DHCP_BARRIERLEVEL" 
        fi
        if [[ -n $UT_DHCP_NEWTFLAGS ]]; then
                print "newtflags=$UT_DHCP_NEWTFLAGS" 
        fi
        if [[ -n $UT_DHCP_NEWTDISPINDEX ]]; then
                print "newtdispindex=$UT_DHCP_NEWTDISPINDEX" 
        fi
}

ValidateOptionsBlock() {
	if [[ -n $UT_DHCP_AUTHPORT ]]; then
		return 0
	fi
	if [[ -n $UT_DHCP_NEWTVER ]]; then
                return 0
        fi
	if [[ -n $UT_DHCP_LOGHOST ]]; then
                return 0
        fi
	if [[ -n $UT_DHCP_LOGKERNEL ]]; then
                return 0
        fi
	if [[ -n $UT_DHCP_LOGNET ]]; then
                return 0
        fi
	if [[ -n $UT_DHCP_LOGUSB ]]; then
                return 0
        fi
	if [[ -n $UT_DHCP_LOGVIDEO ]]; then
                return 0
        fi
	if [[ -n $UT_DHCP_LOGAPPLICATION ]]; then
                return 0
        fi
	if [[ -n $UT_DHCP_NEWTBANDWIDTH ]]; then
                return 0
        fi
	if [[ -n $UT_DHCP_BARRIERLEVEL ]]; then
                return 0
        fi
	if [[ -n $UT_DHCP_NEWTFLAGS ]]; then
                return 0
        fi
	if [[ -n $UT_DHCP_NEWTDISPINDEX ]]; then
                return 0
        fi
	return 1
}

InitEtherBlock() {
	UT_DHCP_MACADDRESS=""
	InitOptionsBlock
	return 0
}

SourceEtherBlock() {
        INFILE=$1

        while read eline
        do
                case $eline in
		(macaddress=*)
			UT_DHCP_MACADDRESS=${eline#macaddress=}
                        ;;
		(*)
			SourceOptions "$eline"
			;;
		esac
	done < $INFILE
}

GenerateEtherBlock() {
        print "begin ether" 
	if [[ -n $UT_DHCP_MACADDRESS ]]; then
                print "macaddress=$UT_DHCP_MACADDRESS" 
        fi
	GenerateOptions
	print "end" 
}

ValidateEtherBlock() {
	if [[ -z $UT_DHCP_MACADDRESS ]]; then
		return 1
	fi
	ValidateOptionsBlock
	return $?
}

InitSubnetBlock() {
	UT_DHCP_NETWORK=""
  	UT_DHCP_NETMASK=""
  	UT_DHCP_BROADCAST=""
  	UT_DHCP_SUBNETMASK=""
  	UT_DHCP_MTU=""
  	UT_DHCP_ROUTERS=""
  	UT_DHCP_RANGE=""
  	UT_DHCP_ASSIGNED=""
	UT_DHCP_AUTHSRVR=""
	UT_DHCP_ALTAUTHLIST=""
	UT_DHCP_FIRMWARESRVR=""
	UT_DHCP_MTU=""
	InitOptionsBlock
	return 0
}

SourceSubnetBlock() {
        INFILE=$1

        while read sline
        do
		SourceSubnet "$sline"
        done < $INFILE
}

SourceSubnet() {
	INARG=$1

	case $INARG in
		(network=*)
                        UT_DHCP_NETWORK=${INARG#network=}
			;;
		(netmask=*)
                        UT_DHCP_NETMASK=${INARG#netmask=}
			;;
		(broadcast=*)
			UT_DHCP_BROADCAST=${INARG#broadcast=}
			;;
		(subnetmask=*)
                        UT_DHCP_SUBNETMASK=${INARG#subnetmask=}
			;;
		(mtu=*)
			UT_DHCP_MTU=${INARG#mtu=}
			;;
		(routers=*)
                        UT_DHCP_ROUTERS=${INARG#routers=}
			;;
		(range=*)
                        UT_DHCP_RANGE=${INARG#range=}
			;;
		(assigned=*)
                        UT_DHCP_ASSIGNED=${INARG#assigned=}
			;;
		(authsrvr=*)
			UT_DHCP_AUTHSRVR=${INARG#authsrvr=}
                        ;;
		(altauthlist=*)
                        UT_DHCP_ALTAUTHLIST=${INARG#altauthlist=}
			UT_DHCP_ALTAUTHLIST=`print -- $UT_DHCP_ALTAUTHLIST | 
                	sed -e 's/,/ /g'`
                        ;;
		(firmwaresrvr=*)
                        UT_DHCP_FIRMWARESRVR=${INARG#firmwaresrvr=}
                        ;;
		(mtu=*)
			UT_DHCP_MTU=${INARG#mtu=}
			;;
		(*)
                   	SourceOptions "$INARG"
                        ;;
	esac
}

GenerateSubnetBlock() {
        print "begin subnet" 
	if [[ -n $UT_DHCP_NETWORK ]]; then
                print "network=$UT_DHCP_NETWORK" 
        fi	
	if [[ -n $UT_DHCP_NETMASK ]]; then
                print "netmask=$UT_DHCP_NETMASK" 
        fi
	if [[ -n $UT_DHCP_BROADCAST ]]; then
                print "broadcast=$UT_DHCP_BROADCAST" 
        fi
	if [[ -n $UT_DHCP_SUBNETMASK ]]; then
                print "subnetmask=$UT_DHCP_SUBNETMASK" 
        fi
	if [[ -n $UT_DHCP_MTU ]]; then
                print "mtu=$UT_DHCP_MTU" 
        fi
	if [[ -n $UT_DHCP_ROUTERS ]]; then
                print "routers=$UT_DHCP_ROUTERS" 
        fi
	if [[ -n $UT_DHCP_RANGE ]]; then
                print "range=$UT_DHCP_RANGE" 
        fi
	if [[ -n $UT_DHCP_ASSIGNED ]]; then
                print "assigned=$UT_DHCP_ASSIGNED" 
        fi
	if [[ -n $UT_DHCP_AUTHSRVR ]]; then
                print "authsrvr=$UT_DHCP_AUTHSRVR" 
        fi
	if [[ -n $UT_DHCP_ALTAUTHLIST ]]; then
                print "altauthlist=$UT_DHCP_ALTAUTHLIST" 
        fi
	if [[ -n $UT_DHCP_FIRMWARESRVR ]]; then
                print "firmwaresrvr=$UT_DHCP_FIRMWARESRVR" 
        fi
	if [[ -n $UT_DHCP_MTU ]]; then
		print "mtu=$UT_DHCP_MTU"
	fi
	GenerateOptions
	print "end" 
}

ValidateSubnetBlock() {
	if [[ -z $UT_DHCP_NETWORK ]]; then
                return 1
        fi
	if [[ -z $UT_DHCP_NETMASK ]]; then
                return 1
        fi
	return 0
}

InitInterfaceBlock() {
	UT_DHCP_INTERFACE=""
  	UT_DHCP_HOSTNAME=""
  	UT_DHCP_IP=""
  	UT_DHCP_NETWORK=""
  	UT_DHCP_NETMASK=""
  	UT_DHCP_BROADCAST=""
  	UT_DHCP_SUBNETMASK=""
  	UT_DHCP_MTU=""
  	UT_DHCP_ROUTERS=""
  	UT_DHCP_RANGE=""
  	UT_DHCP_ASSIGNED=""
  	UT_DHCP_AUTHSRVR=""
  	UT_DHCP_ALTAUTHLIST=""
  	UT_DHCP_FIRMWARESRVR=""
	UT_DHCP_MTU=""
	InitOptionsBlock
	return 0
}

SourceInterfaceBlock() {
        INFILE=$1

        while read iline 
        do
                SourceInterface "$iline"
        done < $INFILE
}

SourceInterface() {
	INARG=$1

	case $INARG in
		(interface=*)
                        UT_DHCP_INTERFACE=${INARG#interface=}
			# strip imbedded quotes if any
                        UT_DHCP_INTERFACE=${UT_DHCP_INTERFACE#\"}
                        UT_DHCP_INTERFACE=${UT_DHCP_INTERFACE%\"}
                        ;;
		(hostname=*)
                        UT_DHCP_HOSTNAME=${INARG#hostname=}
                        ;;
		(ip=*)
                        UT_DHCP_IP=${INARG#ip=}
                        ;;
                (network=*)
                        UT_DHCP_NETWORK=${INARG#network=}
                        ;;
                (netmask=*)
                        UT_DHCP_NETMASK=${INARG#netmask=}
                        ;;
                (broadcast=*)
                        UT_DHCP_BROADCAST=${INARG#broadcast=}
                        ;;
                (subnetmask=*)
                        UT_DHCP_SUBNETMASK=${INARG#subnetmask=}
                        ;;
                (mtu=*)
                        UT_DHCP_MTU=${INARG#mtu=}
                        ;;
                (routers=*)
                        UT_DHCP_ROUTERS=${INARG#routers=}
                        ;;
                (range=*)
                        UT_DHCP_RANGE=${INARG#range=}
                        ;;
                (assigned=*)
                        UT_DHCP_ASSIGNED=${INARG#assigned=}
                        ;;
                (authsrvr=*)
                        UT_DHCP_AUTHSRVR=${INARG#authsrvr=}
                        ;;
                (altauthlist=*)
                        UT_DHCP_ALTAUTHLIST=${INARG#altauthlist=}
                        ;;
                (firmwaresrvr=*)
                        UT_DHCP_FIRMWARESRVR=${INARG#firmwaresrvr=}
                        ;;
		(mtu=*)
			UT_DHCP_MTU=${INARG#mtu=}
			;;
		(*)
			SourceOptions "$INARG"
			;;
	esac
}

GenerateInterfaceBlock() {

        print "begin interface" 
	if [[ -n $UT_DHCP_INTERFACE ]]; then
                print "interface=$UT_DHCP_INTERFACE" 
        fi
	if [[ -n $UT_DHCP_HOSTNAME ]]; then
                print "hostname=$UT_DHCP_HOSTNAME" 
        fi
	if [[ -n $UT_DHCP_IP ]]; then
                print "ip=$UT_DHCP_IP" 
        fi
	if [[ -n $UT_DHCP_NETWORK ]]; then
                print "network=$UT_DHCP_NETWORK" 
        fi
	if [[ -n $UT_DHCP_NETMASK ]]; then
                print "netmask=$UT_DHCP_NETMASK" 
        fi
	if [[ -n $UT_DHCP_BROADCAST ]]; then
                print "broadcast=$UT_DHCP_BROADCAST" 
        fi
	if [[ -n $UT_DHCP_SUBNETMASK ]]; then
                print "subnetmask=$UT_DHCP_SUBNETMASK" 
        fi
        if [[ -n $UT_DHCP_MTU ]]; then
                print "mtu=$UT_DHCP_MTU" 
        fi
	if [[ -n $UT_DHCP_ROUTERS ]]; then
                print "routers=$UT_DHCP_ROUTERS" 
        fi
	if [[ -n $UT_DHCP_RANGE ]]; then
                print "range=$UT_DHCP_RANGE" 
        fi
        if [[ -n $UT_DHCP_ASSIGNED ]]; then
                print "assigned=$UT_DHCP_ASSIGNED" 
        fi
        if [[ -n $UT_DHCP_AUTHSRVR ]]; then
                print "authsrvr=$UT_DHCP_AUTHSRVR" 
        fi
        if [[ -n $UT_DHCP_ALTAUTHLIST ]]; then
                print "altauthlist=$UT_DHCP_ALTAUTHLIST" 
        fi
        if [[ -n $UT_DHCP_FIRMWARESRVR ]]; then
                print "firmwaresrvr=$UT_DHCP_FIRMWARESRVR" 
        fi
	if [[ -n $UT_DHCP_MTU ]]; then
		print "mtu=$UT_DHCP_MTU"
	fi
	GenerateOptions
	print "end" 
}

ValidateInterfaceBlock() {
	if [[ -z $UT_DHCP_INTERFACE ]]; then
                return 1
        fi
        if [[ -z $UT_DHCP_HOSTNAME ]]; then
                return 1
        fi
        if [[ -z $UT_DHCP_IP ]]; then
                return 1
        fi
	if [[ -z $UT_DHCP_NETWORK ]]; then
                return 1
        fi
        if [[ -z $UT_DHCP_NETMASK ]]; then
                return 1
        fi
        return 0
}

InitDhcpstateBlock() {
	UT_DHCP_INSTALLED=""
  	UT_DHCP_ENABLED=""
  	UT_DHCP_CONFIGURED=""
  	UT_DHCP_RUNNING=""
  	UT_DHCP_PACKAGES=""
	return 0
}

SourceDhcpstateBlock() {
        INFILE=$1

        while read dline
        do
                case $dline in
                (installed=*)
                        UT_DHCP_INSTALLED=${dline#installed=}
                        ;;
		(enabled=*)
                        UT_DHCP_ENABLED=${dline#enabled=}
                        ;;
		(configured=*)
                        UT_DHCP_CONFIGURED=${dline#configured=}
                        ;;
		(running=*)
                        UT_DHCP_RUNNING=${dline#running=}
                        ;;
		(packages=*)
                        UT_DHCP_PACKAGES=${dline#packages=}
                        ;;
		esac
	done < $INFILE
}

GenerateDhcpstateBlock() {
	print "begin dhcpstate" 
	if [[ -n $UT_DHCP_INSTALLED ]]; then
                print "installed=$UT_DHCP_INSTALLED" 
        fi
        if [[ -n $UT_DHCP_ENABLED ]]; then
                print "enabled=$UT_DHCP_ENABLED" 
        fi
        if [[ -n $UT_DHCP_CONFIGURED ]]; then
                print "configured=$UT_DHCP_CONFIGURED" 
        fi
        if [[ -n $UT_DHCP_RUNNING ]]; then
                print "running=$UT_DHCP_RUNNING" 
        fi
        if [[ -n $UT_DHCP_PACKAGES ]]; then
                print "packages=$UT_DHCP_PACKAGES" 
        fi
	print "end" 
}

ValidateDhcpstateBlock() {
	if [[ -z $UT_DHCP_INSTALLED ]]; then
                return 1
        fi
        if [[ -z $UT_DHCP_ENABLED ]]; then
                return 1
        fi
        if [[ -z $UT_DHCP_CONFIGURED ]]; then
                return 1
        fi
        return 0	
}

GetNextDHCPBlock() {
	KEY=$1

	GREPKEY=""
	case $KEY in
	(options)
		GREPKEY="options"
		;;
	(ether)
		GREPKEY="ether"
                ;;
	(subnet)
		GREPKEY="subnet"
                ;;
	(interface)
		GREPKEY="interface"
                ;;
	(dhcpstate)
		GREPKEY="dhcpstate"
                ;;
	(all)
		GREPKEY=""
		;;
	(*)
		GREPKEY=""
		;;
	esac
	TMPFILE=$TMPDHCPDIR/order.$$
	RET=1
	if [[ ! -d $TMPDHCPDIR ]]; then
		return 3
	fi
	if [[ -n $GREPKEY ]]; then
		ls $TMPDHCPDIR | grep -v order | sort -n | grep $GREPKEY > $TMPFILE
		if [[ $? != 0 ]]; then
                	return 1
        	fi
	else
		ls $TMPDHCPDIR | grep -v order | sort -n > $TMPFILE
		if [[ $? != 0 ]]; then
                        return 1
                fi
	fi
	read line < $TMPFILE
	if [[ $? != 0 ]]; then
		return 1
	fi

	case $line in
	(*options)
		InitOptionsBlock
		SourceOptionsBlock $TMPDHCPDIR/$line
		ValidateOptionsBlock
		if [[ $? = 0 ]]; then
			BLOCKTYPE=options
			RET=0
		else
			InitOptionsBlock
			RET=2
		fi
		;;
	(*ether)
		InitEtherBlock
		SourceEtherBlock $TMPDHCPDIR/$line
		ValidateEtherBlock
		if [[ $? = 0 ]]; then
			BLOCKTYPE=ether
                        RET=0
                else
                        InitEtherBlock
                        RET=2
                fi
                ;;
	(*subnet)
		InitSubnetBlock
		SourceSubnetBlock $TMPDHCPDIR/$line
                ValidateSubnetBlock
                if [[ $? = 0 ]]; then
			BLOCKTYPE=subnet
                        RET=0
                else
                        InitSubnetBlock
                        RET=2
                fi
                ;;
	(*interface)
		InitInterfaceBlock
		SourceInterfaceBlock $TMPDHCPDIR/$line
                ValidateInterfaceBlock
                if [[ $? = 0 ]]; then
			BLOCKTYPE=interface
                        RET=0
                else
                        InitInterfaceBlock
			RET=2
                fi
                ;;
	(*dhcpstate)
		InitDhcpstateBlock
		SourceDhcpstateBlock $TMPDHCPDIR/$line
                ValidateDhcpstateBlock
                if [[ $? = 0 ]]; then
			BLOCKTYPE=dhcpstate
			RET=0
                else
                        InitDhcpstateBlock
			RET=2
                fi
                ;;
	esac
	rm -f $TMPDHCPDIR/$line
	rm -f $TMPFILE
	
	return $RET
}

CreateDHCPBlock() {
	case $1 in
	(options)
		ValidateOptionsBlock
		if [[ $? != 0 ]]; then
			return 1
		fi
		GenerateOptionsBlock 
		;;
	(ether)
		ValidateEtherBlock
		if [[ $? != 0 ]]; then
                        return 1
                fi
		GenerateEtherBlock 
		;;
	(subnet)
		ValidateSubnetBlock
		if [[ $? != 0 ]]; then
                        return 1
                fi
		GenerateSubnetBlock 
		;;
	(interface)
		ValidateInterfaceBlock
		if [[ $? != 0 ]]; then
                        return 1
                fi
		GenerateInterfaceBlock 
		;;
	(dhcpstate)
		ValidateDhcpstateBlock
		if [[ $? != 0 ]]; then
                        return 1
                fi
		GenerateDhcpstateBlock 
		;;
	(*)
		return 1
		;;
	esac
	return 0
}


#
# IP_Mask2Net() Translate a host IP address to its network address.
# The subnet is printed to stdout.
#
# Parameters:
#	$1 IP address or network number
#	$2 netmask
#
# Returns:
#	0 if successfull
#	1 otherwise
#
IP_Mask2Net() {
	typeset ADDR=$1
	typeset MASK=$2
	typeset SUBNET

  	SUBNET=`print "$ADDR $MASK" | awk '{
		split($1, a, ".")
		split($2, m, ".")
		dot = ""
		out = ""
		for (i = 1; i <= 4; i++) {
			for (j = 1; j <= 256; j *= 2) {
				if ((m[i] + j) == 256) {
					out = out dot a[i] - a[i] % j
					break
				} else if ((m[i] + j) > 256) {
					out = "BadMask"
					i = 5
					break
				}
			}
			dot = "."
		}
		printf "%s\n", out
	}'`
	print $SUBNET
  	if [ $SUBNET == "BadMask" ]; then
		return 1;
	fi
	return 0;
}

