ACC SHELL

Path : /sbin/
File Upload :
Current File : //sbin/ifrenew-dhcp

#! /bin/bash
#
# Copyright (c) 2002 SuSE Linux AG Nuernberg, Germany. All rights reserved.
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA
#
# Author: Christian Zoz <zoz@suse.de>, 2002-2006
#         Peter Poeml <poeml@suse.de>, 2002-2006
#

unset POSIXLY_CORRECT ; set +o posix # we're using non-posix bash features

usage () {
	echo $@
	echo "Usage: if{up,down,status}-dhcp [<config>] <interface> [-o <options>]"
	echo ""
	echo "Options are: boot      : we are currently booting"
	echo "             hotplug   : we are handling a hotplug event"
	echo "             debug     : be verbose"
	echo "             rc        : indicates that we are called from rcnetwork"
	echo "All other or wrong options are silently ignored."
	exit $R_USAGE
}

######################################################################
# change the working direcory and source some common files
#
R_INTERNAL=1      # internal error, e.g. no config or missing scripts
cd /etc/sysconfig/network || exit $R_INTERNAL
test -f ./config && . ./config
test -f scripts/functions && . scripts/functions || exit $R_INTERNAL

test "$DEBUG" = "EXTRA" && . scripts/extradebug

######################################################################
# check arguments and how we are called (in case of links)
#
SCRIPTNAME=${0##*/}
debug "$SCRIPTNAME $*"

case "${SCRIPTNAME}" in
	ifup-*) ACTION=start ;;
	ifdown-*) ACTION=stop ;;
	ifstatus-*) ACTION=status ;;
	ifrenew-*) ACTION=renew ;;
	*) usage
esac
case "$1" in ""|-h|*help*) usage; esac
CONFIG=$1
shift
if [ -n "$1" -a "$1" != "-o" ] ; then
	INTERFACE=$1
else
	INTERFACE=$CONFIG
fi
shift
test "$1" = "-o" && shift
OPTIONS="$@"
MODE=manual
while [ $# -gt 0 ]; do
	case $1 in
		boot|onboot) MODE=onboot ;;
		hotplug)     MODE=hotplug ;;
		quiet)       be_quiet_has_gone ;;
		debug)       DEBUG=yes ;;
		rc)          RUN_FROM_RC=yes ;;
		*)           debug unknown option $1 ;;
	esac
	shift
done

######################################################################
# check presence of configuration files
#
test -f ./dhcp && . ./dhcp
test -f ./ifcfg-$CONFIG && . ./ifcfg-$CONFIG

######################################################################
# get the interface and check if it is up
#
if [ -z "$INTERFACE" ] ; then
	usage "No interface given"
fi
if ! is_iface_available $INTERFACE ; then
	# When a hotplug remove event occurs the interface has already gone.
	# Nevertheless we have to clean up.
	if [ \( "$ACTION" != stop -o "$MODE" != hotplug \) -a "$INTERFACE" != all ] ; then
		logerror "interface ${INTERFACE} is not available"
		exit $R_NODEV
	fi
fi

######################################################################
# Normalize & resolve & cleanup the bootproto value from config
# Note:
# INTERFACE=all is a special case used by rcnetwork stop/ifdown
# to kill all dhcp clients that may still run on some interface
#
explicit_dhcp4=no
explicit_dhcp6=no
BOOTPROTO=$(echo "$BOOTPROTO" | awk '{print tolower($0);}')
# Override with iSCSI Boot Firmware Table (feature 308283, bnc 542225)
if [ "$INTERFACE" != "all" -a "${BOOTPROTO}" = "ibft" ] ; then
	IBFT=yes # not used at the moment... remember before override
	eval BOOTPROTO=none `parse_ifname_ibft_settings "$INTERFACE"`
