#!/bin/sh

Wait_for_carrier ()
{
	# $1 = network device
	echo -n "Waiting for link to come up on $1... "
	ip link set $1 up
	for step in $(seq 1 $ETHDEV_LINK_TIMEOUT)
	do
		carrier=$(cat /sys/class/net/$1/carrier \
		2>/dev/null)
		case "${carrier}" in
			1)
			echo -e "\nLink is up"
			return
			;;
			*)
			# Counter
			echo -n "$step "
			;;
		esac
		sleep 1
	done
	echo -e "\nError - carrier not detected on $1."
}

Select_eth_device ()
{
	# Boot type in initramfs's config
	bootconf=$(egrep '^BOOT=' /conf/initramfs.conf | tail -1)

	# can be superseded by command line (used by Debian-Live's netboot for example)
	for ARGUMENT in ${LIVE_BOOT_CMDLINE}
	do
		case "${ARGUMENT}" in
			netboot=*)
				NETBOOT="${ARGUMENT#netboot=}"
				;;
		esac
	done

	if [ "$bootconf" != "BOOT=nfs" ] && [ -z "$NETBOOT" ] && [ -z "$FETCH" ] && [ -z "$FTPFS" ] && [ -z "$HTTPFS" ]
	then
		# Not a net boot : nothing to do
		return
	fi

	# we want to do some basic IP
	modprobe -q af_packet

	# Ensure all our net modules get loaded so we can actually compare MAC addresses...
	udevadm trigger
	udevadm settle

	# Available Ethernet interfaces ?
	l_interfaces=""

	# See if we can derive the boot device
	Device_from_bootif

	[ -n "$ETHDEV_LINK_TIMEOUT" ] || ETHDEV_LINK_TIMEOUT=15
	echo "Using timeout of $ETHDEV_LINK_TIMEOUT seconds for ethernet device link."

	if [ -z "$DEVICE" ]
	then
		echo "Waiting for ethernet card(s) up... If this fails, maybe the ethernet card is not supported by the kernel `uname -r`?"
		while [ -z "$l_interfaces" ]
		do
			l_interfaces="$(cd /sys/class/net/ && ls -d * 2>/dev/null | grep -v "lo")"
		done

		if [ $(echo $l_interfaces | wc -w) -lt 2 ]
		then
			# only one interface : no choice
			echo "DEVICE=$l_interfaces" >> /conf/param.conf
			Wait_for_carrier $l_interfaces
			return
		fi

		# If user force to use specific device, write it
		for ARGUMENT in ${LIVE_BOOT_CMDLINE}
		do
			case "${ARGUMENT}" in
				live-netdev=*)
				NETDEV="${ARGUMENT#live-netdev=}"

				# Check if NETDEV is a valid MAC address
				if echo "$NETDEV" | grep -Eq '^[0-9A-Fa-f]{2}[:-]([0-9A-Fa-f]{2}[:-]){4}[0-9A-Fa-f]{2}$'
				then
					echo "live-netdev: Finding network device for MAC $NETDEV ..."

					# Retrieve the device name associated with the MAC address
					NETDEV=$(ip -o link | awk -v mac="$NETDEV" '$0 ~ mac{print substr($2, 1, length($2)-1)}')
					if [ -n "$NETDEV" ]
					then
						echo "DEVICE=$NETDEV" >> /conf/param.conf
						echo "live-netdev: Found network device $NETDEV."
						Wait_for_carrier "$NETDEV"
					else
						echo "live-netdev: No matching network device found, ignoring parameter."
					fi
				else
					echo "DEVICE=$NETDEV" >> /conf/param.conf
					echo "Found live-netdev parameter, forcing it to use network device $NETDEV."
					Wait_for_carrier "$NETDEV"
				fi
				return
				;;
			esac
		done
	else
		l_interfaces="$DEVICE"
	fi

	found_eth_dev=""
	echo -n "Looking for a connected Ethernet interface."

	for interface in $l_interfaces
	do
		# ATTR{carrier} is not set if this is not done
		echo -n " $interface ?"
		ipconfig -c none -d $interface -t 1 >/dev/null 2>&1
		sleep 1
	done

	echo ''

	for step in 1 2 3 4 5
	do
		for interface in $l_interfaces
		do
			# Skip the interface if it's already found.
			IN_IT=no
			for DEV in $found_eth_dev ; do
				if [ "${DEV}" = "$interface" ] ; then
					IN_IT=yes
				fi
			done

			if [ "${IN_IT}" = "no" ] ; then
				Wait_for_carrier $interface
				carrier=$(cat /sys/class/net/$interface/carrier \
					2>/dev/null)
				# link detected
				if [ "${carrier}" = 1 ] ; then
					echo "Connected $interface found"
					# inform initrd's init script :
					if [ -z "${found_eth_dev}" ] ; then
						found_eth_dev="$interface"
					else
						found_eth_dev="$found_eth_dev $interface"
					fi
				fi
			fi
		done
		# wait a bit
		sleep 1
	done
	if [ -n "$found_eth_dev" ]
	then
		echo "Done searching for connected Ethernet interface."
		echo "Writing DEVICE='$found_eth_dev' in /conf/param.conf."
		echo "DEVICE='$found_eth_dev'" >> /conf/param.conf
	else
		echo "Could not find an interface that is up: giving-up..."
	fi
	return
}
