#!/usr/local/bin/cbsd
#v10.1.0
MYARG=""
MYOPTARG="nat"
MYDESC="Enable NAT service for RFC1918 Networks"
ADDHELP="
${H3_COLOR}Description${N0_COLOR}:

Enable/apply NAT framework configured via 'cbsd natcfg'

pf firewall notes:

 Also you can re-configure 'cbsd naton' function via ~cbsd/etc/cbsd-pf.conf and switch from
 internal CBSD 'enable' method to custom.

${H3_COLOR}Options${N0_COLOR}:

 ${N2_COLOR}nat${N0_COLOR}    - alternative NAT framework name.

${H3_COLOR}Examples${N0_COLOR}:

 # cbsd naton

${H3_COLOR}See also${N0_COLOR}:

 cbsd natcfg --help
 cbsd natoff --help
 cbsd expose --help

"

. ${subrdir}/nc.subr

. ${cbsdinit}

. ${system}
. ${initenv}

[ -n "${nat}" ] && nat_enable="${nat}"

check_nat_ip()
{
	natoff nat=all
	case "${platform}" in
		Linux)
			${PING_CMD} -c1 -I ${natip} ${natip} > /dev/null 2>&1 || err 1 "${N1_COLOR}Cant assign nat address: ${N2_COLOR}${natip}${N1_COLOR}. Probably wrong ip. Nat cfg skipped${N0_COLOR}"
			;;
		*)
			${PING_CMD} -c1 -S ${natip} ${natip} > /dev/null 2>&1 || err 1 "${N1_COLOR}Cant assign nat address: ${N2_COLOR}${natip}${N1_COLOR}. Probably wrong ip. Nat cfg skipped${N0_COLOR}"
			;;
	esac
	return 0
}

[ "${nat_enable}" = "0" ] && exit 0

# forwarding for NAT mode
${ECHO} "${N1_COLOR}CBSD: Enable IP forwarding for NAT service${N0_COLOR}"
case "${platform}" in
	Linux)
		${SYSCTL_CMD} net.ipv4.ip_forward=1 >/dev/null
		${SYSCTL_CMD} net.ipv6.ip_forward=1 >/dev/null
		;;
	*)
		_res=$( ${SYSCTL_CMD} -qn net.inet6.ip6.forwarding 2>/dev/null )
		_ret=$?
		if [ ${_ret} -ne 0 ]; then
			cbsdlogger NOTICE ${CBSD_APP}: net.inet6.ip6.forwarding not found, skip IPv6 forwarding
		else
			if [ "${_res}" != "1" ]; then
				cbsdlogger NOTICE ${CBSD_APP}: enable net.inet6.ip6.forwarding via sysctl
				${SYSCTL_CMD} net.inet6.ip6.forwarding=1 >/dev/null
			fi
		fi
		_res=$( ${SYSCTL_CMD} -qn net.inet.ip.forwarding 2>/dev/null )
		_ret=$?
		if [ ${_ret} -ne 0 ]; then
			cbsdlogger NOTICE ${CBSD_APP}: net.inet.ip.forwarding not found, skip IPv4 forwarding
		else
			if [ "${_res}" != "1" ]; then
				cbsdlogger NOTICE ${CBSD_APP}: enable net.inet.ip.forwarding via sysctl
				${SYSCTL_CMD} net.inet.ip.forwarding=1 >/dev/null
			fi
		fi
		;;
esac

iptype ${natip} >/dev/null 2>&1
_ret=$?

# if natip is not valid IPv4, assume it is NIC variable.
# so try to find out first IPv4 for aliasing
case ${_ret} in
	1)
		# natip is valid IPv4
		_extiface="${CBSD_UPLINK_IFACE4}"
		;;
	2)
		# natip is valid IPv6
		_extiface="${CBSD_UPLINK_IFACE6}"
		;;
	*)
		_extiface="${natip}"
		natip=$( getip-by-nics nic=${_extiface} 2>/dev/null )
		if [ $? -ne 0 ]; then
			${ECHO} "${N1_COLOR}Unable to determine first IP for nic: ${N2_COLOR}${_extiface}${N0_COLOR}"
			return 1
		fi
		ok="${nat_enable}" # used by make_nat
		make_nat
		;;
esac

case "${nat_enable}" in
	nft)
		[ ! -f "${etcdir}/nft.conf" ] && err 1 "${N1_COLOR}No nft.conf. run ${N2_COLOR}cbsd natcfg${N1_COLOR} first${N0_COLOR}"
		check_nat_ip
		/bin/sh ${etcdir}/nft.conf
		;;
	pf)
		# copy default pf.conf
		if [ ! -r ${workdir}/etc/pf.conf ]; then
			cbsdlogger NOTICE ${CBSD_APP}: first CBSD pf run: use ${workdir}/etc/defaults/pf.conf.tpl as template for: ${workdir}/etc/pf.conf
			${ECHO} "${N1_COLOR}${CBSD_APP}: first CBSD pf run: use ${workdir}/etc/defaults/pf.conf.tpl as template for: ${N2_COLOR}${workdir}/etc/pf.conf${N0_COLOR}"
			${SED_CMD} -e "s:%%CBSD_WORKDIR%%:${workdir}:g" ${workdir}/etc/defaults/pf.conf.tpl > ${workdir}/etc/pf.conf
		fi

		[ ! -r ${workdir}/etc/pfnat.conf ] && ${TOUCH_CMD} ${workdir}/etc/pfnat.conf
		[ ! -r ${workdir}/etc/pfrdr.conf ] && ${TOUCH_CMD} ${workdir}/etc/pfrdr.conf
		[ ! -r ${workdir}/etc/pfcustomflt.conf ] && ${TOUCH_CMD} ${workdir}/etc/pfcustomflt.conf

		readconf cbsd-pf.conf
		if fn_exists cbsd_external_naton 2>/dev/null; then
			cbsd_external_naton
			ret=$?
		else
			err 1 "${W1_COLOR}${CBSD_APP} error: ${N1_COLOR}no such cbsd_external_naton() function, please check: ${N2_COLOR}cbsd-pf.conf${N0_COLOR}"
		fi
	;;
	ipfw)
		[ ! -f "${etcdir}/ipfw.conf" ] && err 1 "${N1_COLOR}No ipfw.conf. run ${N2_COLOR}cbsd natcfg${N1_COLOR} first${N0_COLOR}"
		${KLDSTAT_CMD} -qm alias || ${KLDLOAD_CMD} libalias
		${KLDSTAT_CMD} -qm ipfw_nat || ${KLDLOAD_CMD} ipfw_nat
		check_nat_ip
		/bin/sh ${etcdir}/ipfw.conf
	;;
	ipfilter)
		[ ! -f "${etcdir}/ipfilter.conf" ] && err 1 "No ipfilter.conf. run cbsd natcfg first"
		${KLDSTAT_CMD} -qm ipfilter || ${KLDLOAD_CMD} ipfilter
		check_nat_ip
		/sbin/ipnat -CF -f ${etcdir}/ipfilter.conf
	;;
esac

exit ${ret}