fi
BOOTPROTOS=()
AUTOIP=no
add_bootproto_once() {
	local b p
	for b in $@ ; do
		for p in ${BOOTPROTOS[@]} ; do
			test "$p" = "$b" && continue 2
		done
		BOOTPROTOS=(${BOOTPROTOS[@]} ${b})
	done
}
for bp in ${BOOTPROTO//+/ } ; do
	case "$bp" in
		(dhcp)  add_bootproto_once dhcp4 dhcp6 ;;
		(dhcp4)
			explicit_dhcp4=yes
			add_bootproto_once ${bp}
		;;
		(dhcp6)
			explicit_dhcp6=yes
			add_bootproto_once ${bp}
		;;
		# FIXME: dhcpcd has a builtin autoip support...
		#        at the moment we handle autoip in ifup;
		#        it needs a "quiet minute" to change it.
		#(autoip) AUTOIP=yes ;;
		(*) continue ;;
	esac
done
if [ "$INTERFACE" != all ] ; then
	# Read temporary startmode and handle it
	# [kill -9 on stop, use dhcpcd -p flag on start]
	tmp_startmode=`read_cached_config_data startmode $INTERFACE`
	[ -n "$tmp_startmode" ] && STARTMODE="$tmp_startmode"
fi


######################################################################
# determine type of dhcp client
#
# This script is supposed to work with both dhcpcd and the ISC DHCP client,
# because there's a lot of common stuff.
# If neccesary you can preselect a dhcp client; just set DHCLIENT_BIN in
# one of the used config files. If not we prefer dhcpcd if available.
: ${DHCLIENT_BIN:=dhcpcd}
: ${DHCLIENT6_BIN:=dhcp6c}

DHCLIENT=""
for x in "$DHCLIENT_BIN" \
	 "/sbin/${DHCLIENT_BIN##*/}" \
	 "/sbin/dhcpcd" "/sbin/dhclient" ;
do
	if [ "x$x" != x -a "${x##/*}" != "$x" -a -x "$x" ] ; then
		DHCLIENT_BIN="$x"
		DHCLIENT=${DHCLIENT_BIN##*/}
		break
	fi
done
DHCLIENT6=""
for x in "$DHCLIENT6_BIN" \
	 "/sbin/${DHCLIENT6_BIN##*/}" \
	 "/sbin/dhcp6c" "/sbin/dhclient6" ;
do
	if [ "x$x" != x -a "${x##/*}" != "$x" -a -x "$x" ] ; then
		DHCLIENT6_BIN="$x"
		DHCLIENT6=${DHCLIENT6_BIN##*/}
		break
	fi
done


print_mesg() {
	func=$1 ; shift
	if [ "$RUN_FROM_RC" = yes -a "$INTERFACE" != all ] ; then
		$func "`printf "    %-9s $*" $INTERFACE`"
	else
		$func "$*"
	fi
}

# check installation of supported dhcp clients
case "$ACTION" in
	stop)
	;;
	*)
		HAVE_IPv6=yes
		if test -d /proc/sys/net/ipv6 ; then
			val1=`cat "/proc/sys/net/ipv6/conf/$INTERFACE/disable_ipv6" 2>/dev/null`
			val2=`cat "/proc/sys/net/ipv6/conf/all/disable_ipv6" 2>/dev/null`
			test "x$val1" = x1 -o "x$val2" = x1 && HAVE_IPv6=no
		else
			HAVE_IPv6=no
		fi

		clients=0
		bootprotos=(${BOOTPROTOS[@]})
		BOOTPROTOS=()
		# complain about missed clients
		for BOOTPROTO in ${bootprotos[@]} ; do
			case "$BOOTPROTO" in
			(dhcp4)
				case "$DHCLIENT" in
				(dhcpcd|dhclient)
					if [ -x "$DHCLIENT_BIN" ] ; then
						clients=$((clients + 1))
						BOOTPROTOS=(${BOOTPROTOS[@]} $BOOTPROTO)
					else
						# Huh?!
						DHCLIENT=""
						print_mesg err_mesg \
							"DHCP4 client ($DHCLIENT_BIN) is not available."
						print_mesg err_mesg \
							"      Please install 'dhcpcd' or 'dhcp-client'"
					fi
				;;
				"")
					if [ "x$explicit_dhcp4" = "xyes" ] ; then
						print_mesg err_mesg "DHCP4 client is not available."
						print_mesg err_mesg "      Please install 'dhcpcd' or 'dhcp-client'"
					fi
				;;
				*)
					DHCLIENT=""
					print_mesg err_mesg "DHCP4 client unknown/unsupported: $DHCLIENT_BIN"
					print_mesg err_mesg "      Please install 'dhcpcd' or 'dhcp-client'"
				;;
				esac
			;;
			(dhcp6)
				[ "x$HAVE_IPv6" = xyes ] || DHCLIENT6=""

				case "$DHCLIENT6" in
				(dhcp6c|dhclient6)
					if [ -x "$DHCLIENT6_BIN" ] ; then
						clients=$((clients + 1))
						BOOTPROTOS=(${BOOTPROTOS[@]} $BOOTPROTO)
					else
						# Huh?!
						DHCLIENT6=""
						print_mesg err_mesg \
							"DHCP6 client ($DHCLIENT6_BIN) is not available."
						print_mesg err_mesg \
							"      Please install the 'dhcpv6' or 'dhcp-client' package"
					fi
				;;
				"")
					if [ "x$explicit_dhcp6" = "xyes" ] ; then
						if [ "x$HAVE_IPv6" = xyes ] ; then
							print_mesg err_mesg "DHCP6 client is not available."
							print_mesg err_mesg "      Please install 'dhcpv6' or 'dhcp-client' package'"
						else
							print_mesg err_mesg "DHCP6 disabled - no IPv6 support"
						fi
					fi
				;;
				*)
					DHCLIENT6=""
					print_mesg err_mesg "DHCP6 client unknown/unsupported: $DHCLIENT6_BIN"
					print_mesg err_mesg "      Please install the 'dhcpv6' or 'dhcp-client' package"
				;;
				esac
			;;
			esac
		done

		# exit when not even one of the requested clients is installed
		# or the a client was explicitely requested in bootproto
		[ "x$HAVE_IPv6" = xyes ] && \
		[ "x$explicit_dhcp6" = "xyes" -a "x$DHCLIENT6" = x ] && exit $R_ERROR
		[ "x$explicit_dhcp4" = "xyes" -a "x$DHCLIENT"  = x ] && exit $R_ERROR
		[ $clients -eq 0 ] && exit $R_ERROR
	;;
esac


start_dhcp4_dhcpcd() {
	#
	# Using netconfig, we can request all options and
	# netconfig takes care to apply them properlly...
	#
	args="--netconfig -L"

	#test "$AUTOIP"                      != "yes" && args="$args -L"
	test "$DHCLIENT_USE_LAST_LEASE"      = "yes" && args="$args -E"
	test "$DHCLIENT_DEBUG"               = "yes" && args="$args -d"
	test "$DHCLIENT_SET_HOSTNAME"        = "yes" && args="$args -HHH"
	test "$DHCLIENT_SET_DEFAULT_ROUTE"  != "yes" && args="$args -G"

	# send hostname for DDNS?
	case "$DHCLIENT_HOSTNAME_OPTION" in
		AUTO|auto)
			unset DHCLIENT_HOSTNAME_OPTION
			test -s /etc/HOSTNAME && read -t 1 FQHOSTNAME < /etc/HOSTNAME
			FQHOSTNAME=${FQHOSTNAME%%.*} # strip domain
			FQHOSTNAME=${FQHOSTNAME%% *} # must not contain spaces, just in case
			DHCLIENT_HOSTNAME_OPTION="$FQHOSTNAME"
		;;
	esac

	# hardcoded in the dhcpcd binary when --netconfig is in use, but ...
	args="$args -c /etc/sysconfig/network/scripts/dhcpcd-hook"

	# avoid deconfiguration of the interface at startup in nfsroot case (bnc#397484)
	test "$STARTMODE" = "nfsroot" && args="-p $args"

	DHCLIENT_ARGS="$args"

	# just in case /var is not mounted
	test -d /var/lib/dhcpcd || mkdir -p /var/lib/dhcpcd && \
	touch /var/lib/dhcpcd/dhcpcd-$INTERFACE.timestamp || return 1

	# collect args that may contain spaces and write debug...
	args="$args${DHCLIENT_TIMEOUT:+ -t \"$DHCLIENT_TIMEOUT\"}"
	args="$args${DHCLIENT_CLIENT_ID:+ -I \"$DHCLIENT_CLIENT_ID\"}"
	args="$args${DHCLIENT_VENDOR_CLASS_ID:+ -i \"$DHCLIENT_VENDOR_CLASS_ID\"}"
	args="$args${DHCLIENT_LEASE_TIME:+ -l \"$DHCLIENT_LEASE_TIME\"}"
	args="$args${DHCLIENT_HOSTNAME_OPTION:+ -h \"$DHCLIENT_HOSTNAME_OPTION\"}"
	debug "Starting dhcp client: $DHCLIENT_BIN $DHCPCD_USER_OPTIONS $args $INTERFACE"

	# now start dhcpcd
	$DHCLIENT_BIN $DHCPCD_USER_OPTIONS $DHCLIENT_ARGS \
		${DHCLIENT_TIMEOUT:+-t "$DHCLIENT_TIMEOUT"}                 \
		${DHCLIENT_CLIENT_ID:+-I "$DHCLIENT_CLIENT_ID"}             \
		${DHCLIENT_VENDOR_CLASS_ID:+-i "$DHCLIENT_VENDOR_CLASS_ID"} \
		${DHCLIENT_LEASE_TIME:+-l "$DHCLIENT_LEASE_TIME"}           \
		${DHCLIENT_HOSTNAME_OPTION:+-h "$DHCLIENT_HOSTNAME_OPTION"} \
		$INTERFACE </dev/null &>/dev/null &
}

