network.subr revision 147088
1327952Sdim#
2317017Sdim# Copyright (c) 2003 The FreeBSD Project. All rights reserved.
3353358Sdim#
4353358Sdim# Redistribution and use in source and binary forms, with or without
5353358Sdim# modification, are permitted provided that the following conditions
6317017Sdim# are met:
7317017Sdim# 1. Redistributions of source code must retain the above copyright
8317017Sdim#    notice, this list of conditions and the following disclaimer.
9317017Sdim# 2. Redistributions in binary form must reproduce the above copyright
10317017Sdim#    notice, this list of conditions and the following disclaimer in the
11317017Sdim#    documentation and/or other materials provided with the distribution.
12327952Sdim#
13327952Sdim# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
14327952Sdim# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15317017Sdim# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16317017Sdim# ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
17327952Sdim# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18317017Sdim# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19317017Sdim# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20317017Sdim# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21317017Sdim# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22317017Sdim# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23317017Sdim# SUCH DAMAGE.
24317017Sdim#
25317017Sdim# $FreeBSD: head/etc/network.subr 147088 2005-06-07 04:49:12Z brooks $
26327952Sdim#
27341825Sdim
28327952Sdim#
29360784Sdim# Subroutines commonly used from network startup scripts.
30327952Sdim# Requires that rc.conf be loaded first.
31327952Sdim#
32319799Sdim
33327952Sdim# ifconfig_up if
34317017Sdim#	Evaluate ifconfig(8) arguments for interface $if and
35327952Sdim#	run ifconfig(8) with those arguments. It returns 0 if
36327952Sdim#	arguments were found and executed or 1 if the interface
37317017Sdim#	had no arguments.  Pseudo arguments DHCP and WPA are handled
38327952Sdim#	here.
39317017Sdim#
40327952Sdimifconfig_up()
41327952Sdim{
42327952Sdim	_cfg=1
43341825Sdim
44327952Sdim	ifconfig_args=`ifconfig_getargs $1`
45327952Sdim	if [ -n "${ifconfig_args}" ]; then
46327952Sdim		ifconfig $1 ${ifconfig_args}
47327952Sdim		_cfg=0
48327952Sdim	fi
49327952Sdim
50327952Sdim	if wpaif $1; then
51327952Sdim		#/etc/rc.d/wpa_supplicant start $1
52327952Sdim		_cfg=0		# XXX: not sure this should count
53317017Sdim	fi
54317017Sdim
55317017Sdim	if dhcpif $1; then
56317017Sdim		/etc/rc.d/dhclient start $1
57317017Sdim		_cfg=0
58317017Sdim	fi
59317017Sdim
60317017Sdim	return ${cfg}
61317017Sdim}
62317017Sdim
63317017Sdim# ifconfig_down if
64317017Sdim#	Remove all inet entries from the $if interface. It returns
65317017Sdim#	0 if inet entries were found and removed. It returns 1 if
66327952Sdim#	no entries were found or they could not be removed.
67317017Sdim#
68317017Sdimifconfig_down()
69318681Sdim{
70327952Sdim	[ -z "$1" ] && return 1
71318681Sdim	_ifs="^"
72317017Sdim	_ret=1
73317017Sdim
74317017Sdim	inetList="`ifconfig $1 | grep 'inet ' | tr "\n" "$_ifs"`"
75317017Sdim
76317017Sdim	oldifs="$IFS"
77360784Sdim	IFS="$_ifs"
78360784Sdim	for _inet in $inetList ; do
79319250Sdim		# get rid of extraneous line
80317017Sdim		[ -z "$_inet" ] && break
81317017Sdim
82317017Sdim		_inet=`expr "$_inet" : '.*\(inet \([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*'`
83317017Sdim
84317017Sdim		IFS="$oldifs"
85317017Sdim		ifconfig $1 ${_inet} delete
86317017Sdim		IFS="$_ifs"
87317017Sdim		_ret=0
88317017Sdim	done
89317017Sdim	IFS="$oldifs"
90317017Sdim
91341825Sdim	if wpaif $1; then
92327952Sdim		#/etc/rc.d/wpa_supplicant stop $1
93344779Sdim	fi
94344779Sdim
95344779Sdim	if dhcpif $1; then
96317017Sdim		/etc/rc.d/dhclient stop $1
97341825Sdim		_cfg=0
98317017Sdim	fi
99317017Sdim
100317017Sdim	return $_ret
101317017Sdim}
102317017Sdim
103317017Sdim# _ifconfig_getargs if
104317017Sdim#	Echos the arguments for the supplied interface to stdout.
105317017Sdim#	returns 1 if empty.  In general, ifconfig_getargs should be used
106317017Sdim#	outside this file.
107317017Sdim_ifconfig_getargs()
108317017Sdim{
109317017Sdim	_ifn=$1
110317017Sdim	if [ -z "$_ifn" ]; then
111317017Sdim		return 1
112317017Sdim	fi
113317017Sdim
114317017Sdim	eval _args=\$ifconfig_$1
115317017Sdim	if [ -z "$_args" -a -n "${pccard_ifconfig}" ]; then
116317017Sdim		for _if in ${removable_interfaces} ; do
117317017Sdim			if [ "$_if" = "$_ifn" ] ; then
118317017Sdim				_args=${pccard_ifconfig}
119327952Sdim				break
120317017Sdim			fi
121317017Sdim		done
122317017Sdim	fi
123317017Sdim
124317017Sdim	echo $_args
125317017Sdim}
126317017Sdim
127327952Sdim# ifconfig_getargs if
128317017Sdim#	Takes the result from _ifconfig_getargs and removes pseudo
129317017Sdim#	args such as DHCP and WPA.
130317017Sdimifconfig_getargs()
131327952Sdim{
132327952Sdim	_tmpargs=`_ifconfig_getargs $1`
133327952Sdim	if [ $? -eq 1 ]; then
134327952Sdim		return 1
135327952Sdim	fi
136317017Sdim	_args=
137317017Sdim
138317017Sdim	for _arg in $_tmpargs; do
139317017Sdim		case $_arg in
140317017Sdim		[Dd][Hh][Cc][Pp])
141317017Sdim			;;
142317017Sdim		[Ww][Pp][Aa])
143317017Sdim			;;
144317017Sdim		*)
145317017Sdim			_args="$_args $_arg"
146317017Sdim			;;
147317017Sdim		esac
148317017Sdim	done
149317017Sdim
150317017Sdim	echo $_args
151327952Sdim}
152327952Sdim
153317017Sdim# dhcpif if
154327952Sdim#	Returns 0 if the interface is a DHCP interface and 1 otherwise.
155327952Sdimdhcpif()
156317017Sdim{
157317017Sdim	_tmpargs=`_ifconfig_getargs $1`
158317017Sdim	for _arg in $_tmpargs; do
159317017Sdim		case $_arg in
160317017Sdim		[Dd][Hh][Cc][Pp])
161317017Sdim			return 0
162319799Sdim			;;
163319799Sdim		esac
164327952Sdim	done
165327952Sdim	return 1
166327952Sdim}
167327952Sdim
168317017Sdim# wpaif if
169317017Sdim#	Returns 0 if the interface is a WPA interface and 1 otherwise.
170317017Sdimwpaif()
171317017Sdim{
172317017Sdim	_tmpargs=`_ifconfig_getargs $1`
173317017Sdim	for _arg in $_tmpargs; do
174317017Sdim		case $_arg in
175317017Sdim		[Ww][Pp][Aa])
176327952Sdim			return 0
177317017Sdim			;;
178317017Sdim		esac
179327952Sdim	done
180317017Sdim	return 1
181327952Sdim}
182327952Sdim
183317017Sdim# ifalias_up if
184317017Sdim#	Configure aliases for network interface $if.
185317017Sdim#	It returns 0 if at least one alias was configured or
186327952Sdim#	1 if there were none.
187327952Sdim#
188327952Sdimifalias_up()
189327952Sdim{
190317017Sdim	_ret=1
191317017Sdim	alias=0
192327952Sdim	while : ; do
193327952Sdim		eval ifconfig_args=\$ifconfig_$1_alias${alias}
194327952Sdim		if [ -n "${ifconfig_args}" ]; then
195317017Sdim			ifconfig $1 ${ifconfig_args} alias
196327952Sdim			alias=$((${alias} + 1))
197327952Sdim			_ret=0
198327952Sdim		else
199327952Sdim			break
200327952Sdim		fi
201327952Sdim	done
202327952Sdim	return $_ret
203327952Sdim}
204327952Sdim
205327952Sdim#ifalias_down if
206327952Sdim#	Remove aliases for network interface $if.
207327952Sdim#	It returns 0 if at least one alias was removed or
208327952Sdim#	1 if there were none.
209327952Sdim#
210327952Sdimifalias_down()
211327952Sdim{
212327952Sdim	_ret=1
213317017Sdim	alias=0
214317017Sdim	while : ; do
215317017Sdim		eval ifconfig_args=\$ifconfig_$1_alias${alias}
216317017Sdim		if [ -n "${ifconfig_args}" ]; then
217317017Sdim			ifconfig $1 ${ifconfig_args} -alias
218317017Sdim			alias=$((${alias} + 1))
219317017Sdim			_ret=0
220317017Sdim		else
221317017Sdim			break
222317017Sdim		fi
223317017Sdim	done
224327952Sdim	return $_ret
225341825Sdim}
226317017Sdim
227317017Sdim# ifscript_up if
228317017Sdim#	Evaluate a startup script for the $if interface.
229317017Sdim#	It returns 0 if a script was found and processed or
230317017Sdim#	1 if no script was found.
231317017Sdim#
232317017Sdimifscript_up()
233317017Sdim{
234317017Sdim	if [ -r /etc/start_if.$1 ]; then
235317017Sdim		. /etc/start_if.$1
236317017Sdim		return 0
237317017Sdim	fi
238317017Sdim	return 1
239317017Sdim}
240317017Sdim
241317017Sdim# ifscript_down if
242317017Sdim#	Evaluate a shutdown script for the $if interface.
243317017Sdim#	It returns 0 if a script was found and processed or
244317017Sdim#	1 if no script was found.
245317017Sdim#
246317017Sdimifscript_down()
247327952Sdim{
248327952Sdim	if [ -r /etc/stop_if.$1 ]; then
249327952Sdim		. /etc/stop_if.$1
250327952Sdim		return 0
251327952Sdim	fi
252327952Sdim	return 1
253317017Sdim}
254317017Sdim
255327952Sdim# Create cloneable interfaces.
256327952Sdim#
257327952Sdimclone_up()
258327952Sdim{
259327952Sdim	_prefix=
260327952Sdim	_list=
261327952Sdim	for ifn in ${cloned_interfaces}; do
262327952Sdim		ifconfig ${ifn} create
263327952Sdim		if [ $? -eq 0 ]; then
264327952Sdim			_list="${_list}${_prefix}${ifn}"
265327952Sdim			[ -z "$_prefix" ] && _prefix=' '
266327952Sdim		fi
267327952Sdim	done
268327952Sdim	debug "Cloned: ${_list}"
269317017Sdim}
270317017Sdim
271317017Sdim# Destroy cloned interfaces. Destroyed interfaces are echoed
272317017Sdim# to standard output.
273317017Sdim#
274317017Sdimclone_down()
275317017Sdim{
276317017Sdim	_prefix=
277317017Sdim	_list=
278317017Sdim	for ifn in ${cloned_interfaces}; do
279317017Sdim		ifconfig ${ifn} destroy
280317017Sdim		if [ $? -eq 0 ]; then
281317017Sdim			_list="${_list}${_prefix}${ifn}"
282317017Sdim			[ -z "$_prefix" ] && _prefix=' '
283317017Sdim		fi
284317017Sdim	done
285317017Sdim	debug "Destroyed clones: ${_list}"
286317017Sdim}
287317017Sdim
288317017Sdimgif_up() {
289317017Sdim	case ${gif_interfaces} in
290327952Sdim	[Nn][Oo] | '')
291327952Sdim		;;
292327952Sdim	*)
293327952Sdim		for i in ${gif_interfaces}; do
294320397Sdim			eval peers=\$gifconfig_$i
295327952Sdim			case ${peers} in
296327952Sdim			'')
297327952Sdim				continue
298327952Sdim				;;
299327952Sdim			*)
300317017Sdim				ifconfig $i create >/dev/null 2>&1
301327952Sdim				ifconfig $i tunnel ${peers}
302327952Sdim				ifconfig $i up
303327952Sdim				;;
304327952Sdim			esac
305327952Sdim		done
306327952Sdim		;;
307327952Sdim	esac
308317017Sdim}
309327952Sdim
310327952Sdim#
311317017Sdim# ipx_up ifn
312327952Sdim# Configure any IPX addresses for interface $ifn. Returns 0 if IPX
313327952Sdim# arguments were found and configured; returns 1 otherwise.
314327952Sdim#
315327952Sdimipx_up()
316327952Sdim{
317327952Sdim	ifn="$1"
318327952Sdim	eval ifconfig_args=\$ifconfig_${ifn}_ipx
319327952Sdim	if [ -n "${ifconfig_args}" ]; then
320327952Sdim		ifconfig ${ifn} ${ifconfig_args}
321327952Sdim		return 0
322327952Sdim	fi
323327952Sdim	return 1
324327952Sdim}
325327952Sdim
326327952Sdim# ipx_down ifn
327327952Sdim#	Remove IPX addresses for interface $ifn. Returns 0 if IPX
328317017Sdim#	addresses were found and unconfigured. It returns 1, otherwise.
329317017Sdim#
330319799Sdimipx_down()
331319799Sdim{
332317017Sdim	[ -z "$1" ] && return 1
333319799Sdim	_ifs="^"
334319799Sdim	_ret=1
335319799Sdim
336319799Sdim	ipxList="`ifconfig $1 | grep 'ipx ' | tr "\n" "$_ifs"`"
337319799Sdim
338319799Sdim	oldifs="$IFS"
339319799Sdim	IFS="$_ifs"
340319799Sdim	for _ipx in $ipxList ; do
341319799Sdim		# get rid of extraneous line
342319799Sdim		[ -z "$_ipx" ] && break
343317017Sdim
344317017Sdim		_ipx=`expr "$_ipx" : '.*\(ipx [0-9a-h]\{1,8\}H*\.[0-9a-h]\{1,12\}\).*'`
345317017Sdim
346353358Sdim		IFS="$oldifs"
347353358Sdim		ifconfig $1 ${_ipx} delete
348317017Sdim		IFS="$_ifs"
349317017Sdim		_ret=0
350317017Sdim	done
351317017Sdim	IFS="$oldifs"
352317017Sdim
353317017Sdim	return $_ret
354317017Sdim}
355317017Sdim
356317017Sdim# ifnet_rename
357317017Sdim#	Rename all requested interfaces.
358327952Sdim#
359327952Sdimifnet_rename()
360327952Sdim{
361317017Sdim
362327952Sdim	_ifn_list="`ifconfig -l`"
363317017Sdim	[ -z "$_ifn_list" ] && return 0
364317017Sdim	for _if in ${_ifn_list} ; do
365317017Sdim		eval _ifname=\$ifconfig_${_if}_name
366317017Sdim		if [ ! -z "$_ifname" ]; then
367317017Sdim			ifconfig $_if name $_ifname
368341825Sdim		fi
369317017Sdim	done
370317017Sdim	return 0
371317017Sdim}
372317017Sdim
373319250Sdim#
374317017Sdim# list_net_interfaces type
375341825Sdim#	List all network interfaces. The type of interface returned
376317017Sdim#	can be controlled by the type argument. The type
377317017Sdim#	argument can be any of the following:
378317017Sdim#		nodhcp - all interfaces, excluding DHCP configured interfaces
379317017Sdim#		dhcp   - list only DHCP configured interfaces
380341825Sdim#	If no argument is specified all network interfaces are output.
381341825Sdim#	Note that the list will include cloned interfaces if applicable.
382341825Sdim#	Cloned interfaces must already exist to have a chance to appear
383341825Sdim#	in the list if ${network_interfaces} is set to `auto'.
384341825Sdim#
385341825Sdimlist_net_interfaces()
386341825Sdim{
387341825Sdim	type=$1
388341825Sdim
389341825Sdim	# Get a list of ALL the interfaces
390341825Sdim	#
391341825Sdim	case ${network_interfaces} in
392341825Sdim	[Aa][Uu][Tt][Oo])
393341825Sdim		_tmplist="`ifconfig -l`"
394341825Sdim		;;
395341825Sdim	*)
396341825Sdim		_tmplist="${network_interfaces} ${cloned_interfaces}"
397341825Sdim		;;
398341825Sdim	esac
399341825Sdim
400341825Sdim	if [ -z "$type" ]; then
401341825Sdim		echo $_tmplist
402341825Sdim		return 0
403341825Sdim	fi
404341825Sdim
405341825Sdim	# Separate out dhcp and non-dhcp interfaces
406341825Sdim	#
407341825Sdim	_aprefix=
408341825Sdim	_bprefix=
409341825Sdim	for _if in ${_tmplist} ; do
410341825Sdim		eval _ifarg="\$ifconfig_${_if}"
411341825Sdim		case "$_ifarg" in
412341825Sdim		[Dd][Hh][Cc][Pp])
413341825Sdim			_dhcplist="${_dhcplist}${_aprefix}${_if}"
414341825Sdim			[ -z "$_aprefix" ] && _aprefix=' '
415317017Sdim			;;
416317017Sdim		''|*)
417353358Sdim			_nodhcplist="${_nodhcplist}${_bprefix}${_if}"
418353358Sdim			[ -z "$_bprefix" ] && _bprefix=' '
419353358Sdim			;;
420317017Sdim		esac
421327952Sdim	done
422317017Sdim
423317017Sdim	case ${pccard_ifconfig} in
424317017Sdim	[Dd][Hh][Cc][Pp])
425317017Sdim		for _if in ${removable_interfaces} ; do
426317017Sdim			_test_if=`ifconfig ${_if} 2>&1`
427341825Sdim			case "$_test_if" in
428341825Sdim			"ifconfig: interface $_if does not exist")
429317017Sdim				;;
430317017Sdim			*)
431341825Sdim				_dhcplist="${_dhcplist}${_aprefix}${_if}"
432341825Sdim				[ -z "$_aprefix" ] && _aprefix=' '
433341825Sdim				;;
434341825Sdim			esac
435317017Sdim		done
436317017Sdim		;;
437317017Sdim	*)
438317017Sdim		;;
439317017Sdim	esac
440317017Sdim
441317017Sdim	case "$type" in
442317017Sdim	nodhcp)
443317017Sdim		echo $_nodhcplist
444317017Sdim		;;
445327952Sdim	dhcp)
446327952Sdim		echo $_dhcplist
447327952Sdim		;;
448317017Sdim	esac
449327952Sdim	return 0
450327952Sdim}
451327952Sdim
452317017Sdimhexdigit()
453317017Sdim{
454317017Sdim	if [ $1 -lt 10 ]; then
455327952Sdim		echo $1
456317017Sdim	else
457317017Sdim		case $1 in
458317017Sdim		10)	echo a ;;
459317017Sdim		11)	echo b ;;
460317017Sdim		12)	echo c ;;
461353358Sdim		13)	echo d ;;
462353358Sdim		14)	echo e ;;
463353358Sdim		15)	echo f ;;
464317017Sdim		esac
465317017Sdim	fi
466317017Sdim}
467317017Sdim
468317017Sdimhexprint()
469317017Sdim{
470317017Sdim	val=$1
471317017Sdim	str=''
472317017Sdim
473317017Sdim	dig=`hexdigit $((${val} & 15))`
474317017Sdim	str=${dig}${str}
475317017Sdim	val=$((${val} >> 4))
476317017Sdim	while [ ${val} -gt 0 ]; do
477317017Sdim		dig=`hexdigit $((${val} & 15))`
478317017Sdim		str=${dig}${str}
479317017Sdim		val=$((${val} >> 4))
480317017Sdim	done
481317017Sdim
482317017Sdim	echo ${str}
483317017Sdim}
484317017Sdim
485317017Sdim# Setup the interfaces for IPv6
486317017Sdimnetwork6_interface_setup()
487317017Sdim{
488327952Sdim	interfaces=$*
489327952Sdim	rtsol_interfaces=''
490327952Sdim	case ${ipv6_gateway_enable} in
491327952Sdim	[Yy][Ee][Ss])
492327952Sdim		rtsol_available=no
493327952Sdim		;;
494327952Sdim	*)
495327952Sdim		rtsol_available=yes
496327952Sdim		;;
497327952Sdim	esac
498327952Sdim	for i in $interfaces; do
499327952Sdim		rtsol_interface=yes
500327952Sdim		eval prefix=\$ipv6_prefix_$i
501327952Sdim		if [ -n "${prefix}" ]; then
502327952Sdim			rtsol_available=no
503327952Sdim			rtsol_interface=no
504327952Sdim			laddr=`network6_getladdr $i`
505327952Sdim			hostid=`expr "${laddr}" : 'fe80::\(.*\)%\(.*\)'`
506327952Sdim			for j in ${prefix}; do
507327952Sdim				address=$j\:${hostid}
508327952Sdim				ifconfig $i inet6 ${address} prefixlen 64 alias
509327952Sdim
510327952Sdim				case ${ipv6_gateway_enable} in
511327952Sdim				[Yy][Ee][Ss])
512327952Sdim					# subnet-router anycast address
513327952Sdim					# (rfc2373)
514327952Sdim					ifconfig $i inet6 $j:: prefixlen 64 \
515327952Sdim						alias anycast
516327952Sdim					;;
517327952Sdim				esac
518317017Sdim			done
519317017Sdim		fi
520317017Sdim		eval ipv6_ifconfig=\$ipv6_ifconfig_$i
521317017Sdim		if [ -n "${ipv6_ifconfig}" ]; then
522317017Sdim			rtsol_available=no
523317017Sdim			rtsol_interface=no
524327952Sdim			ifconfig $i inet6 ${ipv6_ifconfig} alias
525317017Sdim		fi
526317017Sdim
527317017Sdim		if [ ${rtsol_available} = yes -a ${rtsol_interface} = yes ]
528317017Sdim		then
529317017Sdim			case ${i} in
530317017Sdim			lo0|gif[0-9]*|stf[0-9]*|faith[0-9]*|lp[0-9]*|sl[0-9]*|tun[0-9]*)
531317017Sdim				;;
532317017Sdim			*)
533317017Sdim				rtsol_interfaces="${rtsol_interfaces} ${i}"
534317017Sdim				;;
535317017Sdim			esac
536317017Sdim		else
537317017Sdim			ifconfig $i inet6
538317017Sdim		fi
539317017Sdim	done
540317017Sdim
541317017Sdim	if [ ${rtsol_available} = yes -a -n "${rtsol_interfaces}" ]; then
542317017Sdim		# Act as endhost - automatically configured.
543317017Sdim		# You can configure only single interface, as
544317017Sdim		# specification assumes that autoconfigured host has
545327952Sdim		# single interface only.
546327952Sdim		sysctl net.inet6.ip6.accept_rtadv=1
547327952Sdim		set ${rtsol_interfaces}
548327952Sdim		ifconfig $1 up
549327952Sdim		rtsol ${rtsol_flags} $1
550327952Sdim	fi
551327952Sdim
552327952Sdim	for i in $interfaces; do
553327952Sdim		alias=0
554327952Sdim		while : ; do
555327952Sdim			eval ipv6_ifconfig=\$ipv6_ifconfig_${i}_alias${alias}
556327952Sdim			if [ -z "${ipv6_ifconfig}" ]; then
557317017Sdim				break;
558327952Sdim			fi
559327952Sdim			ifconfig $i inet6 ${ipv6_ifconfig} alias
560317017Sdim			alias=$((${alias} + 1))
561327952Sdim		done
562327952Sdim	done
563327952Sdim}
564327952Sdim
565327952Sdim# Setup IPv6 to IPv4 mapping
566327952Sdimnetwork6_stf_setup()
567317017Sdim{
568327952Sdim	case ${stf_interface_ipv4addr} in
569327952Sdim	[Nn][Oo] | '')
570317017Sdim		;;
571327952Sdim	*)
572327952Sdim		# assign IPv6 addr and interface route for 6to4 interface
573360784Sdim		stf_prefixlen=$((16+${stf_interface_ipv4plen:-0}))
574360784Sdim		OIFS="$IFS"
575327952Sdim		IFS=".$IFS"
576317017Sdim		set ${stf_interface_ipv4addr}
577327952Sdim		IFS="$OIFS"
578327952Sdim		hexfrag1=`hexprint $(($1*256 + $2))`
579360784Sdim		hexfrag2=`hexprint $(($3*256 + $4))`
580327952Sdim		ipv4_in_hexformat="${hexfrag1}:${hexfrag2}"
581327952Sdim		case ${stf_interface_ipv6_ifid} in
582360784Sdim		[Aa][Uu][Tt][Oo] | '')
583327952Sdim			for i in ${ipv6_network_interfaces}; do
584327952Sdim				laddr=`network6_getladdr ${i}`
585327952Sdim				case ${laddr} in
586327952Sdim				'')
587327952Sdim					;;
588327952Sdim				*)
589317017Sdim					break
590327952Sdim					;;
591327952Sdim				esac
592327952Sdim			done
593327952Sdim			stf_interface_ipv6_ifid=`expr "${laddr}" : \
594327952Sdim						      'fe80::\(.*\)%\(.*\)'`
595327952Sdim			case ${stf_interface_ipv6_ifid} in
596327952Sdim			'')
597327952Sdim				stf_interface_ipv6_ifid=0:0:0:1
598317017Sdim				;;
599327952Sdim			esac
600327952Sdim			;;
601317017Sdim		esac
602327952Sdim		ifconfig stf0 create >/dev/null 2>&1
603327952Sdim		ifconfig stf0 inet6 2002:${ipv4_in_hexformat}:${stf_interface_ipv6_slaid:-0}:${stf_interface_ipv6_ifid} \
604327952Sdim			prefixlen ${stf_prefixlen}
605327952Sdim		# disallow packets to malicious 6to4 prefix
606327952Sdim		route add -inet6 2002:e000:: -prefixlen 20 ::1 -reject
607327952Sdim		route add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject
608317017Sdim		route add -inet6 2002:0000:: -prefixlen 24 ::1 -reject
609327952Sdim		route add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject
610327952Sdim		;;
611317017Sdim	esac
612360784Sdim}
613360784Sdim
614327952Sdim# Setup static routes
615317017Sdimnetwork6_static_routes_setup()
616327952Sdim{
617327952Sdim	# Set up any static routes.
618360784Sdim	case ${ipv6_defaultrouter} in
619327952Sdim	[Nn][Oo] | '')
620360784Sdim		;;
621327952Sdim	*)
622327952Sdim		ipv6_static_routes="default ${ipv6_static_routes}"
623327952Sdim		ipv6_route_default="default ${ipv6_defaultrouter}"
624327952Sdim		;;
625327952Sdim	esac
626327952Sdim	case ${ipv6_static_routes} in
627317017Sdim	[Nn][Oo] | '')
628327952Sdim		;;
629327952Sdim	*)
630327952Sdim		for i in ${ipv6_static_routes}; do
631327952Sdim			eval ipv6_route_args=\$ipv6_route_${i}
632327952Sdim			route add -inet6 ${ipv6_route_args}
633317017Sdim		done
634327952Sdim		;;
635327952Sdim	esac
636327952Sdim}
637327952Sdim
638327952Sdim# Setup faith
639327952Sdimnetwork6_faith_setup()
640327952Sdim{
641327952Sdim	case ${ipv6_faith_prefix} in
642327952Sdim	[Nn][Oo] | '')
643317017Sdim		;;
644327952Sdim	*)
645327952Sdim		sysctl net.inet6.ip6.keepfaith=1
646327952Sdim		ifconfig faith0 create >/dev/null 2>&1
647327952Sdim		ifconfig faith0 up
648317017Sdim		for prefix in ${ipv6_faith_prefix}; do
649327952Sdim			prefixlen=`expr "${prefix}" : ".*/\(.*\)"`
650327952Sdim			case ${prefixlen} in
651327952Sdim			'')
652327952Sdim				prefixlen=96
653317017Sdim				;;
654327952Sdim			*)
655317017Sdim				prefix=`expr "${prefix}" : \
656327952Sdim					     "\(.*\)/${prefixlen}"`
657327952Sdim				;;
658327952Sdim			esac
659327952Sdim			route add -inet6 ${prefix} -prefixlen ${prefixlen} ::1
660327952Sdim			route change -inet6 ${prefix} -prefixlen ${prefixlen} \
661327952Sdim				-ifp faith0
662327952Sdim		done
663327952Sdim		;;
664327952Sdim	esac
665327952Sdim}
666327952Sdim
667327952Sdim# Install the "default interface" to kernel, which will be used
668327952Sdim# as the default route when there's no router.
669327952Sdimnetwork6_default_interface_setup()
670327952Sdim{
671327952Sdim	# Choose IPv6 default interface if it is not clearly specified.
672317017Sdim	case ${ipv6_default_interface} in
673327952Sdim	'')
674327952Sdim		for i in ${ipv6_network_interfaces}; do
675320397Sdim			case $i in
676360784Sdim			lo0|faith[0-9]*)
677360784Sdim				continue
678327952Sdim				;;
679317017Sdim			esac
680360784Sdim			laddr=`network6_getladdr $i exclude_tentative`
681327952Sdim			case ${laddr} in
682327952Sdim			'')
683327952Sdim				;;
684327952Sdim			*)
685327952Sdim				ipv6_default_interface=$i
686327952Sdim				break
687327952Sdim				;;
688327952Sdim			esac
689327952Sdim		done
690327952Sdim		;;
691327952Sdim	esac
692327952Sdim
693327952Sdim	# Disallow unicast packets without outgoing scope identifiers,
694327952Sdim	# or route such packets to a "default" interface, if it is specified.
695327952Sdim	route add -inet6 fe80:: -prefixlen 10 ::1 -reject
696327952Sdim	case ${ipv6_default_interface} in
697327952Sdim	[Nn][Oo] | '')
698327952Sdim		route add -inet6 ff02:: -prefixlen 16 ::1 -reject
699327952Sdim		;;
700327952Sdim	*)
701327952Sdim		laddr=`network6_getladdr ${ipv6_default_interface}`
702327952Sdim		route add -inet6 ff02:: ${laddr} -prefixlen 16 -interface \
703327952Sdim			-cloning
704327952Sdim
705360784Sdim		# Disable installing the default interface with the
706360784Sdim		# case net.inet6.ip6.forwarding=0 and
707327952Sdim		# net.inet6.ip6.accept_rtadv=0, due to avoid conflict
708327952Sdim		# between the default router list and the manual
709360784Sdim		# configured default route.
710327952Sdim		case ${ipv6_gateway_enable} in
711327952Sdim		[Yy][Ee][Ss])
712327952Sdim			;;
713327952Sdim		*)
714327952Sdim			if [ `sysctl -n net.inet6.ip6.accept_rtadv` -eq 1 ]
715327952Sdim			then
716327952Sdim				ndp -I ${ipv6_default_interface}
717327952Sdim			fi
718327952Sdim			;;
719327952Sdim		esac
720327952Sdim		;;
721327952Sdim	esac
722327952Sdim}
723327952Sdim
724327952Sdimnetwork6_getladdr()
725327952Sdim{
726327952Sdim	ifconfig $1 2>/dev/null | while read proto addr rest; do
727327952Sdim		case ${proto} in
728327952Sdim		inet6)
729327952Sdim			case ${addr} in
730327952Sdim			fe80::*)
731327952Sdim				if [ -z "$2" ]; then
732327952Sdim					echo ${addr}
733327952Sdim					return
734327952Sdim				fi
735327952Sdim				case ${rest} in
736327952Sdim				*tentative*)
737327952Sdim					continue
738327952Sdim					;;
739327952Sdim				*)
740327952Sdim					echo ${addr}
741327952Sdim					return
742327952Sdim				esac
743327952Sdim			esac
744327952Sdim		esac
745327952Sdim	done
746327952Sdim}
747327952Sdim