#!/bin/sh
#
# (C) Copyright 1993, 1994 Mike Jagdis (jaggy@purplet.demon.co.uk)
#
#
# Configure the network interfaces according to the descriptions in
# /etc/default/iface, set up routing according to /etc/gateways etc.

# Magic. If you define LOCALHOST to be 127.0.0.1 then the route will
# be added for the host 127.0.0.1 via lo. If you leave it undefined
# the route will be added for the network 127.0.0.0 via lo. If you
# define it to be other than 127.0.0.1 you are stupid :-).
#LOCALHOST=127.0.0.1

# Load the library and find various programs.
. /etc/init.d/LIB

TCPLIB=/etc
HOSTS=$TCPLIB/hosts

ARP=`pathof arp $TCPLIB:/sbin:/etc:/bin:/usr/etc:/usr/bin:/usr/local/bin`
IFCONFIG=`pathof ifconfig $TCPLIB:/sbin:/etc:/bin:/usr/etc:/usr/bin:/usr/local/bin`
IFLINK=`pathof iflink $TCPLIB:/sbin:/etc:/bin:/usr/etc:/usr/bin:/usr/local/bin`
IFSETUP=`pathof ifsetup $TCPLIB:/sbin:/etc:/bin:/usr/etc:/usr/bin:/usr/local/bin`
NETADDR=`pathof netaddr $TCPLIB:/sbin:/etc:/bin:/usr/etc:/usr/bin:/usr/local/bin`
ROUTE=`pathof route $TCPLIB:/sbin:/etc:/bin:/usr/etc:/usr/bin:/usr/local/bin`

# We *should* have the hostname set by now...
HOSTNAME=`hostname`

function clear_spec()
{
	iface=
	family=
	device=

	io=
	aux=
	irq=
	dma=
	maddr=
	msize=

	ipaddr=
	netmask=
	broadcast=
	dstaddr=

	metric=
	mtu=

	arp=
	trailers=
	up=
}


# Configure an interface.
function do_current()
{
	# If there is no interface name there is nothing to do
	if [ -z "$iface" ]; then
		return
	fi

	# Setup a DDI device.
	args=
	if [ -n "$io" ]; then
		args="$args io=$io"
	fi
	if [ -n "$aux" ]; then
		args="$args aux=$aux"
	fi
	if [ -n "$irq" ]; then
		args="$args irq=$irq"
	fi
	if [ -n "$dma" ]; then
		args="$args dma=$dma"
	fi
	if [ -n "$maddr" ]; then
		args="$args maddr=$maddr"
	fi
	if [ -n "$msize" ]; then
		args="$args msize=$msize"
	fi
	if [ -n "$device" -a -n "$args" ]; then
		if [ -z "$IFSETUP" ]; then
			echo "WARNING: ifsetup not found - driver not configured, interface stays down"
			up=no
		else
			$IFSETUP $device $args
		fi
	fi

	# Connect a DDI device to a network interface.
	if [ -n "$device" -a -n "$family" ]; then
		if [ -z "$IFLINK" ]; then
			echo "WARNING: iflink not found - driver not connected, interface stays down"
			up=no
		else
			$IFLINK -f $family $device $iface
		fi
	fi

	# Configure the network interface.
	args=
	if [ -n "$broadcast" ]; then
		args="$args broadcast $broadcast"
	fi
	if [ -n "$netmask" ]; then
		args="$args netmask $netmask"
	fi
	if [ -n "$dstaddr" ]; then
		args="$args dstaddr $dstaddr"
	fi
	if [ -n "$metric" ]; then
		args="$args metric $metric"
	fi
	if [ -n "$mtu" ]; then
		args="$args mtu $mtu"
	fi
	if [ "$arp" = "NO" -o "$arp" = "no" -o "$arp" = "N" -o "$arp" = "n" ]; then
		args="$args -arp"
	else
		args="$args arp"
	fi
	if [ "$trailers" = "YES" -o "$trailers" = "yes" -o "$trailers" = "Y" -o "$trailers" = "y" ]; then
		args="$args trailers"
	else
		args="$args -trailers"
	fi
	if [ "$up" = "NO" -o "$up" = "no" -o "$up" = "N" -o "$up" = "n" ]; then
		args="$args -up"
	else
		args="$args up"
	fi
	if [ -n "$args" ]; then
		$IFCONFIG $iface $ipaddr $args
	fi

	# Establish routing for this interface.
	if [ -n "$dstaddr" ]; then
		# Point-to-point link so add routes for each end of the
		# link. The remote end may be a gateway elsewhere but if
		# so it's either listed in /etc/gateways or established
		# after the link has been brought up. We don't even assume
		# we can route to the destination address' network here.
		$ROUTE add -host $ipaddr dev $iface
		$ROUTE add -host $dstaddr dev $iface
	else
		# If we have (my) netaddr program we work out the network
		# address from the IP address and the netmask (if given)
		# and add it as a route. If we can't work out the network
		# address we have to assume this interface is only used
		# as a target for gateway routing and has no access for
		# whatever network it is on. We can also force hidden,
		# route-through networks by giving a netmask of 0.0.0.0.
		if [ -n "$NETADDR" -a "$ipaddr" != "$LOCALHOST" ]; then
			netaddr=`$NETADDR $ipaddr $netmask`
			if [ "$netaddr" != "0.0.0.0" ]; then
				$ROUTE add -net $netaddr netmask $netmask dev $iface
			fi
		else
			if [ "$ipaddr" = "$LOCALHOST" ]; then
				$ROUTE add -host $ipaddr dev lo
			fi
		fi
	fi

	# Done it all. Clean up.
	clear_spec
}


