#!/bin/sh

link_local() {
	eval $(ipcalc -n ${2}/${3})
	/sbin/ip route add ${NETWORK}/${3} src ${2} dev ${1} scope link proto kernel metric ${4} table ${5}
}

priv_addr() {
	case ${1} in
		10)return 0
		;;
		100)if [ ${2} -gt 63 ] && [ ${2} -lt 128 ];then
			return 1
		fi
		;;
		172)if [ ${2} -lt 32 ];then
			return 0
		fi
		;;
		192)if [ ${2} -eq 168 ];then
			return 0
		fi
		;;
	esac
	return 1
}

del_sit() {
	if [ -d /sys/class/net/sit${1} ];then
		/sbin/ip tun del sit${1}
	fi
}

add_sit() {
	ORIGIFS=${IFS}
	IFS=.
	ip_a=(${2})
	IFS=${ORIGIFS}

	METRIC=$((1024 >> 5-${1}))

	if [ -d /sys/class/net/sit${1} ];then
		/sbin/ip tun del sit${1}
	fi
	/sbin/ip link add name sit${1} type sit local ${2} remote any mode any
	/sbin/ip link set up dev sit${1}
	if priv_addr ${ip_a[0]} ${ip_a[1]};then
		for lip64 in 2002:ac10::/28 2002:a00::/24 2002:c0a8::/32 ;do
			/sbin/ip -6 route add ${lip64} dev sit${1} metric ${METRIC}
		done;
	fi;
	/sbin/ip route del ::/96 dev sit${1}
	/sbin/ip route add ::/96 dev sit${1} metric ${METRIC}

#	/sbin/ip -6 addr add $(printf "2002:%x%x:%x%x:ffff:ffff:2002:%x%x:%x%x/128" ${ip_a[0]} ${ip_a[1]} ${ip_a[2]} ${ip_a[3]} ${ip_a[0]} ${ip_a[1]} ${ip_a[2]} ${ip_a[3]}) dev sit${1}
}

vlan_configure() {
	if [ -e /etc/default/ppp ];then
		source /etc/default/ppp
	else
		VLAN="";
		IPV64WAN="0";
	fi;

	if [ -e /etc/default/vlan_${2} ];then
		source /etc/default/vlan_${2}
	else
		echo "No static config found" && exit 0
	fi;

	table=$((${2} + 10000))
	metric=$((100 + (${METRIC-0} * 2)))
	ametric=$((1200 + ${METRIC-0}))

	/sbin/ip link set dev ${interface} up
	/sbin/ip rule add prio ${table} oif ${1}.${2} table ${table} >/dev/null 2>&1 |:

	if [ "${IP}" ] && [ "${SN}" ];then
		if [ "${VLAN}" == "${2}" ] &&  [ "${IPV64WAN}" == "1" ];then
			add_sit 2 ${IP}
		else
			del_sit 2
		fi;
		/sbin/ip rule add prio ${table} from ${IP} table ${table}
		/sbin/ip addr add dev ${1}.${2} local ${IP}/${SN} broadcast + label ${1}.${2}:static
		(link_local ${1}.${2} ${IP} ${SN} ${metric} ${table})
	elif [ "${ip}" ] && [ "${VLAN}" == "${2}" ] && [ "${IPV64WAN}" == "1" ];then
		add_sit 2 ${ip}
	else
		del_sit 2
	fi;

	if [ "${GW}" ];then
		/sbin/ip route add default via ${GW} metric ${metric} dev ${1}.${2}
		/sbin/ip route add default via ${GW} metric ${metric} dev ${1}.${2} table ${table}
	fi;

	if [ "${VPNGW}" ] && [ "${VPNROUTE}" ];then
		for newrt in ${VPNROUTE};do
			ip route add ${newrt} via ${VPNGW} dev ${1}.${2} metric ${metric}  | :
			ip route add ${newrt} via ${VPNGW} dev ${1}.${2} metric ${metric} table ${table} | :
		done;
	fi;

	if [ "${DNS1}" ];then
		echo "nameserver ${DNS1}" > /tmp/static_resolv_${2}
	elif [ -e /tmp/static_resolv_${2} ];then
		rm /tmp/static_resolv_${2}
	fi;
	if [ "${DNS2}" ];then
		echo "nameserver ${DNS2}" >> /tmp/static_resolv_${2}
	fi;

	if [ -e /tmp/static_resolv_${2} ];then
		cat /tmp/static_resolv_${2} |/sbin/resolvconf -a ${1}.${2}.conf
		rm /tmp/static_resolv_${2}
	else
		/sbin/resolvconf -d ${1}.${2}.conf
	fi;
}

