#!/bin/sh
#
# $NetBSD: network,v 1.57 2008/10/11 17:28:03 christos Exp $
#

# PROVIDE: network
# REQUIRE: mountfs sysclock
# BEFORE:  NETWORKING

$_rc_subr_loaded . /etc/rc.subr

name="network"
start_cmd="network_start"
stop_cmd="network_stop"
required_dirs="/sys/class/net/lo"

nl='
' # a newline

network_start()
{
	# set hostname, turn on network
	#
	echo "=> Starting network."

	# If $hostname is set, use it for my Internet name,
	# otherwise use /etc/myname
	#
	if [ -z "$hostname" ] && [ -f /etc/myname ]; then
		hostname=$(cat /etc/myname)
	fi
	if [ -n "$hostname" ]; then
		echo "=> Setting hostname: $hostname."
		hostname $hostname
	fi

	# Set the address for the first loopback interface, so that the
	# auto-route from a newly configured interface's address to lo0
	# works correctly.
	#
	# NOTE: obscure networking problems will occur if lo0 isn't configured.
	#
	ifconfig lo 127.0.0.1 up

	# Configure all of the network interfaces listed in $net_interfaces;
	# if $auto_ifconfig is YES, grab all interfaces from ifconfig.
	# In the following, "xxN" stands in for interface names, like "le0".
	#
	# For any interfaces that has an $ifconfig_xxN variable
	# associated, we break it into lines using ';' as a separator,
	# then process it just like the contents of an /etc/ifconfig.xxN
	# file.
	#
	# For each line from the $ifconfig_xxN variable or the
	# /etc/ifconfig.xxN file, we ignore comments and blank lines,
	# treat lines beginning with "!" as commands to execute, treat
	# "dhcp" as a special case to invoke dhcpcd, and for any other
	# line we run "ifconfig xxN", using each line of the file as the
	# arguments for a separate "ifconfig" invocation.
	#
	# In order to configure an interface reasonably, you at the very least
	# need to specify "[addr_family] [hostname]" (e.g "inet my.domain.org"),
	# and probably a netmask (as in "netmask 0xffffffe0"). You will
	# frequently need to specify a media type, as in "media UTP", for
	# interface cards with multiple media connections that do not
	# autoconfigure. See the ifconfig manual page for details.
	#
	# Note that /etc/ifconfig.xxN takes multiple lines.  The following
	# configuration is possible:
	#	inet 10.1.1.1 netmask 0xffffff00
	#	inet 10.1.1.2 netmask 0xffffff00 alias
	#	inet6 2001:db8::1 prefixlen 64 alias
	#
	# You can put shell script fragment into /etc/ifconfig.xxN by
	# starting a line with "!".  Refer to ifconfig.if(5) for details.
	#
	if [ "$net_interfaces" != NO ]; then
		if checkyesno auto_ifconfig; then
			tmp=$(/sbin/ifconfig -l)
			for cloner in $(ls /sys/class/net/eth* 2>/dev/null); do
				for int in /etc/ifconfig.${cloner}[0-9]*; do
					[ ! -f $int ] && break
					tmp="$tmp ${int##*.}"
				done
			done
		else
			tmp="$net_interfaces"
		fi

		echo -n '=> Configuring network interfaces:'
		for int in ${tmp}; do
			eval argslist=\$ifconfig_$int

			# Skip interfaces that do not have explicit
			# configuration information.  If auto_ifconfig is
			# false then also warn about such interfaces.
			#
			if [ -z "$argslist" ] && ! [ -f /etc/ifconfig.$int ]
			then
				if ! checkyesno auto_ifconfig; then
					echo
					warn \
			"/etc/ifconfig.$int missing and ifconfig_$int not set;"
					warn "interface $int not configured."
				fi
				continue
			fi

			echo -n " $int"

			# If $ifconfig_xxN is empty, then use
			# /etc/ifconfig.xxN, which we know exists due to
			# an earlier test.
			#
			# If $ifconfig_xxN is non-empty and contains a
			# newline, then just use it as is.  (This allows
			# semicolons through unmolested.)
			#
			# If $ifconfig_xxN is non-empty and does not
			# contain a newline, then convert all semicolons
			# to newlines.
			#
			case "$argslist" in
			'')
				cat /etc/ifconfig.$int
				;;
			*"${nl}"*)
				echo "$argslist"
				;;
			*)
				(
					set -o noglob
					IFS=';'; set -- $argslist
					#echo >&2 "[$#] [$1] [$2] [$3] [$4]"
					IFS="$nl"; echo "$*"
				)
				;;
			esac |
			while read -r args; do
				case "$args" in
				''|"#"*|create)
					;;
				"!"*)
					# Run arbitrary command in a subshell.
					( eval "${args#*!}" )
					;;
				dhcp)
					dhcpcd -n ${dhcpcd_flags} $int
					;;
				*)
					# Pass args to ifconfig.  Note
					# that args may contain embedded
					# shell metacharacters, such as
					# "ssid 'foo;*>bar'". We eval
					# one more time so that things
					# like ssid "Columbia University" work.
					(
						set -o noglob
						eval set -- $args
						#echo >&2 "[$#] [$1] [$2] [$3]"
						ifconfig $int "$@"
					)
					;;
				esac
			done
			configured_interfaces="$configured_interfaces $int"
		done
		echo "."
	fi

	# Check $defaultroute, then /etc/mygate, for the name or address
	# of my IPv4 gateway host. If using a name, that name must be in
	# /etc/hosts.
	#
	if [ -z "$defaultroute" ] && [ -f /etc/mygate ]; then
		defaultroute=$(cat /etc/mygate)
	fi
	if [ -n "$defaultroute" ]; then
		route add default gw $defaultroute
	fi

	# Check $defaultroute6, then /etc/mygate6, for the name or address
	# of my IPv6 gateway host. If using a name, that name must be in
	# /etc/hosts.  Note that the gateway host address must be a link-local
	# address if it is not using an stf* interface.
	#
	if [ -z "$defaultroute6" ] && [ -f /etc/mygate6 ]; then
		defaultroute6=$(cat /etc/mygate6)
	fi
	if [ -n "$defaultroute6" ]; then
		if [ "$ip6mode" = "autohost" ]; then
			echo
			warn \
	    "ip6mode is set to 'autohost' and a v6 default route is also set."
		fi
		route -A inet6 add $defaultroute6
	fi

}

network_stop()
{
	echo "=> Stopping network."

	# down interfaces
	#
	echo -n '=> Downing network interfaces:'
	if [ "$net_interfaces" != NO ]; then
		if checkyesno auto_ifconfig; then
			tmp=$(ls /sys/class/net/eth*)
		else
			tmp="$net_interfaces"
		fi
		for int in $tmp; do
			eval args=\$ifconfig_$int
			if [ -n "$args" ] || [ -f /etc/ifconfig.$int ]; then
				echo -n " $int"
				dhcpcd -k $int 2> /dev/null
				ifconfig $int down
			fi
		done
		echo "."
	fi
}

load_rc_config $name
run_rc_command "$1"
