1247280Sdteskeif [ ! "$_MEDIA_TCPIP_SUBR" ]; then _MEDIA_TCPIP_SUBR=1 2247280Sdteske# 3247280Sdteske# Copyright (c) 2012-2013 Devin Teske 4252980Sdteske# All rights reserved. 5247280Sdteske# 6247280Sdteske# Redistribution and use in source and binary forms, with or without 7247280Sdteske# modification, are permitted provided that the following conditions 8247280Sdteske# are met: 9247280Sdteske# 1. Redistributions of source code must retain the above copyright 10247280Sdteske# notice, this list of conditions and the following disclaimer. 11247280Sdteske# 2. Redistributions in binary form must reproduce the above copyright 12247280Sdteske# notice, this list of conditions and the following disclaimer in the 13247280Sdteske# documentation and/or other materials provided with the distribution. 14247280Sdteske# 15247280Sdteske# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16252987Sdteske# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17247280Sdteske# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18247280Sdteske# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19247280Sdteske# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20252987Sdteske# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21247280Sdteske# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22247280Sdteske# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23247280Sdteske# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24247280Sdteske# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25247280Sdteske# SUCH DAMAGE. 26247280Sdteske# 27247280Sdteske# $FreeBSD: releng/10.3/usr.sbin/bsdconfig/share/media/tcpip.subr 266290 2014-05-17 03:28:43Z dteske $ 28247280Sdteske# 29247280Sdteske############################################################ INCLUDES 30247280Sdteske 31247280SdteskeBSDCFG_SHARE="/usr/share/bsdconfig" 32247280Sdteske. $BSDCFG_SHARE/common.subr || exit 1 33247280Sdteskef_dprintf "%s: loading includes..." media/tcpip.subr 34247280Sdteskef_include $BSDCFG_SHARE/device.subr 35247280Sdteskef_include $BSDCFG_SHARE/dialog.subr 36260678Sdteskef_include $BSDCFG_SHARE/strings.subr 37252077Sdteskef_include $BSDCFG_SHARE/struct.subr 38247280Sdteskef_include $BSDCFG_SHARE/variable.subr 39247280Sdteske 40247280SdteskeBSDCFG_LIBE="/usr/libexec/bsdconfig" 41247280Sdteskef_include_lang $BSDCFG_LIBE/include/messages.subr 42247280Sdteske 43247280SdteskeTCP_HELPFILE=$BSDCFG_LIBE/include/tcp.hlp 44247280SdteskeNETWORK_DEVICE_HELPFILE=$BSDCFG_LIBE/include/network_device.hlp 45247280Sdteske 46247280Sdteske############################################################ GLOBALS 47247280Sdteske 48247280Sdteske# 49247280Sdteske# Path to resolv.conf(5). 50247280Sdteske# 51247280Sdteske: ${RESOLV_CONF:="/etc/resolv.conf"} 52247280Sdteske 53247280Sdteske# 54247280Sdteske# Path to nsswitch.conf(5). 55247280Sdteske# 56247280Sdteske: ${NSSWITCH_CONF:="/etc/nsswitch.conf"} 57247280Sdteske 58247280Sdteske# 59247280Sdteske# Path to hosts(5) 60247280Sdteske# 61247280Sdteske: ${ETC_HOSTS:="/etc/hosts"} 62247280Sdteske 63247280Sdteske# 64247280Sdteske# Structure of dhclient.leases(5) lease { ... } entry 65247280Sdteske# 66247280Sdteskef_struct_define DHCP_LEASE \ 67247280Sdteske interface \ 68247280Sdteske fixed_address \ 69247280Sdteske filename \ 70247280Sdteske server_name \ 71247280Sdteske script \ 72247280Sdteske medium \ 73247280Sdteske host_name \ 74247280Sdteske subnet_mask \ 75247280Sdteske routers \ 76247280Sdteske domain_name_servers \ 77247280Sdteske domain_name \ 78247280Sdteske broadcast_address \ 79247280Sdteske dhcp_lease_time \ 80247280Sdteske dhcp_message_type \ 81247280Sdteske dhcp_server_identifier \ 82247280Sdteske dhcp_renewal_time \ 83247280Sdteske dhcp_rebinding_time \ 84247280Sdteske renew \ 85247280Sdteske rebind \ 86247280Sdteske expire 87247280Sdteske 88247280Sdteske############################################################ FUNCTIONS 89247280Sdteske 90247280Sdteske# f_validate_hostname $hostname 91247280Sdteske# 92247280Sdteske# Returns zero if the given argument (a fully-qualified hostname) is compliant 93247280Sdteske# with standards set-forth in RFC's 952 and 1123 of the Network Working Group: 94247280Sdteske# 95247280Sdteske# RFC 952 - DoD Internet host table specification 96247280Sdteske# http://tools.ietf.org/html/rfc952 97247280Sdteske# 98247280Sdteske# RFC 1123 - Requirements for Internet Hosts - Application and Support 99247280Sdteske# http://tools.ietf.org/html/rfc1123 100247280Sdteske# 101247280Sdteske# See http://en.wikipedia.org/wiki/Hostname for a brief overview. 102247280Sdteske# 103247280Sdteske# The return status for invalid hostnames is one of: 104247280Sdteske# 255 Entire hostname exceeds the maximum length of 255 characters. 105247280Sdteske# 63 One or more individual labels within the hostname (separated by 106247280Sdteske# dots) exceeds the maximum of 63 characters. 107247280Sdteske# 1 One or more individual labels within the hostname contains one 108247280Sdteske# or more invalid characters. 109247280Sdteske# 2 One or more individual labels within the hostname starts or 110247280Sdteske# ends with a hyphen (hyphens are allowed, but a label cannot 111247280Sdteske# begin or end with a hyphen). 112247280Sdteske# 3 One or more individual labels within the hostname are null. 113247280Sdteske# 114260675Sdteske# To call this function and display an appropriate error message to the user 115260675Sdteske# based on the above error codes, use the following function defined in 116260675Sdteske# dialog.subr: 117247280Sdteske# 118260675Sdteske# f_dialog_validate_hostname $hostname 119247280Sdteske# 120247280Sdteskef_validate_hostname() 121247280Sdteske{ 122247280Sdteske local fqhn="$1" 123247280Sdteske 124247280Sdteske # Return error if the hostname exceeds 255 characters 125247280Sdteske [ ${#fqhn} -gt 255 ] && return 255 126247280Sdteske 127247280Sdteske local IFS="." # Split on `dot' 128247280Sdteske for label in $fqhn; do 129247280Sdteske # Return error if the label exceeds 63 characters 130247280Sdteske [ ${#label} -gt 63 ] && return 63 131247280Sdteske 132247280Sdteske # Return error if the label is null 133247280Sdteske [ "$label" ] || return 3 134247280Sdteske 135247280Sdteske # Return error if label begins/ends with dash 136247280Sdteske case "$label" in -*|*-) return 2; esac 137247280Sdteske 138247280Sdteske # Return error if the label contains any invalid chars 139247280Sdteske case "$label" in *[!0-9a-zA-Z-]*) return 1; esac 140247280Sdteske done 141247280Sdteske 142247280Sdteske return $SUCCESS 143247280Sdteske} 144247280Sdteske 145247280Sdteske# f_inet_atoi $ipv4_address [$var_to_set] 146247280Sdteske# 147247280Sdteske# Convert an IPv4 address or mask from dotted-quad notation (e.g., `127.0.0.1' 148247280Sdteske# or `255.255.255.0') to a 32-bit unsigned integer for the purpose of network 149247280Sdteske# and broadcast calculations. For example, one can validate that two addresses 150247280Sdteske# are on the same network: 151247280Sdteske# 152247280Sdteske# f_inet_atoi 1.2.3.4 ip1num 153247280Sdteske# f_inet_atoi 1.2.4.5 ip2num 154247280Sdteske# f_inet_atoi 255.255.0.0 masknum 155247280Sdteske# if [ $(( $ip1num & $masknum )) -eq \ 156247280Sdteske# $(( $ip2num & $masknum )) ] 157247280Sdteske# then 158247280Sdteske# : IP addresses are on same network 159247280Sdteske# fi 160247280Sdteske# 161247280Sdteske# See f_validate_ipaddr() below for an additional example usage, on calculating 162247280Sdteske# network and broadcast addresses. 163247280Sdteske# 164247280Sdteske# If $var_to_set is missing or NULL, the converted IP address is printed to 165247280Sdteske# standard output for capturing in a sub-shell (which is less-recommended 166247280Sdteske# because of performance degredation; for example, when called in a loop). 167247280Sdteske# 168247280Sdteskef_inet_atoi() 169247280Sdteske{ 170247280Sdteske local __addr="$1" __var_to_set="$2" __num=0 171247280Sdteske if f_validate_ipaddr "$__addr"; then 172266290Sdteske local IFS=. 173260678Sdteske set -- $__addr 174260678Sdteske __num=$(( ($1 << 24) + ($2 << 16) + ($3 << 8) + $4 )) 175247280Sdteske fi 176247280Sdteske if [ "$__var_to_set" ]; then 177247280Sdteske setvar "$__var_to_set" $__num 178247280Sdteske else 179247280Sdteske echo $__num 180247280Sdteske fi 181247280Sdteske} 182247280Sdteske 183247280Sdteske# f_validate_ipaddr $ipaddr [$netmask] 184247280Sdteske# 185247280Sdteske# Returns zero if the given argument (an IP address) is of the proper format. 186247280Sdteske# 187247280Sdteske# The return status for invalid IP address is one of: 188247280Sdteske# 1 One or more individual octets within the IP address (separated 189247280Sdteske# by dots) contains one or more invalid characters. 190247280Sdteske# 2 One or more individual octets within the IP address are null 191247280Sdteske# and/or missing. 192247280Sdteske# 3 One or more individual octets within the IP address exceeds the 193247280Sdteske# maximum of 255 (or 2^8, being an octet comprised of 8 bits). 194247280Sdteske# 4 The IP address has either too few or too many octets. 195247280Sdteske# 196247280Sdteske# If a netmask is provided, the IP address is checked further: 197247280Sdteske# 198247280Sdteske# 5 The IP address must not be the network or broadcast address. 199247280Sdteske# 200247280Sdteskef_validate_ipaddr() 201247280Sdteske{ 202247280Sdteske local ip="$1" mask="$2" 203247280Sdteske 204247280Sdteske # Track number of octets for error checking 205247280Sdteske local noctets=0 206247280Sdteske 207266290Sdteske local oldIFS="$IFS" IFS="." # Split on `dot' 208247280Sdteske for octet in $ip; do 209247280Sdteske # Return error if the octet is null 210247280Sdteske [ "$octet" ] || return 2 211247280Sdteske 212247280Sdteske # Return error if not a whole integer 213247280Sdteske f_isinteger "$octet" || return 1 214247280Sdteske 215247280Sdteske # Return error if not a positive integer 216247280Sdteske [ $octet -ge 0 ] || return 1 217247280Sdteske 218247280Sdteske # Return error if the octet exceeds 255 219247280Sdteske [ $octet -gt 255 ] && return 3 220247280Sdteske 221247280Sdteske noctets=$(( $noctets + 1 )) 222247280Sdteske done 223247280Sdteske IFS="$oldIFS" 224247280Sdteske 225247280Sdteske [ $noctets -eq 4 ] || return 4 226247280Sdteske 227247280Sdteske # 228247280Sdteske # The IP address must not be network or broadcast address. 229247280Sdteske # 230247280Sdteske if [ "$mask" ]; then 231247280Sdteske local ipnum masknum netnum bcastnum 232247280Sdteske local max_addr=4294967295 # 255.255.255.255 233247280Sdteske 234247280Sdteske f_inet_atoi $ip ipnum 235247280Sdteske f_inet_atoi $mask masknum 236247280Sdteske 237247280Sdteske netnum=$(( $ipnum & $masknum )) 238247280Sdteske bcastnum=$(( ($ipnum & $masknum)+$max_addr-$masknum )) 239247280Sdteske 240247280Sdteske if [ "$masknum" ] && 241247280Sdteske [ $ipnum -eq $netnum -o $ipnum -eq $bcastnum ] 242247280Sdteske then 243247280Sdteske return 5 244247280Sdteske fi 245247280Sdteske fi 246247280Sdteske 247247280Sdteske return $SUCCESS 248247280Sdteske} 249247280Sdteske 250247280Sdteske# f_validate_ipaddr6 $ipv6_addr 251247280Sdteske# 252247280Sdteske# Returns zero if the given argument (an IPv6 address) is of the proper format. 253247280Sdteske# 254247280Sdteske# The return status for invalid IP address is one of: 255247280Sdteske# 1 One or more individual segments within the IP address 256247280Sdteske# (separated by colons) contains one or more invalid characters. 257247280Sdteske# Segments must contain only combinations of the characters 0-9, 258247280Sdteske# A-F, or a-f. 259247280Sdteske# 2 Too many/incorrect null segments. A single null segment is 260247280Sdteske# allowed within the IP address (separated by colons) but not 261247280Sdteske# allowed at the beginning or end (unless a double-null segment; 262247280Sdteske# i.e., "::*" or "*::"). 263247280Sdteske# 3 One or more individual segments within the IP address 264247280Sdteske# (separated by colons) exceeds the length of 4 hex-digits. 265247280Sdteske# 4 The IP address entered has either too few (less than 3), too 266247280Sdteske# many (more than 8), or not enough segments, separated by 267247280Sdteske# colons. 268247280Sdteske# 5* The IPv4 address at the end of the IPv6 address is invalid. 269247280Sdteske# * When there is an error with the dotted-quad IPv4 address at the 270247280Sdteske# end of the IPv6 address, the return value of 5 is OR'd with a 271247280Sdteske# bit-shifted (<< 4) return of f_validate_ipaddr. 272247280Sdteske# 273247280Sdteskef_validate_ipaddr6() 274247280Sdteske{ 275247280Sdteske local ip="${1%\%*}" # removing the interface specification if-present 276247280Sdteske 277247280Sdteske local IFS=":" # Split on `colon' 278247280Sdteske set -- $ip: 279247280Sdteske 280247280Sdteske # Return error if too many or too few segments 281247280Sdteske # Using 9 as max in case of leading or trailing null spanner 282247280Sdteske [ $# -gt 9 -o $# -lt 3 ] && return 4 283247280Sdteske 284247280Sdteske local h="[0-9A-Fa-f]" 285247280Sdteske local nulls=0 nsegments=$# contains_ipv4_segment= 286247280Sdteske 287247280Sdteske while [ $# -gt 0 ]; do 288247280Sdteske 289247280Sdteske segment="${1%:}" 290247280Sdteske shift 291247280Sdteske 292247280Sdteske # 293247280Sdteske # Return error if this segment makes one null too-many. A 294247280Sdteske # single null segment is allowed anywhere in the middle as well 295247280Sdteske # as double null segments are allowed at the beginning or end 296247280Sdteske # (but not both). 297247280Sdteske # 298247280Sdteske if [ ! "$segment" ]; then 299247280Sdteske nulls=$(( $nulls + 1 )) 300247280Sdteske if [ $nulls -eq 3 ]; then 301247280Sdteske # Only valid syntax for 3 nulls is `::' 302247280Sdteske [ "$ip" = "::" ] || return 2 303247280Sdteske elif [ $nulls -eq 2 ]; then 304247280Sdteske # Only valid if begins/ends with `::' 305247280Sdteske case "$ip" in 306247280Sdteske ::*|*::) : fall thru ;; 307247280Sdteske *) return 2 308247280Sdteske esac 309247280Sdteske fi 310247280Sdteske continue 311247280Sdteske fi 312247280Sdteske 313247280Sdteske # 314247280Sdteske # Return error if not a valid hexadecimal short 315247280Sdteske # 316247280Sdteske case "$segment" in 317247280Sdteske $h|$h$h|$h$h$h|$h$h$h$h) 318247280Sdteske : valid segment of 1-4 hexadecimal digits 319247280Sdteske ;; 320247280Sdteske *[!0-9A-Fa-f]*) 321247280Sdteske # Segment contains at least one invalid char 322247280Sdteske 323247280Sdteske # Return error immediately if not last segment 324247280Sdteske [ $# -eq 0 ] || return 1 325247280Sdteske 326247280Sdteske # Otherwise, check for legacy IPv4 notation 327247280Sdteske case "$segment" in 328247280Sdteske *[!0-9.]*) 329247280Sdteske # Segment contains at least one invalid 330247280Sdteske # character even for an IPv4 address 331247280Sdteske return 1 332247280Sdteske esac 333247280Sdteske 334247280Sdteske # Return error if not enough segments 335247280Sdteske if [ $nulls -eq 0 ]; then 336247280Sdteske [ $nsegments -eq 7 ] || return 4 337247280Sdteske fi 338247280Sdteske 339247280Sdteske contains_ipv4_segment=1 340247280Sdteske 341247280Sdteske # Validate the IPv4 address 342247280Sdteske f_validate_ipaddr "$segment" || 343247280Sdteske return $(( 5 | $? << 4 )) 344247280Sdteske ;; 345247280Sdteske *) 346247280Sdteske # Segment characters are all valid but too many 347247280Sdteske return 3 348247280Sdteske esac 349247280Sdteske 350247280Sdteske done 351247280Sdteske 352247280Sdteske if [ $nulls -eq 1 ]; then 353247280Sdteske # Single null segment cannot be at beginning/end 354247280Sdteske case "$ip" in 355247280Sdteske :*|*:) return 2 356247280Sdteske esac 357247280Sdteske fi 358247280Sdteske 359247280Sdteske # 360247280Sdteske # A legacy IPv4 address can span the last two 16-bit segments, 361247280Sdteske # reducing the amount of maximum allowable segments by-one. 362247280Sdteske # 363247280Sdteske maxsegments=8 364247280Sdteske if [ "$contains_ipv4_segment" ]; then 365247280Sdteske maxsegments=7 366247280Sdteske fi 367247280Sdteske 368247280Sdteske case $nulls in 369247280Sdteske # Return error if missing segments with no null spanner 370247280Sdteske 0) [ $nsegments -eq $maxsegments ] || return 4 ;; 371247280Sdteske # Return error if null spanner with too many segments 372247280Sdteske 1) [ $nsegments -le $maxsegments ] || return 4 ;; 373247280Sdteske # Return error if leading/trailing `::' with too many segments 374247280Sdteske 2) [ $nsegments -le $(( $maxsegments + 1 )) ] || return 4 ;; 375247280Sdteske esac 376247280Sdteske 377247280Sdteske return $SUCCESS 378247280Sdteske} 379247280Sdteske 380247280Sdteske# f_validate_netmask $netmask 381247280Sdteske# 382247280Sdteske# Returns zero if the given argument (a subnet mask) is of the proper format. 383247280Sdteske# 384247280Sdteske# The return status for invalid netmask is one of: 385247280Sdteske# 1 One or more individual fields within the subnet mask (separated 386247280Sdteske# by dots) contains one or more invalid characters. 387247280Sdteske# 2 One or more individual fields within the subnet mask are null 388247280Sdteske# and/or missing. 389247280Sdteske# 3 One or more individual fields within the subnet mask exceeds 390247280Sdteske# the maximum of 255 (a full 8-bit register). 391247280Sdteske# 4 The subnet mask has either too few or too many fields. 392247280Sdteske# 5 One or more individual fields within the subnet mask is an 393247280Sdteske# invalid integer (only 0,128,192,224,240,248,252,254,255 are 394247280Sdteske# valid integers). 395247280Sdteske# 396247280Sdteskef_validate_netmask() 397247280Sdteske{ 398247280Sdteske local mask="$1" 399247280Sdteske 400247280Sdteske # Track number of fields for error checking 401247280Sdteske local nfields=0 402247280Sdteske 403247280Sdteske local IFS="." # Split on `dot' 404247280Sdteske for field in $mask; do 405247280Sdteske # Return error if the field is null 406247280Sdteske [ "$field" ] || return 2 407247280Sdteske 408247280Sdteske # Return error if not a whole positive integer 409247280Sdteske f_isinteger "$field" || return 1 410247280Sdteske 411247280Sdteske # Return error if the field exceeds 255 412247280Sdteske [ $field -gt 255 ] && return 3 413247280Sdteske 414247280Sdteske # Return error if the field is an invalid integer 415247280Sdteske case "$field" in 416252178Sdteske 0|128|192|224|240|248|252|254|255) : ;; 417252178Sdteske *) return 5 ;; 418247280Sdteske esac 419247280Sdteske 420247280Sdteske nfields=$(( $nfields + 1 )) 421247280Sdteske done 422247280Sdteske 423247280Sdteske [ $nfields -eq 4 ] || return 4 424247280Sdteske} 425247280Sdteske 426247280Sdteske# f_validate_gateway $gateway $ipaddr $netmask 427247280Sdteske# 428247280Sdteske# Validate an IPv4 default gateway (aka router) address for a given IP address 429247280Sdteske# making sure the two are in the same network (able to ``talk'' to each other). 430247280Sdteske# Returns success if $ipaddr and $gateway are in the same network given subnet 431247280Sdteske# mask $netmask. 432247280Sdteske# 433247280Sdteskef_validate_gateway() 434247280Sdteske{ 435247280Sdteske local gateway="$1" ipaddr="$2" netmask="$3" 436247280Sdteske local gwnum ipnum masknum 437247280Sdteske 438247280Sdteske f_validate_ipaddr "$gateway" "$netmask" || return $FAILURE 439247280Sdteske 440247280Sdteske f_inet_atoi "$netmask" masknum 441247280Sdteske f_inet_atoi "$ipaddr" ipnum 442247280Sdteske f_inet_atoi "$gateway" gwnum 443247280Sdteske 444247280Sdteske # Gateway must be within set of IPs reachable through interface 445247280Sdteske [ $(( $ipnum & $masknum )) -eq \ 446247280Sdteske $(( $gwnum & $masknum )) ] # Return status 447247280Sdteske} 448247280Sdteske 449247280Sdteske# f_dialog_validate_tcpip $hostname $gateway $nameserver $ipaddr $netmask 450247280Sdteske# 451247280Sdteske# Returns success if the arguments provided are valid for accessing a TCP/IP 452247280Sdteske# network, otherwise returns failure. 453247280Sdteske# 454247280Sdteskef_dialog_validate_tcpip() 455247280Sdteske{ 456247280Sdteske local hostname="$1" gateway="$2" nameserver="$3" 457247280Sdteske local ipaddr="$4" netmask="$5" 458247280Sdteske local ipnum masknum 459247280Sdteske 460247280Sdteske if [ ! "$hostname" ]; then 461252795Sdteske f_show_msg "$msg_must_specify_a_host_name_of_some_sort" 462247280Sdteske elif ! f_validate_hostname "$hostname"; then 463252795Sdteske f_show_msg "$msg_invalid_hostname_value" 464247280Sdteske elif [ "$netmask" ] && ! f_validate_netmask "$netmask"; then 465252795Sdteske f_show_msg "$msg_invalid_netmask_value" 466247280Sdteske elif [ "$nameserver" ] && 467252795Sdteske ! f_validate_ipaddr "$nameserver" && 468252795Sdteske ! f_validate_ipaddr6 "$nameserver"; then 469252795Sdteske f_show_msg "$msg_invalid_name_server_ip_address_specified" 470247280Sdteske elif [ "$ipaddr" ] && ! f_validate_ipaddr "$ipaddr" "$netmask"; then 471252795Sdteske f_show_msg "$msg_invalid_ipv4_address" 472247280Sdteske elif [ "$gateway" -a "$gateway" != "NO" ] && 473252795Sdteske ! f_validate_gateway "$gateway" "$ipaddr" "$netmask"; then 474252795Sdteske f_show_msg "$msg_invalid_gateway_ipv4_address_specified" 475247280Sdteske else 476256181Sdteske return $DIALOG_OK 477247280Sdteske fi 478247280Sdteske 479256181Sdteske return $DIALOG_CANCEL 480247280Sdteske} 481247280Sdteske 482247280Sdteske# f_ifconfig_inet $interface [$var_to_set] 483247280Sdteske# 484247280Sdteske# Returns the IPv4 address associated with $interface. If $var_to_set is 485247280Sdteske# missing or NULL, the IP address is printed to standard output for capturing 486247280Sdteske# in a sub-shell (which is less-recommended because of performance degredation; 487247280Sdteske# for example, when called in a loop). 488247280Sdteske# 489247280Sdteske# This function is a two-parter. Below is the awk(1) portion of the function, 490247280Sdteske# afterward is the sh(1) function which utilizes the below awk script. 491247280Sdteske# 492247280Sdteskef_ifconfig_inet_awk=' 493247280SdteskeBEGIN { found = 0 } 494247280Sdteske( $1 == "inet" ) \ 495247280Sdteske{ 496247280Sdteske print $2 497247280Sdteske found = 1 498247280Sdteske exit 499247280Sdteske} 500247280SdteskeEND { exit ! found } 501247280Sdteske' 502247280Sdteskef_ifconfig_inet() 503247280Sdteske{ 504247280Sdteske local __interface="$1" __var_to_set="$2" 505247280Sdteske if [ "$__var_to_set" ]; then 506247280Sdteske local __ip 507247280Sdteske __ip=$( ifconfig "$__interface" 2> /dev/null | 508247280Sdteske awk "$f_ifconfig_inet_awk" ) 509247280Sdteske setvar "$__var_to_set" "$__ip" 510247280Sdteske else 511247280Sdteske ifconfig "$__interface" 2> /dev/null | 512247280Sdteske awk "$f_ifconfig_inet_awk" 513247280Sdteske fi 514247280Sdteske} 515247280Sdteske 516247280Sdteske# f_ifconfig_inet6 $interface [$var_to_set] 517247280Sdteske# 518247280Sdteske# Returns the IPv6 address associated with $interface. If $var_to_set is 519247280Sdteske# missing or NULL, the IP address is printed to standard output for capturing 520247280Sdteske# in a sub-shell (which is less-recommended because of performance degredation; 521247280Sdteske# for example, when called in a loop). 522247280Sdteske# 523247280Sdteske# This function is a two-parter. Below is the awk(1) portion of the function, 524247280Sdteske# afterward is the sh(1) function which utilizes the below awk script. 525247280Sdteske# 526247280Sdteskef_ifconfig_inet6_awk=' 527247280SdteskeBEGIN { found = 0 } 528247280Sdteske( $1 == "inet6" ) \ 529247280Sdteske{ 530247280Sdteske print $2 531247280Sdteske found = 1 532247280Sdteske exit 533247280Sdteske} 534247280SdteskeEND { exit ! found } 535247280Sdteske' 536247280Sdteskef_ifconfig_inet6() 537247280Sdteske{ 538247280Sdteske local __interface="$1" __var_to_set="$2" 539247280Sdteske if [ "$__var_to_set" ]; then 540247280Sdteske local __ip6 541247280Sdteske __ip6=$( ifconfig "$__interface" 2> /dev/null | 542247280Sdteske awk "$f_ifconfig_inet6_awk" ) 543247280Sdteske setvar "$__var_to_set" "$__ip6" 544247280Sdteske else 545247280Sdteske ifconfig "$__interface" 2> /dev/null | 546247280Sdteske awk "$f_ifconfig_inet6_awk" 547247280Sdteske fi 548247280Sdteske} 549247280Sdteske 550247280Sdteske# f_ifconfig_netmask $interface [$var_to_set] 551247280Sdteske# 552247280Sdteske# Returns the IPv4 subnet mask associated with $interface. If $var_to_set is 553247280Sdteske# missing or NULL, the netmask is printed to standard output for capturing in a 554247280Sdteske# sub-shell (which is less-recommended because of performance degredation; for 555247280Sdteske# example, when called in a loop). 556247280Sdteske# 557247280Sdteskef_ifconfig_netmask() 558247280Sdteske{ 559247280Sdteske local __interface="$1" __var_to_set="$2" __octets 560247280Sdteske __octets=$( ifconfig "$__interface" 2> /dev/null | awk \ 561247280Sdteske ' 562247280Sdteske BEGIN { found = 0 } 563247280Sdteske ( $1 == "inet" ) \ 564247280Sdteske { 565247280Sdteske printf "%s %s %s %s\n", 566247280Sdteske substr($4,3,2), 567247280Sdteske substr($4,5,2), 568247280Sdteske substr($4,7,2), 569247280Sdteske substr($4,9,2) 570247280Sdteske found = 1 571247280Sdteske exit 572247280Sdteske } 573247280Sdteske END { exit ! found } 574247280Sdteske ' ) || return $FAILURE 575247280Sdteske 576247280Sdteske local __octet __netmask= 577247280Sdteske for __octet in $__octets; do 578260678Sdteske f_sprintf __netmask "%s.%u" "$__netmask" "0x$__octet" 579247280Sdteske done 580247280Sdteske __netmask="${__netmask#.}" 581247280Sdteske if [ "$__var_to_set" ]; then 582247280Sdteske setvar "$__var_to_set" "$__netmask" 583247280Sdteske else 584247280Sdteske echo $__netmask 585247280Sdteske fi 586247280Sdteske} 587247280Sdteske 588247280Sdteske# f_route_get_default [$var_to_set] 589247280Sdteske# 590247280Sdteske# Returns the IP address of the currently active default router. If $var_to_set 591247280Sdteske# is missing or NULL, the IP address is printed to standard output for 592247280Sdteske# capturing in a sub-shell (which is less-recommended because of performance 593247280Sdteske# degredation; for example, when called in a loop). 594247280Sdteske# 595247280Sdteske# This function is a two-parter. Below is the awk(1) portion of the function, 596247280Sdteske# afterward is the sh(1) function which utilizes the below awk script. 597247280Sdteske# 598252086Sdteskef_route_get_default_awk=' 599247280SdteskeBEGIN { found = 0 } 600247280Sdteske( $1 == "gateway:" ) \ 601247280Sdteske{ 602247280Sdteske print $2 603247280Sdteske found = 1 604247280Sdteske exit 605247280Sdteske} 606247280SdteskeEND { exit ! found } 607247280Sdteske' 608247280Sdteskef_route_get_default() 609247280Sdteske{ 610247280Sdteske local __var_to_set="$1" 611247280Sdteske if [ "$__var_to_set" ]; then 612247280Sdteske local __ip 613247280Sdteske __ip=$( route -n get default 2> /dev/null | 614247280Sdteske awk "$f_route_get_default_awk" ) 615247280Sdteske setvar "$__var_to_set" "$__ip" 616247280Sdteske else 617247280Sdteske route -n get default 2> /dev/null | 618247280Sdteske awk "$f_route_get_default_awk" 619247280Sdteske fi 620247280Sdteske} 621247280Sdteske 622247280Sdteske# f_resolv_conf_nameservers [$var_to_set] 623247280Sdteske# 624247280Sdteske# Returns nameserver(s) configured in resolv.conf(5). If $var_to_set is missing 625247280Sdteske# or NULL, the list of nameservers is printed to standard output for capturing 626247280Sdteske# in a sub-shell (which is less-recommended because of performance degredation; 627247280Sdteske# for example, when called in a loop). 628247280Sdteske# 629247280Sdteske# This function is a two-parter. Below is the awk(1) portion of the function, 630247280Sdteske# afterward is the sh(1) function which utilizes the below awk script. 631247280Sdteske# 632247280Sdteskef_resolv_conf_nameservers_awk=' 633247280SdteskeBEGIN { found = 0 } 634247280Sdteske( $1 == "nameserver" ) \ 635247280Sdteske{ 636247280Sdteske print $2 637247280Sdteske found = 1 638247280Sdteske} 639247280SdteskeEND { exit ! found } 640247280Sdteske' 641247280Sdteskef_resolv_conf_nameservers() 642247280Sdteske{ 643247280Sdteske local __var_to_set="$1" 644247280Sdteske if [ "$__var_to_set" ]; then 645247280Sdteske local __ns 646247280Sdteske __ns=$( awk "$f_resolv_conf_nameservers_awk" "$RESOLV_CONF" \ 647247280Sdteske 2> /dev/null ) 648247280Sdteske setvar "$__var_to_set" "$__ns" 649247280Sdteske else 650247280Sdteske awk "$f_resolv_conf_nameservers_awk" "$RESOLV_CONF" \ 651247280Sdteske 2> /dev/null 652247280Sdteske fi 653247280Sdteske} 654247280Sdteske 655247280Sdteske# f_config_resolv 656247280Sdteske# 657247280Sdteske# Attempts to configure resolv.conf(5) and ilk. Returns success if able to 658247280Sdteske# write the file(s), otherwise returns error status. 659247280Sdteske# 660247280Sdteske# Variables from variable.subr that are used in configuring resolv.conf(5) are 661247280Sdteske# as follows (all of which can be configured automatically through functions 662247280Sdteske# like f_dhcp_get_info() or manually): 663247280Sdteske# 664247280Sdteske# VAR_NAMESERVER 665247280Sdteske# The nameserver to add in resolv.conf(5). 666247280Sdteske# VAR_DOMAINNAME 667247280Sdteske# The domain to configure in resolv.conf(5). Also used in the 668247280Sdteske# configuration of hosts(5). 669247280Sdteske# VAR_IPADDR 670247280Sdteske# The IPv4 address to configure in hosts(5). 671247280Sdteske# VAR_IPV6ADDR 672247280Sdteske# The IPv6 address to configure in hosts(5). 673247280Sdteske# VAR_HOSTNAME 674247280Sdteske# The hostname to associate with the IPv4 and/or IPv6 address in 675247280Sdteske# hosts(5). 676247280Sdteske# 677247280Sdteskef_config_resolv() 678247280Sdteske{ 679247280Sdteske local cp c6p dp hp 680247280Sdteske 681247280Sdteske f_getvar $VAR_NAMESERVER cp 682247280Sdteske if [ "$cp" ]; then 683247280Sdteske case "$RESOLV_CONF" in 684247280Sdteske */*) f_quietly mkdir -p "${RESOLV_CONF%/*}" ;; 685247280Sdteske esac 686247280Sdteske 687247280Sdteske # Attempt to create/truncate the file 688247280Sdteske ( :> "$RESOLV_CONF" ) 2> /dev/null || return $FAILURE 689247280Sdteske 690247280Sdteske f_getvar $VAR_DOMAINNAME dp && 691247280Sdteske printf "domain\t%s\n" "$dp" >> "$RESOLV_CONF" 692247280Sdteske printf "nameserver\t%s\n" "$cp" >> "$RESOLV_CONF" 693247280Sdteske 694247280Sdteske f_dprintf "Wrote out %s" "$RESOLV_CONF" 695247280Sdteske fi 696247280Sdteske 697247280Sdteske f_getvar $VAR_DOMAINNAME dp 698247280Sdteske f_getvar $VAR_IPADDR cp 699247280Sdteske f_getvar $VAR_IPV6ADDR c6p 700247280Sdteske f_getvar $VAR_HOSTNAME hp 701247280Sdteske 702247280Sdteske # Attempt to create the file if it doesn't already exist 703247280Sdteske if [ ! -e "$ETC_HOSTS" ]; then 704247280Sdteske case "$ETC_HOSTS" in 705247280Sdteske */*) f_quietly mkdir -p "${ETC_HOSTS%/*}" ;; 706247280Sdteske esac 707247280Sdteske 708247280Sdteske ( :> "$ETC_HOSTS" ) 2> /dev/null || return $FAILURE 709247280Sdteske fi 710247280Sdteske 711247280Sdteske # Scan the file and add ourselves if not already configured 712247280Sdteske awk -v dn="$dp" -v ip4="$cp" -v ip6="$c6p" -v hn="$hp" ' 713247280Sdteske BEGIN { 714247280Sdteske local4found = local6found = 0 715247280Sdteske hn4found = hn6found = h4found = h6found = 0 716247280Sdteske h = ( match(hn, /\./) ? substr(hn, 0, RSTART-1) : "" ) 717247280Sdteske } 718247280Sdteske ($1 == "127.0.0.1") { local4found = 1 } 719247280Sdteske ($1 == "::1") { local6found = 1 } 720247280Sdteske { 721247280Sdteske for (n = 2; n <= NF; n++) 722247280Sdteske { 723247280Sdteske if ( $1 == ip4 ) { 724247280Sdteske if ( $n == h ) h4found = 1 725247280Sdteske if ( $n == hn ) hn4found = 1 726247280Sdteske if ( $n == hn "." ) hn4found = 1 727247280Sdteske } 728247280Sdteske if ( $1 == ip6 ) { 729247280Sdteske if ( $n == h ) h6found = 1 730247280Sdteske if ( $n == hn ) hn6found = 1 731247280Sdteske if ( $n == hn "." ) hn6found = 1 732247280Sdteske } 733247280Sdteske } 734247280Sdteske } 735247280Sdteske END { 736247280Sdteske hosts = FILENAME 737247280Sdteske 738247280Sdteske if ( ! local6found ) 739247280Sdteske printf "::1\t\t\tlocalhost%s\n", 740247280Sdteske ( dn ? " localhost." dn : "" ) >> hosts 741247280Sdteske if ( ! local4found ) 742247280Sdteske printf "127.0.0.1\t\tlocalhost%s\n", 743247280Sdteske ( dn ? " localhost." dn : "" ) >> hosts 744247280Sdteske 745247280Sdteske if ( ip6 && ! (h6found && hn6found)) 746247280Sdteske { 747247280Sdteske printf "%s\t%s %s\n", ip6, hn, h >> hosts 748247280Sdteske printf "%s\t%s.\n", ip6, hn >> hosts 749247280Sdteske } 750247280Sdteske else if ( ip6 ) 751247280Sdteske { 752247280Sdteske if ( ! h6found ) 753247280Sdteske printf "%s\t%s.\n", ip6, h >> hosts 754247280Sdteske if ( ! hn6found ) 755247280Sdteske printf "%s\t%s\n", ip6, hn >> hosts 756247280Sdteske } 757247280Sdteske 758247280Sdteske if ( ip4 && ! (h4found && hn4found)) 759247280Sdteske { 760247280Sdteske printf "%s\t\t%s %s\n", ip4, hn, h >> hosts 761247280Sdteske printf "%s\t\t%s.\n", ip4, hn >> hosts 762247280Sdteske } 763247280Sdteske else if ( ip4 ) 764247280Sdteske { 765247280Sdteske if ( ! h4found ) 766247280Sdteske printf "%s\t\t%s.\n", ip4, h >> hosts 767247280Sdteske if ( ! hn4found ) 768247280Sdteske printf "%s\t\t%s\n", ip4, hn >> hosts 769247280Sdteske } 770247280Sdteske } 771247280Sdteske ' "$ETC_HOSTS" 2> /dev/null || return $FAILURE 772247280Sdteske 773247280Sdteske f_dprintf "Wrote out %s" "$ETC_HOSTS" 774247280Sdteske return $SUCCESS 775247280Sdteske} 776247280Sdteske 777247280Sdteske# f_dhcp_parse_leases $leasefile struct_name 778247280Sdteske# 779247280Sdteske# Parse $leasefile and store the information for the most recent lease in a 780247280Sdteske# struct (see struct.subr for additional details) named `struct_name'. See 781247280Sdteske# DHCP_LEASE struct definition in the GLOBALS section above. 782247280Sdteske# 783247280Sdteskef_dhcp_parse_leases() 784247280Sdteske{ 785247280Sdteske local leasefile="$1" struct_name="$2" 786247280Sdteske 787247280Sdteske [ "$struct_name" ] || return $FAILURE 788247280Sdteske 789247280Sdteske if [ ! -e "$leasefile" ]; then 790247280Sdteske f_dprintf "%s: No such file or directory" "$leasefile" 791247280Sdteske return $FAILURE 792247280Sdteske fi 793247280Sdteske 794247280Sdteske f_struct "$struct_name" && f_struct_free "$struct_name" 795247280Sdteske f_struct_new DHCP_LEASE "$struct_name" 796247280Sdteske 797247280Sdteske eval "$( awk -v struct="$struct_name" ' 798247280Sdteske BEGIN { 799247280Sdteske lease_found = 0 800247280Sdteske keyword_list = " \ 801247280Sdteske interface \ 802247280Sdteske fixed-address \ 803247280Sdteske filename \ 804247280Sdteske server-name \ 805247280Sdteske script \ 806247280Sdteske medium \ 807247280Sdteske " 808247280Sdteske split(keyword_list, keywords, FS) 809247280Sdteske 810247280Sdteske time_list = "renew rebind expire" 811247280Sdteske split(time_list, times, FS) 812247280Sdteske 813247280Sdteske option_list = " \ 814247280Sdteske host-name \ 815247280Sdteske subnet-mask \ 816247280Sdteske routers \ 817247280Sdteske domain-name-servers \ 818247280Sdteske domain-name \ 819247280Sdteske broadcast-address \ 820247280Sdteske dhcp-lease-time \ 821247280Sdteske dhcp-message-type \ 822247280Sdteske dhcp-server-identifier \ 823247280Sdteske dhcp-renewal-time \ 824247280Sdteske dhcp-rebinding-time \ 825247280Sdteske " 826247280Sdteske split(option_list, options, FS) 827247280Sdteske } 828247280Sdteske function set_value(prop,value) 829247280Sdteske { 830247280Sdteske lease_found = 1 831247280Sdteske gsub(/[^[:alnum:]_]/, "_", prop) 832247280Sdteske sub(/;$/, "", value) 833247280Sdteske sub(/^"/, "", value) 834247280Sdteske sub(/"$/, "", value) 835247280Sdteske sub(/,.*/, "", value) 836247280Sdteske printf "%s set %s \"%s\"\n", struct, prop, value 837247280Sdteske } 838247280Sdteske /^lease {$/, /^}$/ \ 839247280Sdteske { 840247280Sdteske if ( $0 ~ /^lease {$/ ) next 841247280Sdteske if ( $0 ~ /^}$/ ) exit 842247280Sdteske 843247280Sdteske for (k in keywords) 844247280Sdteske { 845247280Sdteske keyword = keywords[k] 846247280Sdteske if ( $1 == keyword ) 847247280Sdteske { 848247280Sdteske set_value(keyword, $2) 849247280Sdteske next 850247280Sdteske } 851247280Sdteske } 852247280Sdteske 853247280Sdteske for (t in times) 854247280Sdteske { 855247280Sdteske time = times[t] 856247280Sdteske if ( $1 == time ) 857247280Sdteske { 858247280Sdteske set_value(time, $2 " " $3 " " $4) 859247280Sdteske next 860247280Sdteske } 861247280Sdteske } 862247280Sdteske 863247280Sdteske if ( $1 != "option" ) next 864247280Sdteske for (o in options) 865247280Sdteske { 866247280Sdteske option = options[o] 867247280Sdteske if ( $2 == option ) 868247280Sdteske { 869247280Sdteske set_value(option, $3) 870247280Sdteske next 871247280Sdteske } 872247280Sdteske } 873247280Sdteske } 874247280Sdteske EXIT { 875247280Sdteske if ( ! lease_found ) 876247280Sdteske { 877247280Sdteske printf "f_struct_free \"%s\"\n", struct 878247280Sdteske print "return $FAILURE" 879247280Sdteske } 880247280Sdteske } 881247280Sdteske ' "$leasefile" )" 882247280Sdteske} 883247280Sdteske 884247280Sdteske# f_dhcp_get_info $interface 885247280Sdteske# 886247280Sdteske# Parse the dhclient(8) lease database for $interface to obtain all the 887247280Sdteske# necessary IPv4 details necessary to communicate on the network. The retrieved 888247280Sdteske# information is stored in VAR_IPADDR, VAR_NETMASK, VAR_GATEWAY, and 889247280Sdteske# VAR_NAMESERVER. 890247280Sdteske# 891247280Sdteske# If reading the lease database fails, values are obtained from ifconfig(8) and 892247280Sdteske# route(8). If the DHCP lease did not provide a nameserver (or likewise, we 893247280Sdteske# were unable to parse the lease database), fall-back to resolv.conf(5) for 894247280Sdteske# obtaining the nameserver. Always returns success. 895247280Sdteske# 896247280Sdteskef_dhcp_get_info() 897247280Sdteske{ 898247280Sdteske local interface="$1" cp 899247280Sdteske local leasefile="/var/db/dhclient.leases.$interface" 900247280Sdteske 901247280Sdteske # If it fails, do it the old-fashioned way 902247280Sdteske if f_dhcp_parse_leases "$leasefile" lease; then 903247280Sdteske lease get fixed_address $VAR_IPADDR 904247280Sdteske lease get subnet_mask $VAR_NETMASK 905247280Sdteske lease get routers cp 906247280Sdteske setvar $VAR_GATEWAY "${cp%%,*}" 907247280Sdteske lease get domain_name_servers cp 908247280Sdteske setvar $VAR_NAMESERVER "${cp%%,*}" 909247280Sdteske lease get host_name cp && 910247280Sdteske setvar $VAR_HOSTNAME "$cp" 911247280Sdteske f_struct_free lease 912247280Sdteske else 913247280Sdteske # Bah, now we have to get the information from ifconfig 914247280Sdteske if f_debugging; then 915247280Sdteske f_dprintf "DHCP configured interface returns %s" \ 916247280Sdteske "$( ifconfig "$interface" )" 917247280Sdteske fi 918247280Sdteske f_ifconfig_inet "$interface" $VAR_IPADDR 919247280Sdteske f_ifconfig_netmask "$interface" $VAR_NETMASK 920247280Sdteske f_route_get_default $VAR_GATEWAY 921247280Sdteske fi 922247280Sdteske 923247280Sdteske # If we didn't get a name server value, hunt for it in resolv.conf 924247280Sdteske local ns 925247280Sdteske if [ -r "$RESOLV_CONF" ] && ! { 926247280Sdteske f_getvar $VAR_NAMESERVER ns || [ "$ns" ] 927247280Sdteske }; then 928247280Sdteske f_resolv_conf_nameservers cp && 929247280Sdteske setvar $VAR_NAMESERVER ${cp%%[$IFS]*} 930247280Sdteske fi 931247280Sdteske 932247280Sdteske return $SUCCESS 933247280Sdteske} 934247280Sdteske 935247280Sdteske# f_rtsol_get_info $interface 936247280Sdteske# 937247280Sdteske# Returns the rtsol-provided IPv6 address associated with $interface. The 938247280Sdteske# retrieved IP address is stored in VAR_IPV6ADDR. Always returns success. 939247280Sdteske# 940247280Sdteskef_rtsol_get_info() 941247280Sdteske{ 942247280Sdteske local interface="$1" cp 943247280Sdteske cp=$( ifconfig "$interface" 2> /dev/null | awk \ 944247280Sdteske ' 945247280Sdteske BEGIN { found = 0 } 946247280Sdteske ( $1 == "inet6" ) && ( $2 ~ /^fe80:/ ) \ 947247280Sdteske { 948247280Sdteske print $2 949247280Sdteske found = 1 950247280Sdteske exit 951247280Sdteske } 952247280Sdteske END { exit ! found } 953247280Sdteske ' ) && setvar $VAR_IPV6ADDR "$cp" 954247280Sdteske} 955247280Sdteske 956247280Sdteske# f_host_lookup $host [$var_to_set] 957247280Sdteske# 958247280Sdteske# Use host(1) to lookup (or reverse) an Internet number from (or to) a name. 959247280Sdteske# Multiple answers are returned separated by a single space. If host(1) does 960247280Sdteske# not exit cleanly, its full output is provided and the return status is 1. 961247280Sdteske# 962247280Sdteske# If nsswitch.conf(5) has been configured to query local access first for the 963247280Sdteske# `hosts' database, we'll manually check hosts(5) first (preventing host(1) 964247280Sdteske# from hanging in the event that DNS goes awry). 965247280Sdteske# 966247280Sdteske# If $var_to_set is missing or NULL, the list of IP addresses is printed to 967247280Sdteske# standard output for capturing in a sub-shell (which is less-recommended 968247280Sdteske# because of performance degredation; for example, when called in a loop). 969247280Sdteske# 970247280Sdteske# The variables from variable.subr used in looking up the host are as follows 971247280Sdteske# (which are set manually): 972247280Sdteske# 973247280Sdteske# VAR_IPV6_ENABLE [Optional] 974247280Sdteske# If set to "YES", enables the lookup of IPv6 addresses and IPv4 975247280Sdteske# address. IPv6 addresses, if any, will come before IPv4. Note 976247280Sdteske# that if nsswitch.conf(5) shows an affinity for "files" for the 977247280Sdteske# "host" database and there is a valid entry in hosts(5) for 978247280Sdteske# $host, this setting currently has no effect (an IPv4 address 979247280Sdteske# can supersede an IPv6 address). By design, hosts(5) overrides 980247280Sdteske# any preferential treatment. Otherwise, if this variable is not 981247280Sdteske# set, IPv6 addresses will not be used (IPv4 addresses will 982247280Sdteske# specifically be requested from DNS). 983247280Sdteske# 984247280Sdteske# This function is a two-parter. Below is the awk(1) portion of the function, 985247280Sdteske# afterward is the sh(1) function which utilizes the below awk script. 986247280Sdteske# 987247280Sdteskef_host_lookup_awk=' 988247280SdteskeBEGIN{ addrs = "" } 989247280Sdteske!/^[[:space:]]*(#|$)/ \ 990247280Sdteske{ 991247280Sdteske for (n=1; n++ < NF;) if ($n == name) 992247280Sdteske addrs = addrs (addrs ? " " : "") $1 993247280Sdteske} 994247280SdteskeEND { 995247280Sdteske if (addrs) print addrs 996247280Sdteske exit !addrs 997247280Sdteske} 998247280Sdteske' 999247280Sdteskef_host_lookup() 1000247280Sdteske{ 1001247280Sdteske local __host="$1" __var_to_set="$2" 1002247280Sdteske f_dprintf "f_host_lookup: host=[%s]" "$__host" 1003247280Sdteske 1004247280Sdteske # If we're configured to look at local files first, do that 1005247280Sdteske if awk '/^hosts:/{exit !($2=="files")}' "$NSSWITCH_CONF"; then 1006247280Sdteske if [ "$__var_to_set" ]; then 1007247280Sdteske local __cp 1008247280Sdteske if __cp=$( awk -v name="$__host" \ 1009247280Sdteske "$f_host_lookup_awk" "$ETC_HOSTS" ) 1010247280Sdteske then 1011247280Sdteske setvar "$__var_to_set" "$__cp" 1012247280Sdteske return $SUCCESS 1013247280Sdteske fi 1014247280Sdteske else 1015247280Sdteske awk -v name="$__host" \ 1016247280Sdteske "$f_host_lookup_awk" "$ETC_HOSTS" && 1017247280Sdteske return $SUCCESS 1018247280Sdteske fi 1019247280Sdteske fi 1020247280Sdteske 1021247280Sdteske # 1022247280Sdteske # Fall back to host(1) -- which is further governed by nsswitch.conf(5) 1023247280Sdteske # 1024247280Sdteske 1025258420Sdteske local __output __ip6 __addrs= 1026247280Sdteske f_getvar $VAR_IPV6_ENABLE __ip6 1027258420Sdteske 1028258420Sdteske # If we have a TCP media type configured, check for an SRV record 1029258420Sdteske local __srvtypes= 1030258420Sdteske { f_quietly f_getvar $VAR_HTTP_PATH || 1031258420Sdteske f_quietly f_getvar $VAR_HTTP_PROXY_PATH 1032258420Sdteske } && __srvtypes="$__srvtypes _http._tcp" 1033258420Sdteske f_quietly f_getvar $VAR_FTP_PATH && __srvtypes="$__srvtypes _ftp._tcp" 1034258420Sdteske f_quietly f_getvar $VAR_NFS_PATH && 1035258420Sdteske __srvtypes="$__srvtypes _nfs._tcp _nfs._udp" 1036258420Sdteske 1037258420Sdteske # Calculate wait time as dividend of total time and host(1) invocations 1038258420Sdteske local __host_runs __wait 1039260678Sdteske f_count __host_runs $__srvtypes 1040247280Sdteske if [ "$__ip6" = "YES" ]; then 1041260678Sdteske __host_runs=$(( $__host_runs + 2 )) 1042258420Sdteske else 1043260678Sdteske __host_runs=$(( $__host_runs + 1 )) 1044258420Sdteske fi 1045258420Sdteske f_getvar $VAR_MEDIA_TIMEOUT __wait 1046258420Sdteske [ "$__wait" ] && __wait="-W $(( $__wait / $__host_runs ))" 1047258420Sdteske 1048258420Sdteske # Query SRV types first (1st host response taken as new host to query) 1049258420Sdteske for __type in $__srvtypes; do 1050258420Sdteske if __output=$( 1051258420Sdteske host -t SRV $__wait -- "$__type.$__host" \ 1052258420Sdteske 2> /dev/null 1053258420Sdteske ); then 1054258420Sdteske __host=$( echo "$__output" | 1055258420Sdteske awk '/ SRV /{print $NF;exit}' ) 1056258420Sdteske break 1057258420Sdteske fi 1058258420Sdteske done 1059258420Sdteske 1060258420Sdteske # Try IPv6 first (if enabled) 1061258420Sdteske if [ "$__ip6" = "YES" ]; then 1062247280Sdteske if ! __output=$( host -t AAAA $__wait -- "$__host" 2>&1 ); then 1063247280Sdteske # An error occurred, display in-full and return error 1064247280Sdteske [ "$__var_to_set" ] && 1065247280Sdteske setvar "$__var_to_set" "$__output" 1066247280Sdteske return $FAILURE 1067247280Sdteske fi 1068258420Sdteske # Add the IPv6 addresses and fall-through to collect IPv4 too 1069247280Sdteske __addrs=$( echo "$__output" | awk '/ address /{print $NF}' ) 1070247280Sdteske fi 1071258420Sdteske 1072258420Sdteske # Good ol' IPv4 1073247280Sdteske if ! __output=$( host -t A $__wait -- "$__host" 2>&1 ); then 1074247280Sdteske # An error occurred, display it in-full and return error 1075247280Sdteske [ "$__var_to_set" ] && setvar "$__var_to_set" "$__output" 1076247280Sdteske return $FAILURE 1077247280Sdteske fi 1078258420Sdteske 1079247280Sdteske __addrs="$__addrs${__addrs:+ }$( 1080247280Sdteske echo "$__output" | awk '/ address /{print $NF}' )" 1081247280Sdteske if [ "$__var_to_set" ]; then 1082247280Sdteske setvar "$__var_to_set" "$__addrs" 1083247280Sdteske else 1084247280Sdteske echo $__addrs 1085247280Sdteske fi 1086247280Sdteske} 1087247280Sdteske 1088247280Sdteske# f_device_dialog_tcp $device 1089247280Sdteske# 1090247280Sdteske# This is it - how to get TCP setup values. Prompt the user to edit/confirm the 1091247280Sdteske# interface, gateway, nameserver, and hostname settings -- all required for 1092247280Sdteske# general TCP/IP access. 1093247280Sdteske# 1094247280Sdteske# Variables from variable.subr that can be used to sript user input: 1095247280Sdteske# 1096247280Sdteske# VAR_NO_INET6 1097247280Sdteske# If set, prevents asking the user if they would like to use 1098247280Sdteske# rtsol(8) to check for an IPv6 router. 1099247280Sdteske# VAR_TRY_RTSOL 1100247280Sdteske# If set to "YES" (and VAR_NONINTERACTIVE is unset), asks the 1101247280Sdteske# user if they would like to try the IPv6 RouTer SOLicitation 1102247280Sdteske# utility (rtsol(8)) to get IPv6 information. Ignored if 1103247280Sdteske# VAR_NO_INET6 is set. 1104247280Sdteske# VAR_TRY_DHCP 1105247280Sdteske# If set to "YES" (and VAR_NONINTERACTIVE is unset), asks the 1106247280Sdteske# user if they would like to try to acquire IPv4 connection 1107247280Sdteske# settings from a DHCP server using dhclient(8). 1108247280Sdteske# 1109247280Sdteske# VAR_GATEWAY Default gateway to use. 1110247280Sdteske# VAR_IPADDR Interface address to assign. 1111247280Sdteske# VAR_NETMASK Interface subnet mask. 1112247280Sdteske# VAR_EXTRAS Extra interface options to ifconfig(8). 1113247280Sdteske# VAR_HOSTNAME Hostname to set. 1114247280Sdteske# VAR_DOMAINNAME Domain name to use. 1115247280Sdteske# VAR_NAMESERVER DNS nameserver to use when making lookups. 1116247280Sdteske# VAR_IPV6ADDR IPv6 interface address. 1117247280Sdteske# 1118247280Sdteske# In addition, the following variables are used in acquiring network settings 1119247280Sdteske# from the user: 1120247280Sdteske# 1121247280Sdteske# VAR_NONINTERACTIVE 1122247280Sdteske# If set (such as when running in a script), prevents asking the 1123247280Sdteske# user questions or displaying the usual prompts, etc. 1124247280Sdteske# VAR_NETINTERACTIVE 1125247280Sdteske# The one exception to VAR_NONINTERACTIVE is VAR_NETINTERACTIVE, 1126247280Sdteske# which if set will prompt the user to try RTSOL (unless 1127247280Sdteske# VAR_TRY_RTSOL has been set), try DHCP (unless VAR_TRY_DHCP has 1128247280Sdteske# been set), and display the network verification dialog. This 1129247280Sdteske# allows you to have a mostly non-interactive script that still 1130247280Sdteske# prompts for network setup/confirmation. 1131247280Sdteske# 1132247280Sdteske# After successfull execution, the following variables are set: 1133247280Sdteske# 1134247280Sdteske# VAR_IFCONFIG + $device (e.g., `ifconfig_em0') 1135247280Sdteske# Defines the ifconfig(8) properties specific to $device. 1136247280Sdteske# 1137247280Sdteskef_device_dialog_tcp() 1138247280Sdteske{ 1139266290Sdteske local dev="$1" devname cp n 1140247280Sdteske local use_dhcp="" use_rtsol="" 1141247280Sdteske local _ipaddr _netmask _extras 1142247280Sdteske 1143256181Sdteske [ "$dev" ] || return $DIALOG_CANCEL 1144266290Sdteske f_struct "$dev" get name devname || return $DIALOG_CANCEL 1145247280Sdteske 1146247280Sdteske # Initialize vars from previous device values 1147247280Sdteske local private 1148266290Sdteske $dev get private private 1149247280Sdteske if [ "$private" ] && f_struct "$private"; then 1150247280Sdteske $private get ipaddr _ipaddr 1151247280Sdteske $private get netmask _netmask 1152247280Sdteske $private get extras _extras 1153247280Sdteske $private get use_dhcp use_dhcp 1154247280Sdteske $private get use_rtsol use_rtsol 1155247280Sdteske else # See if there are any defaults 1156247280Sdteske 1157247280Sdteske # 1158247280Sdteske # This is a hack so that the dialogs below are interactive in a 1159247280Sdteske # script if we have requested interactive behavior. 1160247280Sdteske # 1161247280Sdteske local old_interactive= 1162247280Sdteske if ! f_interactive && f_netinteractive; then 1163247280Sdteske f_getvar $VAR_NONINTERACTIVE old_interactive 1164247280Sdteske unset $VAR_NONINTERACTIVE 1165247280Sdteske fi 1166247280Sdteske 1167247280Sdteske # 1168247280Sdteske # Try a RTSOL scan if such behavior is desired. 1169247280Sdteske # If the variable was configured and is YES, do it. 1170247280Sdteske # If it was configured to anything else, treat it as NO. 1171247280Sdteske # Otherwise, ask the question interactively. 1172247280Sdteske # 1173247280Sdteske local try6 1174251268Sdteske if ! f_isset $VAR_NO_INET6 && { 1175247280Sdteske { f_getvar $VAR_TRY_RTSOL try6 && [ "$try6" = "YES" ]; } || 1176247280Sdteske { 1177251268Sdteske # Only prompt the user when VAR_TRY_RTSOL is unset 1178251268Sdteske ! f_isset $VAR_TRY_RTSOL && 1179251268Sdteske f_dialog_noyes "$msg_try_ipv6_configuration" 1180247280Sdteske } 1181247280Sdteske }; then 1182247280Sdteske local i 1183247280Sdteske 1184247280Sdteske f_quietly sysctl net.inet6.ip6.forwarding=0 1185247280Sdteske f_quietly sysctl net.inet6.ip6.accept_rtadv=1 1186266290Sdteske f_quietly ifconfig $devname up 1187247280Sdteske 1188247280Sdteske i=$( sysctl -n net.inet6.ip6.dad_count ) 1189247280Sdteske sleep $(( $i + 1 )) 1190247280Sdteske 1191247280Sdteske f_quietly mkdir -p /var/run 1192247280Sdteske f_dialog_info "$msg_scanning_for_ra_servers" 1193266290Sdteske if f_quietly rtsol $devname; then 1194247280Sdteske i=$( sysctl -n net.inet6.ip6.dad_count ) 1195247280Sdteske sleep $(( $i + 1 )) 1196266290Sdteske f_rtsol_get_info $devname 1197247280Sdteske use_rtsol=1 1198247280Sdteske else 1199247280Sdteske use_rtsol= 1200247280Sdteske fi 1201247280Sdteske fi 1202247280Sdteske 1203247280Sdteske # 1204247280Sdteske # Try a DHCP scan if such behavior is desired. 1205247280Sdteske # If the variable was configured and is YES, do it. 1206247280Sdteske # If it was configured to anything else, treat it as NO. 1207247280Sdteske # Otherwise, ask the question interactively. 1208247280Sdteske # 1209247280Sdteske local try4 1210247280Sdteske if { f_getvar $VAR_TRY_DHCP try4 && [ "$try4" = "YES" ]; } || { 1211251268Sdteske # Only prompt the user when VAR_TRY_DHCP is unset 1212251268Sdteske ! f_isset $VAR_TRY_DHCP && 1213251268Sdteske f_dialog_noyes "$msg_try_dhcp_configuration" 1214247280Sdteske }; then 1215266290Sdteske f_quietly ifconfig $devname delete 1216247280Sdteske f_quietly mkdir -p /var/db 1217247280Sdteske f_quietly mkdir -p /var/run 1218247280Sdteske f_quietly mkdir -p /tmp 1219247280Sdteske 1220247280Sdteske local msg="$msg_scanning_for_dhcp_servers" 1221247280Sdteske trap - SIGINT 1222247280Sdteske ( # Execute in sub-shell to allow/catch Ctrl-C 1223247280Sdteske trap 'exit $FAILURE' SIGINT 1224247280Sdteske if [ "$USE_XDIALOG" ]; then 1225266290Sdteske f_quietly dhclient $devname | 1226247280Sdteske f_xdialog_info "$msg" 1227247280Sdteske else 1228247280Sdteske f_dialog_info "$msg" 1229266290Sdteske f_quietly dhclient $devname 1230247280Sdteske fi 1231247280Sdteske ) 1232247280Sdteske local retval=$? 1233247280Sdteske trap 'f_interrupt' SIGINT 1234247280Sdteske if [ $retval -eq $SUCCESS ]; then 1235266290Sdteske f_dhcp_get_info $devname 1236247280Sdteske use_dhcp=1 1237247280Sdteske else 1238247280Sdteske use_dhcp= 1239247280Sdteske fi 1240247280Sdteske fi 1241247280Sdteske 1242247280Sdteske # Restore old VAR_NONINTERACTIVE if needed. 1243247280Sdteske [ "$old_interactive" ] && 1244247280Sdteske setvar $VAR_NONINTERACTIVE "$old_interactive" 1245247280Sdteske 1246247280Sdteske # Special hack so it doesn't show up oddly in the menu 1247247280Sdteske local gw 1248247280Sdteske if f_getvar $VAR_GATEWAY gw && [ "$gw" = "NO" ]; then 1249247280Sdteske setvar $VAR_GATEWAY "" 1250247280Sdteske fi 1251247280Sdteske 1252247280Sdteske # Get old IP address from variable space, if available 1253247280Sdteske if [ ! "$_ipaddr" ]; then 1254247280Sdteske if f_getvar $VAR_IPADDR cp; then 1255247280Sdteske _ipaddr="$cp" 1256266290Sdteske elif f_getvar ${devname}_$VAR_IPADDR cp; then 1257247280Sdteske _ipaddr="$cp" 1258247280Sdteske fi 1259247280Sdteske fi 1260247280Sdteske 1261247280Sdteske # Get old netmask from variable space, if available 1262247280Sdteske if [ ! "$_netmask" ]; then 1263247280Sdteske if f_getvar $VAR_NETMASK cp; then 1264247280Sdteske _netmask="$cp" 1265266290Sdteske elif f_getvar ${devname}_$VAR_NETMASK cp; then 1266247280Sdteske _netmask="$cp" 1267247280Sdteske fi 1268247280Sdteske fi 1269247280Sdteske 1270247280Sdteske # Get old extras string from variable space, if available 1271247280Sdteske if [ ! "$_extras" ]; then 1272247280Sdteske if f_getvar $VAR_EXTRAS cp; then 1273247280Sdteske _extras="$cp" 1274266290Sdteske elif f_getvar ${devname}_$VAR_EXTRAS cp; then 1275247280Sdteske _extras="$cp" 1276247280Sdteske fi 1277247280Sdteske fi 1278247280Sdteske fi 1279247280Sdteske 1280247280Sdteske # Look up values already recorded with the system, or blank the string 1281247280Sdteske # variables ready to accept some new data 1282247280Sdteske local _hostname _gateway _nameserver 1283247280Sdteske f_getvar $VAR_HOSTNAME _hostname 1284247280Sdteske case "$_hostname" in 1285247280Sdteske *.*) : do nothing ;; # Already fully-qualified 1286247280Sdteske *) 1287247280Sdteske f_getvar $VAR_DOMAINNAME cp 1288247280Sdteske [ "$cp" ] && _hostname="$_hostname.$cp" 1289247280Sdteske esac 1290247280Sdteske f_getvar $VAR_GATEWAY _gateway 1291247280Sdteske f_getvar $VAR_NAMESERVER _nameserver 1292247280Sdteske 1293247280Sdteske # Re-check variables for initial inheritance before heading into dialog 1294247280Sdteske [ "$_hostname" ] || _hostname="${HOSTNAME:-$( hostname )}" 1295247280Sdteske [ "$_gateway" ] || f_route_get_default _gateway 1296247280Sdteske [ ! "$_nameserver" ] && 1297247280Sdteske f_resolv_conf_nameservers cp && _nameserver=${cp%%[$IFS]*} 1298266290Sdteske [ "$_ipaddr" ] || f_ifconfig_inet $devname _ipaddr 1299266290Sdteske [ "$_netmask" ] || f_ifconfig_netmask $devname _netmask 1300247280Sdteske 1301247280Sdteske # If non-interactive, jump over dialog section and into config section 1302247280Sdteske if f_netinteractive || f_interactive || [ ! "$_hostname" ] 1303247280Sdteske then 1304247280Sdteske [ ! "$_hostname" ] && f_interactive && 1305252795Sdteske f_show_msg "$msg_hostname_variable_not_set" 1306247280Sdteske 1307247280Sdteske local title=" $msg_network_configuration " 1308247280Sdteske local hline="$hline_alnum_arrows_punc_tab_enter" 1309247280Sdteske local extras_help="$tcplayout_extras_help" 1310247280Sdteske 1311247280Sdteske # Modify the help line for PLIP config 1312266290Sdteske [ "${devname#plip}" != "$devname" ] && 1313247280Sdteske extras_help="$tcplayout_extras_help_for_plip" 1314247280Sdteske 1315247280Sdteske f_getvar $VAR_IPV6ADDR cp && [ "$cp" ] && 1316247280Sdteske title="$title($msg_ipv6_ready) " 1317247280Sdteske 1318247280Sdteske if [ ! "$USE_XDIALOG" ]; then 1319247280Sdteske local prompt="$msg_dialog_mixedform_navigation_help" 1320247280Sdteske # Calculate center position for displaying device label 1321266290Sdteske local devlabel="$msg_configuration_for_interface" 1322266290Sdteske devlabel="$devlabel $devname" 1323247280Sdteske local width=54 1324247280Sdteske local n=$(( $width/2 - (${#devlabel} + 4)/2 - 2 )) 1325247280Sdteske 1326247280Sdteske while :; do 1327247280Sdteske cp=$( $DIALOG \ 1328247280Sdteske --title "$title" \ 1329247280Sdteske --backtitle "$DIALOG_BACKTITLE" \ 1330247280Sdteske --hline "$hline" \ 1331247280Sdteske --item-help \ 1332247280Sdteske --ok-label "$msg_ok" \ 1333247280Sdteske --cancel-label "$msg_cancel" \ 1334247280Sdteske --help-button \ 1335247280Sdteske --help-label "$msg_help" \ 1336247280Sdteske --mixedform "$prompt" 16 $width 9 \ 1337247280Sdteske "$msg_host_name_including_domain:" 1 2 \ 1338247280Sdteske "$_hostname" 2 3 45 255 0 \ 1339247280Sdteske "$tcplayout_hostname_help" \ 1340247280Sdteske "$msg_ipv4_gateway:" 3 2 \ 1341247280Sdteske "$_gateway" 4 3 16 15 0 \ 1342247280Sdteske "$tcplayout_gateway_help" \ 1343247280Sdteske "$msg_name_server:" 3 31 \ 1344247280Sdteske "$_nameserver" 4 32 16 15 0 \ 1345247280Sdteske "$tcplayout_nameserver_help" \ 1346247280Sdteske "- $devlabel -" 5 $n "" 0 0 0 0 3 "" \ 1347247280Sdteske "$msg_ipv4_address:" 6 6 \ 1348247280Sdteske "$_ipaddr" 7 7 16 15 0 \ 1349247280Sdteske "$tcplayout_ipaddr_help" \ 1350247280Sdteske "$msg_netmask:" 6 31 \ 1351247280Sdteske "$_netmask" 7 32 16 15 0 \ 1352247280Sdteske "$tcplayout_netmask_help" \ 1353247280Sdteske "$msg_extra_options_to_ifconfig" 8 6 \ 1354247280Sdteske "$_extras" 9 7 41 2048 0 \ 1355247280Sdteske "$extras_help" \ 1356247280Sdteske 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD ) 1357247280Sdteske 1358247280Sdteske # --mixed-form always returns 0, we have to 1359247280Sdteske # use the returned data to determine button 1360247280Sdteske if [ ! "$cp" ]; then 1361247280Sdteske # User either chose "Cancel", pressed 1362247280Sdteske # ESC, or blanked every form field 1363256181Sdteske return $DIALOG_CANCEL 1364247280Sdteske else 1365247280Sdteske n=$( echo "$cp" | f_number_of_lines ) 1366247280Sdteske [ $n -eq 1 ] && case "$cp" in HELP*) 1367247280Sdteske # User chose "Help" 1368247280Sdteske f_show_help "$TCP_HELPFILE" 1369247280Sdteske continue 1370247280Sdteske esac 1371247280Sdteske fi 1372247280Sdteske 1373247280Sdteske # Turn mixed-form results into env variables 1374247280Sdteske eval "$( echo "$cp" | awk ' 1375247280Sdteske BEGIN { 1376247280Sdteske n = 0 1377247280Sdteske field[++n] = "_hostname" 1378247280Sdteske field[++n] = "_gateway" 1379247280Sdteske field[++n] = "_nameserver" 1380247280Sdteske field[++n] = "_ipaddr" 1381247280Sdteske field[++n] = "_netmask" 1382247280Sdteske field[++n] = "_extras" 1383247280Sdteske nfields = n 1384247280Sdteske n = 0 1385247280Sdteske } 1386247280Sdteske { 1387247280Sdteske gsub(/'\''/, "'\'\\\\\'\''") 1388247280Sdteske sub(/[[:space:]]*$/, "") 1389247280Sdteske value[field[++n]] = $0 1390247280Sdteske } 1391247280Sdteske END { 1392247280Sdteske for ( n = 1; n <= nfields; n++ ) 1393247280Sdteske { 1394247280Sdteske printf "%s='\''%s'\'';\n", 1395247280Sdteske field[n], 1396247280Sdteske value[field[n]] 1397247280Sdteske } 1398247280Sdteske }' )" 1399247280Sdteske 1400247280Sdteske f_dialog_validate_tcpip \ 1401247280Sdteske "$_hostname" \ 1402247280Sdteske "$_gateway" \ 1403247280Sdteske "$_nameserver" \ 1404247280Sdteske "$_ipaddr" \ 1405247280Sdteske "$_netmask" \ 1406247280Sdteske && break 1407247280Sdteske done 1408247280Sdteske else 1409247280Sdteske # Xdialog(1) does not support --mixed-form 1410247280Sdteske # Create a persistent menu instead 1411247280Sdteske 1412247280Sdteske f_dialog_title "$msg_network_configuration" 1413251269Sdteske local prompt= 1414247280Sdteske 1415247280Sdteske while :; do 1416247280Sdteske cp=$( $DIALOG \ 1417247280Sdteske --title "$DIALOG_TITLE" \ 1418247280Sdteske --backtitle "$DIALOG_BACKTITLE" \ 1419247280Sdteske --hline "$hline" \ 1420247280Sdteske --item-help \ 1421247280Sdteske --ok-label "$msg_ok" \ 1422247280Sdteske --cancel-label "$msg_cancel" \ 1423247280Sdteske --help "" \ 1424247280Sdteske --menu "$prompt" 21 60 8 \ 1425247280Sdteske "$msg_accept_continue" "" \ 1426247280Sdteske "$tcplayout_accept_cont_help" \ 1427247280Sdteske "$msg_host_name_including_domain:" \ 1428247280Sdteske "$_hostname" \ 1429247280Sdteske "$tcplayout_hostname_help" \ 1430247280Sdteske "$msg_ipv4_gateway:" "$_gateway" \ 1431247280Sdteske "$tcplayout_gateway_help" \ 1432247280Sdteske "$msg_name_server:" "$_nameserver" \ 1433247280Sdteske "$tcplayout_nameserver_help" \ 1434247280Sdteske "$msg_ipv4_address:" "$_ipaddr" \ 1435247280Sdteske "$tcplayout_ipaddr_help" \ 1436247280Sdteske "$msg_netmask:" "$_netmask" \ 1437247280Sdteske "$tcplayout_netmask_help" \ 1438247280Sdteske "$msg_extra_options_to_ifconfig" \ 1439247280Sdteske "$_extras" "$extras_help" \ 1440247280Sdteske 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 1441247280Sdteske ) 1442247280Sdteske local retval=$? 1443251236Sdteske f_dialog_data_sanitize cp 1444247280Sdteske f_dprintf "retval=%u mtag=[%s]" $retval "$cp" 1445247280Sdteske 1446256181Sdteske if [ $retval -eq $DIALOG_HELP ]; then 1447247280Sdteske f_show_help "$TCP_HELPFILE" 1448247280Sdteske continue 1449256181Sdteske elif [ $retval -ne $DIALOG_OK ]; then 1450247280Sdteske f_dialog_title_restore 1451256181Sdteske return $DIALOG_CANCEL 1452247280Sdteske fi 1453247280Sdteske 1454247280Sdteske case "$cp" in 1455247280Sdteske "$msg_accept_continue") 1456247280Sdteske f_dialog_validate_tcpip \ 1457247280Sdteske "$_hostname" \ 1458247280Sdteske "$_gateway" \ 1459247280Sdteske "$_nameserver" \ 1460247280Sdteske "$_ipaddr" \ 1461247280Sdteske "$_netmask" \ 1462247280Sdteske && break ;; 1463247280Sdteske "$msg_host_name_including_domain:") 1464251242Sdteske f_dialog_input cp "$cp" "$_hostname" \ 1465251242Sdteske && _hostname="$cp" ;; 1466247280Sdteske "$msg_ipv4_gateway:") 1467251242Sdteske f_dialog_input cp "$cp" "$_gateway" \ 1468251242Sdteske && _gateway="$cp" ;; 1469247280Sdteske "$msg_name_server:") 1470251242Sdteske f_dialog_input cp "$cp" "$_nameserver" \ 1471251242Sdteske && _nameserver="$cp" ;; 1472247280Sdteske "$msg_ipv4_address:") 1473251242Sdteske f_dialog_input cp "$cp" "$_ipaddr" \ 1474251242Sdteske && _ipaddr="$cp" ;; 1475247280Sdteske "$msg_netmask:") 1476251242Sdteske f_dialog_input cp "$cp" "$_netmask" \ 1477251242Sdteske && _netmask="$cp" ;; 1478247280Sdteske "$msg_extra_options_to_ifconfig") 1479251242Sdteske f_dialog_input cp "$cp" "$_extras" \ 1480251242Sdteske && _extras="$cp" ;; 1481247280Sdteske esac 1482247280Sdteske done 1483247280Sdteske 1484247280Sdteske f_dialog_title_restore 1485247280Sdteske 1486247280Sdteske fi # XDIALOG 1487247280Sdteske 1488247280Sdteske fi # interactive 1489247280Sdteske 1490247280Sdteske # We actually need to inform the rest of bsdconfig about this 1491247280Sdteske # data now if the user hasn't selected cancel. 1492247280Sdteske 1493247280Sdteske if [ "$_hostname" ]; then 1494247280Sdteske setvar $VAR_HOSTNAME "$_hostname" 1495247280Sdteske f_quietly hostname "$_hostname" 1496247280Sdteske case "$_hostname" in 1497247280Sdteske *.*) setvar $VAR_DOMAINNAME "${_hostname#*.}" ;; 1498247280Sdteske esac 1499247280Sdteske fi 1500247280Sdteske [ "$_gateway" ] && setvar $VAR_GATEWAY "$_gateway" 1501247280Sdteske [ "$_nameserver" ] && setvar $VAR_NAMESERVER "$_nameserver" 1502247280Sdteske [ "$_ipaddr" ] && setvar $VAR_IPADDR "$_ipaddr" 1503247280Sdteske [ "$_netmask" ] && setvar $VAR_NETMASK "$_netmask" 1504247280Sdteske [ "$_extras" ] && setvar $VAR_EXTRAS "$_extras" 1505247280Sdteske 1506247280Sdteske f_dprintf "Creating struct DEVICE_INFO devinfo_%s" "$dev" 1507247280Sdteske f_struct_new DEVICE_INFO devinfo_$dev 1508266290Sdteske $dev set private devinfo_$dev 1509247280Sdteske 1510247280Sdteske devinfo_$dev set ipaddr $_ipaddr 1511247280Sdteske devinfo_$dev set netmask $_netmask 1512247280Sdteske devinfo_$dev set extras $_extras 1513247280Sdteske devinfo_$dev set use_rtsol $use_rtsol 1514247280Sdteske devinfo_$dev set use_dhcp $use_dhcp 1515247280Sdteske 1516247280Sdteske if [ "$use_dhcp" -o "$_ipaddr" ]; then 1517247280Sdteske if [ "$use_dhcp" ]; then 1518247280Sdteske cp="DHCP${extras:+ $extras}" 1519247280Sdteske else 1520247280Sdteske cp="inet $_ipaddr netmask $_netmask${extras:+ $extras}" 1521247280Sdteske fi 1522266290Sdteske setvar $VAR_IFCONFIG$devname "$cp" 1523247280Sdteske fi 1524247280Sdteske [ "$use_rtsol" ] && 1525247280Sdteske setvar $VAR_IPV6_ENABLE "YES" 1526247280Sdteske 1527247280Sdteske [ "$use_dhcp" ] || 1528247280Sdteske f_config_resolv # XXX this will do it on the MFS copy 1529247280Sdteske 1530256181Sdteske return $DIALOG_OK 1531247280Sdteske} 1532247280Sdteske 1533247280Sdteske# f_device_scan_tcp [$var_to_set] 1534247280Sdteske# 1535247280Sdteske# Scan for the first active/configured TCP/IP device. The name of the interface 1536247280Sdteske# is printed to stderr like other dialog(1)-based functions (stdout is reserved 1537247280Sdteske# for dialog(1) interaction) if $var_to_set is missing or NULL. Returns failure 1538247280Sdteske# if no active/configured interface 1539247280Sdteske# 1540247280Sdteskef_device_scan_tcp() 1541247280Sdteske{ 1542247280Sdteske local __var_to_set="$1" __iface 1543247280Sdteske for __iface in $( ifconfig -l ); do 1544247280Sdteske if ifconfig $__iface | awk ' 1545247280Sdteske BEGIN { 1546247280Sdteske has_inet = has_inet6 = is_ethernet = 0 1547247280Sdteske is_usable = 1 1548247280Sdteske } 1549247280Sdteske ( $1 == "status:" && $2 != "active" ) { is_usable = 0; exit } 1550247280Sdteske ( $1 == "inet" ) { 1551247280Sdteske if ($2 == "0.0.0.0") { is_usable = 0; exit } 1552247280Sdteske has_inet++ 1553247280Sdteske } 1554247280Sdteske ( $1 == "inet6") { has_inet6++ } 1555247280Sdteske ( $1 == "media:" ) { 1556247280Sdteske if ($2 != "Ethernet") { is_usable = 0; exit } 1557247280Sdteske is_ethernet = 1 1558247280Sdteske } 1559247280Sdteske END { 1560247280Sdteske if (!(is_ethernet && (has_inet || has_inet6))) 1561247280Sdteske is_usable = 0 1562247280Sdteske exit ! is_usable 1563247280Sdteske }'; then 1564247280Sdteske f_interactive && 1565247280Sdteske f_show_msg "$msg_using_interface" "$__iface" 1566247280Sdteske f_dprintf "f_device_scan_tcp found %s" "$__iface" 1567247280Sdteske if [ "$__var_to_set" ]; then 1568247280Sdteske setvar "$__var_to_set" "$__iface" 1569247280Sdteske else 1570247280Sdteske echo "$__iface" >&2 1571247280Sdteske fi 1572247280Sdteske return $SUCCESS 1573247280Sdteske fi 1574247280Sdteske done 1575247280Sdteske 1576247280Sdteske return $FAILURE 1577247280Sdteske} 1578247280Sdteske 1579247280Sdteske# f_device_select_tcp 1580247280Sdteske# 1581247280Sdteske# Prompt the user to select network interface to use for TCP/IP access. 1582247280Sdteske# Variables from variable.subr that can be used to script user input: 1583247280Sdteske# 1584247280Sdteske# VAR_NETWORK_DEVICE [Optional] 1585247280Sdteske# Either a comma-separated list of network interfaces to try when 1586247280Sdteske# setting up network access (e.g., "fxp0,em0") or "ANY" (case- 1587247280Sdteske# sensitive) to indicate that the first active and configured 1588247280Sdteske# interface is acceptable. If unset, the user is presented with a 1589247280Sdteske# menu of all available network interfaces. 1590247280Sdteske# 1591247280Sdteske# Returns success if a valid network interface has been selected. 1592247280Sdteske# 1593247280Sdteskef_device_select_tcp() 1594247280Sdteske{ 1595266290Sdteske local devs dev cnt if network_dev 1596247280Sdteske f_getvar $VAR_NETWORK_DEVICE network_dev 1597247280Sdteske 1598247280Sdteske f_dprintf "f_device_select_tcp: %s=[%s]" \ 1599247280Sdteske VAR_NETWORK_DEVICE "$network_dev" 1600247280Sdteske 1601247280Sdteske if [ "$network_dev" ]; then 1602247280Sdteske # 1603247280Sdteske # This can be set to several types of values. If set to ANY, 1604247280Sdteske # scan all network devices looking for a valid link, and go 1605247280Sdteske # with the first device found. Can also be specified as a 1606247280Sdteske # comma delimited list, with each network device tried in 1607247280Sdteske # order. Can also be set to a single network device. 1608247280Sdteske # 1609247280Sdteske [ "$network_dev" = "ANY" ] && f_device_scan_tcp network_dev 1610247280Sdteske 1611247280Sdteske while [ "$network_dev" ]; do 1612247280Sdteske case "$network_dev" in 1613266290Sdteske *,*) if="${network_dev%%,*}" 1614247280Sdteske network_dev="${network_dev#*,}" 1615247280Sdteske ;; 1616266290Sdteske *) if="$network_dev" 1617247280Sdteske network_dev= 1618247280Sdteske esac 1619247280Sdteske 1620266290Sdteske f_device_find -1 "$if" $DEVICE_TYPE_NETWORK dev 1621266290Sdteske f_device_dialog_tcp $dev 1622266290Sdteske if [ $? -eq $DIALOG_OK ]; then 1623266290Sdteske setvar $VAR_NETWORK_DEVICE $if 1624266290Sdteske return $DIALOG_OK 1625247280Sdteske fi 1626247280Sdteske done 1627247280Sdteske 1628252795Sdteske f_interactive && f_show_msg "$msg_no_network_devices" 1629256181Sdteske return $DIALOG_CANCEL 1630247280Sdteske 1631247280Sdteske fi # $network_dev 1632247280Sdteske 1633247280Sdteske f_device_find "" $DEVICE_TYPE_NETWORK devs 1634260678Sdteske f_count cnt $devs 1635247280Sdteske dev="${devs%%[$IFS]*}" 1636266290Sdteske $dev get name if 1637247280Sdteske 1638247280Sdteske f_quietly f_getvar NETWORK_CONFIGURED # for debugging info 1639247280Sdteske if ! f_running_as_init && 1640247280Sdteske ! [ "${NETWORK_CONFIGURED+set}" -a "$NETWORK_CONFIGURED" = "NO" ] 1641247280Sdteske then 1642247280Sdteske trap 'f_interrupt' SIGINT 1643247280Sdteske if f_dialog_yesno "$msg_assume_network_is_already_configured" 1644247280Sdteske then 1645266290Sdteske setvar $VAR_NETWORK_DEVICE $if 1646256181Sdteske return $DIALOG_OK 1647247280Sdteske fi 1648247280Sdteske fi 1649247280Sdteske 1650247280Sdteske local retval=$SUCCESS 1651247280Sdteske if [ ${cnt:=0} -eq 0 ]; then 1652252795Sdteske f_show_msg "$msg_no_network_devices" 1653256181Sdteske retval=$DIALOG_CANCEL 1654247280Sdteske elif [ $cnt -eq 1 ]; then 1655247280Sdteske f_device_dialog_tcp $dev 1656247280Sdteske retval=$? 1657266290Sdteske [ $retval -eq $DIALOG_OK ] && setvar $VAR_NETWORK_DEVICE $if 1658247280Sdteske else 1659247280Sdteske local title="$msg_network_interface_information_required" 1660247280Sdteske local prompt="$msg_please_select_ethernet_device_to_configure" 1661247280Sdteske local hline="$hline_arrows_tab_enter" 1662247280Sdteske 1663247280Sdteske dev=$( f_device_menu \ 1664247280Sdteske "$title" "$prompt" "$hline" $DEVICE_TYPE_NETWORK \ 1665247280Sdteske "$NETWORK_DEVICE_HELPFILE" \ 1666266290Sdteske 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD ) || 1667266290Sdteske return $DIALOG_CANCEL 1668247280Sdteske 1669247280Sdteske f_device_dialog_tcp $dev 1670247280Sdteske retval=$? 1671256181Sdteske if [ $retval -eq $DIALOG_OK ]; then 1672266290Sdteske f_struct_copy "$dev" device_network 1673266290Sdteske setvar $VAR_NETWORK_DEVICE device_network 1674247280Sdteske else 1675247280Sdteske f_struct_free device_network 1676247280Sdteske fi 1677247280Sdteske fi 1678247280Sdteske 1679247280Sdteske return $retval 1680247280Sdteske} 1681247280Sdteske 1682247280Sdteske# f_dialog_menu_select_tcp 1683247280Sdteske# 1684247280Sdteske# Like f_dialog_select_tcp() above, but do it from a menu that doesn't care 1685247280Sdteske# about status. In other words, where f_dialog_select_tcp() will not display a 1686247280Sdteske# menu if scripted, this function will always display the menu of available 1687247280Sdteske# network interfaces. 1688247280Sdteske# 1689247280Sdteskef_dialog_menu_select_tcp() 1690247280Sdteske{ 1691247280Sdteske local private use_dhcp name 1692247280Sdteske NETWORK_CONFIGURED=NO f_device_select_tcp 1693247280Sdteske if f_struct device_network && 1694247280Sdteske device_network get private private && 1695247280Sdteske f_struct_copy "$private" di && 1696247280Sdteske di get use_dhcp use_dhcp && 1697247280Sdteske [ ! "$use_dhcp" ] && 1698247280Sdteske device_network get name name && 1699247280Sdteske f_yesno "$msg_would_you_like_to_bring_interface_up" "$name" 1700247280Sdteske then 1701266290Sdteske if ! f_device_init device_network; then 1702247280Sdteske f_show_msg "$msg_initialization_of_device_failed" \ 1703247280Sdteske "$name" 1704247280Sdteske fi 1705247280Sdteske fi 1706256181Sdteske return $DIALOG_OK 1707247280Sdteske} 1708247280Sdteske 1709247280Sdteske############################################################ MAIN 1710247280Sdteske 1711247280Sdteskef_dprintf "%s: Successfully loaded." media/tcpip.subr 1712247280Sdteske 1713247280Sdteskefi # ! $_MEDIA_TCPIP_SUBR 1714