ethernet_configure() {
	if [ -e /etc/default/ppp ];then
		source /etc/default/ppp
	else
		VLAN="";
		IPV64LAN="0";
	fi;

	if [ -e /etc/default/static ];then
		source /etc/default/static
	else
		echo "No static config found" && exit 0
	fi;

	/sbin/ip rule add prio 100 oif ${1} table 100 >/dev/null 2>&1 |:

	if [ "${IP}" ] && [ "${SN}" ];then
		/sbin/ip rule add prio 100 from ${IP} table 100
		/sbin/ip addr add ${IP}/${SN} brd + dev ${1} label ${1}:static | :
		(link_local ${1} ${IP} ${SN} 11 100)
		if [ "${IPV64LAN}" == "1" ];then
			add_sit 3 ${IP}
		else
			del_sit 3
		fi;
	elif [ "${ip}" ];then
		if [ "${IPV64LAN}" == "1" ];then
			add_sit 3 ${ip}
		else
			del_sit 3
		fi;
	fi;

	if [ "${GW}" ];then
		/sbin/ip route add default via ${GW} dev ${1} metric 11 | :
		/sbin/ip route add default via ${GW} dev ${1} metric 11 table 100 | :
	fi;

	if [ "${VPNGW}" ] && [ "${VPNROUTE}" ];then
		for newrt in ${VPNROUTE};do
			ip route add ${newrt} via ${VPNGW} dev ${1} metric 11 | :
			ip route add ${newrt} via ${VPNGW} dev ${1} metric 11 table 100 | :
		done;
	fi;

	if [ "${DNS1}" ];then
		echo "nameserver ${DNS1}" > /tmp/static_resolv
	elif [ -e /tmp/static_resolv ];then
		rm /tmp/static_resolv
	fi;
	if [ "${DNS2}" ];then
		echo "nameserver ${DNS2}" >> /tmp/static_resolv
	fi;

	if [ -e /tmp/static_resolv ];then
		cat /tmp/static_resolv |/sbin/resolvconf -a ${1}.0.conf
		rm /tmp/static_resolv
	else
		/sbin/resolvconf -d ${1}.0.conf
	fi;
}

wifi_configure() {
	if [ -e /etc/default/static ];then
		source /etc/default/wifi
	else
		echo "No static config found" && exit 0
	fi;

	/sbin/ip rule add prio 200 oif ${1} table 200 >/dev/null 2>&1 |:

	if [ "${IP}" ] && [ "${SN}" ] && [ "${STATIC}" == "1" ];then
		/sbin/ip rule add prio 200 from ${IP} table 200
		/sbin/ip addr add ${IP}/${SN} brd + dev ${1} label ${1}:static | :
		(link_local ${1} ${IP} ${SN} 51 200)
		if [ "${IPV64WIFI}" == "1" ];then
			add_sit sit3 ${IP}
		else
			del_sit sit3
		fi;
	elif [ "${ip}" ];then
		if [ "${IPV64WIFI}" == "1" ];then
			add_sit 4 ${ip}
		else
			del_sit 4
		fi;
	fi;

	if [ "${GW}" ];then
		/sbin/ip route add default via ${GW} dev ${1} metric 51 | :
		/sbin/ip route add default via ${GW} dev ${1} metric 51 table 200 | :
	fi;

	if [ "${VPNGW}" ] && [ "${VPNROUTE}" ];then
		for newrt in ${VPNROUTE};do
			ip route add ${newrt} via ${VPNGW} dev ${1} metric 51 | :
			ip route add ${newrt} via ${VPNGW} dev ${1} metric 51 table 200 | :
		done;
	fi;

	if [ "${DNS1}" ];then
		echo "nameserver ${DNS1}" > /tmp/static_resolv_wifi
	elif [ -e /tmp/static_resolv_wifi ];then
		rm /tmp/static_resolv_wifi
	fi;
	if [ "${DNS2}" ];then
		echo "nameserver ${DNS2}" >> /tmp/static_resolv_wifi
	fi;

	if [ -e /tmp/static_resolv_wifi ];then
		cat /tmp/static_resolv_wifi |/sbin/resolvconf -a ${1}.conf
		rm /tmp/static_resolv_wifi
		/sbin/resolvconf -d ${1}.dhcpc
	else
		/sbin/resolvconf -d ${1}.conf
	fi;
}

[ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1

case "$1" in
	deconfig|renew|bound)
		if [ "${interface}" == "eth0" ];then
			ethernet_configure ${interface} >/dev/null 2>&1 | :
		elif [ "${interface}" == "wlan0" ];then
			wifi_configure ${interface} >/dev/null 2>&1 | :
		elif [ "${interface:0:4}" == "eth0" ];then
			vlanid=${interface:5}
			if [ ${vlanid} -gt 0 ] && [ ${vlanid} -lt 4097 ];then
				vlan_configure eth0 ${vlanid} >/dev/null 2>&1 | :
			fi;
		fi
		;;
esac