# Configure the network interfaces.
if [ -f /etc/default/iface ]; then
	echo $use_escapes "Configuring network interfaces:\c"

	trap 'rm -f /tmp/if$$' 0
	clear_spec
	awk '/^[ \t]*[^#]/' /etc/default/iface > /tmp/if$$
	while read i
	do
		set -- $i

		case "$1" in
			interface)
				do_current
				iface=$2
				echo $use_escapes " $iface\c"
				;;

			family)
				family=$2
				;;
			device)
				device=$2
				;;

			io)
				io=$2
				;;
			aux)
				aux=$2
				;;
			irq)
				irq=$2
				;;
			dma)
				dma=$2
				;;
			maddr)
				maddr=$2
				;;
			msize)
				msize=$2
				;;

			ipaddr)
				ipaddr=$2
				;;

			netmask)
				netmask=$2
				;;
			broadcast)
				broadcast=$2
				;;
			dstaddr)
				dstaddr=$2
				;;

			metric)
				metric=$2
				;;
			mtu)
				mtu=$2
				;;

			arp)
				arp=$2
				;;
			trailers)
				trailers=$2
				;;
			up)
				up=$2
				;;
		esac
	done < /tmp/if$$

	# Do the last entry.
	do_current
	echo
	rm -f /tmp/if$$

	# Now set up any (non-external) gateways. If we are going
	# to run a routed later it will of course do it itself
	# but we try and keep our local configuration ready to go
	# regardless. We might not even have a routed on a local
	# filesystem...
	if [ -f /etc/gateways ]; then
		# Add any gateways
		awk '/^[ \t]*[^#]/' /etc/gateways | while read i
		do
			set -- $i
			if [ "$1" = "net" -o "$1" = "host" ]; then
				target=$2
				shift; shift
				if [ "$1" = "gateway" ]; then
					gw="gw $2"
					shift; shift
				fi
				if [ "$1" = "metric" ]; then
					metric="metric $2"
					shift; shift
				fi
				# Should we also add external gateways?
				# They do exist and without routed
				# running we aren't listening to
				# anyone trying to tell us about them.
				if [ "$1" = "passive" -o "$1" = "active" ]; then
					if [ -n "$target" ]; then
						$ROUTE add $target $gw $metric
					fi
				fi
			fi
		done
	fi

	# If we have arp and there is an /etc/default/ethers or
	# an /etc/ethers we prep the arp cache with their contents.
	if [ -n "$ARP" -a -r /etc/default/ethers ]; then
		$ARP -f /etc/default/ethers
	fi
	if [ -n "$ARP" -a -r /etc/ethers ]; then
		$ARP -f /etc/ethers
	fi
	echo
fi
