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