#!/bin/bash
CMDNAME="${0##*/}"
SETEEPROMPROG="/opt/RAYLASE/SPICE3/bin/seteeprom"

function log() {
	/usr/bin/logger --id=$$ --tag "${CMDNAME}" "$*"
}

#set -x
function isActive() {
	local interface="$1"
	local stateunknown=1
	local active=0
	for (( i = 50; i > 0; --i )); do
		printf "waiting for known status: "
		if ip link show "${IFACE}" | grep -q -E 'UNKNOWN' ; then
			printf "%2d\r${CMDNAME}: ${IFACE} " "${i}"
			sleep 0.2
			continue
		fi
		stateunknown=0
		break;
	done
	echo
	if (( stateunknown == 0 )); then
		echo -n "${CMDNAME}: ${IFACE} "
		for (( i = 20; i > 0; --i )); do
			printf "trying to detect carrier: "
			if ip link show "${IFACE}" | grep -q -E 'NO-CARRIER' ; then
				printf "%2d\r${CMDNAME}: ${IFACE} " "${i}"
				sleep 0.5
				continue
			fi

			# When we get here, we can assume that eth1 is being used
			# because the card is inserted in a PCIe slot.
			echo -n "carrier detected OK                "
			return 0	# SUCCESS
		done
		echo "no carrier detected.               "
	else
		echo "state unknown, assuming no carrier."
	fi
	return 1 # FAIL: no carrier, or timeout on unknown
}

# Test an IP address for validity:
# Usage:
#      valid_ip IP_ADDRESS
#      if [[ $? -eq 0 ]]; then echo good; else echo bad; fi
#   OR
#      if valid_ip IP_ADDRESS; then echo good; else echo bad; fi
#
function valid_ip()
{
	local  ip=$1
	local  stat=1

	if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
		OIFS=$IFS
		IFS='.'
		ip=($ip)
		IFS=$OIFS
		[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
			&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
		stat=$?
	fi
	return $stat
}

# Test an IP netmask for validity:
# Usage:
#      valid_netmask IP_NETMASK
#      if [[ $? -eq 0 ]]; then echo good; else echo bad; fi
#   OR
#      if valid_netmask IP_NETMASK; then echo good; else echo bad; fi
#
valid_netmask()
{
    local netmask=$1
    local netmask_binary
    local octet
    local stat

    if [[ $netmask =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        stat=0
        for ((i=0; i<4; i++))
        do
            octet=${netmask%%.*}
            netmask=${netmask#*.}
            [[ $octet -gt 255 ]] && { stat=1; break; }
            netmask_binary=$netmask_binary$( echo "obase=2; $octet" | bc )
            [[ $netmask_binary =~ 01 ]] && { stat=1; break; }
        done
    else
        stat=1
    fi
    return $stat
}

function main()
{
	log "${IFACE} ..."

	case "${IFACE}" in
		'eth0' )
			#
			# first examine the EEPROM to see if and how IPV4ADDR has been set
			#
			if [ -x ${SETEEPROMPROG} ] ; then
				local ipv4addr0=$(${SETEEPROMPROG} 'IPV4ADDR0')
				local ipv4netmask0=$(${SETEEPROMPROG} 'IPV4NETMASK0')
				local nm0="255.255.255.0"
				if valid_netmask "$ipv4netmask0"; then
					nm0="${ipv4netmask0}"
				fi
				local ipv4defaultgw=$(${SETEEPROMPROG} 'IPV4DEFAULTGW')
				local gw=""
				if valid_ip "${ipv4defaultgw}"; then
					gw="${ipv4defaultgw}"
				fi
				
				if valid_ip "${ipv4addr0}"; then
					ip link set dev "${IFACE}" up
					
					interface="${IFACE}" ip="${ipv4addr0}" mask="${nm0}" router="${gw}" /etc/udhcpc.d/50default bound
					interface=${IFACE} /etc/udhcpc.d/75spice3post bound

					exit 1 # because we do NOT want ifup to call udhcpc
				fi
			fi
			#
			# Otherwise, we have nothing to go on, so...
			#
			# just exit normally and let ifup call udhcpc
			#
			;;

		'eth1' )
			#
			# This hack is only neccessary for eth1
			#
			ip link set dev "${IFACE}" up

			if isActive "${IFACE}" ; then
				local ipv4addr1=$(${SETEEPROMPROG} 'IPV4ADDR1')
				local ipv4netmask1=$(${SETEEPROMPROG} 'IPV4NETMASK1')
				local nm1="255.255.255.0"
				if valid_netmask "$ipv4netmask1"; then
					nm1="$ipv4netmask1"
				fi
				local ipv4defaultgw=$(${SETEEPROMPROG} 'IPV4DEFAULTGW')
				local gw=""
				if valid_ip "${ipv4defaultgw}"; then
					gw="${ipv4defaultgw}"
				fi

				if valid_ip "${ipv4addr1}" ; then
					ip link set dev "${IFACE}" up
					interface="${IFACE}" ip="${ipv4addr1}" mask="${nm1}" router="${gw}" /etc/udhcpc.d/50default bound
					interface=${IFACE} /etc/udhcpc.d/75spice3post bound
				else
					log "${IFACE} using APIPA."
					interface=${IFACE} /etc/udhcpc.d/25spice3pre leasefail
					interface=${IFACE} /etc/udhcpc.d/75spice3post bound
				fi

				exit 1 # because we do NOT want ifup to call udhcpc

			else
				# If we get here, we know that eth1 is inactive
				# i.e. the card in NOT inserted in a PCIe slot.
				# In this case, we want to avoid the special case of assiging APIPA
				# to both eth1 and eth0 (which leads to ambiguous entries in the routing table)
				# so we ignore eth1 completely.
				log " apparently not in use."

				ip link set dev "${IFACE}" down

				exit 1	# return FAIL, so that ifup stops trying to initialise the interface.
			fi
			;;

		* )
			log " nothing to do."
			;;
	esac
	exit 0
}
main $*
