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