#!/bin/sh
#
#	@author Forrest Lin
#

TMPFILE=/tmp/dhcp6c-$2.conf.$$
CONFILE=/tmp/dhcp6c-$2.conf
PIDFILE=/var/run/dhcp6c-$2.pid
KEYFILE=/sbin/dhcp6ctlkey
LOCKFILE=/var/run/dhcp6c-$2.lock

# Primitives
usage() {
	echo "Usage: $0 {start|stop|reload|trans} interface"
}

lock() {
	set -o noclobber
	while ! echo PID $$ @ $(date) > ${LOCKFILE} ; do
		sleep 1
	done
	set +o noclobber        
}

unlock() {
	rm -f ${LOCKFILE} > /dev/null 2>&1
}

trans() {
	local if=$1
	# Configuration
	eval `sncfg mget \
DHCP6C_INFO_ONLY  \
DHCP6C_REQ_DNS DHCP6C_REQ_DOMAIN \
DHCP6C_REQ_NTP \
DHCP6C_REQ_SIP DHCP6C_REQ_SIP_DOMAIN \
DHCP6C_REQ_NIS DHCP6C_REQ_NIS_DOMAIN \
DHCP6C_REQ_NISP DHCP6C_REQ_NISP_DOMAIN \
DHCP6C_REQ_REFRESH_TIME \
DHCP6C_RAPID_COMMIT DHCP6C_IANA_ENABLE DHCP6C_IAPD_ENABLE \
DHCP6C_IANA_NUM DHCP6C_IANA \
DHCP6C_IAPD_NUM DHCP6C_IAPD \
DHCP6C_SCRIPT`
	echo "" | awk -v file=${TMPFILE} -v WanIf=${if} \
-v infoOnly=${DHCP6C_INFO_ONLY} \
-v reqDns=${DHCP6C_REQ_DNS} -v reqDomain=${DHCP6C_REQ_DOMAIN} \
-v reqNtp=${DHCP6C_REQ_NTP} \
-v reqSip=${DHCP6C_REQ_SIP} -v reqSipDomain=${DHCP6C_REQ_SIP_DOMAIN} \
-v reqNis=${DHCP6C_REQ_NIS} -v reqNisDomain=${DHCP6C_REQ_NIS_DOMAIN} \
-v reqNisp=${DHCP6C_REQ_NISP} -v reqNispDomain=${DHCP6C_REQ_NISP_DOMAIN} \
-v reqRefreshTime=${DHCP6C_REQ_REFRESH_TIME} \
-v rapidCommit=${DHCP6C_RAPID_COMMIT} -v ianaEnable=${DHCP6C_IANA_ENABLE} -v iapdEnable=${DHCP6C_IAPD_ENABLE} \
-v ianaNum=${DHCP6C_IANA_NUM} -v iana=${DHCP6C_IANA} \
-v iapdNum=${DHCP6C_IAPD_NUM} -v iapd=${DHCP6C_IAPD} \
-v script="${DHCP6C_SCRIPT}" '{
		#
		# WAN Interface
		#
		printf("interface %s {\n", WanIf) > file
		# 
		#   1. Request Options
		#
		if (reqDns == "1") {
			printf("  request domain-name-servers ;\n") >> file
		}
		if (reqDomain == "1") {
			printf("  request domain-name ;\n") >> file
		}
		if (reqNtp == "1") {
			printf("  request ntp-servers ;\n") >> file
		}
		if (reqSip == "1") {
			printf("  request sip-server-address ;\n") >> file
		}
		if (reqSipDomain == "1") {
			printf("  request sip-server-domain-name ;\n") >> file
		}
		if (reqNis == "1") {
			printf("  request nis-server-address ;\n") >> file
		}
		if (reqNisDomain == "1") {
			printf("  request nis-domain-name ;\n") >> file
		}
		if (reqNisp == "1") {
			printf("  request nisp-server-address ;\n") >> file
		}
		if (reqNispDomain == "1") {
			printf("  request nisp-domain-name ;\n") >> file
		}
		if (reqRefreshTime == "1") {
			printf("  request refreshtime ;\n") >> file
		}
		#
		#   2. Send Options
		#
		if (rapidCommit == "1") {
			printf("  send rapid-commit ;\n") >> file
		}
		if (ianaEnable == "1") {
#			printf("  send ia-na 0 ;\n") >> file
			proposal = 0
			num = split(iana, elems, ";")
			for (i = 1; i <= ianaNum && i <= num; i++) {
				split(elems[i], fields, ",")
				if (fields[1] == "1") {
					printf("  send ia-na %d ;\n", i) >> file
					proposal++
				}
			}
			if (proposal == 0) {
				printf("  send ia-na 0 ;\n") >> file
			}			
		}
		if (iapdEnable == "1") {
#			printf("  send ia-pd 0 ;\n") >> file
			proposal = 0
			num = split(iapd, elems, ";")
			for (i = 1; i <= iapdNum && i <= num; i++) {
				split(elems[i], fields, ",")
				if (fields[1] == "1") {
					printf("  send ia-pd %d ;\n", i) >> file
					proposal++
				}
			}
			if (proposal == 0) {
				printf("  send ia-pd 0 ;\n") >> file
			}
		}
		#
		#   3. Other Options
		#
		if (infoOnly == "1") {
			printf("  information-only ;\n") >> file
		}
		if (script != "") {
			printf("  script \"%s\" ;\n", script) >> file
		}
		printf("} ;\n") >> file
		printf("\n") >> file
		#
		#  IA-NA
		#
		printf("id-assoc na {\n") >> file
#		num = split(iana, elems, ";")
#		for (i = 1; i <= ianaNum && i <= num; i++) {
#			split(elems[i], fields, ",")
#			if (fields[1] == "1") {
#				printf("  address %s %d %d ;\n", fields[2], fields[3], fields[4]) >> file
#			}
#		}
		printf("} ;\n") >> file
		num = split(iana, elems, ";")
		for (i = 1; i <= ianaNum && i <= num; i++) {
			split(elems[i], fields, ",")
			if (fields[1] == "1") {
				printf("id-assoc na %d {\n", i) >> file
				if (fields[2] != "::") {
					printf("  address %s %d %d ;\n", fields[2], fields[3], fields[4]) >> file
				}
				printf("} ;\n") >> file
			}
		}
		printf("\n") >> file
		#
		#  IA-PD
		#
		printf("id-assoc pd {\n") >> file
#		printf("  prefix-interface %s {\n", LanIf) >> file
#		printf("    sla-id 0 ;\n") >> file
#		printf("    sla-len 0 ;\n") >> file
#		printf("  } ;\n") >> file
		printf("} ;\n") >> file
		num = split(iapd, elems, ";")
		for (i = 1; i <= iapdNum && i <= num; i++) {
			split(elems[i], fields, ",")
			if (fields[1] == "1") {
				printf("id-assoc pd %d {\n", i) >> file
				split(fields[2], prefix, "/")
				if (prefix[1] != "::") {
					printf("  prefix %s %d %d ;\n", fields[2], fields[3], fields[4]) >> file
				}
				printf("} ;\n") >> file
			}
		}
	}'
	mv ${TMPFILE} ${CONFILE}
}

