network.subr revision 252015
1# 2# Copyright (c) 2003 The FreeBSD Project. All rights reserved. 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions 6# are met: 7# 1. Redistributions of source code must retain the above copyright 8# notice, this list of conditions and the following disclaimer. 9# 2. Redistributions in binary form must reproduce the above copyright 10# notice, this list of conditions and the following disclaimer in the 11# documentation and/or other materials provided with the distribution. 12# 13# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 14# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16# ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 17# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23# SUCH DAMAGE. 24# 25# $FreeBSD: head/etc/network.subr 252015 2013-06-20 02:29:49Z hrs $ 26# 27IFCONFIG_CMD="/sbin/ifconfig" 28 29# Maximum number of addresses expanded from a address range specification. 30_IPEXPANDMAX=31 31 32# 33# Subroutines commonly used from network startup scripts. 34# Requires that rc.conf be loaded first. 35# 36 37# ifn_start ifn 38# Bring up and configure an interface. If some configuration is 39# applied, print the interface configuration. 40# 41ifn_start() 42{ 43 local ifn cfg 44 ifn="$1" 45 cfg=1 46 47 [ -z "$ifn" ] && err 1 "ifn_start called without an interface" 48 49 ifscript_up ${ifn} && cfg=0 50 ifconfig_up ${ifn} && cfg=0 51 afexists inet && ipv4_up ${ifn} && cfg=0 52 afexists inet6 && ipv6_up ${ifn} && cfg=0 53 afexists ipx && ipx_up ${ifn} && cfg=0 54 childif_create ${ifn} && cfg=0 55 56 return $cfg 57} 58 59# ifn_stop ifn 60# Shutdown and de-configure an interface. If action is taken, 61# print the interface name. 62# 63ifn_stop() 64{ 65 local ifn cfg 66 ifn="$1" 67 cfg=1 68 69 [ -z "$ifn" ] && err 1 "ifn_stop called without an interface" 70 71 afexists ipx && ipx_down ${ifn} && cfg=0 72 afexists inet6 && ipv6_down ${ifn} && cfg=0 73 afexists inet && ipv4_down ${ifn} && cfg=0 74 ifconfig_down ${ifn} && cfg=0 75 ifscript_down ${ifn} && cfg=0 76 childif_destroy ${ifn} && cfg=0 77 78 return $cfg 79} 80 81# ifconfig_up if 82# Evaluate ifconfig(8) arguments for interface $if and 83# run ifconfig(8) with those arguments. It returns 0 if 84# arguments were found and executed or 1 if the interface 85# had no arguments. Pseudo arguments DHCP and WPA are handled 86# here. 87# 88ifconfig_up() 89{ 90 local _cfg _ipv6_opts ifconfig_args 91 _cfg=1 92 93 # Make sure lo0 always comes up. 94 if [ "$1" = "lo0" ]; then 95 _cfg=0 96 fi 97 98 # ifconfig_IF 99 ifconfig_args=`ifconfig_getargs $1` 100 if [ -n "${ifconfig_args}" ]; then 101 eval ${IFCONFIG_CMD} $1 ${ifconfig_args} 102 _cfg=0 103 fi 104 105 # inet6 specific 106 if afexists inet6; then 107 if checkyesno ipv6_activate_all_interfaces; then 108 _ipv6_opts="-ifdisabled" 109 elif [ "$1" != "lo0" ]; then 110 _ipv6_opts="ifdisabled" 111 fi 112 113 # backward compatibility: $ipv6_enable 114 case $ipv6_enable in 115 [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 116 if ! checkyesno ipv6_gateway_enable; then 117 _ipv6_opts="${_ipv6_opts} accept_rtadv" 118 fi 119 ;; 120 esac 121 122 case $ipv6_cpe_wanif in 123 $1) 124 _ipv6_opts="${_ipv6_opts} -no_radr accept_rtadv" 125 ;; 126 esac 127 128 if [ -n "${_ipv6_opts}" ]; then 129 ${IFCONFIG_CMD} $1 inet6 ${_ipv6_opts} 130 fi 131 132 # ifconfig_IF_ipv6 133 ifconfig_args=`ifconfig_getargs $1 ipv6` 134 if [ -n "${ifconfig_args}" ]; then 135 # backward compatibility: inet6 keyword 136 case "${ifconfig_args}" in 137 :*|[0-9a-fA-F]*:*) 138 warn "\$ifconfig_$1_ipv6 needs " \ 139 "\"inet6\" keyword for an IPv6 address." 140 ifconfig_args="inet6 ${ifconfig_args}" 141 ;; 142 esac 143 ${IFCONFIG_CMD} $1 inet6 -ifdisabled 144 eval ${IFCONFIG_CMD} $1 ${ifconfig_args} 145 _cfg=0 146 fi 147 148 # $ipv6_prefix_IF will be handled in 149 # ipv6_prefix_hostid_addr_common(). 150 ifconfig_args=`get_if_var $1 ipv6_prefix_IF` 151 if [ -n "${ifconfig_args}" ]; then 152 ${IFCONFIG_CMD} $1 inet6 -ifdisabled 153 _cfg=0 154 fi 155 156 # backward compatibility: $ipv6_ifconfig_IF 157 ifconfig_args=`get_if_var $1 ipv6_ifconfig_IF` 158 if [ -n "${ifconfig_args}" ]; then 159 warn "\$ipv6_ifconfig_$1 is obsolete." \ 160 " Use ifconfig_$1_ipv6 instead." 161 ${IFCONFIG_CMD} $1 inet6 -ifdisabled 162 eval ${IFCONFIG_CMD} $1 inet6 ${ifconfig_args} 163 _cfg=0 164 fi 165 fi 166 167 if [ ${_cfg} -eq 0 ]; then 168 ${IFCONFIG_CMD} $1 up 169 fi 170 171 if wpaif $1; then 172 /etc/rc.d/wpa_supplicant start $1 173 _cfg=0 # XXX: not sure this should count 174 fi 175 176 if dhcpif $1; then 177 if [ $_cfg -ne 0 ] ; then 178 ${IFCONFIG_CMD} $1 up 179 fi 180 if syncdhcpif $1; then 181 /etc/rc.d/dhclient start $1 182 fi 183 _cfg=0 184 fi 185 186 return $_cfg 187} 188 189# ifconfig_down if 190# returns 1 if wpa_supplicant or dhclient was stopped or 191# the interface exists. 192# 193ifconfig_down() 194{ 195 local _cfg 196 _cfg=1 197 198 if wpaif $1; then 199 /etc/rc.d/wpa_supplicant stop $1 200 _cfg=0 201 fi 202 203 if dhcpif $1; then 204 /etc/rc.d/dhclient stop $1 205 _cfg=0 206 fi 207 208 if ifexists $1; then 209 ${IFCONFIG_CMD} $1 down 210 _cfg=0 211 fi 212 213 return $_cfg 214} 215 216# get_if_var if var [default] 217# Return the value of the pseudo-hash corresponding to $if where 218# $var is a string containg the sub-string "IF" which will be 219# replaced with $if after the characters defined in _punct are 220# replaced with '_'. If the variable is unset, replace it with 221# $default if given. 222get_if_var() 223{ 224 local _if _punct _punct_c _var _default prefix suffix 225 226 if [ $# -ne 2 -a $# -ne 3 ]; then 227 err 3 'USAGE: get_if_var name var [default]' 228 fi 229 230 _if=$1 231 _punct=". - / +" 232 for _punct_c in $_punct; do 233 _if=`ltr ${_if} ${_punct_c} '_'` 234 done 235 _var=$2 236 _default=$3 237 238 prefix=${_var%%IF*} 239 suffix=${_var##*IF} 240 eval echo \${${prefix}${_if}${suffix}-${_default}} 241} 242 243# _ifconfig_getargs if [af] 244# Prints the arguments for the supplied interface to stdout. 245# Returns 1 if empty. In general, ifconfig_getargs should be used 246# outside this file. 247_ifconfig_getargs() 248{ 249 local _ifn _af 250 _ifn=$1 251 _af=${2+_$2} 252 253 if [ -z "$_ifn" ]; then 254 return 1 255 fi 256 257 get_if_var $_ifn ifconfig_IF$_af "$ifconfig_DEFAULT" 258} 259 260# ifconfig_getargs if [af] 261# Takes the result from _ifconfig_getargs and removes pseudo 262# args such as DHCP and WPA. 263ifconfig_getargs() 264{ 265 local _tmpargs _arg _args 266 _tmpargs=`_ifconfig_getargs $1 $2` 267 if [ $? -eq 1 ]; then 268 return 1 269 fi 270 _args= 271 272 for _arg in $_tmpargs; do 273 case $_arg in 274 [Dd][Hh][Cc][Pp]) ;; 275 [Nn][Oo][Aa][Uu][Tt][Oo]) ;; 276 [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) ;; 277 [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) ;; 278 [Ww][Pp][Aa]) ;; 279 *) 280 _args="$_args $_arg" 281 ;; 282 esac 283 done 284 285 echo $_args 286} 287 288# autoif 289# Returns 0 if the interface should be automatically configured at 290# boot time and 1 otherwise. 291autoif() 292{ 293 local _tmpargs _arg 294 _tmpargs=`_ifconfig_getargs $1` 295 296 for _arg in $_tmpargs; do 297 case $_arg in 298 [Nn][Oo][Aa][Uu][Tt][Oo]) 299 return 1 300 ;; 301 esac 302 done 303 304 return 0 305} 306 307# dhcpif if 308# Returns 0 if the interface is a DHCP interface and 1 otherwise. 309dhcpif() 310{ 311 local _tmpargs _arg 312 _tmpargs=`_ifconfig_getargs $1` 313 314 if noafif $1; then 315 return 1 316 fi 317 318 for _arg in $_tmpargs; do 319 case $_arg in 320 [Dd][Hh][Cc][Pp]) 321 return 0 322 ;; 323 [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 324 return 0 325 ;; 326 [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 327 return 0 328 ;; 329 esac 330 done 331 332 return 1 333} 334 335# syncdhcpif 336# Returns 0 if the interface should be configured synchronously and 337# 1 otherwise. 338syncdhcpif() 339{ 340 local _tmpargs _arg 341 _tmpargs=`_ifconfig_getargs $1` 342 343 if noafif $1; then 344 return 1 345 fi 346 347 for _arg in $_tmpargs; do 348 case $_arg in 349 [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 350 return 1 351 ;; 352 [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 353 return 0 354 ;; 355 esac 356 done 357 358 checkyesno synchronous_dhclient 359} 360 361# wpaif if 362# Returns 0 if the interface is a WPA interface and 1 otherwise. 363wpaif() 364{ 365 local _tmpargs _arg 366 _tmpargs=`_ifconfig_getargs $1` 367 368 for _arg in $_tmpargs; do 369 case $_arg in 370 [Ww][Pp][Aa]) 371 return 0 372 ;; 373 esac 374 done 375 376 return 1 377} 378 379# afexists af 380# Returns 0 if the address family is enabled in the kernel 381# 1 otherwise. 382afexists() 383{ 384 local _af 385 _af=$1 386 387 case ${_af} in 388 inet|inet6) 389 check_kern_features ${_af} 390 ;; 391 ipx) 392 ${SYSCTL_N} net.ipx > /dev/null 2>&1 393 ;; 394 atm) 395 if [ -x /sbin/atmconfig ]; then 396 /sbin/atmconfig diag list > /dev/null 2>&1 397 else 398 return 1 399 fi 400 ;; 401 *) 402 err 1 "afexists(): Unsupported address family: $_af" 403 ;; 404 esac 405} 406 407# noafif if 408# Returns 0 if the interface has no af configuration and 1 otherwise. 409noafif() 410{ 411 local _if 412 _if=$1 413 414 case $_if in 415 pflog[0-9]*|\ 416 pfsync[0-9]*|\ 417 an[0-9]*|\ 418 ath[0-9]*|\ 419 ipw[0-9]*|\ 420 ipfw[0-9]*|\ 421 iwi[0-9]*|\ 422 iwn[0-9]*|\ 423 ral[0-9]*|\ 424 wi[0-9]*|\ 425 wl[0-9]*|\ 426 wpi[0-9]*) 427 return 0 428 ;; 429 esac 430 431 return 1 432} 433 434# ipv6if if 435# Returns 0 if the interface should be configured for IPv6 and 436# 1 otherwise. 437ipv6if() 438{ 439 local _if _tmpargs i 440 _if=$1 441 442 if ! afexists inet6; then 443 return 1 444 fi 445 446 # lo0 is always IPv6-enabled 447 case $_if in 448 lo0) 449 return 0 450 ;; 451 esac 452 453 case "${ipv6_network_interfaces}" in 454 $_if|"$_if "*|*" $_if"|*" $_if "*|[Aa][Uu][Tt][Oo]) 455 # True if $ifconfig_IF_ipv6 is defined. 456 _tmpargs=`_ifconfig_getargs $_if ipv6` 457 if [ -n "${_tmpargs}" ]; then 458 return 0 459 fi 460 461 # True if $ipv6_prefix_IF is defined. 462 _tmpargs=`get_if_var $_if ipv6_prefix_IF` 463 if [ -n "${_tmpargs}" ]; then 464 return 0 465 fi 466 467 # backward compatibility: True if $ipv6_ifconfig_IF is defined. 468 _tmpargs=`get_if_var $_if ipv6_ifconfig_IF` 469 if [ -n "${_tmpargs}" ]; then 470 return 0 471 fi 472 ;; 473 esac 474 475 return 1 476} 477 478# ipv6_autoconfif if 479# Returns 0 if the interface should be configured for IPv6 with 480# Stateless Address Configuration; 1 otherwise. 481ipv6_autoconfif() 482{ 483 local _if _tmpargs _arg 484 _if=$1 485 486 case $_if in 487 lo0|\ 488 stf[0-9]*|\ 489 faith[0-9]*|\ 490 lp[0-9]*|\ 491 sl[0-9]*) 492 return 1 493 ;; 494 esac 495 if noafif $_if; then 496 return 1 497 fi 498 if ! ipv6if $_if; then 499 return 1 500 fi 501 if checkyesno ipv6_gateway_enable; then 502 return 1 503 fi 504 _tmpargs=`get_if_var $_if ipv6_prefix_IF` 505 if [ -n "${_tmpargs}" ]; then 506 return 1 507 fi 508 # backward compatibility: $ipv6_enable 509 case $ipv6_enable in 510 [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 511 if checkyesno ipv6_gateway_enable; then 512 return 1 513 else 514 return 0 515 fi 516 ;; 517 esac 518 519 _tmpargs=`_ifconfig_getargs $_if ipv6` 520 for _arg in $_tmpargs; do 521 case $_arg in 522 accept_rtadv) 523 return 0 524 ;; 525 esac 526 done 527 528 # backward compatibility: $ipv6_ifconfig_IF 529 _tmpargs=`get_if_var $_if ipv6_ifconfig_IF` 530 for _arg in $_tmpargs; do 531 case $_arg in 532 accept_rtadv) 533 return 0 534 ;; 535 esac 536 done 537 538 return 1 539} 540 541# ifexists if 542# Returns 0 if the interface exists and 1 otherwise. 543ifexists() 544{ 545 [ -z "$1" ] && return 1 546 ${IFCONFIG_CMD} -n $1 > /dev/null 2>&1 547} 548 549# ipv4_up if 550# add IPv4 addresses to the interface $if 551ipv4_up() 552{ 553 local _if _ret 554 _if=$1 555 _ret=1 556 557 # Add 127.0.0.1/8 to lo0 unless otherwise specified. 558 if [ "${_if}" = "lo0" ]; then 559 ifconfig_args=`get_if_var ${_if} ifconfig_IF` 560 if [ -z "${ifconfig_args}" ]; then 561 ${IFCONFIG_CMD} ${_if} inet 127.0.0.1/8 alias 562 fi 563 fi 564 ifalias ${_if} inet alias && _ret=0 565 566 return $_ret 567} 568 569# ipv6_up if 570# add IPv6 addresses to the interface $if 571ipv6_up() 572{ 573 local _if _ret 574 _if=$1 575 _ret=1 576 577 if ! ipv6if $_if; then 578 return 0 579 fi 580 581 ifalias ${_if} inet6 alias && _ret=0 582 ipv6_prefix_hostid_addr_common ${_if} alias && _ret=0 583 ipv6_accept_rtadv_up ${_if} && _ret=0 584 585 return $_ret 586} 587 588# ipv4_down if 589# remove IPv4 addresses from the interface $if 590ipv4_down() 591{ 592 local _if _ifs _ret inetList oldifs _inet 593 _if=$1 594 _ifs="^" 595 _ret=1 596 597 ifalias ${_if} inet -alias && _ret=0 598 599 inetList="`${IFCONFIG_CMD} ${_if} | grep 'inet ' | tr "\n" "$_ifs"`" 600 601 oldifs="$IFS" 602 IFS="$_ifs" 603 for _inet in $inetList ; do 604 # get rid of extraneous line 605 [ -z "$_inet" ] && break 606 607 _inet=`expr "$_inet" : '.*\(inet \([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*'` 608 609 IFS="$oldifs" 610 ${IFCONFIG_CMD} ${_if} ${_inet} delete 611 IFS="$_ifs" 612 _ret=0 613 done 614 IFS="$oldifs" 615 616 return $_ret 617} 618 619# ipv6_down if 620# remove IPv6 addresses from the interface $if 621ipv6_down() 622{ 623 local _if _ifs _ret inetList oldifs _inet6 624 _if=$1 625 _ifs="^" 626 _ret=1 627 628 if ! ipv6if $_if; then 629 return 0 630 fi 631 632 ipv6_accept_rtadv_down ${_if} && _ret=0 633 ipv6_prefix_hostid_addr_common ${_if} -alias && _ret=0 634 ifalias ${_if} inet6 -alias && _ret=0 635 636 inetList="`${IFCONFIG_CMD} ${_if} | grep 'inet6 ' | tr "\n" "$_ifs"`" 637 638 oldifs="$IFS" 639 IFS="$_ifs" 640 for _inet6 in $inetList ; do 641 # get rid of extraneous line 642 [ -z "$_inet6" ] && break 643 644 _inet6=`expr "$_inet6" : '.*\(inet6 \([0-9a-f:]*\)\).*'` 645 646 IFS="$oldifs" 647 ${IFCONFIG_CMD} ${_if} ${_inet6} -alias 648 IFS="$_ifs" 649 _ret=0 650 done 651 IFS="$oldifs" 652 653 return $_ret 654} 655 656# ifalias if af action 657# Configure or remove aliases for network interface $if. 658# It returns 0 if at least one alias was configured or 659# removed, or 1 if there were none. 660# 661ifalias() 662{ 663 local _ret 664 _ret=1 665 666 afexists $2 || return $_ret 667 668 case "$2" in 669 inet|inet6) 670 ifalias_af_common $1 $2 $3 && _ret=0 671 ;; 672 esac 673 674 return $_ret 675} 676 677# ifalias_expand_addr af action addr 678# Expand address range ("N-M") specification in addr. 679# "addr" must not include an address-family keyword. 680# The results will include an address-family keyword. 681# 682ifalias_expand_addr() 683{ 684 685 afexists $1 || return 686 ifalias_expand_addr_$1 $2 $3 687} 688 689# ifalias_expand_addr_inet action addr 690# Helper function for ifalias_expand_addr(). Handles IPv4. 691# 692ifalias_expand_addr_inet() 693{ 694 local _action _arg _cidr _cidr_addr 695 local _ipaddr _plen _range _iphead _iptail _iplow _iphigh _ipcount 696 local _retstr _c 697 _action=$1 698 _arg=$2 699 _retstr= 700 701 case $_action:$_arg in 702 *:*--*) return ;; # invalid 703 tmp:*) echo $_arg && return ;; # already expanded 704 tmp:*-*) _action="alias" ;; # to be expanded 705 *:*-*) ;; # to be expanded 706 *:*) echo inet $_arg && return ;; # already expanded 707 esac 708 709 for _cidr in $_arg; do 710 _ipaddr=${_cidr%%/*} 711 _plen=${_cidr##*/} 712 # When subnet prefix length is not specified, use /32. 713 case $_plen in 714 $_ipaddr) _plen=32 ;; # "/" character not found 715 esac 716 717 OIFS=$IFS 718 IFS=. set -- $_ipaddr 719 _range= 720 _iphead= 721 _iptail= 722 for _c in $@; do 723 case $_range:$_c in 724 :[0-9]*-[0-9]*) 725 _range=$_c 726 ;; 727 :*) 728 _iphead="${_iphead}${_iphead:+.}${_c}" 729 ;; 730 *:*) 731 _iptail="${_iptail}${_iptail:+.}${_c}" 732 ;; 733 esac 734 done 735 IFS=$OIFS 736 _iplow=${_range%-*} 737 _iphigh=${_range#*-} 738 739 # clear netmask when removing aliases 740 if [ "$_action" = "-alias" ]; then 741 _plen="" 742 fi 743 744 _ipcount=$_iplow 745 while [ "$_ipcount" -le "$_iphigh" ]; do 746 _retstr="${_retstr} ${_iphead}${_iphead:+.}${_ipcount}${_iptail:+.}${_iptail}${_plen:+/}${_plen}" 747 if [ $_ipcount -gt $(($_iplow + $_IPEXPANDMAX)) ]; then 748 warn "Range specification is too large (${_iphead}${_iphead:+.}${_iplow}${_iptail:+.}${_iptail}-${_iphead}${_iphead:+.}${_iphigh}${_iptail:+.}${_iptail}). ${_iphead}${_iphead:+.}${_iplow}${_iptail:+.}${_iptail}-${_iphead}${_iphead:+.}${_ipcount}${_iptail:+.}${_iptail} was processed." 749 break 750 else 751 _ipcount=$(($_ipcount + 1)) 752 fi 753 # Forcibly set /32 for remaining aliases. 754 _plen=32 755 done 756 done 757 758 for _c in $_retstr; do 759 ifalias_expand_addr_inet $_action $_c 760 done 761} 762 763# ifalias_expand_addr_inet6 action addr 764# Helper function for ifalias_expand_addr(). Handles IPv6. 765# 766ifalias_expand_addr_inet6() 767{ 768 local _action _arg _cidr _cidr_addr 769 local _ipaddr _plen _ipleft _ipright _iplow _iphigh _ipcount 770 local _ipv4part 771 local _retstr _c 772 _action=$1 773 _arg=$2 774 _retstr= 775 776 case $_action:$_arg in 777 *:*--*) return ;; # invalid 778 tmp:*) echo $_arg && return ;; 779 tmp:*-*) _action="alias" ;; 780 *:*-*) ;; 781 *:*) echo inet6 $_arg && return ;; 782 esac 783 784 for _cidr in $_arg; do 785 _ipaddr="${_cidr%%/*}" 786 _plen="${_cidr##*/}" 787 788 case $_action:$_ipaddr:$_cidr in 789 -alias:*:*) unset _plen ;; 790 *:$_cidr:$_ipaddr) unset _plen ;; 791 esac 792 793 if [ "${_ipaddr%:*.*.*.*}" = "$_ipaddr" ]; then 794 # Handle !v4mapped && !v4compat addresses. 795 796 # The default prefix length is 64. 797 case $_ipaddr:$_cidr in 798 $_cidr:$_ipaddr) _plen="64" ;; 799 esac 800 _ipleft=${_ipaddr%-*} 801 _ipright=${_ipaddr#*-} 802 _iplow=${_ipleft##*:} 803 _iphigh=${_ipright%%:*} 804 _ipleft=${_ipleft%:*} 805 _ipright=${_ipright#*:} 806 807 if [ "$_iphigh" = "$_ipright" ]; then 808 unset _ipright 809 else 810 _ipright=:$_ipright 811 fi 812 813 if [ -n "$_iplow" -a -n "$_iphigh" ]; then 814 _iplow=$((0x$_iplow)) 815 _iphigh=$((0x$_iphigh)) 816 _ipcount=$_iplow 817 while [ $_ipcount -le $_iphigh ]; do 818 _r=`printf "%s:%04x%s%s" \ 819 $_ipleft $_ipcount $_ipright \ 820 ${_plen:+/}$_plen` 821 _retstr="$_retstr $_r" 822 if [ $_ipcount -gt $(($_iplow + $_IPEXPANDMAX)) ] 823 then 824 warn "Range specification is too large $(printf '(%s:%04x%s-%s:%04x%s)' $_ipleft $_iplow $_ipright $_ipleft $_iphigh $_ipright). $(printf '%s:%04x%s-%s:%04x%s' $_ipleft $_iplow $_ipright $_ipleft $_ipcount $_ipright) was processed." 825 break 826 else 827 _ipcount=$(($_ipcount + 1)) 828 fi 829 done 830 else 831 _retstr="${_ipaddr}${_plen:+/}${_plen}" 832 fi 833 834 for _c in $_retstr; do 835 ifalias_expand_addr_inet6 $_action $_c 836 done 837 else 838 # v4mapped/v4compat should handle as an IPv4 alias 839 _ipv4part=${_ipaddr##*:} 840 841 # Adjust prefix length if any. If not, set the 842 # default prefix length as 32. 843 case $_ipaddr:$_cidr in 844 $_cidr:$_ipaddr) _plen=32 ;; 845 *) _plen=$(($_plen - 96)) ;; 846 esac 847 848 _retstr=`ifalias_expand_addr_inet \ 849 tmp ${_ipv4part}${_plen:+/}${_plen}` 850 for _c in $_retstr; do 851 ifalias_expand_addr_inet $_action $_c 852 done 853 fi 854 done 855} 856 857# ifalias_af_common_handler if af action args 858# Helper function for ifalias_af_common(). 859# 860ifalias_af_common_handler() 861{ 862 local _ret _if _af _action _args _c _tmpargs 863 864 _ret=1 865 _if=$1 866 _af=$2 867 _action=$3 868 shift 3 869 _args=$* 870 871 case $_args in 872 ${_af}\ *) ;; 873 *) return ;; 874 esac 875 876 _tmpargs= 877 for _c in $_args; do 878 case $_c in 879 ${_af}) 880 case $_tmpargs in 881 ${_af}\ *-*) 882 ifalias_af_common_handler $_if $_af $_action \ 883 `ifalias_expand_addr $_af $_action ${_tmpargs#${_af}\ }` 884 ;; 885 ${_af}\ *) 886 ${IFCONFIG_CMD} $_if $_tmpargs $_action && _ret=0 887 ;; 888 esac 889 _tmpargs=$_af 890 ;; 891 *) 892 _tmpargs="$_tmpargs $_c" 893 ;; 894 esac 895 done 896 # Process the last component if any. 897 if [ -n "$_tmpargs}" ]; then 898 case $_tmpargs in 899 ${_af}\ *-*) 900 ifalias_af_common_handler $_if $_af $_action \ 901 `ifalias_expand_addr $_af $_action ${_tmpargs#${_af}\ }` 902 ;; 903 ${_af}\ *) 904 ${IFCONFIG_CMD} $_if $_tmpargs $_action && _ret=0 905 ;; 906 esac 907 fi 908 909 return $_ret 910} 911 912# ifalias_af_common if af action 913# Helper function for ifalias(). 914# 915ifalias_af_common() 916{ 917 local _ret _if _af _action alias ifconfig_args _aliasn _c _tmpargs _iaf 918 919 _ret=1 920 _aliasn= 921 _if=$1 922 _af=$2 923 _action=$3 924 925 # ifconfig_IF_aliasN which starts with $_af 926 alias=0 927 while : ; do 928 ifconfig_args=`get_if_var $_if ifconfig_IF_alias${alias}` 929 _iaf= 930 case $ifconfig_args in 931 inet\ *) _iaf=inet ;; 932 inet6\ *) _iaf=inet6 ;; 933 ipx\ *) _iaf=ipx ;; 934 esac 935 936 case ${_af}:${_action}:${_iaf}:"${ifconfig_args}" in 937 ${_af}:*:${_af}:*) 938 _aliasn="$_aliasn $ifconfig_args" 939 ;; 940 ${_af}:*:"":"") 941 break 942 ;; 943 inet:alias:"":*) 944 _aliasn="$_aliasn inet $ifconfig_args" 945 warn "\$ifconfig_${_if}_alias${alias} needs " \ 946 "\"inet\" keyword for an IPv4 address." 947 esac 948 alias=$(($alias + 1)) 949 done 950 951 # backward compatibility: ipv6_ifconfig_IF_aliasN. 952 case $_af in 953 inet6) 954 alias=0 955 while : ; do 956 ifconfig_args=`get_if_var $_if ipv6_ifconfig_IF_alias${alias}` 957 case ${_action}:"${ifconfig_args}" in 958 *:"") 959 break 960 ;; 961 alias:*) 962 _aliasn="${_aliasn} inet6 ${ifconfig_args}" 963 warn "\$ipv6_ifconfig_${_if}_alias${alias} " \ 964 "is obsolete. Use ifconfig_$1_aliasN " \ 965 "instead." 966 ;; 967 esac 968 alias=$(($alias + 1)) 969 done 970 esac 971 972 # backward compatibility: ipv4_addrs_IF. 973 for _tmpargs in `get_if_var $_if ipv4_addrs_IF`; do 974 _aliasn="$_aliasn inet $_tmpargs" 975 done 976 977 # Handle ifconfig_IF_aliases, ifconfig_IF_aliasN, and the others. 978 _tmpargs= 979 for _c in `get_if_var $_if ifconfig_IF_aliases` $_aliasn; do 980 case $_c in 981 inet|inet6|ipx) 982 case $_tmpargs in 983 ${_af}\ *) 984 eval ifalias_af_common_handler $_if $_af $_action $_tmpargs && _ret=0 985 ;; 986 esac 987 _tmpargs=$_c 988 ;; 989 *) 990 _tmpargs="$_tmpargs $_c" 991 esac 992 done 993 # Process the last component 994 case $_tmpargs in 995 ${_af}\ *) 996 ifalias_af_common_handler $_if $_af $_action $_tmpargs && _ret=0 997 ;; 998 esac 999 1000 return $_ret 1001} 1002 1003# ipv6_prefix_hostid_addr_common if action 1004# Add or remove IPv6 prefix + hostid addr on the interface $if 1005# 1006ipv6_prefix_hostid_addr_common() 1007{ 1008 local _if _action prefix laddr hostid j address 1009 _if=$1 1010 _action=$2 1011 prefix=`get_if_var ${_if} ipv6_prefix_IF` 1012 1013 if [ -n "${prefix}" ]; then 1014 laddr=`network6_getladdr ${_if}` 1015 hostid=${laddr#fe80::} 1016 hostid=${hostid%\%*} 1017 1018 for j in ${prefix}; do 1019 # The default prefixlen is 64. 1020 plen=${j#*/} 1021 case $j:$plen in 1022 $plen:$j) plen=64 ;; 1023 *) j=${j%/*} ;; 1024 esac 1025 1026 # Normalize the last part by removing ":" 1027 j=${j%:*} 1028 j=${j%:} 1029 OIFS=$IFS; IFS=":"; set -- $j; nj=$#; IFS=$OIFS 1030 OIFS=$IFS; IFS=":"; set -- $hostid; nh=$#; IFS=$OIFS 1031 if [ $(($nj + $nh)) -eq 8 ]; then 1032 address=$j\:$hostid 1033 else 1034 address=$j\::$hostid 1035 fi 1036 1037 ${IFCONFIG_CMD} ${_if} inet6 ${address} \ 1038 prefixlen $plen ${_action} 1039 1040 # if I am a router, add subnet router 1041 # anycast address (RFC 2373). 1042 if checkyesno ipv6_gateway_enable; then 1043 ${IFCONFIG_CMD} ${_if} inet6 $j:: \ 1044 prefixlen $plen ${_action} anycast 1045 fi 1046 done 1047 fi 1048} 1049 1050# ipv6_accept_rtadv_up if 1051# Enable accepting Router Advertisement and send Router 1052# Solicitation message 1053ipv6_accept_rtadv_up() 1054{ 1055 if ipv6_autoconfif $1; then 1056 ${IFCONFIG_CMD} $1 inet6 accept_rtadv up 1057 if ! checkyesno rtsold_enable; then 1058 rtsol ${rtsol_flags} $1 1059 fi 1060 fi 1061} 1062 1063# ipv6_accept_rtadv_down if 1064# Disable accepting Router Advertisement 1065ipv6_accept_rtadv_down() 1066{ 1067 if ipv6_autoconfif $1; then 1068 ${IFCONFIG_CMD} $1 inet6 -accept_rtadv 1069 fi 1070} 1071 1072# ifscript_up if 1073# Evaluate a startup script for the $if interface. 1074# It returns 0 if a script was found and processed or 1075# 1 if no script was found. 1076# 1077ifscript_up() 1078{ 1079 if [ -r /etc/start_if.$1 ]; then 1080 . /etc/start_if.$1 1081 return 0 1082 else 1083 return 1 1084 fi 1085} 1086 1087# ifscript_down if 1088# Evaluate a shutdown script for the $if interface. 1089# It returns 0 if a script was found and processed or 1090# 1 if no script was found. 1091# 1092ifscript_down() 1093{ 1094 if [ -r /etc/stop_if.$1 ]; then 1095 . /etc/stop_if.$1 1096 return 0 1097 else 1098 return 1 1099 fi 1100} 1101 1102# clone_up 1103# Create cloneable interfaces. 1104# 1105clone_up() 1106{ 1107 local _prefix _list ifn 1108 _prefix= 1109 _list= 1110 1111 # create_args_IF 1112 for ifn in ${cloned_interfaces}; do 1113 ${IFCONFIG_CMD} ${ifn} create `get_if_var ${ifn} create_args_IF` 1114 if [ $? -eq 0 ]; then 1115 _list="${_list}${_prefix}${ifn}" 1116 [ -z "$_prefix" ] && _prefix=' ' 1117 fi 1118 done 1119 debug "Cloned: ${_list}" 1120} 1121 1122# clone_down 1123# Destroy cloned interfaces. Destroyed interfaces are echoed to 1124# standard output. 1125# 1126clone_down() 1127{ 1128 local _prefix _list ifn 1129 _prefix= 1130 _list= 1131 1132 for ifn in ${cloned_interfaces}; do 1133 ${IFCONFIG_CMD} -n ${ifn} destroy 1134 if [ $? -eq 0 ]; then 1135 _list="${_list}${_prefix}${ifn}" 1136 [ -z "$_prefix" ] && _prefix=' ' 1137 fi 1138 done 1139 debug "Destroyed clones: ${_list}" 1140} 1141 1142# childif_create 1143# Create and configure child interfaces. Return 0 if child 1144# interfaces are created. 1145# 1146childif_create() 1147{ 1148 local cfg child child_vlans child_wlans create_args debug_flags ifn i 1149 cfg=1 1150 ifn=$1 1151 1152 # Create wireless interfaces 1153 child_wlans=`get_if_var $ifn wlans_IF` 1154 1155 for child in ${child_wlans}; do 1156 create_args="wlandev $ifn `get_if_var $child create_args_IF`" 1157 debug_flags="`get_if_var $child wlandebug_IF`" 1158 1159 if expr $child : 'wlan[0-9][0-9]*$' >/dev/null 2>&1; then 1160 ${IFCONFIG_CMD} $child create ${create_args} && cfg=0 1161 if [ -n "${debug_flags}" ]; then 1162 wlandebug -i $child ${debug_flags} 1163 fi 1164 else 1165 i=`${IFCONFIG_CMD} wlan create ${create_args}` 1166 if [ -n "${debug_flags}" ]; then 1167 wlandebug -i $i ${debug_flags} 1168 fi 1169 ${IFCONFIG_CMD} $i name $child && cfg=0 1170 fi 1171 if autoif $child; then 1172 ifn_start $child 1173 fi 1174 done 1175 1176 # Create vlan interfaces 1177 child_vlans=`get_if_var $ifn vlans_IF` 1178 1179 if [ -n "${child_vlans}" ]; then 1180 load_kld if_vlan 1181 fi 1182 1183 for child in ${child_vlans}; do 1184 if expr $child : '[1-9][0-9]*$' >/dev/null 2>&1; then 1185 child="${ifn}.${child}" 1186 create_args=`get_if_var $child create_args_IF` 1187 ${IFCONFIG_CMD} $child create ${create_args} && cfg=0 1188 else 1189 create_args="vlandev $ifn `get_if_var $child create_args_IF`" 1190 if expr $child : 'vlan[0-9][0-9]*$' >/dev/null 2>&1; then 1191 ${IFCONFIG_CMD} $child create ${create_args} && cfg=0 1192 else 1193 i=`${IFCONFIG_CMD} vlan create ${create_args}` 1194 ${IFCONFIG_CMD} $i name $child && cfg=0 1195 fi 1196 fi 1197 if autoif $child; then 1198 ifn_start $child 1199 fi 1200 done 1201 1202 return ${cfg} 1203} 1204 1205# childif_destroy 1206# Destroy child interfaces. 1207# 1208childif_destroy() 1209{ 1210 local cfg child child_vlans child_wlans ifn 1211 cfg=1 1212 1213 child_wlans=`get_if_var $ifn wlans_IF` 1214 for child in ${child_wlans}; do 1215 if ! ifexists $child; then 1216 continue 1217 fi 1218 ${IFCONFIG_CMD} -n $child destroy && cfg=0 1219 done 1220 1221 child_vlans=`get_if_var $ifn vlans_IF` 1222 for child in ${child_vlans}; do 1223 if expr $child : '[1-9][0-9]*$' >/dev/null 2>&1; then 1224 child="${ifn}.${child}" 1225 fi 1226 if ! ifexists $child; then 1227 continue 1228 fi 1229 ${IFCONFIG_CMD} -n $child destroy && cfg=0 1230 done 1231 1232 return ${cfg} 1233} 1234 1235# ng_mkpeer 1236# Create netgraph nodes. 1237# 1238ng_mkpeer() 1239{ 1240 ngctl -f - 2> /dev/null <<EOF 1241mkpeer $* 1242msg dummy nodeinfo 1243EOF 1244} 1245 1246# ng_create_one 1247# Create netgraph nodes. 1248# 1249ng_create_one() 1250{ 1251 local t 1252 1253 ng_mkpeer $* | while read line; do 1254 t=`expr "${line}" : '.* name="\([a-z]*[0-9]*\)" .*'` 1255 if [ -n "${t}" ]; then 1256 echo ${t} 1257 return 1258 fi 1259 done 1260} 1261 1262# gif_up 1263# Create gif(4) tunnel interfaces. 1264gif_up() 1265{ 1266 local i peers 1267 1268 for i in ${gif_interfaces}; do 1269 peers=`get_if_var $i gifconfig_IF` 1270 case ${peers} in 1271 '') 1272 continue 1273 ;; 1274 *) 1275 if expr $i : 'gif[0-9][0-9]*$' >/dev/null 2>&1; then 1276 ${IFCONFIG_CMD} $i create >/dev/null 2>&1 1277 else 1278 gif=`${IFCONFIG_CMD} gif create` 1279 ${IFCONFIG_CMD} $gif name $i 1280 fi 1281 ${IFCONFIG_CMD} $i tunnel ${peers} 1282 ${IFCONFIG_CMD} $i up 1283 ;; 1284 esac 1285 done 1286} 1287 1288# ng_fec_create ifn 1289# Configure Fast EtherChannel for interface $ifn. Returns 0 if 1290# FEC arguments were found and configured; returns !0 otherwise. 1291ng_fec_create() 1292{ 1293 local req_iface iface bogus 1294 req_iface="$1" 1295 1296 ngctl shutdown ${req_iface}: > /dev/null 2>&1 1297 1298 bogus="" 1299 while true; do 1300 iface=`ng_create_one fec dummy fec` 1301 if [ -z "${iface}" ]; then 1302 exit 2 1303 fi 1304 if [ "${iface}" = "${req_iface}" ]; then 1305 break 1306 fi 1307 bogus="${bogus} ${iface}" 1308 done 1309 1310 for iface in ${bogus}; do 1311 ngctl shutdown ${iface}: 1312 done 1313} 1314 1315# fec_up 1316# Create Fast EtherChannel interfaces. 1317fec_up() 1318{ 1319 local i j 1320 1321 for i in ${fec_interfaces}; do 1322 ng_fec_create $i 1323 for j in `get_if_var $i fecconfig_IF`; do 1324 case ${j} in 1325 '') 1326 continue 1327 ;; 1328 *) 1329 ngctl msg ${i}: add_iface "\"${j}\"" 1330 ;; 1331 esac 1332 done 1333 done 1334} 1335 1336# ipx_up ifn 1337# Configure any IPX addresses for interface $ifn. Returns 0 if 1338# IPX arguments were found and configured; returns 1 otherwise. 1339# 1340ipx_up() 1341{ 1342 local ifn 1343 ifn="$1" 1344 1345 # ifconfig_IF_ipx 1346 ifconfig_args=`_ifconfig_getargs $ifn ipx` 1347 if [ -n "${ifconfig_args}" ]; then 1348 ${IFCONFIG_CMD} ${ifn} ${ifconfig_args} 1349 return 0 1350 fi 1351 1352 return 1 1353} 1354 1355# ipx_down ifn 1356# Remove IPX addresses for interface $ifn. Returns 0 if IPX 1357# addresses were found and unconfigured. It returns 1, otherwise. 1358# 1359ipx_down() 1360{ 1361 local _if _ifs _ret ipxList oldifs _ipx 1362 _if=$1 1363 _ifs="^" 1364 _ret=1 1365 ipxList="`${IFCONFIG_CMD} ${_if} | grep 'ipx ' | tr "\n" "$_ifs"`" 1366 oldifs="$IFS" 1367 1368 IFS="$_ifs" 1369 for _ipx in $ipxList ; do 1370 # get rid of extraneous line 1371 [ -z "$_ipx" ] && break 1372 1373 _ipx=`expr "$_ipx" : '.*\(ipx [0-9a-h]\{1,8\}H*\.[0-9a-h]\{1,12\}\).*'` 1374 1375 IFS="$oldifs" 1376 ${IFCONFIG_CMD} ${_if} ${_ipx} delete 1377 IFS="$_ifs" 1378 _ret=0 1379 done 1380 IFS="$oldifs" 1381 1382 return $_ret 1383} 1384 1385# ifnet_rename 1386# Rename all requested interfaces. 1387# 1388ifnet_rename() 1389{ 1390 local _if _ifname 1391 1392 # ifconfig_IF_name 1393 for _if in `${IFCONFIG_CMD} -l`; do 1394 _ifname=`get_if_var $_if ifconfig_IF_name` 1395 if [ ! -z "$_ifname" ]; then 1396 ${IFCONFIG_CMD} $_if name $_ifname 1397 fi 1398 done 1399 1400 return 0 1401} 1402 1403# list_net_interfaces type 1404# List all network interfaces. The type of interface returned 1405# can be controlled by the type argument. The type 1406# argument can be any of the following: 1407# nodhcp - all interfaces, excluding DHCP configured interfaces 1408# dhcp - list only DHCP configured interfaces 1409# noautoconf - all interfaces, excluding IPv6 Stateless 1410# Address Autoconf configured interfaces 1411# autoconf - list only IPv6 Stateless Address Autoconf 1412# configured interfaces 1413# If no argument is specified all network interfaces are output. 1414# Note that the list will include cloned interfaces if applicable. 1415# Cloned interfaces must already exist to have a chance to appear 1416# in the list if ${network_interfaces} is set to `auto'. 1417# 1418list_net_interfaces() 1419{ 1420 local type _tmplist _list _autolist _lo _if 1421 type=$1 1422 1423 # Get a list of ALL the interfaces and make lo0 first if it's there. 1424 # 1425 _tmplist= 1426 case ${network_interfaces} in 1427 [Aa][Uu][Tt][Oo]) 1428 _autolist="`${IFCONFIG_CMD} -l`" 1429 _lo= 1430 for _if in ${_autolist} ; do 1431 if autoif $_if; then 1432 if [ "$_if" = "lo0" ]; then 1433 _lo="lo0 " 1434 else 1435 _tmplist="${_tmplist} ${_if}" 1436 fi 1437 fi 1438 done 1439 _tmplist="${_lo}${_tmplist# }" 1440 ;; 1441 *) 1442 _tmplist="${network_interfaces} ${cloned_interfaces}" 1443 1444 # lo0 is effectively mandatory, so help prevent foot-shooting 1445 # 1446 case "$_tmplist" in 1447 lo0|'lo0 '*|*' lo0'|*' lo0 '*) ;; # This is fine, do nothing 1448 *) _tmplist="lo0 ${_tmplist}" ;; 1449 esac 1450 ;; 1451 esac 1452 1453 _list= 1454 case "$type" in 1455 nodhcp) 1456 for _if in ${_tmplist} ; do 1457 if ! dhcpif $_if && \ 1458 [ -n "`_ifconfig_getargs $_if`" ]; then 1459 _list="${_list# } ${_if}" 1460 fi 1461 done 1462 ;; 1463 dhcp) 1464 for _if in ${_tmplist} ; do 1465 if dhcpif $_if; then 1466 _list="${_list# } ${_if}" 1467 fi 1468 done 1469 ;; 1470 noautoconf) 1471 for _if in ${_tmplist} ; do 1472 if ! ipv6_autoconfif $_if && \ 1473 [ -n "`_ifconfig_getargs $_if ipv6`" ]; then 1474 _list="${_list# } ${_if}" 1475 fi 1476 done 1477 ;; 1478 autoconf) 1479 for _if in ${_tmplist} ; do 1480 if ipv6_autoconfif $_if; then 1481 _list="${_list# } ${_if}" 1482 fi 1483 done 1484 ;; 1485 *) 1486 _list=${_tmplist} 1487 ;; 1488 esac 1489 1490 echo $_list 1491 1492 return 0 1493} 1494 1495# get_default_if -address_family 1496# Get the interface of the default route for the given address family. 1497# The -address_family argument must be suitable passing to route(8). 1498# 1499get_default_if() 1500{ 1501 local routeget oldifs defif line 1502 defif= 1503 oldifs="$IFS" 1504 IFS=" 1505" 1506 for line in `route -n get $1 default 2>/dev/null`; do 1507 case $line in 1508 *interface:*) 1509 defif=${line##*: } 1510 ;; 1511 esac 1512 done 1513 IFS=${oldifs} 1514 1515 echo $defif 1516} 1517 1518# hexdigit arg 1519# Echo decimal number $arg (single digit) in hexadecimal format. 1520hexdigit() 1521{ 1522 printf '%x\n' "$1" 1523} 1524 1525# hexprint arg 1526# Echo decimal number $arg (multiple digits) in hexadecimal format. 1527hexprint() 1528{ 1529 printf '%x\n' "$1" 1530} 1531 1532is_wired_interface() 1533{ 1534 local media 1535 1536 case `${IFCONFIG_CMD} $1 2>/dev/null` in 1537 *media:?Ethernet*) media=Ethernet ;; 1538 esac 1539 1540 test "$media" = "Ethernet" 1541} 1542 1543# network6_getladdr if [flag] 1544# Echo link-local address from $if if any. 1545# If flag is defined, tentative ones will be excluded. 1546network6_getladdr() 1547{ 1548 local _if _flag proto addr rest 1549 _if=$1 1550 _flag=$2 1551 1552 ${IFCONFIG_CMD} $_if 2>/dev/null | while read proto addr rest; do 1553 case "${proto}/${addr}/${_flag}/${rest}" in 1554 inet6/fe80::*//*) 1555 echo ${addr} 1556 ;; 1557 inet6/fe80:://*tentative*) # w/o flag 1558 sleep `${SYSCTL_N} net.inet6.ip6.dad_count` 1559 network6_getladdr $_if $_flags 1560 ;; 1561 inet6/fe80::/*/*tentative*) # w/ flag 1562 echo ${addr} 1563 ;; 1564 *) 1565 continue 1566 ;; 1567 esac 1568 1569 return 1570 done 1571} 1572