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/struct.subr
37 f_include $BSDCFG_SHARE/variable.subr
39 BSDCFG_LIBE="/usr/libexec/bsdconfig"
40 f_include_lang $BSDCFG_LIBE/include/messages.subr
42 TCP_HELPFILE=$BSDCFG_LIBE/include/tcp.hlp
43 NETWORK_DEVICE_HELPFILE=$BSDCFG_LIBE/include/network_device.hlp
45 ############################################################ GLOBALS
48 # Path to resolv.conf(5).
50 : ${RESOLV_CONF:="/etc/resolv.conf"}
53 # Path to nsswitch.conf(5).
55 : ${NSSWITCH_CONF:="/etc/nsswitch.conf"}
60 : ${ETC_HOSTS:="/etc/hosts"}
63 # Structure of dhclient.leases(5) lease { ... } entry
65 f_struct_define DHCP_LEASE \
80 dhcp_server_identifier \
87 ############################################################ FUNCTIONS
89 # f_validate_hostname $hostname
91 # Returns zero if the given argument (a fully-qualified hostname) is compliant
92 # with standards set-forth in RFC's 952 and 1123 of the Network Working Group:
94 # RFC 952 - DoD Internet host table specification
95 # http://tools.ietf.org/html/rfc952
97 # RFC 1123 - Requirements for Internet Hosts - Application and Support
98 # http://tools.ietf.org/html/rfc1123
100 # See http://en.wikipedia.org/wiki/Hostname for a brief overview.
102 # The return status for invalid hostnames is one of:
103 # 255 Entire hostname exceeds the maximum length of 255 characters.
104 # 63 One or more individual labels within the hostname (separated by
105 # dots) exceeds the maximum of 63 characters.
106 # 1 One or more individual labels within the hostname contains one
107 # or more invalid characters.
108 # 2 One or more individual labels within the hostname starts or
109 # ends with a hyphen (hyphens are allowed, but a label cannot
110 # begin or end with a hyphen).
111 # 3 One or more individual labels within the hostname are null.
113 # f_dialog_validate_hostname $hostname
115 # If the hostname is determined to be invalid, the appropriate error will be
116 # displayed using the f_show_msg function.
118 f_validate_hostname()
122 # Return error if the hostname exceeds 255 characters
123 [ ${#fqhn} -gt 255 ] && return 255
125 local IFS="." # Split on `dot'
126 for label in $fqhn; do
127 # Return error if the label exceeds 63 characters
128 [ ${#label} -gt 63 ] && return 63
130 # Return error if the label is null
131 [ "$label" ] || return 3
133 # Return error if label begins/ends with dash
134 case "$label" in -*|*-) return 2; esac
136 # Return error if the label contains any invalid chars
137 case "$label" in *[!0-9a-zA-Z-]*) return 1; esac
143 # f_inet_atoi $ipv4_address [$var_to_set]
145 # Convert an IPv4 address or mask from dotted-quad notation (e.g., `127.0.0.1'
146 # or `255.255.255.0') to a 32-bit unsigned integer for the purpose of network
147 # and broadcast calculations. For example, one can validate that two addresses
148 # are on the same network:
150 # f_inet_atoi 1.2.3.4 ip1num
151 # f_inet_atoi 1.2.4.5 ip2num
152 # f_inet_atoi 255.255.0.0 masknum
153 # if [ $(( $ip1num & $masknum )) -eq \
154 # $(( $ip2num & $masknum )) ]
156 # : IP addresses are on same network
159 # See f_validate_ipaddr() below for an additional example usage, on calculating
160 # network and broadcast addresses.
162 # If $var_to_set is missing or NULL, the converted IP address is printed to
163 # standard output for capturing in a sub-shell (which is less-recommended
164 # because of performance degredation; for example, when called in a loop).
168 local __addr="$1" __var_to_set="$2" __num=0
169 if f_validate_ipaddr "$__addr"; then
170 __num=$( IFS=.; set -- $__addr; \
171 echo $(( ($1 << 24) + ($2 << 16) + ($3 << 8) + $4 )) )
173 if [ "$__var_to_set" ]; then
174 setvar "$__var_to_set" $__num
180 # f_validate_ipaddr $ipaddr [$netmask]
182 # Returns zero if the given argument (an IP address) is of the proper format.
184 # The return status for invalid IP address is one of:
185 # 1 One or more individual octets within the IP address (separated
186 # by dots) contains one or more invalid characters.
187 # 2 One or more individual octets within the IP address are null
189 # 3 One or more individual octets within the IP address exceeds the
190 # maximum of 255 (or 2^8, being an octet comprised of 8 bits).
191 # 4 The IP address has either too few or too many octets.
193 # If a netmask is provided, the IP address is checked further:
195 # 5 The IP address must not be the network or broadcast address.
199 local ip="$1" mask="$2"
201 # Track number of octets for error checking
205 local IFS="." # Split on `dot'
207 # Return error if the octet is null
208 [ "$octet" ] || return 2
210 # Return error if not a whole integer
211 f_isinteger "$octet" || return 1
213 # Return error if not a positive integer
214 [ $octet -ge 0 ] || return 1
216 # Return error if the octet exceeds 255
217 [ $octet -gt 255 ] && return 3
219 noctets=$(( $noctets + 1 ))
223 [ $noctets -eq 4 ] || return 4
226 # The IP address must not be network or broadcast address.
229 local ipnum masknum netnum bcastnum
230 local max_addr=4294967295 # 255.255.255.255
232 f_inet_atoi $ip ipnum
233 f_inet_atoi $mask masknum
235 netnum=$(( $ipnum & $masknum ))
236 bcastnum=$(( ($ipnum & $masknum)+$max_addr-$masknum ))
239 [ $ipnum -eq $netnum -o $ipnum -eq $bcastnum ]
248 # f_validate_ipaddr6 $ipv6_addr
250 # Returns zero if the given argument (an IPv6 address) is of the proper format.
252 # The return status for invalid IP address is one of:
253 # 1 One or more individual segments within the IP address
254 # (separated by colons) contains one or more invalid characters.
255 # Segments must contain only combinations of the characters 0-9,
257 # 2 Too many/incorrect null segments. A single null segment is
258 # allowed within the IP address (separated by colons) but not
259 # allowed at the beginning or end (unless a double-null segment;
260 # i.e., "::*" or "*::").
261 # 3 One or more individual segments within the IP address
262 # (separated by colons) exceeds the length of 4 hex-digits.
263 # 4 The IP address entered has either too few (less than 3), too
264 # many (more than 8), or not enough segments, separated by
266 # 5* The IPv4 address at the end of the IPv6 address is invalid.
267 # * When there is an error with the dotted-quad IPv4 address at the
268 # end of the IPv6 address, the return value of 5 is OR'd with a
269 # bit-shifted (<< 4) return of f_validate_ipaddr.
273 local ip="${1%\%*}" # removing the interface specification if-present
275 local IFS=":" # Split on `colon'
278 # Return error if too many or too few segments
279 # Using 9 as max in case of leading or trailing null spanner
280 [ $# -gt 9 -o $# -lt 3 ] && return 4
282 local h="[0-9A-Fa-f]"
283 local nulls=0 nsegments=$# contains_ipv4_segment=
285 while [ $# -gt 0 ]; do
291 # Return error if this segment makes one null too-many. A
292 # single null segment is allowed anywhere in the middle as well
293 # as double null segments are allowed at the beginning or end
296 if [ ! "$segment" ]; then
297 nulls=$(( $nulls + 1 ))
298 if [ $nulls -eq 3 ]; then
299 # Only valid syntax for 3 nulls is `::'
300 [ "$ip" = "::" ] || return 2
301 elif [ $nulls -eq 2 ]; then
302 # Only valid if begins/ends with `::'
304 ::*|*::) : fall thru ;;
312 # Return error if not a valid hexadecimal short
315 $h|$h$h|$h$h$h|$h$h$h$h)
316 : valid segment of 1-4 hexadecimal digits
319 # Segment contains at least one invalid char
321 # Return error immediately if not last segment
322 [ $# -eq 0 ] || return 1
324 # Otherwise, check for legacy IPv4 notation
327 # Segment contains at least one invalid
328 # character even for an IPv4 address
332 # Return error if not enough segments
333 if [ $nulls -eq 0 ]; then
334 [ $nsegments -eq 7 ] || return 4
337 contains_ipv4_segment=1
339 # Validate the IPv4 address
340 f_validate_ipaddr "$segment" ||
341 return $(( 5 | $? << 4 ))
344 # Segment characters are all valid but too many
350 if [ $nulls -eq 1 ]; then
351 # Single null segment cannot be at beginning/end
358 # A legacy IPv4 address can span the last two 16-bit segments,
359 # reducing the amount of maximum allowable segments by-one.
362 if [ "$contains_ipv4_segment" ]; then
367 # Return error if missing segments with no null spanner
368 0) [ $nsegments -eq $maxsegments ] || return 4 ;;
369 # Return error if null spanner with too many segments
370 1) [ $nsegments -le $maxsegments ] || return 4 ;;
371 # Return error if leading/trailing `::' with too many segments
372 2) [ $nsegments -le $(( $maxsegments + 1 )) ] || return 4 ;;
378 # f_validate_netmask $netmask
380 # Returns zero if the given argument (a subnet mask) is of the proper format.
382 # The return status for invalid netmask is one of:
383 # 1 One or more individual fields within the subnet mask (separated
384 # by dots) contains one or more invalid characters.
385 # 2 One or more individual fields within the subnet mask are null
387 # 3 One or more individual fields within the subnet mask exceeds
388 # the maximum of 255 (a full 8-bit register).
389 # 4 The subnet mask has either too few or too many fields.
390 # 5 One or more individual fields within the subnet mask is an
391 # invalid integer (only 0,128,192,224,240,248,252,254,255 are
398 # Track number of fields for error checking
401 local IFS="." # Split on `dot'
402 for field in $mask; do
403 # Return error if the field is null
404 [ "$field" ] || return 2
406 # Return error if not a whole positive integer
407 f_isinteger "$field" || return 1
409 # Return error if the field exceeds 255
410 [ $field -gt 255 ] && return 3
412 # Return error if the field is an invalid integer
414 0|128|192|224|240|248|252|254|255) : ;;
418 nfields=$(( $nfields + 1 ))
421 [ $nfields -eq 4 ] || return 4
424 # f_validate_gateway $gateway $ipaddr $netmask
426 # Validate an IPv4 default gateway (aka router) address for a given IP address
427 # making sure the two are in the same network (able to ``talk'' to each other).
428 # Returns success if $ipaddr and $gateway are in the same network given subnet
433 local gateway="$1" ipaddr="$2" netmask="$3"
434 local gwnum ipnum masknum
436 f_validate_ipaddr "$gateway" "$netmask" || return $FAILURE
438 f_inet_atoi "$netmask" masknum
439 f_inet_atoi "$ipaddr" ipnum
440 f_inet_atoi "$gateway" gwnum
442 # Gateway must be within set of IPs reachable through interface
443 [ $(( $ipnum & $masknum )) -eq \
444 $(( $gwnum & $masknum )) ] # Return status
447 # f_dialog_validate_tcpip $hostname $gateway $nameserver $ipaddr $netmask
449 # Returns success if the arguments provided are valid for accessing a TCP/IP
450 # network, otherwise returns failure.
452 f_dialog_validate_tcpip()
454 local hostname="$1" gateway="$2" nameserver="$3"
455 local ipaddr="$4" netmask="$5"
458 if [ ! "$hostname" ]; then
459 f_show_msg "$msg_must_specify_a_host_name_of_some_sort"
460 elif ! f_validate_hostname "$hostname"; then
461 f_show_msg "$msg_invalid_hostname_value"
462 elif [ "$netmask" ] && ! f_validate_netmask "$netmask"; then
463 f_show_msg "$msg_invalid_netmask_value"
464 elif [ "$nameserver" ] &&
465 ! f_validate_ipaddr "$nameserver" &&
466 ! f_validate_ipaddr6 "$nameserver"; then
467 f_show_msg "$msg_invalid_name_server_ip_address_specified"
468 elif [ "$ipaddr" ] && ! f_validate_ipaddr "$ipaddr" "$netmask"; then
469 f_show_msg "$msg_invalid_ipv4_address"
470 elif [ "$gateway" -a "$gateway" != "NO" ] &&
471 ! f_validate_gateway "$gateway" "$ipaddr" "$netmask"; then
472 f_show_msg "$msg_invalid_gateway_ipv4_address_specified"
477 return $DIALOG_CANCEL
480 # f_ifconfig_inet $interface [$var_to_set]
482 # Returns the IPv4 address associated with $interface. If $var_to_set is
483 # missing or NULL, the IP address is printed to standard output for capturing
484 # in a sub-shell (which is less-recommended because of performance degredation;
485 # for example, when called in a loop).
487 # This function is a two-parter. Below is the awk(1) portion of the function,
488 # afterward is the sh(1) function which utilizes the below awk script.
490 f_ifconfig_inet_awk='
502 local __interface="$1" __var_to_set="$2"
503 if [ "$__var_to_set" ]; then
505 __ip=$( ifconfig "$__interface" 2> /dev/null |
506 awk "$f_ifconfig_inet_awk" )
507 setvar "$__var_to_set" "$__ip"
509 ifconfig "$__interface" 2> /dev/null |
510 awk "$f_ifconfig_inet_awk"
514 # f_ifconfig_inet6 $interface [$var_to_set]
516 # Returns the IPv6 address associated with $interface. If $var_to_set is
517 # missing or NULL, the IP address is printed to standard output for capturing
518 # in a sub-shell (which is less-recommended because of performance degredation;
519 # for example, when called in a loop).
521 # This function is a two-parter. Below is the awk(1) portion of the function,
522 # afterward is the sh(1) function which utilizes the below awk script.
524 f_ifconfig_inet6_awk='
536 local __interface="$1" __var_to_set="$2"
537 if [ "$__var_to_set" ]; then
539 __ip6=$( ifconfig "$__interface" 2> /dev/null |
540 awk "$f_ifconfig_inet6_awk" )
541 setvar "$__var_to_set" "$__ip6"
543 ifconfig "$__interface" 2> /dev/null |
544 awk "$f_ifconfig_inet6_awk"
548 # f_ifconfig_netmask $interface [$var_to_set]
550 # Returns the IPv4 subnet mask associated with $interface. If $var_to_set is
551 # missing or NULL, the netmask is printed to standard output for capturing in a
552 # sub-shell (which is less-recommended because of performance degredation; for
553 # example, when called in a loop).
557 local __interface="$1" __var_to_set="$2" __octets
558 __octets=$( ifconfig "$__interface" 2> /dev/null | awk \
563 printf "%s %s %s %s\n",
572 ' ) || return $FAILURE
574 local __octet __netmask=
575 for __octet in $__octets; do
576 __netmask="$__netmask.$( printf "%u" "0x$__octet" )"
578 __netmask="${__netmask#.}"
579 if [ "$__var_to_set" ]; then
580 setvar "$__var_to_set" "$__netmask"
586 # f_route_get_default [$var_to_set]
588 # Returns the IP address of the currently active default router. If $var_to_set
589 # is missing or NULL, the IP address is printed to standard output for
590 # capturing in a sub-shell (which is less-recommended because of performance
591 # degredation; for example, when called in a loop).
593 # This function is a two-parter. Below is the awk(1) portion of the function,
594 # afterward is the sh(1) function which utilizes the below awk script.
596 f_route_get_default_awk='
598 ( $1 == "gateway:" ) \
606 f_route_get_default()
608 local __var_to_set="$1"
609 if [ "$__var_to_set" ]; then
611 __ip=$( route -n get default 2> /dev/null |
612 awk "$f_route_get_default_awk" )
613 setvar "$__var_to_set" "$__ip"
615 route -n get default 2> /dev/null |
616 awk "$f_route_get_default_awk"
620 # f_resolv_conf_nameservers [$var_to_set]
622 # Returns nameserver(s) configured in resolv.conf(5). If $var_to_set is missing
623 # or NULL, the list of nameservers is printed to standard output for capturing
624 # in a sub-shell (which is less-recommended because of performance degredation;
625 # for example, when called in a loop).
627 # This function is a two-parter. Below is the awk(1) portion of the function,
628 # afterward is the sh(1) function which utilizes the below awk script.
630 f_resolv_conf_nameservers_awk='
632 ( $1 == "nameserver" ) \
639 f_resolv_conf_nameservers()
641 local __var_to_set="$1"
642 if [ "$__var_to_set" ]; then
644 __ns=$( awk "$f_resolv_conf_nameservers_awk" "$RESOLV_CONF" \
646 setvar "$__var_to_set" "$__ns"
648 awk "$f_resolv_conf_nameservers_awk" "$RESOLV_CONF" \
655 # Attempts to configure resolv.conf(5) and ilk. Returns success if able to
656 # write the file(s), otherwise returns error status.
658 # Variables from variable.subr that are used in configuring resolv.conf(5) are
659 # as follows (all of which can be configured automatically through functions
660 # like f_dhcp_get_info() or manually):
663 # The nameserver to add in resolv.conf(5).
665 # The domain to configure in resolv.conf(5). Also used in the
666 # configuration of hosts(5).
668 # The IPv4 address to configure in hosts(5).
670 # The IPv6 address to configure in hosts(5).
672 # The hostname to associate with the IPv4 and/or IPv6 address in
679 f_getvar $VAR_NAMESERVER cp
681 case "$RESOLV_CONF" in
682 */*) f_quietly mkdir -p "${RESOLV_CONF%/*}" ;;
685 # Attempt to create/truncate the file
686 ( :> "$RESOLV_CONF" ) 2> /dev/null || return $FAILURE
688 f_getvar $VAR_DOMAINNAME dp &&
689 printf "domain\t%s\n" "$dp" >> "$RESOLV_CONF"
690 printf "nameserver\t%s\n" "$cp" >> "$RESOLV_CONF"
692 f_dprintf "Wrote out %s" "$RESOLV_CONF"
695 f_getvar $VAR_DOMAINNAME dp
696 f_getvar $VAR_IPADDR cp
697 f_getvar $VAR_IPV6ADDR c6p
698 f_getvar $VAR_HOSTNAME hp
700 # Attempt to create the file if it doesn't already exist
701 if [ ! -e "$ETC_HOSTS" ]; then
703 */*) f_quietly mkdir -p "${ETC_HOSTS%/*}" ;;
706 ( :> "$ETC_HOSTS" ) 2> /dev/null || return $FAILURE
709 # Scan the file and add ourselves if not already configured
710 awk -v dn="$dp" -v ip4="$cp" -v ip6="$c6p" -v hn="$hp" '
712 local4found = local6found = 0
713 hn4found = hn6found = h4found = h6found = 0
714 h = ( match(hn, /\./) ? substr(hn, 0, RSTART-1) : "" )
716 ($1 == "127.0.0.1") { local4found = 1 }
717 ($1 == "::1") { local6found = 1 }
719 for (n = 2; n <= NF; n++)
722 if ( $n == h ) h4found = 1
723 if ( $n == hn ) hn4found = 1
724 if ( $n == hn "." ) hn4found = 1
727 if ( $n == h ) h6found = 1
728 if ( $n == hn ) hn6found = 1
729 if ( $n == hn "." ) hn6found = 1
737 printf "::1\t\t\tlocalhost%s\n",
738 ( dn ? " localhost." dn : "" ) >> hosts
740 printf "127.0.0.1\t\tlocalhost%s\n",
741 ( dn ? " localhost." dn : "" ) >> hosts
743 if ( ip6 && ! (h6found && hn6found))
745 printf "%s\t%s %s\n", ip6, hn, h >> hosts
746 printf "%s\t%s.\n", ip6, hn >> hosts
751 printf "%s\t%s.\n", ip6, h >> hosts
753 printf "%s\t%s\n", ip6, hn >> hosts
756 if ( ip4 && ! (h4found && hn4found))
758 printf "%s\t\t%s %s\n", ip4, hn, h >> hosts
759 printf "%s\t\t%s.\n", ip4, hn >> hosts
764 printf "%s\t\t%s.\n", ip4, h >> hosts
766 printf "%s\t\t%s\n", ip4, hn >> hosts
769 ' "$ETC_HOSTS" 2> /dev/null || return $FAILURE
771 f_dprintf "Wrote out %s" "$ETC_HOSTS"
775 # f_dhcp_parse_leases $leasefile struct_name
777 # Parse $leasefile and store the information for the most recent lease in a
778 # struct (see struct.subr for additional details) named `struct_name'. See
779 # DHCP_LEASE struct definition in the GLOBALS section above.
781 f_dhcp_parse_leases()
783 local leasefile="$1" struct_name="$2"
785 [ "$struct_name" ] || return $FAILURE
787 if [ ! -e "$leasefile" ]; then
788 f_dprintf "%s: No such file or directory" "$leasefile"
792 f_struct "$struct_name" && f_struct_free "$struct_name"
793 f_struct_new DHCP_LEASE "$struct_name"
795 eval "$( awk -v struct="$struct_name" '
806 split(keyword_list, keywords, FS)
808 time_list = "renew rebind expire"
809 split(time_list, times, FS)
815 domain-name-servers \
820 dhcp-server-identifier \
822 dhcp-rebinding-time \
824 split(option_list, options, FS)
826 function set_value(prop,value)
829 gsub(/[^[:alnum:]_]/, "_", prop)
833 sub(/,.*/, "", value)
834 printf "%s set %s \"%s\"\n", struct, prop, value
838 if ( $0 ~ /^lease {$/ ) next
839 if ( $0 ~ /^}$/ ) exit
843 keyword = keywords[k]
846 set_value(keyword, $2)
856 set_value(time, $2 " " $3 " " $4)
861 if ( $1 != "option" ) next
867 set_value(option, $3)
875 printf "f_struct_free \"%s\"\n", struct
876 print "return $FAILURE"
882 # f_dhcp_get_info $interface
884 # Parse the dhclient(8) lease database for $interface to obtain all the
885 # necessary IPv4 details necessary to communicate on the network. The retrieved
886 # information is stored in VAR_IPADDR, VAR_NETMASK, VAR_GATEWAY, and
889 # If reading the lease database fails, values are obtained from ifconfig(8) and
890 # route(8). If the DHCP lease did not provide a nameserver (or likewise, we
891 # were unable to parse the lease database), fall-back to resolv.conf(5) for
892 # obtaining the nameserver. Always returns success.
896 local interface="$1" cp
897 local leasefile="/var/db/dhclient.leases.$interface"
899 # If it fails, do it the old-fashioned way
900 if f_dhcp_parse_leases "$leasefile" lease; then
901 lease get fixed_address $VAR_IPADDR
902 lease get subnet_mask $VAR_NETMASK
904 setvar $VAR_GATEWAY "${cp%%,*}"
905 lease get domain_name_servers cp
906 setvar $VAR_NAMESERVER "${cp%%,*}"
907 lease get host_name cp &&
908 setvar $VAR_HOSTNAME "$cp"
911 # Bah, now we have to get the information from ifconfig
913 f_dprintf "DHCP configured interface returns %s" \
914 "$( ifconfig "$interface" )"
916 f_ifconfig_inet "$interface" $VAR_IPADDR
917 f_ifconfig_netmask "$interface" $VAR_NETMASK
918 f_route_get_default $VAR_GATEWAY
921 # If we didn't get a name server value, hunt for it in resolv.conf
923 if [ -r "$RESOLV_CONF" ] && ! {
924 f_getvar $VAR_NAMESERVER ns || [ "$ns" ]
926 f_resolv_conf_nameservers cp &&
927 setvar $VAR_NAMESERVER ${cp%%[$IFS]*}
933 # f_rtsol_get_info $interface
935 # Returns the rtsol-provided IPv6 address associated with $interface. The
936 # retrieved IP address is stored in VAR_IPV6ADDR. Always returns success.
940 local interface="$1" cp
941 cp=$( ifconfig "$interface" 2> /dev/null | awk \
944 ( $1 == "inet6" ) && ( $2 ~ /^fe80:/ ) \
951 ' ) && setvar $VAR_IPV6ADDR "$cp"
954 # f_host_lookup $host [$var_to_set]
956 # Use host(1) to lookup (or reverse) an Internet number from (or to) a name.
957 # Multiple answers are returned separated by a single space. If host(1) does
958 # not exit cleanly, its full output is provided and the return status is 1.
960 # If nsswitch.conf(5) has been configured to query local access first for the
961 # `hosts' database, we'll manually check hosts(5) first (preventing host(1)
962 # from hanging in the event that DNS goes awry).
964 # If $var_to_set is missing or NULL, the list of IP addresses is printed to
965 # standard output for capturing in a sub-shell (which is less-recommended
966 # because of performance degredation; for example, when called in a loop).
968 # The variables from variable.subr used in looking up the host are as follows
969 # (which are set manually):
971 # VAR_IPV6_ENABLE [Optional]
972 # If set to "YES", enables the lookup of IPv6 addresses and IPv4
973 # address. IPv6 addresses, if any, will come before IPv4. Note
974 # that if nsswitch.conf(5) shows an affinity for "files" for the
975 # "host" database and there is a valid entry in hosts(5) for
976 # $host, this setting currently has no effect (an IPv4 address
977 # can supersede an IPv6 address). By design, hosts(5) overrides
978 # any preferential treatment. Otherwise, if this variable is not
979 # set, IPv6 addresses will not be used (IPv4 addresses will
980 # specifically be requested from DNS).
982 # This function is a two-parter. Below is the awk(1) portion of the function,
983 # afterward is the sh(1) function which utilizes the below awk script.
987 !/^[[:space:]]*(#|$)/ \
989 for (n=1; n++ < NF;) if ($n == name)
990 addrs = addrs (addrs ? " " : "") $1
993 if (addrs) print addrs
999 local __host="$1" __var_to_set="$2"
1000 f_dprintf "f_host_lookup: host=[%s]" "$__host"
1002 # If we're configured to look at local files first, do that
1003 if awk '/^hosts:/{exit !($2=="files")}' "$NSSWITCH_CONF"; then
1004 if [ "$__var_to_set" ]; then
1006 if __cp=$( awk -v name="$__host" \
1007 "$f_host_lookup_awk" "$ETC_HOSTS" )
1009 setvar "$__var_to_set" "$__cp"
1013 awk -v name="$__host" \
1014 "$f_host_lookup_awk" "$ETC_HOSTS" &&
1020 # Fall back to host(1) -- which is further governed by nsswitch.conf(5)
1023 local __output __ip6 __addrs=
1024 f_getvar $VAR_IPV6_ENABLE __ip6
1026 # If we have a TCP media type configured, check for an SRV record
1028 { f_quietly f_getvar $VAR_HTTP_PATH ||
1029 f_quietly f_getvar $VAR_HTTP_PROXY_PATH
1030 } && __srvtypes="$__srvtypes _http._tcp"
1031 f_quietly f_getvar $VAR_FTP_PATH && __srvtypes="$__srvtypes _ftp._tcp"
1032 f_quietly f_getvar $VAR_NFS_PATH &&
1033 __srvtypes="$__srvtypes _nfs._tcp _nfs._udp"
1035 # Calculate wait time as dividend of total time and host(1) invocations
1036 local __host_runs __wait
1037 if [ "$__ip6" = "YES" ]; then
1038 __host_runs=$(( 2 + $( set -- $__srvtypes; echo $# ) ))
1040 __host_runs=$(( 1 + $( set -- $__srvtypes; echo $# ) ))
1042 f_getvar $VAR_MEDIA_TIMEOUT __wait
1043 [ "$__wait" ] && __wait="-W $(( $__wait / $__host_runs ))"
1045 # Query SRV types first (1st host response taken as new host to query)
1046 for __type in $__srvtypes; do
1048 host -t SRV $__wait -- "$__type.$__host" \
1051 __host=$( echo "$__output" |
1052 awk '/ SRV /{print $NF;exit}' )
1057 # Try IPv6 first (if enabled)
1058 if [ "$__ip6" = "YES" ]; then
1059 if ! __output=$( host -t AAAA $__wait -- "$__host" 2>&1 ); then
1060 # An error occurred, display in-full and return error
1061 [ "$__var_to_set" ] &&
1062 setvar "$__var_to_set" "$__output"
1065 # Add the IPv6 addresses and fall-through to collect IPv4 too
1066 __addrs=$( echo "$__output" | awk '/ address /{print $NF}' )
1070 if ! __output=$( host -t A $__wait -- "$__host" 2>&1 ); then
1071 # An error occurred, display it in-full and return error
1072 [ "$__var_to_set" ] && setvar "$__var_to_set" "$__output"
1076 __addrs="$__addrs${__addrs:+ }$(
1077 echo "$__output" | awk '/ address /{print $NF}' )"
1078 if [ "$__var_to_set" ]; then
1079 setvar "$__var_to_set" "$__addrs"
1085 # f_device_dialog_tcp $device
1087 # This is it - how to get TCP setup values. Prompt the user to edit/confirm the
1088 # interface, gateway, nameserver, and hostname settings -- all required for
1089 # general TCP/IP access.
1091 # Variables from variable.subr that can be used to sript user input:
1094 # If set, prevents asking the user if they would like to use
1095 # rtsol(8) to check for an IPv6 router.
1097 # If set to "YES" (and VAR_NONINTERACTIVE is unset), asks the
1098 # user if they would like to try the IPv6 RouTer SOLicitation
1099 # utility (rtsol(8)) to get IPv6 information. Ignored if
1100 # VAR_NO_INET6 is set.
1102 # If set to "YES" (and VAR_NONINTERACTIVE is unset), asks the
1103 # user if they would like to try to acquire IPv4 connection
1104 # settings from a DHCP server using dhclient(8).
1106 # VAR_GATEWAY Default gateway to use.
1107 # VAR_IPADDR Interface address to assign.
1108 # VAR_NETMASK Interface subnet mask.
1109 # VAR_EXTRAS Extra interface options to ifconfig(8).
1110 # VAR_HOSTNAME Hostname to set.
1111 # VAR_DOMAINNAME Domain name to use.
1112 # VAR_NAMESERVER DNS nameserver to use when making lookups.
1113 # VAR_IPV6ADDR IPv6 interface address.
1115 # In addition, the following variables are used in acquiring network settings
1118 # VAR_NONINTERACTIVE
1119 # If set (such as when running in a script), prevents asking the
1120 # user questions or displaying the usual prompts, etc.
1121 # VAR_NETINTERACTIVE
1122 # The one exception to VAR_NONINTERACTIVE is VAR_NETINTERACTIVE,
1123 # which if set will prompt the user to try RTSOL (unless
1124 # VAR_TRY_RTSOL has been set), try DHCP (unless VAR_TRY_DHCP has
1125 # been set), and display the network verification dialog. This
1126 # allows you to have a mostly non-interactive script that still
1127 # prompts for network setup/confirmation.
1129 # After successfull execution, the following variables are set:
1131 # VAR_IFCONFIG + $device (e.g., `ifconfig_em0')
1132 # Defines the ifconfig(8) properties specific to $device.
1134 f_device_dialog_tcp()
1137 local use_dhcp="" use_rtsol=""
1138 local _ipaddr _netmask _extras
1140 [ "$dev" ] || return $DIALOG_CANCEL
1142 # Initialize vars from previous device values
1144 device_$dev get private private
1145 if [ "$private" ] && f_struct "$private"; then
1146 $private get ipaddr _ipaddr
1147 $private get netmask _netmask
1148 $private get extras _extras
1149 $private get use_dhcp use_dhcp
1150 $private get use_rtsol use_rtsol
1151 else # See if there are any defaults
1154 # This is a hack so that the dialogs below are interactive in a
1155 # script if we have requested interactive behavior.
1157 local old_interactive=
1158 if ! f_interactive && f_netinteractive; then
1159 f_getvar $VAR_NONINTERACTIVE old_interactive
1160 unset $VAR_NONINTERACTIVE
1164 # Try a RTSOL scan if such behavior is desired.
1165 # If the variable was configured and is YES, do it.
1166 # If it was configured to anything else, treat it as NO.
1167 # Otherwise, ask the question interactively.
1170 if ! f_isset $VAR_NO_INET6 && {
1171 { f_getvar $VAR_TRY_RTSOL try6 && [ "$try6" = "YES" ]; } ||
1173 # Only prompt the user when VAR_TRY_RTSOL is unset
1174 ! f_isset $VAR_TRY_RTSOL &&
1175 f_dialog_noyes "$msg_try_ipv6_configuration"
1180 f_quietly sysctl net.inet6.ip6.forwarding=0
1181 f_quietly sysctl net.inet6.ip6.accept_rtadv=1
1182 f_quietly ifconfig $dev up
1184 i=$( sysctl -n net.inet6.ip6.dad_count )
1187 f_quietly mkdir -p /var/run
1188 f_dialog_info "$msg_scanning_for_ra_servers"
1189 if f_quietly rtsol $dev; then
1190 i=$( sysctl -n net.inet6.ip6.dad_count )
1192 f_rtsol_get_info $dev
1200 # Try a DHCP scan if such behavior is desired.
1201 # If the variable was configured and is YES, do it.
1202 # If it was configured to anything else, treat it as NO.
1203 # Otherwise, ask the question interactively.
1206 if { f_getvar $VAR_TRY_DHCP try4 && [ "$try4" = "YES" ]; } || {
1207 # Only prompt the user when VAR_TRY_DHCP is unset
1208 ! f_isset $VAR_TRY_DHCP &&
1209 f_dialog_noyes "$msg_try_dhcp_configuration"
1211 f_quietly ifconfig $dev delete
1212 f_quietly mkdir -p /var/db
1213 f_quietly mkdir -p /var/run
1214 f_quietly mkdir -p /tmp
1216 local msg="$msg_scanning_for_dhcp_servers"
1218 ( # Execute in sub-shell to allow/catch Ctrl-C
1219 trap 'exit $FAILURE' SIGINT
1220 if [ "$USE_XDIALOG" ]; then
1221 f_quietly dhclient $dev |
1222 f_xdialog_info "$msg"
1224 f_dialog_info "$msg"
1225 f_quietly dhclient $dev
1229 trap 'f_interrupt' SIGINT
1230 if [ $retval -eq $SUCCESS ]; then
1231 f_dhcp_get_info $dev
1238 # Restore old VAR_NONINTERACTIVE if needed.
1239 [ "$old_interactive" ] &&
1240 setvar $VAR_NONINTERACTIVE "$old_interactive"
1242 # Special hack so it doesn't show up oddly in the menu
1244 if f_getvar $VAR_GATEWAY gw && [ "$gw" = "NO" ]; then
1245 setvar $VAR_GATEWAY ""
1248 # Get old IP address from variable space, if available
1249 if [ ! "$_ipaddr" ]; then
1250 if f_getvar $VAR_IPADDR cp; then
1252 elif f_getvar ${dev}_$VAR_IPADDR cp; then
1257 # Get old netmask from variable space, if available
1258 if [ ! "$_netmask" ]; then
1259 if f_getvar $VAR_NETMASK cp; then
1261 elif f_getvar ${dev}_$VAR_NETMASK cp; then
1266 # Get old extras string from variable space, if available
1267 if [ ! "$_extras" ]; then
1268 if f_getvar $VAR_EXTRAS cp; then
1270 elif f_getvar ${dev}_$VAR_EXTRAS cp; then
1276 # Look up values already recorded with the system, or blank the string
1277 # variables ready to accept some new data
1278 local _hostname _gateway _nameserver
1279 f_getvar $VAR_HOSTNAME _hostname
1280 case "$_hostname" in
1281 *.*) : do nothing ;; # Already fully-qualified
1283 f_getvar $VAR_DOMAINNAME cp
1284 [ "$cp" ] && _hostname="$_hostname.$cp"
1286 f_getvar $VAR_GATEWAY _gateway
1287 f_getvar $VAR_NAMESERVER _nameserver
1289 # Re-check variables for initial inheritance before heading into dialog
1290 [ "$_hostname" ] || _hostname="${HOSTNAME:-$( hostname )}"
1291 [ "$_gateway" ] || f_route_get_default _gateway
1292 [ ! "$_nameserver" ] &&
1293 f_resolv_conf_nameservers cp && _nameserver=${cp%%[$IFS]*}
1294 [ "$_ipaddr" ] || f_ifconfig_inet $dev _ipaddr
1295 [ "$_netmask" ] || f_ifconfig_netmask $dev _netmask
1297 # If non-interactive, jump over dialog section and into config section
1298 if f_netinteractive || f_interactive || [ ! "$_hostname" ]
1300 [ ! "$_hostname" ] && f_interactive &&
1301 f_show_msg "$msg_hostname_variable_not_set"
1303 local title=" $msg_network_configuration "
1304 local hline="$hline_alnum_arrows_punc_tab_enter"
1305 local extras_help="$tcplayout_extras_help"
1307 # Modify the help line for PLIP config
1308 [ "${dev#plip}" != "$dev" ] &&
1309 extras_help="$tcplayout_extras_help_for_plip"
1311 f_getvar $VAR_IPV6ADDR cp && [ "$cp" ] &&
1312 title="$title($msg_ipv6_ready) "
1314 if [ ! "$USE_XDIALOG" ]; then
1315 local prompt="$msg_dialog_mixedform_navigation_help"
1316 # Calculate center position for displaying device label
1317 local devlabel="$msg_configuration_for_interface $dev"
1319 local n=$(( $width/2 - (${#devlabel} + 4)/2 - 2 ))
1324 --backtitle "$DIALOG_BACKTITLE" \
1327 --ok-label "$msg_ok" \
1328 --cancel-label "$msg_cancel" \
1330 --help-label "$msg_help" \
1331 --mixedform "$prompt" 16 $width 9 \
1332 "$msg_host_name_including_domain:" 1 2 \
1333 "$_hostname" 2 3 45 255 0 \
1334 "$tcplayout_hostname_help" \
1335 "$msg_ipv4_gateway:" 3 2 \
1336 "$_gateway" 4 3 16 15 0 \
1337 "$tcplayout_gateway_help" \
1338 "$msg_name_server:" 3 31 \
1339 "$_nameserver" 4 32 16 15 0 \
1340 "$tcplayout_nameserver_help" \
1341 "- $devlabel -" 5 $n "" 0 0 0 0 3 "" \
1342 "$msg_ipv4_address:" 6 6 \
1343 "$_ipaddr" 7 7 16 15 0 \
1344 "$tcplayout_ipaddr_help" \
1345 "$msg_netmask:" 6 31 \
1346 "$_netmask" 7 32 16 15 0 \
1347 "$tcplayout_netmask_help" \
1348 "$msg_extra_options_to_ifconfig" 8 6 \
1349 "$_extras" 9 7 41 2048 0 \
1351 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD )
1353 # --mixed-form always returns 0, we have to
1354 # use the returned data to determine button
1355 if [ ! "$cp" ]; then
1356 # User either chose "Cancel", pressed
1357 # ESC, or blanked every form field
1358 return $DIALOG_CANCEL
1360 n=$( echo "$cp" | f_number_of_lines )
1361 [ $n -eq 1 ] && case "$cp" in HELP*)
1363 f_show_help "$TCP_HELPFILE"
1368 # Turn mixed-form results into env variables
1369 eval "$( echo "$cp" | awk '
1372 field[++n] = "_hostname"
1373 field[++n] = "_gateway"
1374 field[++n] = "_nameserver"
1375 field[++n] = "_ipaddr"
1376 field[++n] = "_netmask"
1377 field[++n] = "_extras"
1382 gsub(/'\''/, "'\'\\\\\'\''")
1383 sub(/[[:space:]]*$/, "")
1384 value[field[++n]] = $0
1387 for ( n = 1; n <= nfields; n++ )
1389 printf "%s='\''%s'\'';\n",
1395 f_dialog_validate_tcpip \
1404 # Xdialog(1) does not support --mixed-form
1405 # Create a persistent menu instead
1407 f_dialog_title "$msg_network_configuration"
1412 --title "$DIALOG_TITLE" \
1413 --backtitle "$DIALOG_BACKTITLE" \
1416 --ok-label "$msg_ok" \
1417 --cancel-label "$msg_cancel" \
1419 --menu "$prompt" 21 60 8 \
1420 "$msg_accept_continue" "" \
1421 "$tcplayout_accept_cont_help" \
1422 "$msg_host_name_including_domain:" \
1424 "$tcplayout_hostname_help" \
1425 "$msg_ipv4_gateway:" "$_gateway" \
1426 "$tcplayout_gateway_help" \
1427 "$msg_name_server:" "$_nameserver" \
1428 "$tcplayout_nameserver_help" \
1429 "$msg_ipv4_address:" "$_ipaddr" \
1430 "$tcplayout_ipaddr_help" \
1431 "$msg_netmask:" "$_netmask" \
1432 "$tcplayout_netmask_help" \
1433 "$msg_extra_options_to_ifconfig" \
1434 "$_extras" "$extras_help" \
1435 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
1438 f_dialog_data_sanitize cp
1439 f_dprintf "retval=%u mtag=[%s]" $retval "$cp"
1441 if [ $retval -eq $DIALOG_HELP ]; then
1442 f_show_help "$TCP_HELPFILE"
1444 elif [ $retval -ne $DIALOG_OK ]; then
1445 f_dialog_title_restore
1446 return $DIALOG_CANCEL
1450 "$msg_accept_continue")
1451 f_dialog_validate_tcpip \
1458 "$msg_host_name_including_domain:")
1459 f_dialog_input cp "$cp" "$_hostname" \
1460 && _hostname="$cp" ;;
1461 "$msg_ipv4_gateway:")
1462 f_dialog_input cp "$cp" "$_gateway" \
1463 && _gateway="$cp" ;;
1464 "$msg_name_server:")
1465 f_dialog_input cp "$cp" "$_nameserver" \
1466 && _nameserver="$cp" ;;
1467 "$msg_ipv4_address:")
1468 f_dialog_input cp "$cp" "$_ipaddr" \
1471 f_dialog_input cp "$cp" "$_netmask" \
1472 && _netmask="$cp" ;;
1473 "$msg_extra_options_to_ifconfig")
1474 f_dialog_input cp "$cp" "$_extras" \
1479 f_dialog_title_restore
1485 # We actually need to inform the rest of bsdconfig about this
1486 # data now if the user hasn't selected cancel.
1488 if [ "$_hostname" ]; then
1489 setvar $VAR_HOSTNAME "$_hostname"
1490 f_quietly hostname "$_hostname"
1491 case "$_hostname" in
1492 *.*) setvar $VAR_DOMAINNAME "${_hostname#*.}" ;;
1495 [ "$_gateway" ] && setvar $VAR_GATEWAY "$_gateway"
1496 [ "$_nameserver" ] && setvar $VAR_NAMESERVER "$_nameserver"
1497 [ "$_ipaddr" ] && setvar $VAR_IPADDR "$_ipaddr"
1498 [ "$_netmask" ] && setvar $VAR_NETMASK "$_netmask"
1499 [ "$_extras" ] && setvar $VAR_EXTRAS "$_extras"
1501 f_dprintf "Creating struct DEVICE_INFO devinfo_%s" "$dev"
1502 f_struct_new DEVICE_INFO devinfo_$dev
1503 device_$dev set private devinfo_$dev
1505 devinfo_$dev set ipaddr $_ipaddr
1506 devinfo_$dev set netmask $_netmask
1507 devinfo_$dev set extras $_extras
1508 devinfo_$dev set use_rtsol $use_rtsol
1509 devinfo_$dev set use_dhcp $use_dhcp
1511 if [ "$use_dhcp" -o "$_ipaddr" ]; then
1512 if [ "$use_dhcp" ]; then
1513 cp="DHCP${extras:+ $extras}"
1515 cp="inet $_ipaddr netmask $_netmask${extras:+ $extras}"
1517 setvar $VAR_IFCONFIG$dev "$cp"
1520 setvar $VAR_IPV6_ENABLE "YES"
1523 f_config_resolv # XXX this will do it on the MFS copy
1528 # f_device_scan_tcp [$var_to_set]
1530 # Scan for the first active/configured TCP/IP device. The name of the interface
1531 # is printed to stderr like other dialog(1)-based functions (stdout is reserved
1532 # for dialog(1) interaction) if $var_to_set is missing or NULL. Returns failure
1533 # if no active/configured interface
1537 local __var_to_set="$1" __iface
1538 for __iface in $( ifconfig -l ); do
1539 if ifconfig $__iface | awk '
1541 has_inet = has_inet6 = is_ethernet = 0
1544 ( $1 == "status:" && $2 != "active" ) { is_usable = 0; exit }
1546 if ($2 == "0.0.0.0") { is_usable = 0; exit }
1549 ( $1 == "inet6") { has_inet6++ }
1550 ( $1 == "media:" ) {
1551 if ($2 != "Ethernet") { is_usable = 0; exit }
1555 if (!(is_ethernet && (has_inet || has_inet6)))
1560 f_show_msg "$msg_using_interface" "$__iface"
1561 f_dprintf "f_device_scan_tcp found %s" "$__iface"
1562 if [ "$__var_to_set" ]; then
1563 setvar "$__var_to_set" "$__iface"
1574 # f_device_select_tcp
1576 # Prompt the user to select network interface to use for TCP/IP access.
1577 # Variables from variable.subr that can be used to script user input:
1579 # VAR_NETWORK_DEVICE [Optional]
1580 # Either a comma-separated list of network interfaces to try when
1581 # setting up network access (e.g., "fxp0,em0") or "ANY" (case-
1582 # sensitive) to indicate that the first active and configured
1583 # interface is acceptable. If unset, the user is presented with a
1584 # menu of all available network interfaces.
1586 # Returns success if a valid network interface has been selected.
1588 f_device_select_tcp()
1590 local devs dev cnt network_dev
1591 f_getvar $VAR_NETWORK_DEVICE network_dev
1593 f_dprintf "f_device_select_tcp: %s=[%s]" \
1594 VAR_NETWORK_DEVICE "$network_dev"
1596 if [ "$network_dev" ]; then
1598 # This can be set to several types of values. If set to ANY,
1599 # scan all network devices looking for a valid link, and go
1600 # with the first device found. Can also be specified as a
1601 # comma delimited list, with each network device tried in
1602 # order. Can also be set to a single network device.
1604 [ "$network_dev" = "ANY" ] && f_device_scan_tcp network_dev
1606 while [ "$network_dev" ]; do
1607 case "$network_dev" in
1608 *,*) dev="${network_dev%%,*}"
1609 network_dev="${network_dev#*,}"
1611 *) dev="$network_dev"
1615 f_device_find "$dev" $DEVICE_TYPE_NETWORK devs
1616 cnt=$( set -- $devs; echo $# )
1618 if [ ${cnt:=0} -gt 0 ]; then
1619 dev="${devs%%[$IFS]*}"
1620 f_device_dialog_tcp $dev
1621 if [ $? -eq $DIALOG_OK ]; then
1622 setvar $VAR_NETWORK_DEVICE $dev
1628 f_interactive && f_show_msg "$msg_no_network_devices"
1629 return $DIALOG_CANCEL
1633 f_device_find "" $DEVICE_TYPE_NETWORK devs
1634 cnt=$( set -- $devs; echo $# )
1635 dev="${devs%%[$IFS]*}"
1637 f_quietly f_getvar NETWORK_CONFIGURED # for debugging info
1638 if ! f_running_as_init &&
1639 ! [ "${NETWORK_CONFIGURED+set}" -a "$NETWORK_CONFIGURED" = "NO" ]
1641 trap 'f_interrupt' SIGINT
1642 if f_dialog_yesno "$msg_assume_network_is_already_configured"
1644 setvar $VAR_NETWORK_DEVICE $dev
1649 local retval=$SUCCESS
1650 if [ ${cnt:=0} -eq 0 ]; then
1651 f_show_msg "$msg_no_network_devices"
1652 retval=$DIALOG_CANCEL
1653 elif [ $cnt -eq 1 ]; then
1654 f_device_dialog_tcp $dev
1656 [ $retval -eq $DIALOG_OK ] && setvar $VAR_NETWORK_DEVICE $dev
1658 local title="$msg_network_interface_information_required"
1659 local prompt="$msg_please_select_ethernet_device_to_configure"
1660 local hline="$hline_arrows_tab_enter"
1662 dev=$( f_device_menu \
1663 "$title" "$prompt" "$hline" $DEVICE_TYPE_NETWORK \
1664 "$NETWORK_DEVICE_HELPFILE" \
1665 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD )
1667 [ "$dev" ] || return $DIALOG_CANCEL
1669 f_device_find "$dev" $DEVICE_TYPE_NETWORK devs
1670 [ "$devs" ] || return $DIALOG_CANCEL
1671 dev="${devs%%[$IFS]*}"
1673 f_device_dialog_tcp $dev
1675 if [ $retval -eq $DIALOG_OK ]; then
1676 f_struct_copy device_$dev device_network
1677 setvar $VAR_NETWORK_DEVICE network
1679 f_struct_free device_network
1686 # f_dialog_menu_select_tcp
1688 # Like f_dialog_select_tcp() above, but do it from a menu that doesn't care
1689 # about status. In other words, where f_dialog_select_tcp() will not display a
1690 # menu if scripted, this function will always display the menu of available
1691 # network interfaces.
1693 f_dialog_menu_select_tcp()
1695 local private use_dhcp name
1696 NETWORK_CONFIGURED=NO f_device_select_tcp
1697 if f_struct device_network &&
1698 device_network get private private &&
1699 f_struct_copy "$private" di &&
1700 di get use_dhcp use_dhcp &&
1701 [ ! "$use_dhcp" ] &&
1702 device_network get name name &&
1703 f_yesno "$msg_would_you_like_to_bring_interface_up" "$name"
1705 if ! f_device_init network; then
1706 f_show_msg "$msg_initialization_of_device_failed" \
1713 ############################################################ MAIN
1715 f_dprintf "%s: Successfully loaded." media/tcpip.subr
1717 fi # ! $_MEDIA_TCPIP_SUBR