start() {
	local if=$1
	local pid=`cat ${PIDFILE} 2> /dev/null`
	if grep dhcp6c /proc/${pid}/stat > /dev/null 2>&1 ; then
#		eval `sncfg mget WanIf`
#		echo -n "dhcp6ctl -C -k ${KEYFILE} start interface ${WanIf} ... "
#		dhcp6ctl -C -k ${KEYFILE} start interface ${WanIf}
#		ret=$?
		echo -n "dhcp6c for interface ${if} was already running ... "
		ret=0
		return
	fi
	trans ${if}
	eval `sncfg mget DHCP6C_DEBUG`
	if [ "${DHCP6C_DEBUG}" == "1" ] ; then
		echo -n "dhcp6c -p ${PIDFILE} -c ${CONFILE} -dDf ${if} & ... "
		dhcp6c -p ${PIDFILE} -c ${CONFILE} -dDf ${if} &
	else
		echo -n "dhcp6c -p ${PIDFILE} -c ${CONFILE} ${if} ..."
		dhcp6c -p ${PIDFILE} -c ${CONFILE} ${if}
	fi
	ret=$?
}

stop() {
	local if=$1
	local pid=`cat ${PIDFILE} 2> /dev/null`
	if grep dhcp6c /proc/${pid}/stat > /dev/null 2>&1 ; then
#		eval `sncfg mget WanIf`
#		echo -n "dhcp6ctl -C -k ${KEYFILE} stop interface ${WanIf} ... "
#		dhcp6ctl -C -k ${KEYFILE} stop interface ${WanIf}
		echo -n "kill ${pid} ... "
		kill ${pid} > /dev/null 2>&1
		ret=$?
		rm -f ${PIDFILE} > /dev/null 2>&1
	else
		ret=1
	fi
}

reload() {
	local pid=`cat ${PIDFILE} 2> /dev/null`
	if grep dhcp6c /proc/${pid}/stat > /dev/null 2>&1 ; then
		trans
		echo -n "dhcp6ctl -C -k ${KEYFILE} reload ... "
		dhcp6ctl -C -k ${KEYFILE} reload
		ret=$?
	else
		start
	fi
}

confirm() {
	local pid=`cat ${PIDFILE} 2> /dev/null`
	if grep dhcp6c /proc/${pid}/stat > /dev/null 2>&1 ; then
		eval `sncfg mget WanIf`
		echo -n "dhcp6ctl -C -k ${KEYFILE} confirm interface ${WanIf} ... "
		dhcp6ctl -C -k ${KEYFILE} confirm interface ${WanIf}
		ret=$?
	else
		ret=0
	fi
}

if echo "$0" | grep "trans" ; then
#	lock
#	trans
#	unlock
	exit 0
fi
if [ $# != 2 ] ; then
	usage
	exit 1
fi
case "$1" in
	start)
		echo -n "[Starting] dhcp6c ... "
		lock
		start $2
		unlock
	;;
	stop)
		echo -n "[Stopping] dhcp6c ... "
		lock
		stop $2
		unlock
	;;
	reload)
		echo -n "[Reloading] dhcp6c ... "
		lock
#		reload
		stop $2
		start $2
		unlock
	;;
#	confirm)
#		echo -n "[Confirming] dhcp6c ... "
#		lock
#		confirm
#		unlock
#	;;
	trans)
		echo -n "[Translating] dhcp6c configuration ... "
		lock
		trans $2
		unlock
		ret=0
	;;
	*)
		usage
		exit 1
	;;
esac
if [ $ret == 0 ] ; then
	echo "OK"
	exit 0
else
	echo "FAIL"
	exit 1
fi