start_dhcp4_dhclient() {
	#
	# TODO: filter out statements (e.g. inerface blocks),
	#       apply DHCLIENT_* variables
	#
	local DHCPIFLEASE="/var/lib/dhcp/dhclient.${INTERFACE}.lease"
	local DHCPIFCONF="/var/lib/dhcp/dhclient.${INTERFACE}.conf"
	local DHCPIFPID="/var/run/dhclient.${INTERFACE}.pid"

	# don't write copyright info
	local args="-q" 
	test "$DHCLIENT_DEBUG" = "yes" && args=""

	# send hostname for DDNS?
	case "$DHCLIENT_HOSTNAME_OPTION" in
		AUTO|auto)
			unset DHCLIENT_HOSTNAME_OPTION
			test -s /etc/HOSTNAME && read -t 1 FQHOSTNAME < /etc/HOSTNAME
			FQHOSTNAME=${FQHOSTNAME%%.*} # strip domain
			FQHOSTNAME=${FQHOSTNAME%% *} # must not contain spaces, just in case
			DHCLIENT_HOSTNAME_OPTION="$FQHOSTNAME"
		;;
	esac
	test -n "$DHCLIENT_HOSTNAME_OPTION" && args="$args -H $DHCLIENT_HOSTNAME_OPTION"

	rm -f "$DHCPIFCONF" && awk '
		/#/             { sub("#.*", ""); }
		/^[ \t]*$/      { next; }
	        	        { print $0; }
	' < /etc/dhclient.conf > "$DHCPIFCONF" || return 1

	debug "Starting dhcp client: $DHCLIENT_BIN $DHCLIENT_USER_OPTIONS -cf "$DHCPIFCONF" -lf "$DHCPIFLEASE" -pf "$DHCPIFPID" $args $INTERFACE"
	$DHCLIENT_BIN $DHCLIENT_USER_OPTIONS -cf "$DHCPIFCONF" -lf "$DHCPIFLEASE" -pf "$DHCPIFPID" $args $INTERFACE </dev/null &>/dev/null &
}

start_dhcp6_dhcp6c() {
	DHCP6IFCONF="/var/lib/dhcpv6/dhcp6c.${INTERFACE}.conf"
	DHCP6IFPID="/var/run/dhcp6c.${INTERFACE}.pid"

	args="--netconfig"

	test "$DHCLIENT_DEBUG" = "yes" && \
	args="$args -v"

	args="${args} -c ${DHCP6IFCONF}"
	args="${args} -p ${DHCP6IFPID}"

	# TODO: more features on the todo list ...
	# TODO: pid file handling ...
	rm -f "$DHCP6IFCONF" && {
		echo "# dhcp6c config generated by ifup-dhcp"
		echo "interface $INTERFACE {"
		echo "	request domain-name-servers;"
		echo "	request domain-search-list;"
		echo "};"
	} > "$DHCP6IFCONF" || return 1

	debug "Starting dhcp client: $DHCLIENT6_BIN $DHCP6C_USER_OPTIONS $args $INTERFACE"
	$DHCLIENT6_BIN $DHCP6C_USER_OPTIONS $args $INTERFACE </dev/null &>/dev/null &
}

start_dhcp6_dhclient() {
	#
	# TODO: filter out statements (e.g. inerface blocks),
	#       apply DHCLIENT6_* variables
	#
	local DHCP6IFLEASE="/var/lib/dhcp6/dhclient6.${INTERFACE}.lease"
	local DHCP6IFCONF="/var/lib/dhcp6/dhclient6.${INTERFACE}.conf"
	local DHCP6IFPID="/var/run/dhclient6.${INTERFACE}.pid"

	# don't write copyright info
	local args="-q" 
	test "$DHCLIENT6_DEBUG" = "yes" && args=""

	# send hostname for DDNS?
	case "$DHCLIENT6_HOSTNAME_OPTION" in
		AUTO|auto)
			unset DHCLIENT6_HOSTNAME_OPTION
			test -s /etc/HOSTNAME && read -t 1 FQHOSTNAME < /etc/HOSTNAME
			FQHOSTNAME=${FQHOSTNAME%%.*} # strip domain
			FQHOSTNAME=${FQHOSTNAME%% *} # must not contain spaces, just in case
			DHCLIENT6_HOSTNAME_OPTION="$FQHOSTNAME"
		;;
	esac
	test -n "$DHCLIENT6_HOSTNAME_OPTION" && args="$args -H $DHCLIENT6_HOSTNAME_OPTION"

	rm -f "$DHCP6IFCONF" && awk '
		/#/             { sub("#.*", ""); }
		/^[ \t]*$/      { next; }
	        	        { print $0; }
	' < /etc/dhclient6.conf > "$DHCP6IFCONF" || return 1

	debug "Starting dhcp client: $DHCLIENT6_BIN -6 $DHCLIENT6_USER_OPTIONS -cf "$DHCP6IFCONF" -lf "$DHCP6IFLEASE" -pf "$DHCP6IFPID" $args $INTERFACE"
	$DHCLIENT6_BIN -6 $DHCLIENT6_USER_OPTIONS -cf "$DHCP6IFCONF" -lf "$DHCP6IFLEASE" -pf "$DHCP6IFPID" $args $INTERFACE </dev/null &>/dev/null &
}


