1 if [ ! "$_MEDIA_TCPIP_SUBR" ]; then _MEDIA_TCPIP_SUBR=1
3 # Copyright (c) 2012-2013 Devin Teske
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
9 # 1. Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 # notice, this list of conditions and the following disclaimer in the
13 # documentation and/or other materials provided with the distribution.
15 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 ############################################################ INCLUDES
31 BSDCFG_SHARE="/usr/share/bsdconfig"
32 . $BSDCFG_SHARE/common.subr || exit 1
33 f_dprintf "%s: loading includes..." media/tcpip.subr
34 f_include $BSDCFG_SHARE/device.subr
35 f_include $BSDCFG_SHARE/dialog.subr
36 f_include $BSDCFG_SHARE/strings.subr
37 f_include $BSDCFG_SHARE/struct.subr
38 f_include $BSDCFG_SHARE/variable.subr
40 BSDCFG_LIBE="/usr/libexec/bsdconfig"
41 f_include_lang $BSDCFG_LIBE/include/messages.subr
43 TCP_HELPFILE=$BSDCFG_LIBE/include/tcp.hlp
44 NETWORK_DEVICE_HELPFILE=$BSDCFG_LIBE/include/network_device.hlp
46 ############################################################ GLOBALS
49 # Path to resolv.conf(5).
51 : ${RESOLV_CONF:="/etc/resolv.conf"}
54 # Path to nsswitch.conf(5).
56 : ${NSSWITCH_CONF:="/etc/nsswitch.conf"}
61 : ${ETC_HOSTS:="/etc/hosts"}
64 # Structure of dhclient.leases(5) lease { ... } entry
66 f_struct_define DHCP_LEASE \
81 dhcp_server_identifier \
88 ############################################################ FUNCTIONS
90 # f_validate_hostname $hostname
92 # Returns zero if the given argument (a fully-qualified hostname) is compliant
93 # with standards set-forth in RFC's 952 and 1123 of the Network Working Group:
95 # RFC 952 - DoD Internet host table specification
96 # http://tools.ietf.org/html/rfc952
98 # RFC 1123 - Requirements for Internet Hosts - Application and Support
99 # http://tools.ietf.org/html/rfc1123
101 # See http://en.wikipedia.org/wiki/Hostname for a brief overview.
103 # The return status for invalid hostnames is one of:
104 # 255 Entire hostname exceeds the maximum length of 255 characters.
105 # 63 One or more individual labels within the hostname (separated by
106 # dots) exceeds the maximum of 63 characters.
107 # 1 One or more individual labels within the hostname contains one
108 # or more invalid characters.
109 # 2 One or more individual labels within the hostname starts or
110 # ends with a hyphen (hyphens are allowed, but a label cannot
111 # begin or end with a hyphen).
112 # 3 One or more individual labels within the hostname are null.
114 # To call this function and display an appropriate error message to the user
115 # based on the above error codes, use the following function defined in
118 # f_dialog_validate_hostname $hostname
120 f_validate_hostname()
124 # Return error if the hostname exceeds 255 characters
125 [ ${#fqhn} -gt 255 ] && return 255
127 local IFS="." # Split on `dot'
128 for label in $fqhn; do
129 # Return error if the label exceeds 63 characters
130 [ ${#label} -gt 63 ] && return 63
132 # Return error if the label is null
133 [ "$label" ] || return 3
135 # Return error if label begins/ends with dash
136 case "$label" in -*|*-) return 2; esac
138 # Return error if the label contains any invalid chars
139 case "$label" in *[!0-9a-zA-Z-]*) return 1; esac
145 # f_inet_atoi $ipv4_address [$var_to_set]
147 # Convert an IPv4 address or mask from dotted-quad notation (e.g., `127.0.0.1'
148 # or `255.255.255.0') to a 32-bit unsigned integer for the purpose of network
149 # and broadcast calculations. For example, one can validate that two addresses
150 # are on the same network:
152 # f_inet_atoi 1.2.3.4 ip1num
153 # f_inet_atoi 1.2.4.5 ip2num
154 # f_inet_atoi 255.255.0.0 masknum
155 # if [ $(( $ip1num & $masknum )) -eq \
156 # $(( $ip2num & $masknum )) ]
158 # : IP addresses are on same network
161 # See f_validate_ipaddr() below for an additional example usage, on calculating
162 # network and broadcast addresses.
164 # If $var_to_set is missing or NULL, the converted IP address is printed to
165 # standard output for capturing in a sub-shell (which is less-recommended
166 # because of performance degredation; for example, when called in a loop).
170 local __addr="$1" __var_to_set="$2" __num=0
171 if f_validate_ipaddr "$__addr"; then
174 __num=$(( ($1 << 24) + ($2 << 16) + ($3 << 8) + $4 ))
176 if [ "$__var_to_set" ]; then
177 setvar "$__var_to_set" $__num
183 # f_validate_ipaddr $ipaddr [$netmask]
185 # Returns zero if the given argument (an IP address) is of the proper format.
187 # The return status for invalid IP address is one of:
188 # 1 One or more individual octets within the IP address (separated
189 # by dots) contains one or more invalid characters.
190 # 2 One or more individual octets within the IP address are null
192 # 3 One or more individual octets within the IP address exceeds the
193 # maximum of 255 (or 2^8, being an octet comprised of 8 bits).
194 # 4 The IP address has either too few or too many octets.
196 # If a netmask is provided, the IP address is checked further:
198 # 5 The IP address must not be the network or broadcast address.
202 local ip="$1" mask="$2"
204 # Track number of octets for error checking
207 local oldIFS="$IFS" IFS="." # Split on `dot'
209 # Return error if the octet is null
210 [ "$octet" ] || return 2
212 # Return error if not a whole integer
213 f_isinteger "$octet" || return 1
215 # Return error if not a positive integer
216 [ $octet -ge 0 ] || return 1
218 # Return error if the octet exceeds 255
219 [ $octet -gt 255 ] && return 3
221 noctets=$(( $noctets + 1 ))
225 [ $noctets -eq 4 ] || return 4
228 # The IP address must not be network or broadcast address.
231 local ipnum masknum netnum bcastnum
232 local max_addr=4294967295 # 255.255.255.255
234 f_inet_atoi $ip ipnum
235 f_inet_atoi $mask masknum
237 netnum=$(( $ipnum & $masknum ))
238 bcastnum=$(( ($ipnum & $masknum)+$max_addr-$masknum ))
241 [ $ipnum -eq $netnum -o $ipnum -eq $bcastnum ]
250 # f_validate_ipaddr6 $ipv6_addr
252 # Returns zero if the given argument (an IPv6 address) is of the proper format.
254 # The return status for invalid IP address is one of:
255 # 1 One or more individual segments within the IP address
256 # (separated by colons) contains one or more invalid characters.
257 # Segments must contain only combinations of the characters 0-9,
259 # 2 Too many/incorrect null segments. A single null segment is
260 # allowed within the IP address (separated by colons) but not
261 # allowed at the beginning or end (unless a double-null segment;
262 # i.e., "::*" or "*::").
263 # 3 One or more individual segments within the IP address
264 # (separated by colons) exceeds the length of 4 hex-digits.
265 # 4 The IP address entered has either too few (less than 3), too
266 # many (more than 8), or not enough segments, separated by
268 # 5* The IPv4 address at the end of the IPv6 address is invalid.
269 # * When there is an error with the dotted-quad IPv4 address at the
270 # end of the IPv6 address, the return value of 5 is OR'd with a
271 # bit-shifted (<< 4) return of f_validate_ipaddr.
275 local ip="${1%\%*}" # removing the interface specification if-present
277 local IFS=":" # Split on `colon'
280 # Return error if too many or too few segments
281 # Using 9 as max in case of leading or trailing null spanner
282 [ $# -gt 9 -o $# -lt 3 ] && return 4
284 local h="[0-9A-Fa-f]"
285 local nulls=0 nsegments=$# contains_ipv4_segment=
287 while [ $# -gt 0 ]; do
293 # Return error if this segment makes one null too-many. A
294 # single null segment is allowed anywhere in the middle as well
295 # as double null segments are allowed at the beginning or end
298 if [ ! "$segment" ]; then
299 nulls=$(( $nulls + 1 ))
300 if [ $nulls -eq 3 ]; then
301 # Only valid syntax for 3 nulls is `::'
302 [ "$ip" = "::" ] || return 2
303 elif [ $nulls -eq 2 ]; then
304 # Only valid if begins/ends with `::'
306 ::*|*::) : fall thru ;;
314 # Return error if not a valid hexadecimal short
317 $h|$h$h|$h$h$h|$h$h$h$h)
318 : valid segment of 1-4 hexadecimal digits
321 # Segment contains at least one invalid char
323 # Return error immediately if not last segment
324 [ $# -eq 0 ] || return 1
326 # Otherwise, check for legacy IPv4 notation
329 # Segment contains at least one invalid
330 # character even for an IPv4 address
334 # Return error if not enough segments
335 if [ $nulls -eq 0 ]; then
336 [ $nsegments -eq 7 ] || return 4
339 contains_ipv4_segment=1
341 # Validate the IPv4 address
342 f_validate_ipaddr "$segment" ||
343 return $(( 5 | $? << 4 ))
346 # Segment characters are all valid but too many
352 if [ $nulls -eq 1 ]; then
353 # Single null segment cannot be at beginning/end
360 # A legacy IPv4 address can span the last two 16-bit segments,
361 # reducing the amount of maximum allowable segments by-one.
364 if [ "$contains_ipv4_segment" ]; then
369 # Return error if missing segments with no null spanner
370 0) [ $nsegments -eq $maxsegments ] || return 4 ;;
371 # Return error if null spanner with too many segments
372 1) [ $nsegments -le $maxsegments ] || return 4 ;;
373 # Return error if leading/trailing `::' with too many segments
374 2) [ $nsegments -le $(( $maxsegments + 1 )) ] || return 4 ;;
380 # f_validate_netmask $netmask
382 # Returns zero if the given argument (a subnet mask) is of the proper format.
384 # The return status for invalid netmask is one of:
385 # 1 One or more individual fields within the subnet mask (separated
386 # by dots) contains one or more invalid characters.
387 # 2 One or more individual fields within the subnet mask are null
389 # 3 One or more individual fields within the subnet mask exceeds
390 # the maximum of 255 (a full 8-bit register).
391 # 4 The subnet mask has either too few or too many fields.
392 # 5 One or more individual fields within the subnet mask is an
393 # invalid integer (only 0,128,192,224,240,248,252,254,255 are
400 # Track number of fields for error checking
403 local IFS="." # Split on `dot'
404 for field in $mask; do
405 # Return error if the field is null
406 [ "$field" ] || return 2
408 # Return error if not a whole positive integer
409 f_isinteger "$field" || return 1
411 # Return error if the field exceeds 255
412 [ $field -gt 255 ] && return 3
414 # Return error if the field is an invalid integer
416 0|128|192|224|240|248|252|254|255) : ;;
420 nfields=$(( $nfields + 1 ))
423 [ $nfields -eq 4 ] || return 4
426 # f_validate_gateway $gateway $ipaddr $netmask
428 # Validate an IPv4 default gateway (aka router) address for a given IP address
429 # making sure the two are in the same network (able to ``talk'' to each other).
430 # Returns success if $ipaddr and $gateway are in the same network given subnet
435 local gateway="$1" ipaddr="$2" netmask="$3"
436 local gwnum ipnum masknum
438 f_validate_ipaddr "$gateway" "$netmask" || return $FAILURE
440 f_inet_atoi "$netmask" masknum
441 f_inet_atoi "$ipaddr" ipnum
442 f_inet_atoi "$gateway" gwnum
444 # Gateway must be within set of IPs reachable through interface
445 [ $(( $ipnum & $masknum )) -eq \
446 $(( $gwnum & $masknum )) ] # Return status
449 # f_dialog_validate_tcpip $hostname $gateway $nameserver $ipaddr $netmask
451 # Returns success if the arguments provided are valid for accessing a TCP/IP
452 # network, otherwise returns failure.
454 f_dialog_validate_tcpip()
456 local hostname="$1" gateway="$2" nameserver="$3"
457 local ipaddr="$4" netmask="$5"
460 if [ ! "$hostname" ]; then
461 f_show_msg "$msg_must_specify_a_host_name_of_some_sort"
462 elif ! f_validate_hostname "$hostname"; then
463 f_show_msg "$msg_invalid_hostname_value"
464 elif [ "$netmask" ] && ! f_validate_netmask "$netmask"; then
465 f_show_msg "$msg_invalid_netmask_value"
466 elif [ "$nameserver" ] &&
467 ! f_validate_ipaddr "$nameserver" &&
468 ! f_validate_ipaddr6 "$nameserver"; then
469 f_show_msg "$msg_invalid_name_server_ip_address_specified"
470 elif [ "$ipaddr" ] && ! f_validate_ipaddr "$ipaddr" "$netmask"; then
471 f_show_msg "$msg_invalid_ipv4_address"
472 elif [ "$gateway" -a "$gateway" != "NO" ] &&
473 ! f_validate_gateway "$gateway" "$ipaddr" "$netmask"; then
474 f_show_msg "$msg_invalid_gateway_ipv4_address_specified"
479 return $DIALOG_CANCEL
482 # f_ifconfig_inet $interface [$var_to_set]
484 # Returns the IPv4 address associated with $interface. If $var_to_set is
485 # missing or NULL, the IP address is printed to standard output for capturing
486 # in a sub-shell (which is less-recommended because of performance degredation;
487 # for example, when called in a loop).
489 # This function is a two-parter. Below is the awk(1) portion of the function,
490 # afterward is the sh(1) function which utilizes the below awk script.
492 f_ifconfig_inet_awk='
504 local __interface="$1" __var_to_set="$2"
505 if [ "$__var_to_set" ]; then
507 __ip=$( ifconfig "$__interface" 2> /dev/null |
508 awk "$f_ifconfig_inet_awk" )
509 setvar "$__var_to_set" "$__ip"
511 ifconfig "$__interface" 2> /dev/null |
512 awk "$f_ifconfig_inet_awk"
516 # f_ifconfig_inet6 $interface [$var_to_set]
518 # Returns the IPv6 address associated with $interface. If $var_to_set is
519 # missing or NULL, the IP address is printed to standard output for capturing
520 # in a sub-shell (which is less-recommended because of performance degredation;
521 # for example, when called in a loop).
523 # This function is a two-parter. Below is the awk(1) portion of the function,
524 # afterward is the sh(1) function which utilizes the below awk script.
526 f_ifconfig_inet6_awk='
538 local __interface="$1" __var_to_set="$2"
539 if [ "$__var_to_set" ]; then
541 __ip6=$( ifconfig "$__interface" 2> /dev/null |
542 awk "$f_ifconfig_inet6_awk" )
543 setvar "$__var_to_set" "$__ip6"
545 ifconfig "$__interface" 2> /dev/null |
546 awk "$f_ifconfig_inet6_awk"
550 # f_ifconfig_netmask $interface [$var_to_set]
552 # Returns the IPv4 subnet mask associated with $interface. If $var_to_set is
553 # missing or NULL, the netmask is printed to standard output for capturing in a
554 # sub-shell (which is less-recommended because of performance degredation; for
555 # example, when called in a loop).
559 local __interface="$1" __var_to_set="$2" __octets
560 __octets=$( ifconfig "$__interface" 2> /dev/null | awk \
565 printf "%s %s %s %s\n",
574 ' ) || return $FAILURE
576 local __octet __netmask=
577 for __octet in $__octets; do
578 f_sprintf __netmask "%s.%u" "$__netmask" "0x$__octet"
580 __netmask="${__netmask#.}"
581 if [ "$__var_to_set" ]; then
582 setvar "$__var_to_set" "$__netmask"
588 # f_route_get_default [$var_to_set]
590 # Returns the IP address of the currently active default router. If $var_to_set
591 # is missing or NULL, the IP address is printed to standard output for
592 # capturing in a sub-shell (which is less-recommended because of performance
593 # degredation; for example, when called in a loop).
595 # This function is a two-parter. Below is the awk(1) portion of the function,
596 # afterward is the sh(1) function which utilizes the below awk script.
598 f_route_get_default_awk='
600 ( $1 == "gateway:" ) \
608 f_route_get_default()
610 local __var_to_set="$1"
611 if [ "$__var_to_set" ]; then
613 __ip=$( route -n get default 2> /dev/null |
614 awk "$f_route_get_default_awk" )
615 setvar "$__var_to_set" "$__ip"
617 route -n get default 2> /dev/null |
618 awk "$f_route_get_default_awk"
622 # f_resolv_conf_nameservers [$var_to_set]
624 # Returns nameserver(s) configured in resolv.conf(5). If $var_to_set is missing
625 # or NULL, the list of nameservers is printed to standard output for capturing
626 # in a sub-shell (which is less-recommended because of performance degredation;
627 # for example, when called in a loop).
629 # This function is a two-parter. Below is the awk(1) portion of the function,
630 # afterward is the sh(1) function which utilizes the below awk script.
632 f_resolv_conf_nameservers_awk='
634 ( $1 == "nameserver" ) \
641 f_resolv_conf_nameservers()
643 local __var_to_set="$1"
644 if [ "$__var_to_set" ]; then
646 __ns=$( awk "$f_resolv_conf_nameservers_awk" "$RESOLV_CONF" \
648 setvar "$__var_to_set" "$__ns"
650 awk "$f_resolv_conf_nameservers_awk" "$RESOLV_CONF" \
657 # Attempts to configure resolv.conf(5) and ilk. Returns success if able to
658 # write the file(s), otherwise returns error status.
660 # Variables from variable.subr that are used in configuring resolv.conf(5) are
661 # as follows (all of which can be configured automatically through functions
662 # like f_dhcp_get_info() or manually):
665 # The nameserver to add in resolv.conf(5).
667 # The domain to configure in resolv.conf(5). Also used in the
668 # configuration of hosts(5).
670 # The IPv4 address to configure in hosts(5).
672 # The IPv6 address to configure in hosts(5).
674 # The hostname to associate with the IPv4 and/or IPv6 address in
681 f_getvar $VAR_NAMESERVER cp
683 case "$RESOLV_CONF" in
684 */*) f_quietly mkdir -p "${RESOLV_CONF%/*}" ;;
687 # Attempt to create/truncate the file
688 ( :> "$RESOLV_CONF" ) 2> /dev/null || return $FAILURE
690 f_getvar $VAR_DOMAINNAME dp &&
691 printf "domain\t%s\n" "$dp" >> "$RESOLV_CONF"
692 printf "nameserver\t%s\n" "$cp" >> "$RESOLV_CONF"
694 f_dprintf "Wrote out %s" "$RESOLV_CONF"
697 f_getvar $VAR_DOMAINNAME dp
698 f_getvar $VAR_IPADDR cp
699 f_getvar $VAR_IPV6ADDR c6p
700 f_getvar $VAR_HOSTNAME hp
702 # Attempt to create the file if it doesn't already exist
703 if [ ! -e "$ETC_HOSTS" ]; then
705 */*) f_quietly mkdir -p "${ETC_HOSTS%/*}" ;;
708 ( :> "$ETC_HOSTS" ) 2> /dev/null || return $FAILURE
711 # Scan the file and add ourselves if not already configured
712 awk -v dn="$dp" -v ip4="$cp" -v ip6="$c6p" -v hn="$hp" '
714 local4found = local6found = 0
715 hn4found = hn6found = h4found = h6found = 0
716 h = ( match(hn, /\./) ? substr(hn, 0, RSTART-1) : "" )
718 ($1 == "127.0.0.1") { local4found = 1 }
719 ($1 == "::1") { local6found = 1 }
721 for (n = 2; n <= NF; n++)
724 if ( $n == h ) h4found = 1
725 if ( $n == hn ) hn4found = 1
726 if ( $n == hn "." ) hn4found = 1
729 if ( $n == h ) h6found = 1
730 if ( $n == hn ) hn6found = 1
731 if ( $n == hn "." ) hn6found = 1
739 printf "::1\t\t\tlocalhost%s\n",
740 ( dn ? " localhost." dn : "" ) >> hosts
742 printf "127.0.0.1\t\tlocalhost%s\n",
743 ( dn ? " localhost." dn : "" ) >> hosts
745 if ( ip6 && ! (h6found && hn6found))
747 printf "%s\t%s %s\n", ip6, hn, h >> hosts
748 printf "%s\t%s.\n", ip6, hn >> hosts
753 printf "%s\t%s.\n", ip6, h >> hosts
755 printf "%s\t%s\n", ip6, hn >> hosts
758 if ( ip4 && ! (h4found && hn4found))
760 printf "%s\t\t%s %s\n", ip4, hn, h >> hosts
761 printf "%s\t\t%s.\n", ip4, hn >> hosts
766 printf "%s\t\t%s.\n", ip4, h >> hosts
768 printf "%s\t\t%s\n", ip4, hn >> hosts
771 ' "$ETC_HOSTS" 2> /dev/null || return $FAILURE
773 f_dprintf "Wrote out %s" "$ETC_HOSTS"
777 # f_dhcp_parse_leases $leasefile struct_name
779 # Parse $leasefile and store the information for the most recent lease in a
780 # struct (see struct.subr for additional details) named `struct_name'. See
781 # DHCP_LEASE struct definition in the GLOBALS section above.
783 f_dhcp_parse_leases()
785 local leasefile="$1" struct_name="$2"
787 [ "$struct_name" ] || return $FAILURE
789 if [ ! -e "$leasefile" ]; then
790 f_dprintf "%s: No such file or directory" "$leasefile"
794 f_struct "$struct_name" && f_struct_free "$struct_name"
795 f_struct_new DHCP_LEASE "$struct_name"
797 eval "$( awk -v struct="$struct_name" '
808 split(keyword_list, keywords, FS)
810 time_list = "renew rebind expire"
811 split(time_list, times, FS)
817 domain-name-servers \
822 dhcp-server-identifier \
824 dhcp-rebinding-time \
826 split(option_list, options, FS)
828 function set_value(prop,value)
831 gsub(/[^[:alnum:]_]/, "_", prop)
835 sub(/,.*/, "", value)
836 printf "%s set %s \"%s\"\n", struct, prop, value
840 if ( $0 ~ /^lease {$/ ) next
841 if ( $0 ~ /^}$/ ) exit
845 keyword = keywords[k]
848 set_value(keyword, $2)
858 set_value(time, $2 " " $3 " " $4)
863 if ( $1 != "option" ) next
869 set_value(option, $3)
877 printf "f_struct_free \"%s\"\n", struct
878 print "return $FAILURE"
884 # f_dhcp_get_info $interface
886 # Parse the dhclient(8) lease database for $interface to obtain all the
887 # necessary IPv4 details necessary to communicate on the network. The retrieved
888 # information is stored in VAR_IPADDR, VAR_NETMASK, VAR_GATEWAY, and
891 # If reading the lease database fails, values are obtained from ifconfig(8) and
892 # route(8). If the DHCP lease did not provide a nameserver (or likewise, we
893 # were unable to parse the lease database), fall-back to resolv.conf(5) for
894 # obtaining the nameserver. Always returns success.
898 local interface="$1" cp
899 local leasefile="/var/db/dhclient.leases.$interface"
901 # If it fails, do it the old-fashioned way
902 if f_dhcp_parse_leases "$leasefile" lease; then
903 lease get fixed_address $VAR_IPADDR
904 lease get subnet_mask $VAR_NETMASK
906 setvar $VAR_GATEWAY "${cp%%,*}"
907 lease get domain_name_servers cp
908 setvar $VAR_NAMESERVER "${cp%%,*}"
909 lease get host_name cp &&
910 setvar $VAR_HOSTNAME "$cp"
913 # Bah, now we have to get the information from ifconfig
915 f_dprintf "DHCP configured interface returns %s" \
916 "$( ifconfig "$interface" )"
918 f_ifconfig_inet "$interface" $VAR_IPADDR
919 f_ifconfig_netmask "$interface" $VAR_NETMASK
920 f_route_get_default $VAR_GATEWAY
923 # If we didn't get a name server value, hunt for it in resolv.conf
925 if [ -r "$RESOLV_CONF" ] && ! {
926 f_getvar $VAR_NAMESERVER ns || [ "$ns" ]
928 f_resolv_conf_nameservers cp &&
929 setvar $VAR_NAMESERVER ${cp%%[$IFS]*}
935 # f_rtsol_get_info $interface
937 # Returns the rtsol-provided IPv6 address associated with $interface. The
938 # retrieved IP address is stored in VAR_IPV6ADDR. Always returns success.
942 local interface="$1" cp
943 cp=$( ifconfig "$interface" 2> /dev/null | awk \
946 ( $1 == "inet6" ) && ( $2 ~ /^fe80:/ ) \
953 ' ) && setvar $VAR_IPV6ADDR "$cp"
956 # f_host_lookup $host [$var_to_set]
958 # Use host(1) to lookup (or reverse) an Internet number from (or to) a name.
959 # Multiple answers are returned separated by a single space. If host(1) does
960 # not exit cleanly, its full output is provided and the return status is 1.
962 # If nsswitch.conf(5) has been configured to query local access first for the
963 # `hosts' database, we'll manually check hosts(5) first (preventing host(1)
964 # from hanging in the event that DNS goes awry).
966 # If $var_to_set is missing or NULL, the list of IP addresses is printed to
967 # standard output for capturing in a sub-shell (which is less-recommended
968 # because of performance degredation; for example, when called in a loop).
970 # The variables from variable.subr used in looking up the host are as follows
971 # (which are set manually):
973 # VAR_IPV6_ENABLE [Optional]
974 # If set to "YES", enables the lookup of IPv6 addresses and IPv4
975 # address. IPv6 addresses, if any, will come before IPv4. Note
976 # that if nsswitch.conf(5) shows an affinity for "files" for the
977 # "host" database and there is a valid entry in hosts(5) for
978 # $host, this setting currently has no effect (an IPv4 address
979 # can supersede an IPv6 address). By design, hosts(5) overrides
980 # any preferential treatment. Otherwise, if this variable is not
981 # set, IPv6 addresses will not be used (IPv4 addresses will
982 # specifically be requested from DNS).
984 # This function is a two-parter. Below is the awk(1) portion of the function,
985 # afterward is the sh(1) function which utilizes the below awk script.
989 !/^[[:space:]]*(#|$)/ \
991 for (n=1; n++ < NF;) if ($n == name)
992 addrs = addrs (addrs ? " " : "") $1
995 if (addrs) print addrs
1001 local __host="$1" __var_to_set="$2"
1002 f_dprintf "f_host_lookup: host=[%s]" "$__host"
1004 # If we're configured to look at local files first, do that
1005 if awk '/^hosts:/{exit !($2=="files")}' "$NSSWITCH_CONF"; then
1006 if [ "$__var_to_set" ]; then
1008 if __cp=$( awk -v name="$__host" \
1009 "$f_host_lookup_awk" "$ETC_HOSTS" )
1011 setvar "$__var_to_set" "$__cp"
1015 awk -v name="$__host" \
1016 "$f_host_lookup_awk" "$ETC_HOSTS" &&
1022 # Fall back to host(1) -- which is further governed by nsswitch.conf(5)
1025 local __output __ip6 __addrs=
1026 f_getvar $VAR_IPV6_ENABLE __ip6
1028 # If we have a TCP media type configured, check for an SRV record
1030 { f_quietly f_getvar $VAR_HTTP_PATH ||
1031 f_quietly f_getvar $VAR_HTTP_PROXY_PATH
1032 } && __srvtypes="$__srvtypes _http._tcp"
1033 f_quietly f_getvar $VAR_FTP_PATH && __srvtypes="$__srvtypes _ftp._tcp"
1034 f_quietly f_getvar $VAR_NFS_PATH &&
1035 __srvtypes="$__srvtypes _nfs._tcp _nfs._udp"
1037 # Calculate wait time as dividend of total time and host(1) invocations
1038 local __host_runs __wait
1039 f_count __host_runs $__srvtypes
1040 if [ "$__ip6" = "YES" ]; then
1041 __host_runs=$(( $__host_runs + 2 ))
1043 __host_runs=$(( $__host_runs + 1 ))
1045 f_getvar $VAR_MEDIA_TIMEOUT __wait
1046 [ "$__wait" ] && __wait="-W $(( $__wait / $__host_runs ))"
1048 # Query SRV types first (1st host response taken as new host to query)
1049 for __type in $__srvtypes; do
1051 host -t SRV $__wait -- "$__type.$__host" \
1054 __host=$( echo "$__output" |
1055 awk '/ SRV /{print $NF;exit}' )
1060 # Try IPv6 first (if enabled)
1061 if [ "$__ip6" = "YES" ]; then
1062 if ! __output=$( host -t AAAA $__wait -- "$__host" 2>&1 ); then
1063 # An error occurred, display in-full and return error
1064 [ "$__var_to_set" ] &&
1065 setvar "$__var_to_set" "$__output"
1068 # Add the IPv6 addresses and fall-through to collect IPv4 too
1069 __addrs=$( echo "$__output" | awk '/ address /{print $NF}' )
1073 if ! __output=$( host -t A $__wait -- "$__host" 2>&1 ); then
1074 # An error occurred, display it in-full and return error
1075 [ "$__var_to_set" ] && setvar "$__var_to_set" "$__output"
1079 __addrs="$__addrs${__addrs:+ }$(
1080 echo "$__output" | awk '/ address /{print $NF}' )"
1081 if [ "$__var_to_set" ]; then
1082 setvar "$__var_to_set" "$__addrs"
1088 # f_device_dialog_tcp $device
1090 # This is it - how to get TCP setup values. Prompt the user to edit/confirm the
1091 # interface, gateway, nameserver, and hostname settings -- all required for
1092 # general TCP/IP access.
1094 # Variables from variable.subr that can be used to sript user input:
1097 # If set, prevents asking the user if they would like to use
1098 # rtsol(8) to check for an IPv6 router.
1100 # If set to "YES" (and VAR_NONINTERACTIVE is unset), asks the
1101 # user if they would like to try the IPv6 RouTer SOLicitation
1102 # utility (rtsol(8)) to get IPv6 information. Ignored if
1103 # VAR_NO_INET6 is set.
1105 # If set to "YES" (and VAR_NONINTERACTIVE is unset), asks the
1106 # user if they would like to try to acquire IPv4 connection
1107 # settings from a DHCP server using dhclient(8).
1109 # VAR_GATEWAY Default gateway to use.
1110 # VAR_IPADDR Interface address to assign.
1111 # VAR_NETMASK Interface subnet mask.
1112 # VAR_EXTRAS Extra interface options to ifconfig(8).
1113 # VAR_HOSTNAME Hostname to set.
1114 # VAR_DOMAINNAME Domain name to use.
1115 # VAR_NAMESERVER DNS nameserver to use when making lookups.
1116 # VAR_IPV6ADDR IPv6 interface address.
1118 # In addition, the following variables are used in acquiring network settings
1121 # VAR_NONINTERACTIVE
1122 # If set (such as when running in a script), prevents asking the
1123 # user questions or displaying the usual prompts, etc.
1124 # VAR_NETINTERACTIVE
1125 # The one exception to VAR_NONINTERACTIVE is VAR_NETINTERACTIVE,
1126 # which if set will prompt the user to try RTSOL (unless
1127 # VAR_TRY_RTSOL has been set), try DHCP (unless VAR_TRY_DHCP has
1128 # been set), and display the network verification dialog. This
1129 # allows you to have a mostly non-interactive script that still
1130 # prompts for network setup/confirmation.
1132 # After successful execution, the following variables are set:
1134 # VAR_IFCONFIG + $device (e.g., `ifconfig_em0')
1135 # Defines the ifconfig(8) properties specific to $device.
1137 f_device_dialog_tcp()
1139 local dev="$1" devname cp n
1140 local use_dhcp="" use_rtsol=""
1141 local _ipaddr _netmask _extras
1143 [ "$dev" ] || return $DIALOG_CANCEL
1144 f_struct "$dev" get name devname || return $DIALOG_CANCEL
1146 # Initialize vars from previous device values
1148 $dev get private private
1149 if [ "$private" ] && f_struct "$private"; then
1150 $private get ipaddr _ipaddr
1151 $private get netmask _netmask
1152 $private get extras _extras
1153 $private get use_dhcp use_dhcp
1154 $private get use_rtsol use_rtsol
1155 else # See if there are any defaults
1158 # This is a hack so that the dialogs below are interactive in a
1159 # script if we have requested interactive behavior.
1161 local old_interactive=
1162 if ! f_interactive && f_netinteractive; then
1163 f_getvar $VAR_NONINTERACTIVE old_interactive
1164 unset $VAR_NONINTERACTIVE
1168 # Try a RTSOL scan if such behavior is desired.
1169 # If the variable was configured and is YES, do it.
1170 # If it was configured to anything else, treat it as NO.
1171 # Otherwise, ask the question interactively.
1174 if ! f_isset $VAR_NO_INET6 && {
1175 { f_getvar $VAR_TRY_RTSOL try6 && [ "$try6" = "YES" ]; } ||
1177 # Only prompt the user when VAR_TRY_RTSOL is unset
1178 ! f_isset $VAR_TRY_RTSOL &&
1179 f_dialog_noyes "$msg_try_ipv6_configuration"
1184 f_quietly sysctl net.inet6.ip6.forwarding=0
1185 f_quietly sysctl net.inet6.ip6.accept_rtadv=1
1186 f_quietly ifconfig $devname up
1188 i=$( sysctl -n net.inet6.ip6.dad_count )
1191 f_quietly mkdir -p /var/run
1192 f_dialog_info "$msg_scanning_for_ra_servers"
1193 if f_quietly rtsol $devname; then
1194 i=$( sysctl -n net.inet6.ip6.dad_count )
1196 f_rtsol_get_info $devname
1204 # Try a DHCP scan if such behavior is desired.
1205 # If the variable was configured and is YES, do it.
1206 # If it was configured to anything else, treat it as NO.
1207 # Otherwise, ask the question interactively.
1210 if { f_getvar $VAR_TRY_DHCP try4 && [ "$try4" = "YES" ]; } || {
1211 # Only prompt the user when VAR_TRY_DHCP is unset
1212 ! f_isset $VAR_TRY_DHCP &&
1213 f_dialog_noyes "$msg_try_dhcp_configuration"
1215 f_quietly ifconfig $devname delete
1216 f_quietly mkdir -p /var/db
1217 f_quietly mkdir -p /var/run
1218 f_quietly mkdir -p /tmp
1220 local msg="$msg_scanning_for_dhcp_servers"
1222 ( # Execute in sub-shell to allow/catch Ctrl-C
1223 trap 'exit $FAILURE' SIGINT
1224 if [ "$USE_XDIALOG" ]; then
1225 f_quietly dhclient $devname |
1226 f_xdialog_info "$msg"
1228 f_dialog_info "$msg"
1229 f_quietly dhclient $devname
1233 trap 'f_interrupt' SIGINT
1234 if [ $retval -eq $SUCCESS ]; then
1235 f_dhcp_get_info $devname
1242 # Restore old VAR_NONINTERACTIVE if needed.
1243 [ "$old_interactive" ] &&
1244 setvar $VAR_NONINTERACTIVE "$old_interactive"
1246 # Special hack so it doesn't show up oddly in the menu
1248 if f_getvar $VAR_GATEWAY gw && [ "$gw" = "NO" ]; then
1249 setvar $VAR_GATEWAY ""
1252 # Get old IP address from variable space, if available
1253 if [ ! "$_ipaddr" ]; then
1254 if f_getvar $VAR_IPADDR cp; then
1256 elif f_getvar ${devname}_$VAR_IPADDR cp; then
1261 # Get old netmask from variable space, if available
1262 if [ ! "$_netmask" ]; then
1263 if f_getvar $VAR_NETMASK cp; then
1265 elif f_getvar ${devname}_$VAR_NETMASK cp; then
1270 # Get old extras string from variable space, if available
1271 if [ ! "$_extras" ]; then
1272 if f_getvar $VAR_EXTRAS cp; then
1274 elif f_getvar ${devname}_$VAR_EXTRAS cp; then
1280 # Look up values already recorded with the system, or blank the string
1281 # variables ready to accept some new data
1282 local _hostname _gateway _nameserver
1283 f_getvar $VAR_HOSTNAME _hostname
1284 case "$_hostname" in
1285 *.*) : do nothing ;; # Already fully-qualified
1287 f_getvar $VAR_DOMAINNAME cp
1288 [ "$cp" ] && _hostname="$_hostname.$cp"
1290 f_getvar $VAR_GATEWAY _gateway
1291 f_getvar $VAR_NAMESERVER _nameserver
1293 # Re-check variables for initial inheritance before heading into dialog
1294 [ "$_hostname" ] || _hostname="${HOSTNAME:-$( hostname )}"
1295 [ "$_gateway" ] || f_route_get_default _gateway
1296 [ ! "$_nameserver" ] &&
1297 f_resolv_conf_nameservers cp && _nameserver=${cp%%[$IFS]*}
1298 [ "$_ipaddr" ] || f_ifconfig_inet $devname _ipaddr
1299 [ "$_netmask" ] || f_ifconfig_netmask $devname _netmask
1301 # If non-interactive, jump over dialog section and into config section
1302 if f_netinteractive || f_interactive || [ ! "$_hostname" ]
1304 [ ! "$_hostname" ] && f_interactive &&
1305 f_show_msg "$msg_hostname_variable_not_set"
1307 local title=" $msg_network_configuration "
1308 local hline="$hline_alnum_arrows_punc_tab_enter"
1309 local extras_help="$tcplayout_extras_help"
1311 # Modify the help line for PLIP config
1312 [ "${devname#plip}" != "$devname" ] &&
1313 extras_help="$tcplayout_extras_help_for_plip"
1315 f_getvar $VAR_IPV6ADDR cp && [ "$cp" ] &&
1316 title="$title($msg_ipv6_ready) "
1318 if [ ! "$USE_XDIALOG" ]; then
1319 local prompt="$msg_dialog_mixedform_navigation_help"
1320 # Calculate center position for displaying device label
1321 local devlabel="$msg_configuration_for_interface"
1322 devlabel="$devlabel $devname"
1324 local n=$(( $width/2 - (${#devlabel} + 4)/2 - 2 ))
1329 --backtitle "$DIALOG_BACKTITLE" \
1332 --ok-label "$msg_ok" \
1333 --cancel-label "$msg_cancel" \
1335 --help-label "$msg_help" \
1336 --mixedform "$prompt" 16 $width 9 \
1337 "$msg_host_name_including_domain:" 1 2 \
1338 "$_hostname" 2 3 45 255 0 \
1339 "$tcplayout_hostname_help" \
1340 "$msg_ipv4_gateway:" 3 2 \
1341 "$_gateway" 4 3 16 15 0 \
1342 "$tcplayout_gateway_help" \
1343 "$msg_name_server:" 3 31 \
1344 "$_nameserver" 4 32 16 15 0 \
1345 "$tcplayout_nameserver_help" \
1346 "- $devlabel -" 5 $n "" 0 0 0 0 3 "" \
1347 "$msg_ipv4_address:" 6 6 \
1348 "$_ipaddr" 7 7 16 15 0 \
1349 "$tcplayout_ipaddr_help" \
1350 "$msg_netmask:" 6 31 \
1351 "$_netmask" 7 32 16 15 0 \
1352 "$tcplayout_netmask_help" \
1353 "$msg_extra_options_to_ifconfig" 8 6 \
1354 "$_extras" 9 7 41 2048 0 \
1356 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD )
1358 # --mixed-form always returns 0, we have to
1359 # use the returned data to determine button
1360 if [ ! "$cp" ]; then
1361 # User either chose "Cancel", pressed
1362 # ESC, or blanked every form field
1363 return $DIALOG_CANCEL
1365 n=$( echo "$cp" | f_number_of_lines )
1366 [ $n -eq 1 ] && case "$cp" in HELP*)
1368 f_show_help "$TCP_HELPFILE"
1373 # Turn mixed-form results into env variables
1374 eval "$( echo "$cp" | awk '
1377 field[++n] = "_hostname"
1378 field[++n] = "_gateway"
1379 field[++n] = "_nameserver"
1380 field[++n] = "_ipaddr"
1381 field[++n] = "_netmask"
1382 field[++n] = "_extras"
1387 gsub(/'\''/, "'\'\\\\\'\''")
1388 sub(/[[:space:]]*$/, "")
1389 value[field[++n]] = $0
1392 for ( n = 1; n <= nfields; n++ )
1394 printf "%s='\''%s'\'';\n",
1400 f_dialog_validate_tcpip \
1409 # Xdialog(1) does not support --mixed-form
1410 # Create a persistent menu instead
1412 f_dialog_title "$msg_network_configuration"
1417 --title "$DIALOG_TITLE" \
1418 --backtitle "$DIALOG_BACKTITLE" \
1421 --ok-label "$msg_ok" \
1422 --cancel-label "$msg_cancel" \
1424 --menu "$prompt" 21 60 8 \
1425 "$msg_accept_continue" "" \
1426 "$tcplayout_accept_cont_help" \
1427 "$msg_host_name_including_domain:" \
1429 "$tcplayout_hostname_help" \
1430 "$msg_ipv4_gateway:" "$_gateway" \
1431 "$tcplayout_gateway_help" \
1432 "$msg_name_server:" "$_nameserver" \
1433 "$tcplayout_nameserver_help" \
1434 "$msg_ipv4_address:" "$_ipaddr" \
1435 "$tcplayout_ipaddr_help" \
1436 "$msg_netmask:" "$_netmask" \
1437 "$tcplayout_netmask_help" \
1438 "$msg_extra_options_to_ifconfig" \
1439 "$_extras" "$extras_help" \
1440 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
1443 f_dialog_data_sanitize cp
1444 f_dprintf "retval=%u mtag=[%s]" $retval "$cp"
1446 if [ $retval -eq $DIALOG_HELP ]; then
1447 f_show_help "$TCP_HELPFILE"
1449 elif [ $retval -ne $DIALOG_OK ]; then
1450 f_dialog_title_restore
1451 return $DIALOG_CANCEL
1455 "$msg_accept_continue")
1456 f_dialog_validate_tcpip \
1463 "$msg_host_name_including_domain:")
1464 f_dialog_input cp "$cp" "$_hostname" \
1465 && _hostname="$cp" ;;
1466 "$msg_ipv4_gateway:")
1467 f_dialog_input cp "$cp" "$_gateway" \
1468 && _gateway="$cp" ;;
1469 "$msg_name_server:")
1470 f_dialog_input cp "$cp" "$_nameserver" \
1471 && _nameserver="$cp" ;;
1472 "$msg_ipv4_address:")
1473 f_dialog_input cp "$cp" "$_ipaddr" \
1476 f_dialog_input cp "$cp" "$_netmask" \
1477 && _netmask="$cp" ;;
1478 "$msg_extra_options_to_ifconfig")
1479 f_dialog_input cp "$cp" "$_extras" \
1484 f_dialog_title_restore
1490 # We actually need to inform the rest of bsdconfig about this
1491 # data now if the user hasn't selected cancel.
1493 if [ "$_hostname" ]; then
1494 setvar $VAR_HOSTNAME "$_hostname"
1495 f_quietly hostname "$_hostname"
1496 case "$_hostname" in
1497 *.*) setvar $VAR_DOMAINNAME "${_hostname#*.}" ;;
1500 [ "$_gateway" ] && setvar $VAR_GATEWAY "$_gateway"
1501 [ "$_nameserver" ] && setvar $VAR_NAMESERVER "$_nameserver"
1502 [ "$_ipaddr" ] && setvar $VAR_IPADDR "$_ipaddr"
1503 [ "$_netmask" ] && setvar $VAR_NETMASK "$_netmask"
1504 [ "$_extras" ] && setvar $VAR_EXTRAS "$_extras"
1506 f_dprintf "Creating struct DEVICE_INFO devinfo_%s" "$dev"
1507 f_struct_new DEVICE_INFO devinfo_$dev
1508 $dev set private devinfo_$dev
1510 devinfo_$dev set ipaddr $_ipaddr
1511 devinfo_$dev set netmask $_netmask
1512 devinfo_$dev set extras $_extras
1513 devinfo_$dev set use_rtsol $use_rtsol
1514 devinfo_$dev set use_dhcp $use_dhcp
1516 if [ "$use_dhcp" -o "$_ipaddr" ]; then
1517 if [ "$use_dhcp" ]; then
1518 cp="DHCP${extras:+ $extras}"
1520 cp="inet $_ipaddr netmask $_netmask${extras:+ $extras}"
1522 setvar $VAR_IFCONFIG$devname "$cp"
1525 setvar $VAR_IPV6_ENABLE "YES"
1528 f_config_resolv # XXX this will do it on the MFS copy
1533 # f_device_scan_tcp [$var_to_set]
1535 # Scan for the first active/configured TCP/IP device. The name of the interface
1536 # is printed to stderr like other dialog(1)-based functions (stdout is reserved
1537 # for dialog(1) interaction) if $var_to_set is missing or NULL. Returns failure
1538 # if no active/configured interface
1542 local __var_to_set="$1" __iface
1543 for __iface in $( ifconfig -l ); do
1544 if ifconfig $__iface | awk '
1546 has_inet = has_inet6 = is_ethernet = 0
1549 ( $1 == "status:" && $2 != "active" ) { is_usable = 0; exit }
1551 if ($2 == "0.0.0.0") { is_usable = 0; exit }
1554 ( $1 == "inet6") { has_inet6++ }
1555 ( $1 == "media:" ) {
1556 if ($2 != "Ethernet") { is_usable = 0; exit }
1560 if (!(is_ethernet && (has_inet || has_inet6)))
1565 f_show_msg "$msg_using_interface" "$__iface"
1566 f_dprintf "f_device_scan_tcp found %s" "$__iface"
1567 if [ "$__var_to_set" ]; then
1568 setvar "$__var_to_set" "$__iface"
1579 # f_device_select_tcp
1581 # Prompt the user to select network interface to use for TCP/IP access.
1582 # Variables from variable.subr that can be used to script user input:
1584 # VAR_NETWORK_DEVICE [Optional]
1585 # Either a comma-separated list of network interfaces to try when
1586 # setting up network access (e.g., "fxp0,em0") or "ANY" (case-
1587 # sensitive) to indicate that the first active and configured
1588 # interface is acceptable. If unset, the user is presented with a
1589 # menu of all available network interfaces.
1591 # Returns success if a valid network interface has been selected.
1593 f_device_select_tcp()
1595 local devs dev cnt if network_dev
1596 f_getvar $VAR_NETWORK_DEVICE network_dev
1598 f_dprintf "f_device_select_tcp: %s=[%s]" \
1599 VAR_NETWORK_DEVICE "$network_dev"
1601 if [ "$network_dev" ]; then
1603 # This can be set to several types of values. If set to ANY,
1604 # scan all network devices looking for a valid link, and go
1605 # with the first device found. Can also be specified as a
1606 # comma delimited list, with each network device tried in
1607 # order. Can also be set to a single network device.
1609 [ "$network_dev" = "ANY" ] && f_device_scan_tcp network_dev
1611 while [ "$network_dev" ]; do
1612 case "$network_dev" in
1613 *,*) if="${network_dev%%,*}"
1614 network_dev="${network_dev#*,}"
1616 *) if="$network_dev"
1620 f_device_find -1 "$if" $DEVICE_TYPE_NETWORK dev
1621 f_device_dialog_tcp $dev
1622 if [ $? -eq $DIALOG_OK ]; then
1623 setvar $VAR_NETWORK_DEVICE $if
1628 f_interactive && f_show_msg "$msg_no_network_devices"
1629 return $DIALOG_CANCEL
1633 f_device_find "" $DEVICE_TYPE_NETWORK devs
1635 dev="${devs%%[$IFS]*}"
1638 f_quietly f_getvar NETWORK_CONFIGURED # for debugging info
1639 if ! f_running_as_init &&
1640 ! [ "${NETWORK_CONFIGURED+set}" -a "$NETWORK_CONFIGURED" = "NO" ]
1642 trap 'f_interrupt' SIGINT
1643 if f_dialog_yesno "$msg_assume_network_is_already_configured"
1645 setvar $VAR_NETWORK_DEVICE $if
1650 local retval=$SUCCESS
1651 if [ ${cnt:=0} -eq 0 ]; then
1652 f_show_msg "$msg_no_network_devices"
1653 retval=$DIALOG_CANCEL
1654 elif [ $cnt -eq 1 ]; then
1655 f_device_dialog_tcp $dev
1657 [ $retval -eq $DIALOG_OK ] && setvar $VAR_NETWORK_DEVICE $if
1659 local title="$msg_network_interface_information_required"
1660 local prompt="$msg_please_select_ethernet_device_to_configure"
1661 local hline="$hline_arrows_tab_enter"
1663 dev=$( f_device_menu \
1664 "$title" "$prompt" "$hline" $DEVICE_TYPE_NETWORK \
1665 "$NETWORK_DEVICE_HELPFILE" \
1666 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD ) ||
1667 return $DIALOG_CANCEL
1669 f_device_dialog_tcp $dev
1671 if [ $retval -eq $DIALOG_OK ]; then
1672 f_struct_copy "$dev" device_network
1673 setvar $VAR_NETWORK_DEVICE device_network
1675 f_struct_free device_network
1682 # f_dialog_menu_select_tcp
1684 # Like f_dialog_select_tcp() above, but do it from a menu that doesn't care
1685 # about status. In other words, where f_dialog_select_tcp() will not display a
1686 # menu if scripted, this function will always display the menu of available
1687 # network interfaces.
1689 f_dialog_menu_select_tcp()
1691 local private use_dhcp name
1692 NETWORK_CONFIGURED=NO f_device_select_tcp
1693 if f_struct device_network &&
1694 device_network get private private &&
1695 f_struct_copy "$private" di &&
1696 di get use_dhcp use_dhcp &&
1697 [ ! "$use_dhcp" ] &&
1698 device_network get name name &&
1699 f_yesno "$msg_would_you_like_to_bring_interface_up" "$name"
1701 if ! f_device_init device_network; then
1702 f_show_msg "$msg_initialization_of_device_failed" \
1709 ############################################################ MAIN
1711 f_dprintf "%s: Successfully loaded." media/tcpip.subr
1713 fi # ! $_MEDIA_TCPIP_SUBR