#!/usr/local/bin/cbsd
#v12.1.6
# return 0 - not in NC pool range
# return 1 - all ok
# return 2 - ip already in use
# check = 0 - check for pool only 
# check = 1 - check for local interface + arp
# check = 2 - check the availability of IP
# check = 3 - check for local interface only
MYARG="ip check"
MYOPTARG=""
MYDESC="Check for IP exist or in pool"

. ${subrdir}/nc.subr
. ${cbsdinit}

CL_IP=${ip%%/*}
INNET=0

check_for_pool()
{
	local _ippool=

	for _ippool in ${node_ippool}; do
		NC_RANGE=$( echo ${_ippool} | ${TR_CMD} "/" " " )
		netmask ${NC_RANGE} ${CL_IP} > /dev/null 2>&1
		res=$?

		if [ ${res} -eq 1 ]; then
			INNET=$(( INNET + 1 ))
		fi
	done
}

check_local_ifaces()
{
	local _res=

	iptype ${CL_IP}

	case $? in
		1)
			case "${platform}" in
				Linux)
					_res=$( ${IP_CMD} addr | ${AWK_CMD} '/inet [0-9]+/{print $2}' | ${GREP_CMD} "^${CL_IP}/" 2>/dev/null )
					;;
				*)
					_res=$( ${IFCONFIG_CMD} | ${AWK_CMD} '/inet [0-9]+/{print $2}' | ${GREP_CMD} "^${CL_IP}$" 2>/dev/null )
					;;
			esac
			;;
		2)
			case "${platform}" in
				Linux)
					_res=$( ${IP_CMD} addr | ${AWK_CMD} '/inet6 *:*+/{print $2}' | ${GREP_CMD} "^${CL_IP}/" 2>/dev/null )
					;;
				*)
					_res=$( ${IFCONFIG_CMD} | ${AWK_CMD} '/inet6 *:*+/{print $2}' | ${GREP_CMD} "^${CL_IP}$" 2>/dev/null )
					;;
			esac
			;;
	esac
	[ -n "${_res}" ] && return 1
	return 0
}

check_local_ip()
{
	local _ret=0

	case "${platform}" in
		Linux)
			${GREP_CMD} -q "^${tmpip} " /proc/net/arp 2>/dev/null
			_ret=$?
			if [ ${_ret} -eq 0 ]; then
				# found
				_ret=1
			else
				_ret=0
			fi
			;;
		*)
			${miscdir}/chk_arp_byip --ip=${CL_IP} > /dev/null 2>&1
			_ret=$?
			;;
	esac
	return ${_ret}
}

## MAIN

# this part is for not empty IPs or DHCP mode
case ${CL_IP} in
	[Dd][Hh][Cc][Pp]|[Dd][Hh][Cc][Pp][Vv]6|0)
		exit 1
		;;
esac

# force IPv6 to check mode 2 (via ping)
# due to 0,1 not implemented yet
iptype ${CL_IP}
[ $? -eq 2 ] && check=2

case ${check} in
	0)
		check_for_pool
		[ ${INNET} -gt 0 ] && exit 1
		exit 0
		;;
	1)
		check_local_ifaces
		[ $? -eq 1 ] && exit 2
		check_local_ip
		[ $? -eq 0 ] && exit 1
		exit 2
		;;
	2)
		check_local_ifaces
		[ $? -eq 1 ] && exit 2
		iptype ${CL_IP}
		case $? in
			1)
				${PING_CMD} -n -t1 -i0.3 -W 300 -c2 -q ${CL_IP} > /dev/null 2>&1
				[ $? -eq 0 ] && exit 2
				exit 1
				;;
			2)
				if [ ${freebsdhostversion} -gt 1300131 ]; then
					# https://svnweb.freebsd.org/base?view=revision&revision=r368045
					${PING_CMD} -6 -n -t1 -i0.3 -W 300 -c2 -q ${CL_IP} > /dev/null 2>&1
					ret=$?
				else
					${PING6_CMD} -n -t1 -i0.3 -W 300 -c2 -q ${CL_IP} > /dev/null 2>&1
					ret=$?
				fi
				if [ ${ret} -eq 0 ]; then
					# second check via NDP
					${NDP_CMD} ${CL_IP} > /dev/null 2>&1
					ret=$?
				fi
				[ ${ret} -eq 0 ] && exit 2
				exit 1
				;;
		esac
		;;
	3)
		check_local_ifaces
		[ $? -eq 1 ] && exit 2
		exit 1
		;;
esac

exit 0