case "$ACTION" in
	start|renew)
		# if we were called at boot time, increase the time startproc waits,
		# because the next scripts might rely on a configured network
		# test "$MODE" = "boot" && STARTPROC_TIMEOUT=5

		# a previous dhcpcd daemon could have been killed leaving its pidfile, 
		# and we need to remove it before we can start a new one.
		case "$DHCLIENT" in
		(dhcpcd)
			if [ -s /var/run/dhcpcd-$INTERFACE.pid ]; then
				p=$(</var/run/dhcpcd-$INTERFACE.pid)
				if [ "x$p" != x -a $((p)) -gt 0 ] ; then
					cmdline="/proc/$p/cmdline"
					[ -r "$cmdline" ] && \
					grep -q "^$DHCLIENT_BIN" "$cmdline" || {
						message_if_not_run_from_rc \
						"Removing stale pid file /var/run/dhcpcd-$INTERFACE.pid"
						rm -f /var/run/dhcpcd-$INTERFACE.pid
					}
				fi
			fi
		;;
		dhclient)
			if [ -s /var/run/dhclient.$INTERFACE.pid ]; then
				p=$(</var/run/dhclient.$INTERFACE.pid)
				if [ "x$p" != x -a $((p)) -gt 0 ] ; then
					cmdline="/proc/$p/cmdline"
					[ -r "$cmdline" ] && \
					grep -q "^$DHCLIENT_BIN" "$cmdline" || {
						message_if_not_run_from_rc \
						"Removing stale pid file /var/run/dhclient.$INTERFACE.pid"
						rm -f /var/run/dhclient.$INTERFACE.pid
					}
				fi
			fi
		;;
		esac
		case "$DHCLIENT6" in
		(dhcp6c)
			: # TODO: the new 1.0.20 version seems to write one...
		;;
		(dhclient6)
			if [ -s /var/run/dhclient6.$INTERFACE.pid ]; then
				p=$(</var/run/dhclient6.$INTERFACE.pid)
				if [ "x$p" != x -a $((p)) -gt 0 ] ; then
					cmdline="/proc/$p/cmdline"
					[ -r "$cmdline" ] && \
					grep -q "^$DHCLIENT6_BIN" "$cmdline" || {
						message_if_not_run_from_rc \
						"Removing stale pid file /var/run/dhclient6.$INTERFACE.pid"
						rm -f /var/run/dhclient6.$INTERFACE.pid
					}
				fi
			fi
		;;
		esac

		# the following code block, is only relevant if DHCLIENT_PRIMARY_DEVICE is
		# empty. it basically sets DHCLIENT_PRIMARY_DEVICE based on the informationen 
		# that is provided by the cached config data in a way that a user-defined  
		# DHCLIENT_PRIMARY_DEVICE remains untouched.

		if [ -z "$DHCLIENT_PRIMARY_DEVICE" ]; then

			# read cached config data into PRIMARY_FROM_CACHE
			PRIMARY_FROM_CACHE="`grep_cached_config_data primary yes`"

			if [ -z "$PRIMARY_FROM_CACHE" ]; then
				# no primary interface up-> we're the primary interface
				DHCLIENT_PRIMARY_DEVICE='yes'

 				# save this fact to cached config data		
				write_cached_config_data primary yes $INTERFACE
				commit_cached_config_data $INTERFACE
			else
				# primary interface already up -> DHCLIENT_PRIMARY_DEVICE='no'
				if [ "${PRIMARY_FROM_CACHE% }" = $INTERFACE ]; then
					# special case for ifrenew:
					# we are the primary interface which is up 
					DHCLIENT_PRIMARY_DEVICE='yes'
				else
					DHCLIENT_PRIMARY_DEVICE='no'
				fi
			fi

		fi		

		DHCP4_STATUS=$R_NOTCONFIGURED
		DHCP6_STATUS=$R_NOTCONFIGURED
		DHCP4_STARTED="no"
		DHCP6_STARTED="no"
		case "$ACTION" in
		(start)
			for BOOTPROTO in ${BOOTPROTOS[@]} ; do
				case "$BOOTPROTO" in
				(dhcp4)
					# reset dhcp4 status
					DHCP4_STATUS=""
					#if ( checkproc $DHCLIENT_BIN || [ "$DHCLIENT_PRIMARY_DEVICE" = no ] ) ; then
						# let's first test if the running dhcpcd actually runs on this
						# interface, because then we don't want to start another one:
						if dhcpc4_on_iface -q; then
							DHCP4_STATUS=$R_DHCP_BG
							if test "$RUN_FROM_RC" = yes; then
								print_mesg mesg "DHCP4 client is already running"
							else
								mesg "DHCP4 client is already running on $INTERFACE"
							fi
							while read a b c d e f g h i; do
								case "$d" in
								169.254.*) continue ;;
								esac
								print_mesg mesg "IP address: $d"
								DHCP4_STATUS=$R_SUCCESS
							done < <(ip -o -4 addr show $INTERFACE)
						fi
					#fi
				;;
				(dhcp6)
					# reset dhcp6 status
					DHCP6_STATUS=""
					#if ( checkproc $DHCLIENT6_BIN || [ "$DHCLIENT_PRIMARY_DEVICE" = no ] ) ; then
						# let's first test if the running dhcp6c actually runs on this
						# interface, because then we don't want to start another one:
						if dhcpc6_on_iface -q; then
							DHCP6_STATUS=$R_DHCP_BG
							if test "$RUN_FROM_RC" = yes; then
								print_mesg mesg "DHCP6 client is already running"
							else
								mesg "DHCP6 client is already running on $INTERFACE"
							fi
							while read a b c d rest; do
								case "$d" in
								fe80::*) continue ;;
								esac
								print_mesg mesg "IP address: $d"
								DHCP6_STATUS=$R_SUCCESS
							done < <(ip -o -6 addr show $INTERFACE)
						fi
					#fi
				;;
				esac
			done
		;;
		(renew)
			for BOOTPROTO in ${BOOTPROTOS[@]} ; do
				case "$BOOTPROTO" in
				(dhcp4)
					# reset dhcp4 status
					DHCP4_STATUS=""
					case "$DHCLIENT" in
					(dhcpcd|dhclient)
						$DHCLIENT_BIN -x $INTERFACE
					;;
					esac
					for i in `dhcpc4_on_iface`; do
						kill -TERM $i &>/dev/null
					done
					sleep 1
				;;
				(dhcp6)
					# reset dhcp6 status
					DHCP6_STATUS=""
					case "$DHCLIENT6" in
					(dhclient6)
						$DHCLIENT6_BIN -6 -x $INTERFACE
					;;
					esac
					for i in `dhcpc6_on_iface`; do
						kill -TERM $i &>/dev/null
					done
					sleep 1
				;;
				esac
			done
		;;
		esac

		# start requested dhcp clients...
		if [ -z "$DHCP4_STATUS" -o -z "$DHCP6_STATUS" ] ; then

			# there is maybe already a dhcp client running (or scheduled). We probably
			# don't want to set another default gateway and so on. Let's clear some
			# variables and source the ifcfg-$CONFIG again -- unless
			# DHCLIENT_PRIMARY_DEVICE is set to "yes".
			if [ "$DHCLIENT_PRIMARY_DEVICE" != yes ]; then 
				unset DHCLIENT_SET_HOSTNAME \
				      DHCLIENT_SET_DEFAULT_ROUTE

				test -f ./ifcfg-$CONFIG && . ./ifcfg-$CONFIG
			fi

			# remember the hostname to handle a change later
			write_cached_config_data hostname "`hostname 2>/dev/null`" $INTERFACE
			commit_cached_config_data                                  $INTERFACE

			debug "Activating interface $INTERFACE"
			if ! is_iface_up $INTERFACE ; then

				ip link set $INTERFACE up ${MTU:+mtu $MTU} \
				   ${LLADDR:+address $LLADDR} $LINK_OPTIONS

				# wait a bit or dhclient(6) may produce false send errors
				link_ready_wait "$INTERFACE" 3

				# (optionally) wait until a device is really configured
				sleep ${DHCLIENT_SLEEP:-0}
			fi

			MESSAGE=""
			for BOOTPROTO in ${BOOTPROTOS[@]} ; do
				case "$BOOTPROTO" in
				(dhcp4) test -n "$DHCP4_STATUS" || MESSAGE="$MESSAGE $BOOTPROTO" ;;
				(dhcp6) test -n "$DHCP6_STATUS" || MESSAGE="$MESSAGE $BOOTPROTO" ;;
				esac
			done
			MESSAGE=$(echo ${MESSAGE} | awk '{print toupper($0);}')
			if [ "$RUN_FROM_RC" = "yes" ]; then
				print_mesg mesg_n "Starting ${MESSAGE// /+} client"
			else
				mesg_n "Starting ${MESSAGE// /+} client on $INTERFACE"
			fi

			for BOOTPROTO in ${BOOTPROTOS[@]} ; do
				case "$BOOTPROTO" in
				(dhcp4)
					case "$DHCLIENT" in
					(dhcpcd)
						test -n "$DHCP4_STATUS" || {
							start_dhcp4_dhcpcd && {
								DHCP4_STARTED="yes"
								write_cached_config_data dhcp4_client $DHCLIENT  $INTERFACE
								write_cached_config_data dhcp4_state  started    $INTERFACE
								commit_cached_config_data                        $INTERFACE
							} || DHCP4_STATUS=$?
						}
					;;
					(dhclient)
						test -n "$DHCP4_STATUS" || {
							start_dhcp4_dhclient && {
								DHCP4_STARTED="yes"
								write_cached_config_data dhcp4_client $DHCLIENT  $INTERFACE
								write_cached_config_data dhcp4_state  started    $INTERFACE
								commit_cached_config_data                        $INTERFACE
							} || DHCP4_STATUS=$?
						}
					;;
					esac
				;;
				(dhcp6)
					case "$DHCLIENT6" in
					(dhcp6c)
						test -n "$DHCP6_STATUS" || {
							start_dhcp6_dhcp6c && {
								DHCP6_STARTED="yes"
								write_cached_config_data dhcp6_client $DHCLIENT  $INTERFACE
								write_cached_config_data dhcp6_state  started    $INTERFACE
								commit_cached_config_data                        $INTERFACE
							} || DHCP6_STATUS=$?
						}
					;;
					(dhclient6)
						test -n "$DHCP6_STATUS" || {
							start_dhcp6_dhclient && {
								DHCP6_STARTED="yes"
								write_cached_config_data dhcp6_client $DHCLIENT  $INTERFACE
								write_cached_config_data dhcp6_state  started    $INTERFACE
								commit_cached_config_data                        $INTERFACE
							} || DHCP6_STATUS=$?
						}
					;;
					esac
				;;
				esac
			done

			#
			# in case we've started at least one client, wait the specified
			# time until the dhcp client has done its job and show the results.
			#
			DHCP4_MESSAGE=''
			DHCP6_MESSAGE=''

			typeset -i wusleep=100000
			typeset -i wab_max=${DHCLIENT_WAIT_AT_BOOT:-15};
			let wab_max\*=10
			for ((wab_cnt=0; wab_cnt<=wab_max; wab_cnt++)); do
				for BOOTPROTO in ${BOOTPROTOS[@]} ; do
					case "$BOOTPROTO" in
					(dhcp4)
						if ! dhcpc4_on_iface -q ; then
							((wab_cnt== 0 || wab_cnt==10)) && message_n .\ .\ 
							DHCP4_MESSAGE="DHCP4 client NOT running"
							DHCP4_STATUS=$R_NOTRUNNING
							continue
						fi
						[ -n "$DHCP4_STATUS" ] && continue

						case "$DHCLIENT" in
						(dhcpcd)
							stamp=/var/lib/dhcpcd/dhcpcd-$INTERFACE.timestamp
							info=/var/lib/dhcpcd/dhcpcd-$INTERFACE.info

							state=`read_cached_config_data dhcp4_state $INTERFACE`
							if [ "x$state" = "xcomplete" -a -e $info -a ! $info -ot $stamp ]; then
								DHCP4_STATUS=$R_SUCCESS
								IP='' ; NM='' ; HN=''
								while read line ; do
									case "$line" in
									IPADDR=*)   eval "${line/IPADDR=/IP=}"   ;;
									NETMASK=*)  eval "${line/NETMASK=/NM=}"  ;;
									HOSTNAME=*) eval "${line/HOSTNAME=/HN=}" ;;
									esac
								done < $info
								if test -n "$IP" ; then
									DHCP4_MESSAGE="IP address: $IP"
									NL=$(mask2pfxlen $NM)
									if test -n "$NM" ; then
										DHCP4_MESSAGE="$DHCP4_MESSAGE/$NL"
									fi
									if test -n "$HN" ; then
										DHCP4_MESSAGE="$DHCP4_MESSAGE ($HN)"
									fi
								fi
							fi
						;;
						(dhclient)
							lease="/var/lib/dhcp/dhclient.${INTERFACE}.lease"
							config="/var/lib/dhcp/dhclient.${INTERFACE}.conf"
							state=`read_cached_config_data dhcp4_state $INTERFACE`
							if [ "x$state" = "xcomplete" -a -e "$lease" -a "$lease" -nt "$config" ] ; then
								DHCP4_STATUS=$R_SUCCESS
								while read a b c d e f g h i ; do
									case "$d" in
									169.254.*) continue ;;
									esac
									if grep -q "${d%/*}" "$lease" &>/dev/null ; then
										DHCP4_MESSAGE="IP address: $d"
									fi
								done < <(ip -o -4 addr show $INTERFACE)
							fi
						;;
						esac
					;;
					(dhcp6)
						if ! dhcpc6_on_iface -q ; then
							((wab_cnt== 0 || wab_cnt==10)) && message_n .\ .\ 
							DHCP6_MESSAGE="DHCP6 client NOT running"
							DHCP6_STATUS=$R_NOTRUNNING
							continue
						fi
						[ -n "$DHCP6_STATUS" ] && continue

						case "$DHCLIENT6" in
						(dhcp6c)
							while read a b c d rest; do
								config="/var/lib/dhcpv6/dhcp6c.${INTERFACE}.conf"
								leases="/var/lib/dhcpv6/client6.leases*"
								leases=$(grep -sl "^lease[ \t]\+${d}" $leases 2>/dev/null)
								for lease in ${leases} ; do
									if [ "$lease" -nt "$config" ] ; then
										DHCP6_MESSAGE="IP address: $d"
										DHCP6_STATUS=$R_SUCCESS
										break 2
									fi
								done
							done < <(ip -o -6 addr show $INTERFACE)
						;;
						(dhclient6)
							lease="/var/lib/dhcp6/dhclient6.${INTERFACE}.lease"
							config="/var/lib/dhcp6/dhclient6.${INTERFACE}.conf"
							state=`read_cached_config_data dhcp6_state $INTERFACE`
							if [ "x$state" = "xcomplete" ] ; then
								DHCP6_STATUS=$R_SUCCESS
								while read a b c d e f g h i ; do
									case "$d" in
									fe80:*) continue ;;
									esac
									if grep -q "${d%/*}" "$lease" &>/dev/null ; then
										DHCP6_MESSAGE="IP address: $d"
									fi
								done < <(ip -o -6 addr show $INTERFACE)
							fi
						;;
						esac
					;;
					esac
				done
				if [ -z "$DHCP4_STATUS" -o -z "$DHCP6_STATUS" ] ; then
					((wab_cnt % 20 == 1)) && message_n .\ 
					usleep $wusleep
				else
					# ok, we have status from both clients now => done
					break
				fi
			done
			message " "

			[ "$DHCP4_STARTED" = yes -a -z "$DHCP4_STATUS" ] && DHCP4_STATUS=$R_DHCP_BG
			[ "$DHCP6_STARTED" = yes -a -z "$DHCP6_STATUS" ] && DHCP6_STATUS=$R_DHCP_BG

			if test -n "$DHCP4_MESSAGE" ; then
				message "`printf "    %-9s $DHCP4_MESSAGE" $INTERFACE`"
			elif [ $DHCP4_STATUS = $R_DHCP_BG ] ; then
				message "`printf "    %-9s DHCP4 continues in background" $INTERFACE`"
			fi
			if test -n "$DHCP6_MESSAGE" ; then
				message "`printf "    %-9s $DHCP6_MESSAGE" $INTERFACE`"
			elif [ $DHCP6_STATUS = $R_DHCP_BG ] ; then
				message "`printf "    %-9s DHCP6 continues in background" $INTERFACE`"
			fi
		fi
		debug "DHCP4(required=$explicit_dhcp4) STARTED=$DHCP4_STARTED STATUS=$DHCP4_STATUS"
		debug "DHCP6(required=$explicit_dhcp6) STARTED=$DHCP6_STARTED STATUS=$DHCP6_STATUS"
		[ -z "$DHCP4_STATUS" ] && DHCP4_STATUS=$R_ERROR
		[ -z "$DHCP6_STATUS" ] && DHCP6_STATUS=$R_ERROR

		case "${explicit_dhcp4}_${explicit_dhcp6}" in
		(yes_yes)	# BOOTPROTO=dhcp4+dhcp6	    (need both to report success)
			if   [ $DHCP4_STATUS = $R_SUCCESS        -a $DHCP6_STATUS = $R_SUCCESS    ] ; then
				exit $R_SUCCESS
			elif [ $DHCP4_STATUS = $R_DHCP_BG        -o $DHCP6_STATUS = $R_DHCP_BG    ] ; then
				exit $R_DHCP_BG
			elif [ $DHCP4_STATUS != $R_NOTCONFIGURED ] ; then
				exit $DHCP4_STATUS
			elif [ $DHCP6_STATUS != $R_NOTCONFIGURED ] ; then
				exit $DHCP6_STATUS
			fi
		;;
		(no_no)		# BOOTPROTO=dhcp	    (one is sufficient)
			if   [ $DHCP4_STATUS = $R_SUCCESS        -o $DHCP6_STATUS = $R_SUCCESS    ] ; then
				exit $R_SUCCESS
			elif [ $DHCP4_STATUS = $R_DHCP_BG        -o $DHCP6_STATUS = $R_DHCP_BG    ] ; then
				exit $R_DHCP_BG
			elif [ $DHCP4_STATUS != $R_NOTCONFIGURED ] ; then
				exit $DHCP4_STATUS
			elif [ $DHCP6_STATUS != $R_NOTCONFIGURED ] ; then
				exit $DHCP6_STATUS
			fi
		;;
		(yes_no)	# BOOTPROTO=dhcp4
			exit $DHCP4_STATUS
		;;
		(no_yes)	# BOOTPROTO=dhcp6
			exit $DHCP6_STATUS
		;;
		esac
		exit $R_ERROR

	;;
	stop)
		ALL_INTERFACES=()
		STOPPED_IFACES=()

		if [ "$INTERFACE" != all ]; then
			ALL_INTERFACES=($INTERFACE)

			dhcpc4_pids=""
			dhcpc6_pids=""
			dhcpc4_signal="-TERM"
			dhcpc6_signal="-TERM"

			debug "Shutting down dhcp clients on $INTERFACE"

			# first try the configured way
			for BOOTPROTO in ${BOOTPROTOS[@]} ; do
				case "$BOOTPROTO" in
				(dhcp4)
					dhcpc4_pids="`dhcpc4_on_iface`"

					case $DHCLIENT in
					(dhcpcd)
						DHCPIFLEASE="/var/lib/dhcpcd/dhcpcd-$INTERFACE.info"
						DHCPIFPID="/var/run/dhcpcd-$INTERFACE.pid"

						if test "$STARTMODE" = "nfsroot" ;
						then
							dhcpc4_signal="-KILL"
						elif test "$DHCLIENT_RELEASE_BEFORE_QUIT" = "yes" ;
						then
							$DHCLIENT_BIN --release \
								$INTERFACE </dev/null &>/dev/null
						else
							$DHCLIENT_BIN --exit \
								$INTERFACE </dev/null &>/dev/null
						fi
					;;
					(dhclient)
						DHCPIFLEASE="/var/lib/dhcp/dhclient.${INTERFACE}.lease"
						DHCPIFPID="/var/run/dhclient.${INTERFACE}.pid"

						if test "$STARTMODE" = "nfsroot" ;
						then
							dhcpc4_signal="-KILL"
						elif test "$DHCLIENT_RELEASE_BEFORE_QUIT" = "yes" ;
						then
							$DHCLIENT_BIN -r \
								-cf /dev/null \
								-lf "$DHCPIFLEASE" \
								-pf "$DHCPIFPID" \
								$INTERFACE </dev/null &>/dev/null
						else
							$DHCLIENT_BIN -x \
								$INTERFACE </dev/null &>/dev/null
						fi
					;;
					esac

				;;
				(dhcp6)
					dhcpc6_pids="`dhcpc6_on_iface`"

					case $DHCLIENT6 in
					(dhcp6c)
						DHCP6IFCONF="/var/lib/dhcpv6/dhcp6c.${INTERFACE}.conf"
						DHCP6IFPID="/var/run/dhcp6c.${INTERFACE}.pid"

						if test "$STARTMODE" = "nfsroot" ;
						then
							dhcpc6_signal="-KILL"
						elif test "$DHCLIENT6_RELEASE_BEFORE_QUIT" = "yes" ;
						then
							# dhcp6c daemon needs to get killed or
							# dhcp6c -r fails to bind the interface
							for i in $dhcpc6_pids; do
								kill $dhcpc6_signal $i &>/dev/null
							done
							for i in $dhcpc6_pids; do
								for ((wait=0; wait<=20; wait++)); do
									if test -d /proc/$i ; then
										usleep 300000
									else
										continue 2
									fi
								done
							done

							# then release the lease but stay in foreground
							$DHCLIENT6_BIN -f -r all \
								-c /dev/null \
								-p "$DHCP6IFPID" \
								$INTERFACE </dev/null &>/dev/null
						fi
					;;
					(dhclient6)
						DHCP6IFLEASE="/var/lib/dhcp6/dhclient6.${INTERFACE}.lease"
						DHCP6IFPID="/var/run/dhclient6.${INTERFACE}.pid"

						if test "$STARTMODE" = "nfsroot" ;
						then
							dhcpc6_signal="-KILL"
						elif test "$DHCLIENT6_RELEASE_BEFORE_QUIT" = "yes" ;
						then
							$DHCLIENT6_BIN -6 -r \
								-cf /dev/null \
								-lf "$DHCP6IFLEASE" \
								-pf "$DHCP6IFPID" \
								$INTERFACE </dev/null &>/dev/null
						else
							$DHCLIENT6_BIN -6 -x \
								$INTERFACE </dev/null &>/dev/null
						fi
					;;
					esac

				;;
				esac
			done

			# same game again...
			for BOOTPROTO in ${BOOTPROTOS[@]} ; do
				case "$BOOTPROTO" in
				(dhcp4)
					# send termination signal
					for i in $dhcpc4_pids; do
						kill $dhcpc4_signal $i &>/dev/null
					done

					# wait until the processes are gone
					for i in $dhcpc4_pids; do
						for ((wait=0; wait<=20; wait++)); do
							if test -d /proc/$i ; then
								usleep 300000
							else
								continue 2
							fi
							if [ $wait -eq 20 ]; then
								debug "process $i still not dead, sending SIGKILL"
								kill -KILL $i &>/dev/null
							fi
						done
					done

					# remove old lease file and pid when they still exist
					if test "$DHCLIENT_RELEASE_BEFORE_QUIT" = "yes" ; then
						rm -f "$DHCPIFLEASE"
					fi
					rm -f "$DHCPIFPID"
				;;
				(dhcp6)
					# send termination signal
					for i in $dhcpc6_pids; do
						kill $dhcpc6_signal $i &>/dev/null
					done

					# wait until the processes are gone
					for i in $dhcpc6_pids; do
						for ((wait=0; wait<=20; wait++)); do
							if test -d /proc/$i ; then
								usleep 300000
							else
								continue 2
							fi
							if [ $wait -eq 20 ]; then
								debug "process $i still not dead, sending SIGKILL"
								kill -KILL $i &>/dev/null
							fi
						done
					done

					# remove old lease file and pid when they still exist
					if test "$DHCLIENT6_RELEASE_BEFORE_QUIT" = "yes" ; then
						rm -f "$DHCP6IFLEASE"
					fi
					rm -f "$DHCP6IFPID"
				;;
				esac
			done
		else
			debug "Shutting down dhcp clients on all interfaces"
			for i in `ls -1 /sys/class/net 2>/dev/null` ; do
				test -d "/sys/class/net/$i" || continue
				ALL_INTERFACES=(${ALL_INTERFACES[@]} $i)
			done
		fi

		STATUS=$R_SUCCESS
		# now verify it & "kill them all"
		# catching also INTERFACE=all case
		for INTERFACE in ${ALL_INTERFACES[@]} ; do
			# Read temporary startmode and use kill -9 to stop
			tmp_startmode=`read_cached_config_data startmode $INTERFACE`
			[ -n "$tmp_startmode" ] && STARTMODE="$tmp_startmode"

			# try to catch also config changes
			dhcpcd_on_device=`any_dhcpc_on_iface`

			if test -n "$dhcpcd_on_device" ; then
				# send termination signal
				test "$STARTMODE" = "nfsroot" && \
					USE_SIGNAL="-KILL" || \
					USE_SIGNAL="-TERM"

				for i in $dhcpcd_on_device; do
					kill $USE_SIGNAL $i &>/dev/null
				done

				# wait until the processes are gone
				for i in $dhcpcd_on_device; do
					for ((wait=0; wait<=10; wait++)); do
						if test -d /proc/$i ; then
							usleep 300000
						else
							continue 2
						fi
						if [ $wait -eq 10 ]; then
							debug "process $i still not dead, sending SIGKILL"
							kill -KILL $i &>/dev/null
						fi
					done
				done

				# double check & set status
				for i in $dhcpcd_on_device; do
					kill -0 $i 2>/dev/null && STATUS=$R_ERROR
				done
			fi

			# Hmm...:
			#if [ $STATUS -eq $R_SUCCESS ] ; then

			# delete primary flag from cache file if needed
			delete_from_cached_config_data primary yes  $INTERFACE
			delete_from_cached_config_data 'dhcp4_*' '' $INTERFACE
			delete_from_cached_config_data 'dhcp6_*' '' $INTERFACE
			commit_cached_config_data                   $INTERFACE

			# This is useful for pcmcia interfaces... before the modules can be
			# unloaded, the device must be unused.
			if [ "$STARTMODE" != "nfsroot" -a "$DHCLIENT_SET_DOWN_LINK" = yes ] ; then
				if [ -d /sys/class/net/$INTERFACE ] ; then
					ip link set down dev $INTERFACE
				fi
			fi

			#fi
		done

		exit $STATUS
	;;
	status)
		if ifup_on_iface ; then
			print_mesg mesg ". . . is just beeing set up"
			exit $R_DHCP_BG
		fi

		DHCP4_STATUS=$R_NOTCONFIGURED
		DHCP6_STATUS=$R_NOTCONFIGURED
		for BOOTPROTO in ${BOOTPROTOS[@]} ; do
			case "$BOOTPROTO" in
			(dhcp4)
				if dhcpc4_on_iface -q; then
					print_mesg mesg "DHCP4 client ($DHCLIENT) is running"
					case "$DHCLIENT" in
					(dhcpcd)
						stamp=/var/lib/dhcpcd/dhcpcd-$INTERFACE.timestamp
						info=/var/lib/dhcpcd/dhcpcd-$INTERFACE.info

						state=`read_cached_config_data dhcp4_state $INTERFACE`
						if [ "x$state" = "xcomplete" -a \
						     \( -e $info -a ! $info -ot $stamp \) -a -n \
						     "`ip -o -f inet addr show $INTERFACE`" ]; then
							while read line ; do
								case "$line" in
								IPADDR=*)   eval "${line/IPADDR=/IP=}"   ;;
								NETMASK=*)  eval "${line/NETMASK=/NM=}"  ;;
								HOSTNAME=*) eval "${line/HOSTNAME=/HN=}" ;;
								esac
							done < $info
							if test -n "$IP" ; then
								DHCP4_MESSAGE="IP address: $IP"
								NL=$(mask2pfxlen $NM)
								if test -n "$NM" ; then
									DHCP4_MESSAGE="$DHCP4_MESSAGE/$NL"
								fi
								if test -n "$HN" ; then
									DHCP4_MESSAGE="$DHCP4_MESSAGE ($HN)"
								fi
								print_mesg mesg "$DHCP4_MESSAGE"
							fi
							DHCP4_STATUS=$R_SUCCESS
						else
							print_mesg mesg ". . . but is still waiting for data"
							DHCP4_STATUS=$R_DHCP_BG
						fi
					;;
					dhclient)
						state=`read_cached_config_data dhcp4_state $INTERFACE`
						if [ "x$state" = "xcomplete" -a \
						     -n "`ip -o -f inet addr show $INTERFACE`" ]; then
							:
							DHCP4_STATUS=$R_SUCCESS
						else
							print_mesg mesg ". . . but is still waiting for data"
							DHCP4_STATUS=$R_DHCP_BG
						fi
					;;
					esac
				else
					print_mesg mesg "DHCP4 client NOT running"
					DHCP4_STATUS=$R_NOTRUNNING
				fi
			;;
			(dhcp6)
				if dhcpc6_on_iface -q; then
					print_mesg mesg "DHCP6 client ($DHCLIENT6) is running"
					case "$DHCLIENT6" in
					(dhcp6c)
						DHCP6_STATUS=$R_DHCP_BG
						DHCP6_MESSAGE=''
						while read a b c d rest; do
							config="/var/lib/dhcpv6/dhcp6c.${INTERFACE}.conf"
							leases="/var/lib/dhcpv6/client6.leases*"
							leases=$(grep -sl "^lease[ \t]\+${d}" $leases 2>/dev/null)
							for lease in ${leases} ; do
								if [ $lease -nt $config ] ; then
									DHCP6_MESSAGE="IP address: $d"
									DHCP6_STATUS=$R_SUCCESS
									break 2
								fi
							done
						done < <(ip -o -6 addr show $INTERFACE)
						if [ -n "$DHCP6_MESSAGE" ] ; then
							print_mesg mesg "$DHCP6_MESSAGE"
						else
							print_mesg mesg ". . . but is still waiting for data"
						fi
					;;
					dhclient6)
						state=`read_cached_config_data dhcp6_state $INTERFACE`
						if [ "x$state" = "xcomplete" -a \
						     -n "`ip -o -f inet6 addr show $INTERFACE`" ]; then
							:
							DHCP6_STATUS=$R_SUCCESS
						else
							DHCP6_STATUS=$R_DHCP_BG
							print_mesg mesg ". . . but is still waiting for data"
						fi
					;;
					esac
				else
					print_mesg mesg "DHCP6 client NOT running"
					DHCP6_STATUS=$R_NOTRUNNING
				fi
			;;
			esac
		done

		debug "DHCP4(required=$explicit_dhcp4) STATUS=$DHCP4_STATUS"
		debug "DHCP6(required=$explicit_dhcp6) STATUS=$DHCP6_STATUS"

		case "${explicit_dhcp4}_${explicit_dhcp6}" in
		(yes_yes)	# BOOTPROTO=dhcp4+dhcp6	    (need both to report success)
			if   [ $DHCP4_STATUS = $R_SUCCESS        -a $DHCP6_STATUS = $R_SUCCESS    ] ; then
				exit $R_SUCCESS
			elif [ $DHCP4_STATUS = $R_DHCP_BG        -o $DHCP6_STATUS = $R_DHCP_BG    ] ; then
				exit $R_DHCP_BG
			elif [ $DHCP4_STATUS != $R_NOTCONFIGURED ] ; then
				exit $DHCP4_STATUS
			elif [ $DHCP6_STATUS != $R_NOTCONFIGURED ] ; then
				exit $DHCP6_STATUS
			fi
		;;
		(no_no)		# BOOTPROTO=dhcp	    (one is sufficient)
			if   [ $DHCP4_STATUS = $R_SUCCESS        -o $DHCP6_STATUS = $R_SUCCESS    ] ; then
				exit $R_SUCCESS
			elif [ $DHCP4_STATUS = $R_DHCP_BG        -o $DHCP6_STATUS = $R_DHCP_BG    ] ; then
				exit $R_DHCP_BG
			elif [ $DHCP4_STATUS != $R_NOTCONFIGURED ] ; then
				exit $DHCP4_STATUS
			elif [ $DHCP6_STATUS != $R_NOTCONFIGURED ] ; then
				exit $DHCP6_STATUS
			fi
		;;
		(yes_no)	# BOOTPROTO=dhcp4
			exit $DHCP4_STATUS
		;;
		(no_yes)	# BOOTPROTO=dhcp6
			exit $DHCP6_STATUS
		;;
		esac
		exit $R_ERROR
	;;
esac

ACC SHELL 2018