1*7323adacSDevin Teskeif [ ! "$_MEDIA_TCPIP_SUBR" ]; then _MEDIA_TCPIP_SUBR=1 2*7323adacSDevin Teske# 3*7323adacSDevin Teske# Copyright (c) 2012-2013 Devin Teske 4*7323adacSDevin Teske# All Rights Reserved. 5*7323adacSDevin Teske# 6*7323adacSDevin Teske# Redistribution and use in source and binary forms, with or without 7*7323adacSDevin Teske# modification, are permitted provided that the following conditions 8*7323adacSDevin Teske# are met: 9*7323adacSDevin Teske# 1. Redistributions of source code must retain the above copyright 10*7323adacSDevin Teske# notice, this list of conditions and the following disclaimer. 11*7323adacSDevin Teske# 2. Redistributions in binary form must reproduce the above copyright 12*7323adacSDevin Teske# notice, this list of conditions and the following disclaimer in the 13*7323adacSDevin Teske# documentation and/or other materials provided with the distribution. 14*7323adacSDevin Teske# 15*7323adacSDevin Teske# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16*7323adacSDevin Teske# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE 17*7323adacSDevin Teske# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*7323adacSDevin Teske# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19*7323adacSDevin Teske# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20*7323adacSDevin Teske# DAMAGES (INLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21*7323adacSDevin Teske# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22*7323adacSDevin Teske# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23*7323adacSDevin Teske# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24*7323adacSDevin Teske# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25*7323adacSDevin Teske# SUCH DAMAGE. 26*7323adacSDevin Teske# 27*7323adacSDevin Teske# $FreeBSD$ 28*7323adacSDevin Teske# 29*7323adacSDevin Teske############################################################ INCLUDES 30*7323adacSDevin Teske 31*7323adacSDevin TeskeBSDCFG_SHARE="/usr/share/bsdconfig" 32*7323adacSDevin Teske. $BSDCFG_SHARE/common.subr || exit 1 33*7323adacSDevin Teskef_dprintf "%s: loading includes..." media/tcpip.subr 34*7323adacSDevin Teskef_include $BSDCFG_SHARE/struct.subr 35*7323adacSDevin Teskef_include $BSDCFG_SHARE/device.subr 36*7323adacSDevin Teskef_include $BSDCFG_SHARE/dialog.subr 37*7323adacSDevin Teskef_include $BSDCFG_SHARE/variable.subr 38*7323adacSDevin Teske 39*7323adacSDevin TeskeBSDCFG_LIBE="/usr/libexec/bsdconfig" 40*7323adacSDevin Teskef_include_lang $BSDCFG_LIBE/include/messages.subr 41*7323adacSDevin Teske 42*7323adacSDevin TeskeTCP_HELPFILE=$BSDCFG_LIBE/include/tcp.hlp 43*7323adacSDevin TeskeNETWORK_DEVICE_HELPFILE=$BSDCFG_LIBE/include/network_device.hlp 44*7323adacSDevin Teske 45*7323adacSDevin Teske############################################################ GLOBALS 46*7323adacSDevin Teske 47*7323adacSDevin Teske# 48*7323adacSDevin Teske# Path to resolv.conf(5). 49*7323adacSDevin Teske# 50*7323adacSDevin Teske: ${RESOLV_CONF:="/etc/resolv.conf"} 51*7323adacSDevin Teske 52*7323adacSDevin Teske# 53*7323adacSDevin Teske# Path to nsswitch.conf(5). 54*7323adacSDevin Teske# 55*7323adacSDevin Teske: ${NSSWITCH_CONF:="/etc/nsswitch.conf"} 56*7323adacSDevin Teske 57*7323adacSDevin Teske# 58*7323adacSDevin Teske# Path to hosts(5) 59*7323adacSDevin Teske# 60*7323adacSDevin Teske: ${ETC_HOSTS:="/etc/hosts"} 61*7323adacSDevin Teske 62*7323adacSDevin Teske# 63*7323adacSDevin Teske# Structure of dhclient.leases(5) lease { ... } entry 64*7323adacSDevin Teske# 65*7323adacSDevin Teskef_struct_define DHCP_LEASE \ 66*7323adacSDevin Teske interface \ 67*7323adacSDevin Teske fixed_address \ 68*7323adacSDevin Teske filename \ 69*7323adacSDevin Teske server_name \ 70*7323adacSDevin Teske script \ 71*7323adacSDevin Teske medium \ 72*7323adacSDevin Teske host_name \ 73*7323adacSDevin Teske subnet_mask \ 74*7323adacSDevin Teske routers \ 75*7323adacSDevin Teske domain_name_servers \ 76*7323adacSDevin Teske domain_name \ 77*7323adacSDevin Teske broadcast_address \ 78*7323adacSDevin Teske dhcp_lease_time \ 79*7323adacSDevin Teske dhcp_message_type \ 80*7323adacSDevin Teske dhcp_server_identifier \ 81*7323adacSDevin Teske dhcp_renewal_time \ 82*7323adacSDevin Teske dhcp_rebinding_time \ 83*7323adacSDevin Teske renew \ 84*7323adacSDevin Teske rebind \ 85*7323adacSDevin Teske expire 86*7323adacSDevin Teske 87*7323adacSDevin Teske############################################################ FUNCTIONS 88*7323adacSDevin Teske 89*7323adacSDevin Teske# f_validate_hostname $hostname 90*7323adacSDevin Teske# 91*7323adacSDevin Teske# Returns zero if the given argument (a fully-qualified hostname) is compliant 92*7323adacSDevin Teske# with standards set-forth in RFC's 952 and 1123 of the Network Working Group: 93*7323adacSDevin Teske# 94*7323adacSDevin Teske# RFC 952 - DoD Internet host table specification 95*7323adacSDevin Teske# http://tools.ietf.org/html/rfc952 96*7323adacSDevin Teske# 97*7323adacSDevin Teske# RFC 1123 - Requirements for Internet Hosts - Application and Support 98*7323adacSDevin Teske# http://tools.ietf.org/html/rfc1123 99*7323adacSDevin Teske# 100*7323adacSDevin Teske# See http://en.wikipedia.org/wiki/Hostname for a brief overview. 101*7323adacSDevin Teske# 102*7323adacSDevin Teske# The return status for invalid hostnames is one of: 103*7323adacSDevin Teske# 255 Entire hostname exceeds the maximum length of 255 characters. 104*7323adacSDevin Teske# 63 One or more individual labels within the hostname (separated by 105*7323adacSDevin Teske# dots) exceeds the maximum of 63 characters. 106*7323adacSDevin Teske# 1 One or more individual labels within the hostname contains one 107*7323adacSDevin Teske# or more invalid characters. 108*7323adacSDevin Teske# 2 One or more individual labels within the hostname starts or 109*7323adacSDevin Teske# ends with a hyphen (hyphens are allowed, but a label cannot 110*7323adacSDevin Teske# begin or end with a hyphen). 111*7323adacSDevin Teske# 3 One or more individual labels within the hostname are null. 112*7323adacSDevin Teske# 113*7323adacSDevin Teske# f_dialog_validate_hostname $hostname 114*7323adacSDevin Teske# 115*7323adacSDevin Teske# If the hostname is determined to be invalid, the appropriate error will be 116*7323adacSDevin Teske# displayed using the f_show_msg function. 117*7323adacSDevin Teske# 118*7323adacSDevin Teskef_validate_hostname() 119*7323adacSDevin Teske{ 120*7323adacSDevin Teske local fqhn="$1" 121*7323adacSDevin Teske 122*7323adacSDevin Teske # Return error if the hostname exceeds 255 characters 123*7323adacSDevin Teske [ ${#fqhn} -gt 255 ] && return 255 124*7323adacSDevin Teske 125*7323adacSDevin Teske local IFS="." # Split on `dot' 126*7323adacSDevin Teske for label in $fqhn; do 127*7323adacSDevin Teske # Return error if the label exceeds 63 characters 128*7323adacSDevin Teske [ ${#label} -gt 63 ] && return 63 129*7323adacSDevin Teske 130*7323adacSDevin Teske # Return error if the label is null 131*7323adacSDevin Teske [ "$label" ] || return 3 132*7323adacSDevin Teske 133*7323adacSDevin Teske # Return error if label begins/ends with dash 134*7323adacSDevin Teske case "$label" in -*|*-) return 2; esac 135*7323adacSDevin Teske 136*7323adacSDevin Teske # Return error if the label contains any invalid chars 137*7323adacSDevin Teske case "$label" in *[!0-9a-zA-Z-]*) return 1; esac 138*7323adacSDevin Teske done 139*7323adacSDevin Teske 140*7323adacSDevin Teske return $SUCCESS 141*7323adacSDevin Teske} 142*7323adacSDevin Teske 143*7323adacSDevin Teske# f_inet_atoi $ipv4_address [$var_to_set] 144*7323adacSDevin Teske# 145*7323adacSDevin Teske# Convert an IPv4 address or mask from dotted-quad notation (e.g., `127.0.0.1' 146*7323adacSDevin Teske# or `255.255.255.0') to a 32-bit unsigned integer for the purpose of network 147*7323adacSDevin Teske# and broadcast calculations. For example, one can validate that two addresses 148*7323adacSDevin Teske# are on the same network: 149*7323adacSDevin Teske# 150*7323adacSDevin Teske# f_inet_atoi 1.2.3.4 ip1num 151*7323adacSDevin Teske# f_inet_atoi 1.2.4.5 ip2num 152*7323adacSDevin Teske# f_inet_atoi 255.255.0.0 masknum 153*7323adacSDevin Teske# if [ $(( $ip1num & $masknum )) -eq \ 154*7323adacSDevin Teske# $(( $ip2num & $masknum )) ] 155*7323adacSDevin Teske# then 156*7323adacSDevin Teske# : IP addresses are on same network 157*7323adacSDevin Teske# fi 158*7323adacSDevin Teske# 159*7323adacSDevin Teske# See f_validate_ipaddr() below for an additional example usage, on calculating 160*7323adacSDevin Teske# network and broadcast addresses. 161*7323adacSDevin Teske# 162*7323adacSDevin Teske# If $var_to_set is missing or NULL, the converted IP address is printed to 163*7323adacSDevin Teske# standard output for capturing in a sub-shell (which is less-recommended 164*7323adacSDevin Teske# because of performance degredation; for example, when called in a loop). 165*7323adacSDevin Teske# 166*7323adacSDevin Teskef_inet_atoi() 167*7323adacSDevin Teske{ 168*7323adacSDevin Teske local __addr="$1" __var_to_set="$2" __num=0 169*7323adacSDevin Teske if f_validate_ipaddr "$__addr"; then 170*7323adacSDevin Teske __num=$( IFS=.; set -- $__addr; \ 171*7323adacSDevin Teske echo $(( ($1 << 24) + ($2 << 16) + ($3 << 8) + $4 )) ) 172*7323adacSDevin Teske fi 173*7323adacSDevin Teske if [ "$__var_to_set" ]; then 174*7323adacSDevin Teske setvar "$__var_to_set" $__num 175*7323adacSDevin Teske else 176*7323adacSDevin Teske echo $__num 177*7323adacSDevin Teske fi 178*7323adacSDevin Teske} 179*7323adacSDevin Teske 180*7323adacSDevin Teske# f_validate_ipaddr $ipaddr [$netmask] 181*7323adacSDevin Teske# 182*7323adacSDevin Teske# Returns zero if the given argument (an IP address) is of the proper format. 183*7323adacSDevin Teske# 184*7323adacSDevin Teske# The return status for invalid IP address is one of: 185*7323adacSDevin Teske# 1 One or more individual octets within the IP address (separated 186*7323adacSDevin Teske# by dots) contains one or more invalid characters. 187*7323adacSDevin Teske# 2 One or more individual octets within the IP address are null 188*7323adacSDevin Teske# and/or missing. 189*7323adacSDevin Teske# 3 One or more individual octets within the IP address exceeds the 190*7323adacSDevin Teske# maximum of 255 (or 2^8, being an octet comprised of 8 bits). 191*7323adacSDevin Teske# 4 The IP address has either too few or too many octets. 192*7323adacSDevin Teske# 193*7323adacSDevin Teske# If a netmask is provided, the IP address is checked further: 194*7323adacSDevin Teske# 195*7323adacSDevin Teske# 5 The IP address must not be the network or broadcast address. 196*7323adacSDevin Teske# 197*7323adacSDevin Teskef_validate_ipaddr() 198*7323adacSDevin Teske{ 199*7323adacSDevin Teske local ip="$1" mask="$2" 200*7323adacSDevin Teske 201*7323adacSDevin Teske # Track number of octets for error checking 202*7323adacSDevin Teske local noctets=0 203*7323adacSDevin Teske 204*7323adacSDevin Teske local oldIFS="$IFS" 205*7323adacSDevin Teske local IFS="." # Split on `dot' 206*7323adacSDevin Teske for octet in $ip; do 207*7323adacSDevin Teske # Return error if the octet is null 208*7323adacSDevin Teske [ "$octet" ] || return 2 209*7323adacSDevin Teske 210*7323adacSDevin Teske # Return error if not a whole integer 211*7323adacSDevin Teske f_isinteger "$octet" || return 1 212*7323adacSDevin Teske 213*7323adacSDevin Teske # Return error if not a positive integer 214*7323adacSDevin Teske [ $octet -ge 0 ] || return 1 215*7323adacSDevin Teske 216*7323adacSDevin Teske # Return error if the octet exceeds 255 217*7323adacSDevin Teske [ $octet -gt 255 ] && return 3 218*7323adacSDevin Teske 219*7323adacSDevin Teske noctets=$(( $noctets + 1 )) 220*7323adacSDevin Teske done 221*7323adacSDevin Teske IFS="$oldIFS" 222*7323adacSDevin Teske 223*7323adacSDevin Teske [ $noctets -eq 4 ] || return 4 224*7323adacSDevin Teske 225*7323adacSDevin Teske # 226*7323adacSDevin Teske # The IP address must not be network or broadcast address. 227*7323adacSDevin Teske # 228*7323adacSDevin Teske if [ "$mask" ]; then 229*7323adacSDevin Teske local ipnum masknum netnum bcastnum 230*7323adacSDevin Teske local max_addr=4294967295 # 255.255.255.255 231*7323adacSDevin Teske 232*7323adacSDevin Teske f_inet_atoi $ip ipnum 233*7323adacSDevin Teske f_inet_atoi $mask masknum 234*7323adacSDevin Teske 235*7323adacSDevin Teske netnum=$(( $ipnum & $masknum )) 236*7323adacSDevin Teske bcastnum=$(( ($ipnum & $masknum)+$max_addr-$masknum )) 237*7323adacSDevin Teske 238*7323adacSDevin Teske if [ "$masknum" ] && 239*7323adacSDevin Teske [ $ipnum -eq $netnum -o $ipnum -eq $bcastnum ] 240*7323adacSDevin Teske then 241*7323adacSDevin Teske return 5 242*7323adacSDevin Teske fi 243*7323adacSDevin Teske fi 244*7323adacSDevin Teske 245*7323adacSDevin Teske return $SUCCESS 246*7323adacSDevin Teske} 247*7323adacSDevin Teske 248*7323adacSDevin Teske# f_validate_ipaddr6 $ipv6_addr 249*7323adacSDevin Teske# 250*7323adacSDevin Teske# Returns zero if the given argument (an IPv6 address) is of the proper format. 251*7323adacSDevin Teske# 252*7323adacSDevin Teske# The return status for invalid IP address is one of: 253*7323adacSDevin Teske# 1 One or more individual segments within the IP address 254*7323adacSDevin Teske# (separated by colons) contains one or more invalid characters. 255*7323adacSDevin Teske# Segments must contain only combinations of the characters 0-9, 256*7323adacSDevin Teske# A-F, or a-f. 257*7323adacSDevin Teske# 2 Too many/incorrect null segments. A single null segment is 258*7323adacSDevin Teske# allowed within the IP address (separated by colons) but not 259*7323adacSDevin Teske# allowed at the beginning or end (unless a double-null segment; 260*7323adacSDevin Teske# i.e., "::*" or "*::"). 261*7323adacSDevin Teske# 3 One or more individual segments within the IP address 262*7323adacSDevin Teske# (separated by colons) exceeds the length of 4 hex-digits. 263*7323adacSDevin Teske# 4 The IP address entered has either too few (less than 3), too 264*7323adacSDevin Teske# many (more than 8), or not enough segments, separated by 265*7323adacSDevin Teske# colons. 266*7323adacSDevin Teske# 5* The IPv4 address at the end of the IPv6 address is invalid. 267*7323adacSDevin Teske# * When there is an error with the dotted-quad IPv4 address at the 268*7323adacSDevin Teske# end of the IPv6 address, the return value of 5 is OR'd with a 269*7323adacSDevin Teske# bit-shifted (<< 4) return of f_validate_ipaddr. 270*7323adacSDevin Teske# 271*7323adacSDevin Teskef_validate_ipaddr6() 272*7323adacSDevin Teske{ 273*7323adacSDevin Teske local ip="${1%\%*}" # removing the interface specification if-present 274*7323adacSDevin Teske 275*7323adacSDevin Teske local IFS=":" # Split on `colon' 276*7323adacSDevin Teske set -- $ip: 277*7323adacSDevin Teske 278*7323adacSDevin Teske # Return error if too many or too few segments 279*7323adacSDevin Teske # Using 9 as max in case of leading or trailing null spanner 280*7323adacSDevin Teske [ $# -gt 9 -o $# -lt 3 ] && return 4 281*7323adacSDevin Teske 282*7323adacSDevin Teske local h="[0-9A-Fa-f]" 283*7323adacSDevin Teske local nulls=0 nsegments=$# contains_ipv4_segment= 284*7323adacSDevin Teske 285*7323adacSDevin Teske while [ $# -gt 0 ]; do 286*7323adacSDevin Teske 287*7323adacSDevin Teske segment="${1%:}" 288*7323adacSDevin Teske shift 289*7323adacSDevin Teske 290*7323adacSDevin Teske # 291*7323adacSDevin Teske # Return error if this segment makes one null too-many. A 292*7323adacSDevin Teske # single null segment is allowed anywhere in the middle as well 293*7323adacSDevin Teske # as double null segments are allowed at the beginning or end 294*7323adacSDevin Teske # (but not both). 295*7323adacSDevin Teske # 296*7323adacSDevin Teske if [ ! "$segment" ]; then 297*7323adacSDevin Teske nulls=$(( $nulls + 1 )) 298*7323adacSDevin Teske if [ $nulls -eq 3 ]; then 299*7323adacSDevin Teske # Only valid syntax for 3 nulls is `::' 300*7323adacSDevin Teske [ "$ip" = "::" ] || return 2 301*7323adacSDevin Teske elif [ $nulls -eq 2 ]; then 302*7323adacSDevin Teske # Only valid if begins/ends with `::' 303*7323adacSDevin Teske case "$ip" in 304*7323adacSDevin Teske ::*|*::) : fall thru ;; 305*7323adacSDevin Teske *) return 2 306*7323adacSDevin Teske esac 307*7323adacSDevin Teske fi 308*7323adacSDevin Teske continue 309*7323adacSDevin Teske fi 310*7323adacSDevin Teske 311*7323adacSDevin Teske # 312*7323adacSDevin Teske # Return error if not a valid hexadecimal short 313*7323adacSDevin Teske # 314*7323adacSDevin Teske case "$segment" in 315*7323adacSDevin Teske $h|$h$h|$h$h$h|$h$h$h$h) 316*7323adacSDevin Teske : valid segment of 1-4 hexadecimal digits 317*7323adacSDevin Teske ;; 318*7323adacSDevin Teske *[!0-9A-Fa-f]*) 319*7323adacSDevin Teske # Segment contains at least one invalid char 320*7323adacSDevin Teske 321*7323adacSDevin Teske # Return error immediately if not last segment 322*7323adacSDevin Teske [ $# -eq 0 ] || return 1 323*7323adacSDevin Teske 324*7323adacSDevin Teske # Otherwise, check for legacy IPv4 notation 325*7323adacSDevin Teske case "$segment" in 326*7323adacSDevin Teske *[!0-9.]*) 327*7323adacSDevin Teske # Segment contains at least one invalid 328*7323adacSDevin Teske # character even for an IPv4 address 329*7323adacSDevin Teske return 1 330*7323adacSDevin Teske esac 331*7323adacSDevin Teske 332*7323adacSDevin Teske # Return error if not enough segments 333*7323adacSDevin Teske if [ $nulls -eq 0 ]; then 334*7323adacSDevin Teske [ $nsegments -eq 7 ] || return 4 335*7323adacSDevin Teske fi 336*7323adacSDevin Teske 337*7323adacSDevin Teske contains_ipv4_segment=1 338*7323adacSDevin Teske 339*7323adacSDevin Teske # Validate the IPv4 address 340*7323adacSDevin Teske f_validate_ipaddr "$segment" || 341*7323adacSDevin Teske return $(( 5 | $? << 4 )) 342*7323adacSDevin Teske ;; 343*7323adacSDevin Teske *) 344*7323adacSDevin Teske # Segment characters are all valid but too many 345*7323adacSDevin Teske return 3 346*7323adacSDevin Teske esac 347*7323adacSDevin Teske 348*7323adacSDevin Teske done 349*7323adacSDevin Teske 350*7323adacSDevin Teske if [ $nulls -eq 1 ]; then 351*7323adacSDevin Teske # Single null segment cannot be at beginning/end 352*7323adacSDevin Teske case "$ip" in 353*7323adacSDevin Teske :*|*:) return 2 354*7323adacSDevin Teske esac 355*7323adacSDevin Teske fi 356*7323adacSDevin Teske 357*7323adacSDevin Teske # 358*7323adacSDevin Teske # A legacy IPv4 address can span the last two 16-bit segments, 359*7323adacSDevin Teske # reducing the amount of maximum allowable segments by-one. 360*7323adacSDevin Teske # 361*7323adacSDevin Teske maxsegments=8 362*7323adacSDevin Teske if [ "$contains_ipv4_segment" ]; then 363*7323adacSDevin Teske maxsegments=7 364*7323adacSDevin Teske fi 365*7323adacSDevin Teske 366*7323adacSDevin Teske case $nulls in 367*7323adacSDevin Teske # Return error if missing segments with no null spanner 368*7323adacSDevin Teske 0) [ $nsegments -eq $maxsegments ] || return 4 ;; 369*7323adacSDevin Teske # Return error if null spanner with too many segments 370*7323adacSDevin Teske 1) [ $nsegments -le $maxsegments ] || return 4 ;; 371*7323adacSDevin Teske # Return error if leading/trailing `::' with too many segments 372*7323adacSDevin Teske 2) [ $nsegments -le $(( $maxsegments + 1 )) ] || return 4 ;; 373*7323adacSDevin Teske esac 374*7323adacSDevin Teske 375*7323adacSDevin Teske return $SUCCESS 376*7323adacSDevin Teske} 377*7323adacSDevin Teske 378*7323adacSDevin Teske# f_validate_netmask $netmask 379*7323adacSDevin Teske# 380*7323adacSDevin Teske# Returns zero if the given argument (a subnet mask) is of the proper format. 381*7323adacSDevin Teske# 382*7323adacSDevin Teske# The return status for invalid netmask is one of: 383*7323adacSDevin Teske# 1 One or more individual fields within the subnet mask (separated 384*7323adacSDevin Teske# by dots) contains one or more invalid characters. 385*7323adacSDevin Teske# 2 One or more individual fields within the subnet mask are null 386*7323adacSDevin Teske# and/or missing. 387*7323adacSDevin Teske# 3 One or more individual fields within the subnet mask exceeds 388*7323adacSDevin Teske# the maximum of 255 (a full 8-bit register). 389*7323adacSDevin Teske# 4 The subnet mask has either too few or too many fields. 390*7323adacSDevin Teske# 5 One or more individual fields within the subnet mask is an 391*7323adacSDevin Teske# invalid integer (only 0,128,192,224,240,248,252,254,255 are 392*7323adacSDevin Teske# valid integers). 393*7323adacSDevin Teske# 394*7323adacSDevin Teskef_validate_netmask() 395*7323adacSDevin Teske{ 396*7323adacSDevin Teske local mask="$1" 397*7323adacSDevin Teske 398*7323adacSDevin Teske # Track number of fields for error checking 399*7323adacSDevin Teske local nfields=0 400*7323adacSDevin Teske 401*7323adacSDevin Teske local IFS="." # Split on `dot' 402*7323adacSDevin Teske for field in $mask; do 403*7323adacSDevin Teske # Return error if the field is null 404*7323adacSDevin Teske [ "$field" ] || return 2 405*7323adacSDevin Teske 406*7323adacSDevin Teske # Return error if not a whole positive integer 407*7323adacSDevin Teske f_isinteger "$field" || return 1 408*7323adacSDevin Teske 409*7323adacSDevin Teske # Return error if the field exceeds 255 410*7323adacSDevin Teske [ $field -gt 255 ] && return 3 411*7323adacSDevin Teske 412*7323adacSDevin Teske # Return error if the field is an invalid integer 413*7323adacSDevin Teske case "$field" in 414*7323adacSDevin Teske 0|128|192|224|240|248|252|254|255) :;; 415*7323adacSDevin Teske *) return 5;; 416*7323adacSDevin Teske esac 417*7323adacSDevin Teske 418*7323adacSDevin Teske nfields=$(( $nfields + 1 )) 419*7323adacSDevin Teske done 420*7323adacSDevin Teske 421*7323adacSDevin Teske [ $nfields -eq 4 ] || return 4 422*7323adacSDevin Teske} 423*7323adacSDevin Teske 424*7323adacSDevin Teske# f_validate_gateway $gateway $ipaddr $netmask 425*7323adacSDevin Teske# 426*7323adacSDevin Teske# Validate an IPv4 default gateway (aka router) address for a given IP address 427*7323adacSDevin Teske# making sure the two are in the same network (able to ``talk'' to each other). 428*7323adacSDevin Teske# Returns success if $ipaddr and $gateway are in the same network given subnet 429*7323adacSDevin Teske# mask $netmask. 430*7323adacSDevin Teske# 431*7323adacSDevin Teskef_validate_gateway() 432*7323adacSDevin Teske{ 433*7323adacSDevin Teske local gateway="$1" ipaddr="$2" netmask="$3" 434*7323adacSDevin Teske local gwnum ipnum masknum 435*7323adacSDevin Teske 436*7323adacSDevin Teske f_validate_ipaddr "$gateway" "$netmask" || return $FAILURE 437*7323adacSDevin Teske 438*7323adacSDevin Teske f_inet_atoi "$netmask" masknum 439*7323adacSDevin Teske f_inet_atoi "$ipaddr" ipnum 440*7323adacSDevin Teske f_inet_atoi "$gateway" gwnum 441*7323adacSDevin Teske 442*7323adacSDevin Teske # Gateway must be within set of IPs reachable through interface 443*7323adacSDevin Teske [ $(( $ipnum & $masknum )) -eq \ 444*7323adacSDevin Teske $(( $gwnum & $masknum )) ] # Return status 445*7323adacSDevin Teske} 446*7323adacSDevin Teske 447*7323adacSDevin Teske# f_dialog_validate_tcpip $hostname $gateway $nameserver $ipaddr $netmask 448*7323adacSDevin Teske# 449*7323adacSDevin Teske# Returns success if the arguments provided are valid for accessing a TCP/IP 450*7323adacSDevin Teske# network, otherwise returns failure. 451*7323adacSDevin Teske# 452*7323adacSDevin Teskef_dialog_validate_tcpip() 453*7323adacSDevin Teske{ 454*7323adacSDevin Teske local hostname="$1" gateway="$2" nameserver="$3" 455*7323adacSDevin Teske local ipaddr="$4" netmask="$5" 456*7323adacSDevin Teske local ipnum masknum 457*7323adacSDevin Teske 458*7323adacSDevin Teske if [ ! "$hostname" ]; then 459*7323adacSDevin Teske f_dialog_msgbox "$msg_must_specify_a_host_name_of_some_sort" 460*7323adacSDevin Teske elif ! f_validate_hostname "$hostname"; then 461*7323adacSDevin Teske f_dialog_msgbox "$msg_invalid_hostname_value" 462*7323adacSDevin Teske elif [ "$netmask" ] && ! f_validate_netmask "$netmask"; then 463*7323adacSDevin Teske f_dialog_msgbox "$msg_invalid_netmask_value" 464*7323adacSDevin Teske elif [ "$nameserver" ] && 465*7323adacSDevin Teske ! f_validate_ipaddr "$nameserver" && 466*7323adacSDevin Teske ! f_validate_ipaddr6 "$nameserver"; then 467*7323adacSDevin Teske f_dialog_msgbox "$msg_invalid_name_server_ip_address_specified" 468*7323adacSDevin Teske elif [ "$ipaddr" ] && ! f_validate_ipaddr "$ipaddr" "$netmask"; then 469*7323adacSDevin Teske f_dialog_msgbox "$msg_invalid_ipv4_address" 470*7323adacSDevin Teske elif [ "$gateway" -a "$gateway" != "NO" ] && 471*7323adacSDevin Teske ! f_validate_gateway "$gateway" "$ipaddr" "$netmask"; then 472*7323adacSDevin Teske f_dialog_msgbox "$msg_invalid_gateway_ipv4_address_specified" 473*7323adacSDevin Teske else 474*7323adacSDevin Teske return $SUCCESS 475*7323adacSDevin Teske fi 476*7323adacSDevin Teske 477*7323adacSDevin Teske return $FAILURE 478*7323adacSDevin Teske} 479*7323adacSDevin Teske 480*7323adacSDevin Teske# f_ifconfig_inet $interface [$var_to_set] 481*7323adacSDevin Teske# 482*7323adacSDevin Teske# Returns the IPv4 address associated with $interface. If $var_to_set is 483*7323adacSDevin Teske# missing or NULL, the IP address is printed to standard output for capturing 484*7323adacSDevin Teske# in a sub-shell (which is less-recommended because of performance degredation; 485*7323adacSDevin Teske# for example, when called in a loop). 486*7323adacSDevin Teske# 487*7323adacSDevin Teske# This function is a two-parter. Below is the awk(1) portion of the function, 488*7323adacSDevin Teske# afterward is the sh(1) function which utilizes the below awk script. 489*7323adacSDevin Teske# 490*7323adacSDevin Teskef_ifconfig_inet_awk=' 491*7323adacSDevin TeskeBEGIN { found = 0 } 492*7323adacSDevin Teske( $1 == "inet" ) \ 493*7323adacSDevin Teske{ 494*7323adacSDevin Teske print $2 495*7323adacSDevin Teske found = 1 496*7323adacSDevin Teske exit 497*7323adacSDevin Teske} 498*7323adacSDevin TeskeEND { exit ! found } 499*7323adacSDevin Teske' 500*7323adacSDevin Teskef_ifconfig_inet() 501*7323adacSDevin Teske{ 502*7323adacSDevin Teske local __interface="$1" __var_to_set="$2" 503*7323adacSDevin Teske if [ "$__var_to_set" ]; then 504*7323adacSDevin Teske local __ip 505*7323adacSDevin Teske __ip=$( ifconfig "$__interface" 2> /dev/null | 506*7323adacSDevin Teske awk "$f_ifconfig_inet_awk" ) 507*7323adacSDevin Teske setvar "$__var_to_set" "$__ip" 508*7323adacSDevin Teske else 509*7323adacSDevin Teske ifconfig "$__interface" 2> /dev/null | 510*7323adacSDevin Teske awk "$f_ifconfig_inet_awk" 511*7323adacSDevin Teske fi 512*7323adacSDevin Teske} 513*7323adacSDevin Teske 514*7323adacSDevin Teske# f_ifconfig_inet6 $interface [$var_to_set] 515*7323adacSDevin Teske# 516*7323adacSDevin Teske# Returns the IPv6 address associated with $interface. If $var_to_set is 517*7323adacSDevin Teske# missing or NULL, the IP address is printed to standard output for capturing 518*7323adacSDevin Teske# in a sub-shell (which is less-recommended because of performance degredation; 519*7323adacSDevin Teske# for example, when called in a loop). 520*7323adacSDevin Teske# 521*7323adacSDevin Teske# This function is a two-parter. Below is the awk(1) portion of the function, 522*7323adacSDevin Teske# afterward is the sh(1) function which utilizes the below awk script. 523*7323adacSDevin Teske# 524*7323adacSDevin Teskef_ifconfig_inet6_awk=' 525*7323adacSDevin TeskeBEGIN { found = 0 } 526*7323adacSDevin Teske( $1 == "inet6" ) \ 527*7323adacSDevin Teske{ 528*7323adacSDevin Teske print $2 529*7323adacSDevin Teske found = 1 530*7323adacSDevin Teske exit 531*7323adacSDevin Teske} 532*7323adacSDevin TeskeEND { exit ! found } 533*7323adacSDevin Teske' 534*7323adacSDevin Teskef_ifconfig_inet6() 535*7323adacSDevin Teske{ 536*7323adacSDevin Teske local __interface="$1" __var_to_set="$2" 537*7323adacSDevin Teske if [ "$__var_to_set" ]; then 538*7323adacSDevin Teske local __ip6 539*7323adacSDevin Teske __ip6=$( ifconfig "$__interface" 2> /dev/null | 540*7323adacSDevin Teske awk "$f_ifconfig_inet6_awk" ) 541*7323adacSDevin Teske setvar "$__var_to_set" "$__ip6" 542*7323adacSDevin Teske else 543*7323adacSDevin Teske ifconfig "$__interface" 2> /dev/null | 544*7323adacSDevin Teske awk "$f_ifconfig_inet6_awk" 545*7323adacSDevin Teske fi 546*7323adacSDevin Teske} 547*7323adacSDevin Teske 548*7323adacSDevin Teske# f_ifconfig_netmask $interface [$var_to_set] 549*7323adacSDevin Teske# 550*7323adacSDevin Teske# Returns the IPv4 subnet mask associated with $interface. If $var_to_set is 551*7323adacSDevin Teske# missing or NULL, the netmask is printed to standard output for capturing in a 552*7323adacSDevin Teske# sub-shell (which is less-recommended because of performance degredation; for 553*7323adacSDevin Teske# example, when called in a loop). 554*7323adacSDevin Teske# 555*7323adacSDevin Teskef_ifconfig_netmask() 556*7323adacSDevin Teske{ 557*7323adacSDevin Teske local __interface="$1" __var_to_set="$2" __octets 558*7323adacSDevin Teske __octets=$( ifconfig "$__interface" 2> /dev/null | awk \ 559*7323adacSDevin Teske ' 560*7323adacSDevin Teske BEGIN { found = 0 } 561*7323adacSDevin Teske ( $1 == "inet" ) \ 562*7323adacSDevin Teske { 563*7323adacSDevin Teske printf "%s %s %s %s\n", 564*7323adacSDevin Teske substr($4,3,2), 565*7323adacSDevin Teske substr($4,5,2), 566*7323adacSDevin Teske substr($4,7,2), 567*7323adacSDevin Teske substr($4,9,2) 568*7323adacSDevin Teske found = 1 569*7323adacSDevin Teske exit 570*7323adacSDevin Teske } 571*7323adacSDevin Teske END { exit ! found } 572*7323adacSDevin Teske ' ) || return $FAILURE 573*7323adacSDevin Teske 574*7323adacSDevin Teske local __octet __netmask= 575*7323adacSDevin Teske for __octet in $__octets; do 576*7323adacSDevin Teske __netmask="$__netmask.$( printf "%u" "0x$__octet" )" 577*7323adacSDevin Teske done 578*7323adacSDevin Teske __netmask="${__netmask#.}" 579*7323adacSDevin Teske if [ "$__var_to_set" ]; then 580*7323adacSDevin Teske setvar "$__var_to_set" "$__netmask" 581*7323adacSDevin Teske else 582*7323adacSDevin Teske echo $__netmask 583*7323adacSDevin Teske fi 584*7323adacSDevin Teske} 585*7323adacSDevin Teske 586*7323adacSDevin Teske# f_route_get_default [$var_to_set] 587*7323adacSDevin Teske# 588*7323adacSDevin Teske# Returns the IP address of the currently active default router. If $var_to_set 589*7323adacSDevin Teske# is missing or NULL, the IP address is printed to standard output for 590*7323adacSDevin Teske# capturing in a sub-shell (which is less-recommended because of performance 591*7323adacSDevin Teske# degredation; for example, when called in a loop). 592*7323adacSDevin Teske# 593*7323adacSDevin Teske# This function is a two-parter. Below is the awk(1) portion of the function, 594*7323adacSDevin Teske# afterward is the sh(1) function which utilizes the below awk script. 595*7323adacSDevin Teske# 596*7323adacSDevin Teskef_route_get_default=' 597*7323adacSDevin TeskeBEGIN { found = 0 } 598*7323adacSDevin Teske( $1 == "gateway:" ) \ 599*7323adacSDevin Teske{ 600*7323adacSDevin Teske print $2 601*7323adacSDevin Teske found = 1 602*7323adacSDevin Teske exit 603*7323adacSDevin Teske} 604*7323adacSDevin TeskeEND { exit ! found } 605*7323adacSDevin Teske' 606*7323adacSDevin Teskef_route_get_default() 607*7323adacSDevin Teske{ 608*7323adacSDevin Teske local __var_to_set="$1" 609*7323adacSDevin Teske if [ "$__var_to_set" ]; then 610*7323adacSDevin Teske local __ip 611*7323adacSDevin Teske __ip=$( route -n get default 2> /dev/null | 612*7323adacSDevin Teske awk "$f_route_get_default_awk" ) 613*7323adacSDevin Teske setvar "$__var_to_set" "$__ip" 614*7323adacSDevin Teske else 615*7323adacSDevin Teske route -n get default 2> /dev/null | 616*7323adacSDevin Teske awk "$f_route_get_default_awk" 617*7323adacSDevin Teske fi 618*7323adacSDevin Teske} 619*7323adacSDevin Teske 620*7323adacSDevin Teske# f_resolv_conf_nameservers [$var_to_set] 621*7323adacSDevin Teske# 622*7323adacSDevin Teske# Returns nameserver(s) configured in resolv.conf(5). If $var_to_set is missing 623*7323adacSDevin Teske# or NULL, the list of nameservers is printed to standard output for capturing 624*7323adacSDevin Teske# in a sub-shell (which is less-recommended because of performance degredation; 625*7323adacSDevin Teske# for example, when called in a loop). 626*7323adacSDevin Teske# 627*7323adacSDevin Teske# This function is a two-parter. Below is the awk(1) portion of the function, 628*7323adacSDevin Teske# afterward is the sh(1) function which utilizes the below awk script. 629*7323adacSDevin Teske# 630*7323adacSDevin Teskef_resolv_conf_nameservers_awk=' 631*7323adacSDevin TeskeBEGIN { found = 0 } 632*7323adacSDevin Teske( $1 == "nameserver" ) \ 633*7323adacSDevin Teske{ 634*7323adacSDevin Teske print $2 635*7323adacSDevin Teske found = 1 636*7323adacSDevin Teske} 637*7323adacSDevin TeskeEND { exit ! found } 638*7323adacSDevin Teske' 639*7323adacSDevin Teskef_resolv_conf_nameservers() 640*7323adacSDevin Teske{ 641*7323adacSDevin Teske local __var_to_set="$1" 642*7323adacSDevin Teske if [ "$__var_to_set" ]; then 643*7323adacSDevin Teske local __ns 644*7323adacSDevin Teske __ns=$( awk "$f_resolv_conf_nameservers_awk" "$RESOLV_CONF" \ 645*7323adacSDevin Teske 2> /dev/null ) 646*7323adacSDevin Teske setvar "$__var_to_set" "$__ns" 647*7323adacSDevin Teske else 648*7323adacSDevin Teske awk "$f_resolv_conf_nameservers_awk" "$RESOLV_CONF" \ 649*7323adacSDevin Teske 2> /dev/null 650*7323adacSDevin Teske fi 651*7323adacSDevin Teske} 652*7323adacSDevin Teske 653*7323adacSDevin Teske# f_config_resolv 654*7323adacSDevin Teske# 655*7323adacSDevin Teske# Attempts to configure resolv.conf(5) and ilk. Returns success if able to 656*7323adacSDevin Teske# write the file(s), otherwise returns error status. 657*7323adacSDevin Teske# 658*7323adacSDevin Teske# Variables from variable.subr that are used in configuring resolv.conf(5) are 659*7323adacSDevin Teske# as follows (all of which can be configured automatically through functions 660*7323adacSDevin Teske# like f_dhcp_get_info() or manually): 661*7323adacSDevin Teske# 662*7323adacSDevin Teske# VAR_NAMESERVER 663*7323adacSDevin Teske# The nameserver to add in resolv.conf(5). 664*7323adacSDevin Teske# VAR_DOMAINNAME 665*7323adacSDevin Teske# The domain to configure in resolv.conf(5). Also used in the 666*7323adacSDevin Teske# configuration of hosts(5). 667*7323adacSDevin Teske# VAR_IPADDR 668*7323adacSDevin Teske# The IPv4 address to configure in hosts(5). 669*7323adacSDevin Teske# VAR_IPV6ADDR 670*7323adacSDevin Teske# The IPv6 address to configure in hosts(5). 671*7323adacSDevin Teske# VAR_HOSTNAME 672*7323adacSDevin Teske# The hostname to associate with the IPv4 and/or IPv6 address in 673*7323adacSDevin Teske# hosts(5). 674*7323adacSDevin Teske# 675*7323adacSDevin Teskef_config_resolv() 676*7323adacSDevin Teske{ 677*7323adacSDevin Teske local cp c6p dp hp 678*7323adacSDevin Teske 679*7323adacSDevin Teske f_getvar $VAR_NAMESERVER cp 680*7323adacSDevin Teske if [ "$cp" ]; then 681*7323adacSDevin Teske case "$RESOLV_CONF" in 682*7323adacSDevin Teske */*) f_quietly mkdir -p "${RESOLV_CONF%/*}" ;; 683*7323adacSDevin Teske esac 684*7323adacSDevin Teske 685*7323adacSDevin Teske # Attempt to create/truncate the file 686*7323adacSDevin Teske ( :> "$RESOLV_CONF" ) 2> /dev/null || return $FAILURE 687*7323adacSDevin Teske 688*7323adacSDevin Teske f_getvar $VAR_DOMAINNAME dp && 689*7323adacSDevin Teske printf "domain\t%s\n" "$dp" >> "$RESOLV_CONF" 690*7323adacSDevin Teske printf "nameserver\t%s\n" "$cp" >> "$RESOLV_CONF" 691*7323adacSDevin Teske 692*7323adacSDevin Teske f_dprintf "Wrote out %s" "$RESOLV_CONF" 693*7323adacSDevin Teske fi 694*7323adacSDevin Teske 695*7323adacSDevin Teske f_getvar $VAR_DOMAINNAME dp 696*7323adacSDevin Teske f_getvar $VAR_IPADDR cp 697*7323adacSDevin Teske f_getvar $VAR_IPV6ADDR c6p 698*7323adacSDevin Teske f_getvar $VAR_HOSTNAME hp 699*7323adacSDevin Teske 700*7323adacSDevin Teske # Attempt to create the file if it doesn't already exist 701*7323adacSDevin Teske if [ ! -e "$ETC_HOSTS" ]; then 702*7323adacSDevin Teske case "$ETC_HOSTS" in 703*7323adacSDevin Teske */*) f_quietly mkdir -p "${ETC_HOSTS%/*}" ;; 704*7323adacSDevin Teske esac 705*7323adacSDevin Teske 706*7323adacSDevin Teske ( :> "$ETC_HOSTS" ) 2> /dev/null || return $FAILURE 707*7323adacSDevin Teske fi 708*7323adacSDevin Teske 709*7323adacSDevin Teske # Scan the file and add ourselves if not already configured 710*7323adacSDevin Teske awk -v dn="$dp" -v ip4="$cp" -v ip6="$c6p" -v hn="$hp" ' 711*7323adacSDevin Teske BEGIN { 712*7323adacSDevin Teske local4found = local6found = 0 713*7323adacSDevin Teske hn4found = hn6found = h4found = h6found = 0 714*7323adacSDevin Teske h = ( match(hn, /\./) ? substr(hn, 0, RSTART-1) : "" ) 715*7323adacSDevin Teske } 716*7323adacSDevin Teske ($1 == "127.0.0.1") { local4found = 1 } 717*7323adacSDevin Teske ($1 == "::1") { local6found = 1 } 718*7323adacSDevin Teske { 719*7323adacSDevin Teske for (n = 2; n <= NF; n++) 720*7323adacSDevin Teske { 721*7323adacSDevin Teske if ( $1 == ip4 ) { 722*7323adacSDevin Teske if ( $n == h ) h4found = 1 723*7323adacSDevin Teske if ( $n == hn ) hn4found = 1 724*7323adacSDevin Teske if ( $n == hn "." ) hn4found = 1 725*7323adacSDevin Teske } 726*7323adacSDevin Teske if ( $1 == ip6 ) { 727*7323adacSDevin Teske if ( $n == h ) h6found = 1 728*7323adacSDevin Teske if ( $n == hn ) hn6found = 1 729*7323adacSDevin Teske if ( $n == hn "." ) hn6found = 1 730*7323adacSDevin Teske } 731*7323adacSDevin Teske } 732*7323adacSDevin Teske } 733*7323adacSDevin Teske END { 734*7323adacSDevin Teske hosts = FILENAME 735*7323adacSDevin Teske 736*7323adacSDevin Teske if ( ! local6found ) 737*7323adacSDevin Teske printf "::1\t\t\tlocalhost%s\n", 738*7323adacSDevin Teske ( dn ? " localhost." dn : "" ) >> hosts 739*7323adacSDevin Teske if ( ! local4found ) 740*7323adacSDevin Teske printf "127.0.0.1\t\tlocalhost%s\n", 741*7323adacSDevin Teske ( dn ? " localhost." dn : "" ) >> hosts 742*7323adacSDevin Teske 743*7323adacSDevin Teske if ( ip6 && ! (h6found && hn6found)) 744*7323adacSDevin Teske { 745*7323adacSDevin Teske printf "%s\t%s %s\n", ip6, hn, h >> hosts 746*7323adacSDevin Teske printf "%s\t%s.\n", ip6, hn >> hosts 747*7323adacSDevin Teske } 748*7323adacSDevin Teske else if ( ip6 ) 749*7323adacSDevin Teske { 750*7323adacSDevin Teske if ( ! h6found ) 751*7323adacSDevin Teske printf "%s\t%s.\n", ip6, h >> hosts 752*7323adacSDevin Teske if ( ! hn6found ) 753*7323adacSDevin Teske printf "%s\t%s\n", ip6, hn >> hosts 754*7323adacSDevin Teske } 755*7323adacSDevin Teske 756*7323adacSDevin Teske if ( ip4 && ! (h4found && hn4found)) 757*7323adacSDevin Teske { 758*7323adacSDevin Teske printf "%s\t\t%s %s\n", ip4, hn, h >> hosts 759*7323adacSDevin Teske printf "%s\t\t%s.\n", ip4, hn >> hosts 760*7323adacSDevin Teske } 761*7323adacSDevin Teske else if ( ip4 ) 762*7323adacSDevin Teske { 763*7323adacSDevin Teske if ( ! h4found ) 764*7323adacSDevin Teske printf "%s\t\t%s.\n", ip4, h >> hosts 765*7323adacSDevin Teske if ( ! hn4found ) 766*7323adacSDevin Teske printf "%s\t\t%s\n", ip4, hn >> hosts 767*7323adacSDevin Teske } 768*7323adacSDevin Teske } 769*7323adacSDevin Teske ' "$ETC_HOSTS" 2> /dev/null || return $FAILURE 770*7323adacSDevin Teske 771*7323adacSDevin Teske f_dprintf "Wrote out %s" "$ETC_HOSTS" 772*7323adacSDevin Teske return $SUCCESS 773*7323adacSDevin Teske} 774*7323adacSDevin Teske 775*7323adacSDevin Teske# f_dhcp_parse_leases $leasefile struct_name 776*7323adacSDevin Teske# 777*7323adacSDevin Teske# Parse $leasefile and store the information for the most recent lease in a 778*7323adacSDevin Teske# struct (see struct.subr for additional details) named `struct_name'. See 779*7323adacSDevin Teske# DHCP_LEASE struct definition in the GLOBALS section above. 780*7323adacSDevin Teske# 781*7323adacSDevin Teskef_dhcp_parse_leases() 782*7323adacSDevin Teske{ 783*7323adacSDevin Teske local leasefile="$1" struct_name="$2" 784*7323adacSDevin Teske 785*7323adacSDevin Teske [ "$struct_name" ] || return $FAILURE 786*7323adacSDevin Teske 787*7323adacSDevin Teske if [ ! -e "$leasefile" ]; then 788*7323adacSDevin Teske f_dprintf "%s: No such file or directory" "$leasefile" 789*7323adacSDevin Teske return $FAILURE 790*7323adacSDevin Teske fi 791*7323adacSDevin Teske 792*7323adacSDevin Teske f_struct "$struct_name" && f_struct_free "$struct_name" 793*7323adacSDevin Teske f_struct_new DHCP_LEASE "$struct_name" 794*7323adacSDevin Teske 795*7323adacSDevin Teske eval "$( awk -v struct="$struct_name" ' 796*7323adacSDevin Teske BEGIN { 797*7323adacSDevin Teske lease_found = 0 798*7323adacSDevin Teske keyword_list = " \ 799*7323adacSDevin Teske interface \ 800*7323adacSDevin Teske fixed-address \ 801*7323adacSDevin Teske filename \ 802*7323adacSDevin Teske server-name \ 803*7323adacSDevin Teske script \ 804*7323adacSDevin Teske medium \ 805*7323adacSDevin Teske " 806*7323adacSDevin Teske split(keyword_list, keywords, FS) 807*7323adacSDevin Teske 808*7323adacSDevin Teske time_list = "renew rebind expire" 809*7323adacSDevin Teske split(time_list, times, FS) 810*7323adacSDevin Teske 811*7323adacSDevin Teske option_list = " \ 812*7323adacSDevin Teske host-name \ 813*7323adacSDevin Teske subnet-mask \ 814*7323adacSDevin Teske routers \ 815*7323adacSDevin Teske domain-name-servers \ 816*7323adacSDevin Teske domain-name \ 817*7323adacSDevin Teske broadcast-address \ 818*7323adacSDevin Teske dhcp-lease-time \ 819*7323adacSDevin Teske dhcp-message-type \ 820*7323adacSDevin Teske dhcp-server-identifier \ 821*7323adacSDevin Teske dhcp-renewal-time \ 822*7323adacSDevin Teske dhcp-rebinding-time \ 823*7323adacSDevin Teske " 824*7323adacSDevin Teske split(option_list, options, FS) 825*7323adacSDevin Teske } 826*7323adacSDevin Teske function set_value(prop,value) 827*7323adacSDevin Teske { 828*7323adacSDevin Teske lease_found = 1 829*7323adacSDevin Teske gsub(/[^[:alnum:]_]/, "_", prop) 830*7323adacSDevin Teske sub(/;$/, "", value) 831*7323adacSDevin Teske sub(/^"/, "", value) 832*7323adacSDevin Teske sub(/"$/, "", value) 833*7323adacSDevin Teske sub(/,.*/, "", value) 834*7323adacSDevin Teske printf "%s set %s \"%s\"\n", struct, prop, value 835*7323adacSDevin Teske } 836*7323adacSDevin Teske /^lease {$/, /^}$/ \ 837*7323adacSDevin Teske { 838*7323adacSDevin Teske if ( $0 ~ /^lease {$/ ) next 839*7323adacSDevin Teske if ( $0 ~ /^}$/ ) exit 840*7323adacSDevin Teske 841*7323adacSDevin Teske for (k in keywords) 842*7323adacSDevin Teske { 843*7323adacSDevin Teske keyword = keywords[k] 844*7323adacSDevin Teske if ( $1 == keyword ) 845*7323adacSDevin Teske { 846*7323adacSDevin Teske set_value(keyword, $2) 847*7323adacSDevin Teske next 848*7323adacSDevin Teske } 849*7323adacSDevin Teske } 850*7323adacSDevin Teske 851*7323adacSDevin Teske for (t in times) 852*7323adacSDevin Teske { 853*7323adacSDevin Teske time = times[t] 854*7323adacSDevin Teske if ( $1 == time ) 855*7323adacSDevin Teske { 856*7323adacSDevin Teske set_value(time, $2 " " $3 " " $4) 857*7323adacSDevin Teske next 858*7323adacSDevin Teske } 859*7323adacSDevin Teske } 860*7323adacSDevin Teske 861*7323adacSDevin Teske if ( $1 != "option" ) next 862*7323adacSDevin Teske for (o in options) 863*7323adacSDevin Teske { 864*7323adacSDevin Teske option = options[o] 865*7323adacSDevin Teske if ( $2 == option ) 866*7323adacSDevin Teske { 867*7323adacSDevin Teske set_value(option, $3) 868*7323adacSDevin Teske next 869*7323adacSDevin Teske } 870*7323adacSDevin Teske } 871*7323adacSDevin Teske } 872*7323adacSDevin Teske EXIT { 873*7323adacSDevin Teske if ( ! lease_found ) 874*7323adacSDevin Teske { 875*7323adacSDevin Teske printf "f_struct_free \"%s\"\n", struct 876*7323adacSDevin Teske print "return $FAILURE" 877*7323adacSDevin Teske } 878*7323adacSDevin Teske } 879*7323adacSDevin Teske ' "$leasefile" )" 880*7323adacSDevin Teske} 881*7323adacSDevin Teske 882*7323adacSDevin Teske# f_dhcp_get_info $interface 883*7323adacSDevin Teske# 884*7323adacSDevin Teske# Parse the dhclient(8) lease database for $interface to obtain all the 885*7323adacSDevin Teske# necessary IPv4 details necessary to communicate on the network. The retrieved 886*7323adacSDevin Teske# information is stored in VAR_IPADDR, VAR_NETMASK, VAR_GATEWAY, and 887*7323adacSDevin Teske# VAR_NAMESERVER. 888*7323adacSDevin Teske# 889*7323adacSDevin Teske# If reading the lease database fails, values are obtained from ifconfig(8) and 890*7323adacSDevin Teske# route(8). If the DHCP lease did not provide a nameserver (or likewise, we 891*7323adacSDevin Teske# were unable to parse the lease database), fall-back to resolv.conf(5) for 892*7323adacSDevin Teske# obtaining the nameserver. Always returns success. 893*7323adacSDevin Teske# 894*7323adacSDevin Teskef_dhcp_get_info() 895*7323adacSDevin Teske{ 896*7323adacSDevin Teske local interface="$1" cp 897*7323adacSDevin Teske local leasefile="/var/db/dhclient.leases.$interface" 898*7323adacSDevin Teske 899*7323adacSDevin Teske # If it fails, do it the old-fashioned way 900*7323adacSDevin Teske if f_dhcp_parse_leases "$leasefile" lease; then 901*7323adacSDevin Teske lease get fixed_address $VAR_IPADDR 902*7323adacSDevin Teske lease get subnet_mask $VAR_NETMASK 903*7323adacSDevin Teske lease get routers cp 904*7323adacSDevin Teske setvar $VAR_GATEWAY "${cp%%,*}" 905*7323adacSDevin Teske lease get domain_name_servers cp 906*7323adacSDevin Teske setvar $VAR_NAMESERVER "${cp%%,*}" 907*7323adacSDevin Teske lease get host_name cp && 908*7323adacSDevin Teske setvar $VAR_HOSTNAME "$cp" 909*7323adacSDevin Teske f_struct_free lease 910*7323adacSDevin Teske else 911*7323adacSDevin Teske # Bah, now we have to get the information from ifconfig 912*7323adacSDevin Teske if f_debugging; then 913*7323adacSDevin Teske f_dprintf "DHCP configured interface returns %s" \ 914*7323adacSDevin Teske "$( ifconfig "$interface" )" 915*7323adacSDevin Teske fi 916*7323adacSDevin Teske f_ifconfig_inet "$interface" $VAR_IPADDR 917*7323adacSDevin Teske f_ifconfig_netmask "$interface" $VAR_NETMASK 918*7323adacSDevin Teske f_route_get_default $VAR_GATEWAY 919*7323adacSDevin Teske fi 920*7323adacSDevin Teske 921*7323adacSDevin Teske # If we didn't get a name server value, hunt for it in resolv.conf 922*7323adacSDevin Teske local ns 923*7323adacSDevin Teske if [ -r "$RESOLV_CONF" ] && ! { 924*7323adacSDevin Teske f_getvar $VAR_NAMESERVER ns || [ "$ns" ] 925*7323adacSDevin Teske }; then 926*7323adacSDevin Teske f_resolv_conf_nameservers cp && 927*7323adacSDevin Teske setvar $VAR_NAMESERVER ${cp%%[$IFS]*} 928*7323adacSDevin Teske fi 929*7323adacSDevin Teske 930*7323adacSDevin Teske return $SUCCESS 931*7323adacSDevin Teske} 932*7323adacSDevin Teske 933*7323adacSDevin Teske# f_rtsol_get_info $interface 934*7323adacSDevin Teske# 935*7323adacSDevin Teske# Returns the rtsol-provided IPv6 address associated with $interface. The 936*7323adacSDevin Teske# retrieved IP address is stored in VAR_IPV6ADDR. Always returns success. 937*7323adacSDevin Teske# 938*7323adacSDevin Teskef_rtsol_get_info() 939*7323adacSDevin Teske{ 940*7323adacSDevin Teske local interface="$1" cp 941*7323adacSDevin Teske cp=$( ifconfig "$interface" 2> /dev/null | awk \ 942*7323adacSDevin Teske ' 943*7323adacSDevin Teske BEGIN { found = 0 } 944*7323adacSDevin Teske ( $1 == "inet6" ) && ( $2 ~ /^fe80:/ ) \ 945*7323adacSDevin Teske { 946*7323adacSDevin Teske print $2 947*7323adacSDevin Teske found = 1 948*7323adacSDevin Teske exit 949*7323adacSDevin Teske } 950*7323adacSDevin Teske END { exit ! found } 951*7323adacSDevin Teske ' ) && setvar $VAR_IPV6ADDR "$cp" 952*7323adacSDevin Teske} 953*7323adacSDevin Teske 954*7323adacSDevin Teske# f_host_lookup $host [$var_to_set] 955*7323adacSDevin Teske# 956*7323adacSDevin Teske# Use host(1) to lookup (or reverse) an Internet number from (or to) a name. 957*7323adacSDevin Teske# Multiple answers are returned separated by a single space. If host(1) does 958*7323adacSDevin Teske# not exit cleanly, its full output is provided and the return status is 1. 959*7323adacSDevin Teske# 960*7323adacSDevin Teske# If nsswitch.conf(5) has been configured to query local access first for the 961*7323adacSDevin Teske# `hosts' database, we'll manually check hosts(5) first (preventing host(1) 962*7323adacSDevin Teske# from hanging in the event that DNS goes awry). 963*7323adacSDevin Teske# 964*7323adacSDevin Teske# If $var_to_set is missing or NULL, the list of IP addresses is printed to 965*7323adacSDevin Teske# standard output for capturing in a sub-shell (which is less-recommended 966*7323adacSDevin Teske# because of performance degredation; for example, when called in a loop). 967*7323adacSDevin Teske# 968*7323adacSDevin Teske# The variables from variable.subr used in looking up the host are as follows 969*7323adacSDevin Teske# (which are set manually): 970*7323adacSDevin Teske# 971*7323adacSDevin Teske# VAR_IPV6_ENABLE [Optional] 972*7323adacSDevin Teske# If set to "YES", enables the lookup of IPv6 addresses and IPv4 973*7323adacSDevin Teske# address. IPv6 addresses, if any, will come before IPv4. Note 974*7323adacSDevin Teske# that if nsswitch.conf(5) shows an affinity for "files" for the 975*7323adacSDevin Teske# "host" database and there is a valid entry in hosts(5) for 976*7323adacSDevin Teske# $host, this setting currently has no effect (an IPv4 address 977*7323adacSDevin Teske# can supersede an IPv6 address). By design, hosts(5) overrides 978*7323adacSDevin Teske# any preferential treatment. Otherwise, if this variable is not 979*7323adacSDevin Teske# set, IPv6 addresses will not be used (IPv4 addresses will 980*7323adacSDevin Teske# specifically be requested from DNS). 981*7323adacSDevin Teske# 982*7323adacSDevin Teske# This function is a two-parter. Below is the awk(1) portion of the function, 983*7323adacSDevin Teske# afterward is the sh(1) function which utilizes the below awk script. 984*7323adacSDevin Teske# 985*7323adacSDevin Teskef_host_lookup_awk=' 986*7323adacSDevin TeskeBEGIN{ addrs = "" } 987*7323adacSDevin Teske!/^[[:space:]]*(#|$)/ \ 988*7323adacSDevin Teske{ 989*7323adacSDevin Teske for (n=1; n++ < NF;) if ($n == name) 990*7323adacSDevin Teske addrs = addrs (addrs ? " " : "") $1 991*7323adacSDevin Teske} 992*7323adacSDevin TeskeEND { 993*7323adacSDevin Teske if (addrs) print addrs 994*7323adacSDevin Teske exit !addrs 995*7323adacSDevin Teske} 996*7323adacSDevin Teske' 997*7323adacSDevin Teskef_host_lookup() 998*7323adacSDevin Teske{ 999*7323adacSDevin Teske local __host="$1" __var_to_set="$2" 1000*7323adacSDevin Teske f_dprintf "f_host_lookup: host=[%s]" "$__host" 1001*7323adacSDevin Teske 1002*7323adacSDevin Teske # If we're configured to look at local files first, do that 1003*7323adacSDevin Teske if awk '/^hosts:/{exit !($2=="files")}' "$NSSWITCH_CONF"; then 1004*7323adacSDevin Teske if [ "$__var_to_set" ]; then 1005*7323adacSDevin Teske local __cp 1006*7323adacSDevin Teske if __cp=$( awk -v name="$__host" \ 1007*7323adacSDevin Teske "$f_host_lookup_awk" "$ETC_HOSTS" ) 1008*7323adacSDevin Teske then 1009*7323adacSDevin Teske setvar "$__var_to_set" "$__cp" 1010*7323adacSDevin Teske return $SUCCESS 1011*7323adacSDevin Teske fi 1012*7323adacSDevin Teske else 1013*7323adacSDevin Teske awk -v name="$__host" \ 1014*7323adacSDevin Teske "$f_host_lookup_awk" "$ETC_HOSTS" && 1015*7323adacSDevin Teske return $SUCCESS 1016*7323adacSDevin Teske fi 1017*7323adacSDevin Teske fi 1018*7323adacSDevin Teske 1019*7323adacSDevin Teske # 1020*7323adacSDevin Teske # Fall back to host(1) -- which is further governed by nsswitch.conf(5) 1021*7323adacSDevin Teske # 1022*7323adacSDevin Teske 1023*7323adacSDevin Teske local __output __ip6 __addrs="" __wait="" 1024*7323adacSDevin Teske f_getvar $VAR_MEDIA_TIMEOUT __wait 1025*7323adacSDevin Teske [ "$__wait" ] && __wait="-W $(( $__wait / 2 ))" 1026*7323adacSDevin Teske f_getvar $VAR_IPV6_ENABLE __ip6 1027*7323adacSDevin Teske if [ "$__ip6" = "YES" ]; then 1028*7323adacSDevin Teske if ! __output=$( host -t AAAA $__wait -- "$__host" 2>&1 ); then 1029*7323adacSDevin Teske # An error occurred, display in-full and return error 1030*7323adacSDevin Teske [ "$__var_to_set" ] && 1031*7323adacSDevin Teske setvar "$__var_to_set" "$__output" 1032*7323adacSDevin Teske return $FAILURE 1033*7323adacSDevin Teske fi 1034*7323adacSDevin Teske __addrs=$( echo "$__output" | awk '/ address /{print $NF}' ) 1035*7323adacSDevin Teske fi 1036*7323adacSDevin Teske if ! __output=$( host -t A $__wait -- "$__host" 2>&1 ); then 1037*7323adacSDevin Teske # An error occurred, display it in-full and return error 1038*7323adacSDevin Teske [ "$__var_to_set" ] && setvar "$__var_to_set" "$__output" 1039*7323adacSDevin Teske return $FAILURE 1040*7323adacSDevin Teske fi 1041*7323adacSDevin Teske __addrs="$__addrs${__addrs:+ }$( 1042*7323adacSDevin Teske echo "$__output" | awk '/ address /{print $NF}' )" 1043*7323adacSDevin Teske if [ "$__var_to_set" ]; then 1044*7323adacSDevin Teske setvar "$__var_to_set" "$__addrs" 1045*7323adacSDevin Teske else 1046*7323adacSDevin Teske echo $__addrs 1047*7323adacSDevin Teske fi 1048*7323adacSDevin Teske} 1049*7323adacSDevin Teske 1050*7323adacSDevin Teske# f_device_dialog_tcp $device 1051*7323adacSDevin Teske# 1052*7323adacSDevin Teske# This is it - how to get TCP setup values. Prompt the user to edit/confirm the 1053*7323adacSDevin Teske# interface, gateway, nameserver, and hostname settings -- all required for 1054*7323adacSDevin Teske# general TCP/IP access. 1055*7323adacSDevin Teske# 1056*7323adacSDevin Teske# Variables from variable.subr that can be used to sript user input: 1057*7323adacSDevin Teske# 1058*7323adacSDevin Teske# VAR_NO_INET6 1059*7323adacSDevin Teske# If set, prevents asking the user if they would like to use 1060*7323adacSDevin Teske# rtsol(8) to check for an IPv6 router. 1061*7323adacSDevin Teske# VAR_TRY_RTSOL 1062*7323adacSDevin Teske# If set to "YES" (and VAR_NONINTERACTIVE is unset), asks the 1063*7323adacSDevin Teske# user if they would like to try the IPv6 RouTer SOLicitation 1064*7323adacSDevin Teske# utility (rtsol(8)) to get IPv6 information. Ignored if 1065*7323adacSDevin Teske# VAR_NO_INET6 is set. 1066*7323adacSDevin Teske# VAR_TRY_DHCP 1067*7323adacSDevin Teske# If set to "YES" (and VAR_NONINTERACTIVE is unset), asks the 1068*7323adacSDevin Teske# user if they would like to try to acquire IPv4 connection 1069*7323adacSDevin Teske# settings from a DHCP server using dhclient(8). 1070*7323adacSDevin Teske# 1071*7323adacSDevin Teske# VAR_GATEWAY Default gateway to use. 1072*7323adacSDevin Teske# VAR_IPADDR Interface address to assign. 1073*7323adacSDevin Teske# VAR_NETMASK Interface subnet mask. 1074*7323adacSDevin Teske# VAR_EXTRAS Extra interface options to ifconfig(8). 1075*7323adacSDevin Teske# VAR_HOSTNAME Hostname to set. 1076*7323adacSDevin Teske# VAR_DOMAINNAME Domain name to use. 1077*7323adacSDevin Teske# VAR_NAMESERVER DNS nameserver to use when making lookups. 1078*7323adacSDevin Teske# VAR_IPV6ADDR IPv6 interface address. 1079*7323adacSDevin Teske# 1080*7323adacSDevin Teske# In addition, the following variables are used in acquiring network settings 1081*7323adacSDevin Teske# from the user: 1082*7323adacSDevin Teske# 1083*7323adacSDevin Teske# VAR_NONINTERACTIVE 1084*7323adacSDevin Teske# If set (such as when running in a script), prevents asking the 1085*7323adacSDevin Teske# user questions or displaying the usual prompts, etc. 1086*7323adacSDevin Teske# VAR_NETINTERACTIVE 1087*7323adacSDevin Teske# The one exception to VAR_NONINTERACTIVE is VAR_NETINTERACTIVE, 1088*7323adacSDevin Teske# which if set will prompt the user to try RTSOL (unless 1089*7323adacSDevin Teske# VAR_TRY_RTSOL has been set), try DHCP (unless VAR_TRY_DHCP has 1090*7323adacSDevin Teske# been set), and display the network verification dialog. This 1091*7323adacSDevin Teske# allows you to have a mostly non-interactive script that still 1092*7323adacSDevin Teske# prompts for network setup/confirmation. 1093*7323adacSDevin Teske# 1094*7323adacSDevin Teske# After successfull execution, the following variables are set: 1095*7323adacSDevin Teske# 1096*7323adacSDevin Teske# VAR_IFCONFIG + $device (e.g., `ifconfig_em0') 1097*7323adacSDevin Teske# Defines the ifconfig(8) properties specific to $device. 1098*7323adacSDevin Teske# 1099*7323adacSDevin Teskef_device_dialog_tcp() 1100*7323adacSDevin Teske{ 1101*7323adacSDevin Teske local dev="$1" cp n 1102*7323adacSDevin Teske local use_dhcp="" use_rtsol="" 1103*7323adacSDevin Teske local _ipaddr _netmask _extras 1104*7323adacSDevin Teske 1105*7323adacSDevin Teske [ "$dev" ] || return $FAILURE 1106*7323adacSDevin Teske 1107*7323adacSDevin Teske # Initialize vars from previous device values 1108*7323adacSDevin Teske local private 1109*7323adacSDevin Teske device_$dev get private private 1110*7323adacSDevin Teske if [ "$private" ] && f_struct "$private"; then 1111*7323adacSDevin Teske $private get ipaddr _ipaddr 1112*7323adacSDevin Teske $private get netmask _netmask 1113*7323adacSDevin Teske $private get extras _extras 1114*7323adacSDevin Teske $private get use_dhcp use_dhcp 1115*7323adacSDevin Teske $private get use_rtsol use_rtsol 1116*7323adacSDevin Teske else # See if there are any defaults 1117*7323adacSDevin Teske 1118*7323adacSDevin Teske # 1119*7323adacSDevin Teske # This is a hack so that the dialogs below are interactive in a 1120*7323adacSDevin Teske # script if we have requested interactive behavior. 1121*7323adacSDevin Teske # 1122*7323adacSDevin Teske local old_interactive= 1123*7323adacSDevin Teske if ! f_interactive && f_netinteractive; then 1124*7323adacSDevin Teske f_getvar $VAR_NONINTERACTIVE old_interactive 1125*7323adacSDevin Teske unset $VAR_NONINTERACTIVE 1126*7323adacSDevin Teske fi 1127*7323adacSDevin Teske 1128*7323adacSDevin Teske 1129*7323adacSDevin Teske # 1130*7323adacSDevin Teske # Try a RTSOL scan if such behavior is desired. 1131*7323adacSDevin Teske # If the variable was configured and is YES, do it. 1132*7323adacSDevin Teske # If it was configured to anything else, treat it as NO. 1133*7323adacSDevin Teske # Otherwise, ask the question interactively. 1134*7323adacSDevin Teske # 1135*7323adacSDevin Teske local try6 1136*7323adacSDevin Teske if ! f_quietly f_getvar $VAR_NO_INET6 && { 1137*7323adacSDevin Teske { f_getvar $VAR_TRY_RTSOL try6 && [ "$try6" = "YES" ]; } || 1138*7323adacSDevin Teske { 1139*7323adacSDevin Teske ! f_quietly f_getvar $VAR_TRY_RTSOL && 1140*7323adacSDevin Teske f_dialog_noyes "$msg_try_ipv6_configuration" 1141*7323adacSDevin Teske } 1142*7323adacSDevin Teske }; then 1143*7323adacSDevin Teske local i 1144*7323adacSDevin Teske 1145*7323adacSDevin Teske f_quietly sysctl net.inet6.ip6.forwarding=0 1146*7323adacSDevin Teske f_quietly sysctl net.inet6.ip6.accept_rtadv=1 1147*7323adacSDevin Teske f_quietly ifconfig $dev up 1148*7323adacSDevin Teske 1149*7323adacSDevin Teske i=$( sysctl -n net.inet6.ip6.dad_count ) 1150*7323adacSDevin Teske sleep $(( $i + 1 )) 1151*7323adacSDevin Teske 1152*7323adacSDevin Teske f_quietly mkdir -p /var/run 1153*7323adacSDevin Teske f_dialog_info "$msg_scanning_for_ra_servers" 1154*7323adacSDevin Teske if f_quietly rtsol $dev; then 1155*7323adacSDevin Teske i=$( sysctl -n net.inet6.ip6.dad_count ) 1156*7323adacSDevin Teske sleep $(( $i + 1 )) 1157*7323adacSDevin Teske f_rtsol_get_info $dev 1158*7323adacSDevin Teske use_rtsol=1 1159*7323adacSDevin Teske else 1160*7323adacSDevin Teske use_rtsol= 1161*7323adacSDevin Teske fi 1162*7323adacSDevin Teske fi 1163*7323adacSDevin Teske 1164*7323adacSDevin Teske # 1165*7323adacSDevin Teske # Try a DHCP scan if such behavior is desired. 1166*7323adacSDevin Teske # If the variable was configured and is YES, do it. 1167*7323adacSDevin Teske # If it was configured to anything else, treat it as NO. 1168*7323adacSDevin Teske # Otherwise, ask the question interactively. 1169*7323adacSDevin Teske # 1170*7323adacSDevin Teske local try4 1171*7323adacSDevin Teske if { f_getvar $VAR_TRY_DHCP try4 && [ "$try4" = "YES" ]; } || { 1172*7323adacSDevin Teske ! f_quietly f_getvar $VAR_TRY_DHCP && 1173*7323adacSDevin Teske f_dialog_noyes "$msg_try_dhcp_configuration" 1174*7323adacSDevin Teske }; then 1175*7323adacSDevin Teske f_quietly ifconfig $dev delete 1176*7323adacSDevin Teske f_quietly mkdir -p /var/db 1177*7323adacSDevin Teske f_quietly mkdir -p /var/run 1178*7323adacSDevin Teske f_quietly mkdir -p /tmp 1179*7323adacSDevin Teske 1180*7323adacSDevin Teske local msg="$msg_scanning_for_dhcp_servers" 1181*7323adacSDevin Teske trap - SIGINT 1182*7323adacSDevin Teske ( # Execute in sub-shell to allow/catch Ctrl-C 1183*7323adacSDevin Teske trap 'exit $FAILURE' SIGINT 1184*7323adacSDevin Teske if [ "$USE_XDIALOG" ]; then 1185*7323adacSDevin Teske f_quietly dhclient $dev | 1186*7323adacSDevin Teske f_xdialog_info "$msg" 1187*7323adacSDevin Teske else 1188*7323adacSDevin Teske f_dialog_info "$msg" 1189*7323adacSDevin Teske f_quietly dhclient $dev 1190*7323adacSDevin Teske fi 1191*7323adacSDevin Teske ) 1192*7323adacSDevin Teske local retval=$? 1193*7323adacSDevin Teske trap 'f_interrupt' SIGINT 1194*7323adacSDevin Teske if [ $retval -eq $SUCCESS ]; then 1195*7323adacSDevin Teske f_dhcp_get_info $dev 1196*7323adacSDevin Teske use_dhcp=1 1197*7323adacSDevin Teske else 1198*7323adacSDevin Teske use_dhcp= 1199*7323adacSDevin Teske fi 1200*7323adacSDevin Teske fi 1201*7323adacSDevin Teske 1202*7323adacSDevin Teske # Restore old VAR_NONINTERACTIVE if needed. 1203*7323adacSDevin Teske [ "$old_interactive" ] && 1204*7323adacSDevin Teske setvar $VAR_NONINTERACTIVE "$old_interactive" 1205*7323adacSDevin Teske 1206*7323adacSDevin Teske # Special hack so it doesn't show up oddly in the menu 1207*7323adacSDevin Teske local gw 1208*7323adacSDevin Teske if f_getvar $VAR_GATEWAY gw && [ "$gw" = "NO" ]; then 1209*7323adacSDevin Teske setvar $VAR_GATEWAY "" 1210*7323adacSDevin Teske fi 1211*7323adacSDevin Teske 1212*7323adacSDevin Teske # Get old IP address from variable space, if available 1213*7323adacSDevin Teske if [ ! "$_ipaddr" ]; then 1214*7323adacSDevin Teske if f_getvar $VAR_IPADDR cp; then 1215*7323adacSDevin Teske _ipaddr="$cp" 1216*7323adacSDevin Teske elif f_getvar ${dev}_$VAR_IPADDR cp; then 1217*7323adacSDevin Teske _ipaddr="$cp" 1218*7323adacSDevin Teske fi 1219*7323adacSDevin Teske fi 1220*7323adacSDevin Teske 1221*7323adacSDevin Teske # Get old netmask from variable space, if available 1222*7323adacSDevin Teske if [ ! "$_netmask" ]; then 1223*7323adacSDevin Teske if f_getvar $VAR_NETMASK cp; then 1224*7323adacSDevin Teske _netmask="$cp" 1225*7323adacSDevin Teske elif f_getvar ${dev}_$VAR_NETMASK cp; then 1226*7323adacSDevin Teske _netmask="$cp" 1227*7323adacSDevin Teske fi 1228*7323adacSDevin Teske fi 1229*7323adacSDevin Teske 1230*7323adacSDevin Teske # Get old extras string from variable space, if available 1231*7323adacSDevin Teske if [ ! "$_extras" ]; then 1232*7323adacSDevin Teske if f_getvar $VAR_EXTRAS cp; then 1233*7323adacSDevin Teske _extras="$cp" 1234*7323adacSDevin Teske elif f_getvar ${dev}_$VAR_EXTRAS cp; then 1235*7323adacSDevin Teske _extras="$cp" 1236*7323adacSDevin Teske fi 1237*7323adacSDevin Teske fi 1238*7323adacSDevin Teske fi 1239*7323adacSDevin Teske 1240*7323adacSDevin Teske # Look up values already recorded with the system, or blank the string 1241*7323adacSDevin Teske # variables ready to accept some new data 1242*7323adacSDevin Teske local _hostname _gateway _nameserver 1243*7323adacSDevin Teske f_getvar $VAR_HOSTNAME _hostname 1244*7323adacSDevin Teske case "$_hostname" in 1245*7323adacSDevin Teske *.*) : do nothing ;; # Already fully-qualified 1246*7323adacSDevin Teske *) 1247*7323adacSDevin Teske f_getvar $VAR_DOMAINNAME cp 1248*7323adacSDevin Teske [ "$cp" ] && _hostname="$_hostname.$cp" 1249*7323adacSDevin Teske esac 1250*7323adacSDevin Teske f_getvar $VAR_GATEWAY _gateway 1251*7323adacSDevin Teske f_getvar $VAR_NAMESERVER _nameserver 1252*7323adacSDevin Teske 1253*7323adacSDevin Teske # Re-check variables for initial inheritance before heading into dialog 1254*7323adacSDevin Teske [ "$_hostname" ] || _hostname="${HOSTNAME:-$( hostname )}" 1255*7323adacSDevin Teske [ "$_gateway" ] || f_route_get_default _gateway 1256*7323adacSDevin Teske [ ! "$_nameserver" ] && 1257*7323adacSDevin Teske f_resolv_conf_nameservers cp && _nameserver=${cp%%[$IFS]*} 1258*7323adacSDevin Teske [ "$_ipaddr" ] || f_ifconfig_inet $dev _ipaddr 1259*7323adacSDevin Teske [ "$_netmask" ] || f_ifconfig_netmask $dev _netmask 1260*7323adacSDevin Teske 1261*7323adacSDevin Teske # If non-interactive, jump over dialog section and into config section 1262*7323adacSDevin Teske if f_netinteractive || f_interactive || [ ! "$_hostname" ] 1263*7323adacSDevin Teske then 1264*7323adacSDevin Teske [ ! "$_hostname" ] && f_interactive && 1265*7323adacSDevin Teske f_dialog_msgbox "$msg_hostname_variable_not_set" 1266*7323adacSDevin Teske 1267*7323adacSDevin Teske local title=" $msg_network_configuration " 1268*7323adacSDevin Teske local hline="$hline_alnum_arrows_punc_tab_enter" 1269*7323adacSDevin Teske local extras_help="$tcplayout_extras_help" 1270*7323adacSDevin Teske 1271*7323adacSDevin Teske # Modify the help line for PLIP config 1272*7323adacSDevin Teske [ "${dev#plip}" != "$dev" ] && 1273*7323adacSDevin Teske extras_help="$tcplayout_extras_help_for_plip" 1274*7323adacSDevin Teske 1275*7323adacSDevin Teske f_getvar $VAR_IPV6ADDR cp && [ "$cp" ] && 1276*7323adacSDevin Teske title="$title($msg_ipv6_ready) " 1277*7323adacSDevin Teske 1278*7323adacSDevin Teske if [ ! "$USE_XDIALOG" ]; then 1279*7323adacSDevin Teske local prompt="$msg_dialog_mixedform_navigation_help" 1280*7323adacSDevin Teske # Calculate center position for displaying device label 1281*7323adacSDevin Teske local devlabel="$msg_configuration_for_interface $dev" 1282*7323adacSDevin Teske local width=54 1283*7323adacSDevin Teske local n=$(( $width/2 - (${#devlabel} + 4)/2 - 2 )) 1284*7323adacSDevin Teske 1285*7323adacSDevin Teske while :; do 1286*7323adacSDevin Teske cp=$( $DIALOG \ 1287*7323adacSDevin Teske --title "$title" \ 1288*7323adacSDevin Teske --backtitle "$DIALOG_BACKTITLE" \ 1289*7323adacSDevin Teske --hline "$hline" \ 1290*7323adacSDevin Teske --item-help \ 1291*7323adacSDevin Teske --ok-label "$msg_ok" \ 1292*7323adacSDevin Teske --cancel-label "$msg_cancel" \ 1293*7323adacSDevin Teske --help-button \ 1294*7323adacSDevin Teske --help-label "$msg_help" \ 1295*7323adacSDevin Teske --mixedform "$prompt" 16 $width 9 \ 1296*7323adacSDevin Teske "$msg_host_name_including_domain:" 1 2 \ 1297*7323adacSDevin Teske "$_hostname" 2 3 45 255 0 \ 1298*7323adacSDevin Teske "$tcplayout_hostname_help" \ 1299*7323adacSDevin Teske "$msg_ipv4_gateway:" 3 2 \ 1300*7323adacSDevin Teske "$_gateway" 4 3 16 15 0 \ 1301*7323adacSDevin Teske "$tcplayout_gateway_help" \ 1302*7323adacSDevin Teske "$msg_name_server:" 3 31 \ 1303*7323adacSDevin Teske "$_nameserver" 4 32 16 15 0 \ 1304*7323adacSDevin Teske "$tcplayout_nameserver_help" \ 1305*7323adacSDevin Teske "- $devlabel -" 5 $n "" 0 0 0 0 3 "" \ 1306*7323adacSDevin Teske "$msg_ipv4_address:" 6 6 \ 1307*7323adacSDevin Teske "$_ipaddr" 7 7 16 15 0 \ 1308*7323adacSDevin Teske "$tcplayout_ipaddr_help" \ 1309*7323adacSDevin Teske "$msg_netmask:" 6 31 \ 1310*7323adacSDevin Teske "$_netmask" 7 32 16 15 0 \ 1311*7323adacSDevin Teske "$tcplayout_netmask_help" \ 1312*7323adacSDevin Teske "$msg_extra_options_to_ifconfig" 8 6 \ 1313*7323adacSDevin Teske "$_extras" 9 7 41 2048 0 \ 1314*7323adacSDevin Teske "$extras_help" \ 1315*7323adacSDevin Teske 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD ) 1316*7323adacSDevin Teske 1317*7323adacSDevin Teske # --mixed-form always returns 0, we have to 1318*7323adacSDevin Teske # use the returned data to determine button 1319*7323adacSDevin Teske if [ ! "$cp" ]; then 1320*7323adacSDevin Teske # User either chose "Cancel", pressed 1321*7323adacSDevin Teske # ESC, or blanked every form field 1322*7323adacSDevin Teske return $FAILURE 1323*7323adacSDevin Teske else 1324*7323adacSDevin Teske n=$( echo "$cp" | f_number_of_lines ) 1325*7323adacSDevin Teske [ $n -eq 1 ] && case "$cp" in HELP*) 1326*7323adacSDevin Teske # User chose "Help" 1327*7323adacSDevin Teske f_show_help "$TCP_HELPFILE" 1328*7323adacSDevin Teske continue 1329*7323adacSDevin Teske esac 1330*7323adacSDevin Teske fi 1331*7323adacSDevin Teske 1332*7323adacSDevin Teske # Turn mixed-form results into env variables 1333*7323adacSDevin Teske eval "$( echo "$cp" | awk ' 1334*7323adacSDevin Teske BEGIN { 1335*7323adacSDevin Teske n = 0 1336*7323adacSDevin Teske field[++n] = "_hostname" 1337*7323adacSDevin Teske field[++n] = "_gateway" 1338*7323adacSDevin Teske field[++n] = "_nameserver" 1339*7323adacSDevin Teske field[++n] = "_ipaddr" 1340*7323adacSDevin Teske field[++n] = "_netmask" 1341*7323adacSDevin Teske field[++n] = "_extras" 1342*7323adacSDevin Teske nfields = n 1343*7323adacSDevin Teske n = 0 1344*7323adacSDevin Teske } 1345*7323adacSDevin Teske { 1346*7323adacSDevin Teske gsub(/'\''/, "'\'\\\\\'\''") 1347*7323adacSDevin Teske sub(/[[:space:]]*$/, "") 1348*7323adacSDevin Teske value[field[++n]] = $0 1349*7323adacSDevin Teske } 1350*7323adacSDevin Teske END { 1351*7323adacSDevin Teske for ( n = 1; n <= nfields; n++ ) 1352*7323adacSDevin Teske { 1353*7323adacSDevin Teske printf "%s='\''%s'\'';\n", 1354*7323adacSDevin Teske field[n], 1355*7323adacSDevin Teske value[field[n]] 1356*7323adacSDevin Teske } 1357*7323adacSDevin Teske }' )" 1358*7323adacSDevin Teske 1359*7323adacSDevin Teske f_dialog_validate_tcpip \ 1360*7323adacSDevin Teske "$_hostname" \ 1361*7323adacSDevin Teske "$_gateway" \ 1362*7323adacSDevin Teske "$_nameserver" \ 1363*7323adacSDevin Teske "$_ipaddr" \ 1364*7323adacSDevin Teske "$_netmask" \ 1365*7323adacSDevin Teske && break 1366*7323adacSDevin Teske done 1367*7323adacSDevin Teske else 1368*7323adacSDevin Teske # Xdialog(1) does not support --mixed-form 1369*7323adacSDevin Teske # Create a persistent menu instead 1370*7323adacSDevin Teske 1371*7323adacSDevin Teske f_dialog_title "$msg_network_configuration" 1372*7323adacSDevin Teske local prompt="" 1373*7323adacSDevin Teske 1374*7323adacSDevin Teske while :; do 1375*7323adacSDevin Teske cp=$( $DIALOG \ 1376*7323adacSDevin Teske --title "$DIALOG_TITLE" \ 1377*7323adacSDevin Teske --backtitle "$DIALOG_BACKTITLE" \ 1378*7323adacSDevin Teske --hline "$hline" \ 1379*7323adacSDevin Teske --item-help \ 1380*7323adacSDevin Teske --ok-label "$msg_ok" \ 1381*7323adacSDevin Teske --cancel-label "$msg_cancel" \ 1382*7323adacSDevin Teske --help "" \ 1383*7323adacSDevin Teske --menu "$prompt" 21 60 8 \ 1384*7323adacSDevin Teske "$msg_accept_continue" "" \ 1385*7323adacSDevin Teske "$tcplayout_accept_cont_help" \ 1386*7323adacSDevin Teske "$msg_host_name_including_domain:" \ 1387*7323adacSDevin Teske "$_hostname" \ 1388*7323adacSDevin Teske "$tcplayout_hostname_help" \ 1389*7323adacSDevin Teske "$msg_ipv4_gateway:" "$_gateway" \ 1390*7323adacSDevin Teske "$tcplayout_gateway_help" \ 1391*7323adacSDevin Teske "$msg_name_server:" "$_nameserver" \ 1392*7323adacSDevin Teske "$tcplayout_nameserver_help" \ 1393*7323adacSDevin Teske "$msg_ipv4_address:" "$_ipaddr" \ 1394*7323adacSDevin Teske "$tcplayout_ipaddr_help" \ 1395*7323adacSDevin Teske "$msg_netmask:" "$_netmask" \ 1396*7323adacSDevin Teske "$tcplayout_netmask_help" \ 1397*7323adacSDevin Teske "$msg_extra_options_to_ifconfig" \ 1398*7323adacSDevin Teske "$_extras" "$extras_help" \ 1399*7323adacSDevin Teske 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 1400*7323adacSDevin Teske ) 1401*7323adacSDevin Teske local retval=$? 1402*7323adacSDevin Teske f_dprintf "retval=%u mtag=[%s]" $retval "$cp" 1403*7323adacSDevin Teske 1404*7323adacSDevin Teske if [ $retval -eq 2 ]; then 1405*7323adacSDevin Teske # The Help button was pressed 1406*7323adacSDevin Teske f_show_help "$TCP_HELPFILE" 1407*7323adacSDevin Teske continue 1408*7323adacSDevin Teske elif [ $retval -ne 0 ]; then 1409*7323adacSDevin Teske # User chose "Cancel" or pressed ESC 1410*7323adacSDevin Teske f_dialog_title_restore 1411*7323adacSDevin Teske return $FAILURE 1412*7323adacSDevin Teske fi 1413*7323adacSDevin Teske 1414*7323adacSDevin Teske case "$cp" in 1415*7323adacSDevin Teske "$msg_accept_continue") 1416*7323adacSDevin Teske f_dialog_validate_tcpip \ 1417*7323adacSDevin Teske "$_hostname" \ 1418*7323adacSDevin Teske "$_gateway" \ 1419*7323adacSDevin Teske "$_nameserver" \ 1420*7323adacSDevin Teske "$_ipaddr" \ 1421*7323adacSDevin Teske "$_netmask" \ 1422*7323adacSDevin Teske && break ;; 1423*7323adacSDevin Teske "$msg_host_name_including_domain:") 1424*7323adacSDevin Teske cp=$( f_dialog_input "$cp" \ 1425*7323adacSDevin Teske "$_hostname" 1426*7323adacSDevin Teske ) && _hostname="$cp" ;; 1427*7323adacSDevin Teske "$msg_ipv4_gateway:") 1428*7323adacSDevin Teske cp=$( f_dialog_input "$cp" \ 1429*7323adacSDevin Teske "$_gateway" 1430*7323adacSDevin Teske ) && _gateway="$cp" ;; 1431*7323adacSDevin Teske "$msg_name_server:") 1432*7323adacSDevin Teske cp=$( f_dialog_input "$cp" \ 1433*7323adacSDevin Teske "$_nameserver" 1434*7323adacSDevin Teske ) && _nameserver="$cp" ;; 1435*7323adacSDevin Teske "$msg_ipv4_address:") 1436*7323adacSDevin Teske cp=$( f_dialog_input "$cp" \ 1437*7323adacSDevin Teske "$_ipaddr" 1438*7323adacSDevin Teske ) && _ipaddr="$cp" ;; 1439*7323adacSDevin Teske "$msg_netmask:") 1440*7323adacSDevin Teske cp=$( f_dialog_input "$cp" \ 1441*7323adacSDevin Teske "$_netmask" 1442*7323adacSDevin Teske ) && _netmask="$cp" ;; 1443*7323adacSDevin Teske "$msg_extra_options_to_ifconfig") 1444*7323adacSDevin Teske cp=$( f_dialog_input "$cp" \ 1445*7323adacSDevin Teske "$_extras" 1446*7323adacSDevin Teske ) && _extras="$cp" ;; 1447*7323adacSDevin Teske esac 1448*7323adacSDevin Teske done 1449*7323adacSDevin Teske 1450*7323adacSDevin Teske f_dialog_title_restore 1451*7323adacSDevin Teske 1452*7323adacSDevin Teske fi # XDIALOG 1453*7323adacSDevin Teske 1454*7323adacSDevin Teske fi # interactive 1455*7323adacSDevin Teske 1456*7323adacSDevin Teske # We actually need to inform the rest of bsdconfig about this 1457*7323adacSDevin Teske # data now if the user hasn't selected cancel. 1458*7323adacSDevin Teske 1459*7323adacSDevin Teske if [ "$_hostname" ]; then 1460*7323adacSDevin Teske setvar $VAR_HOSTNAME "$_hostname" 1461*7323adacSDevin Teske f_quietly hostname "$_hostname" 1462*7323adacSDevin Teske case "$_hostname" in 1463*7323adacSDevin Teske *.*) setvar $VAR_DOMAINNAME "${_hostname#*.}" ;; 1464*7323adacSDevin Teske esac 1465*7323adacSDevin Teske fi 1466*7323adacSDevin Teske [ "$_gateway" ] && setvar $VAR_GATEWAY "$_gateway" 1467*7323adacSDevin Teske [ "$_nameserver" ] && setvar $VAR_NAMESERVER "$_nameserver" 1468*7323adacSDevin Teske [ "$_ipaddr" ] && setvar $VAR_IPADDR "$_ipaddr" 1469*7323adacSDevin Teske [ "$_netmask" ] && setvar $VAR_NETMASK "$_netmask" 1470*7323adacSDevin Teske [ "$_extras" ] && setvar $VAR_EXTRAS "$_extras" 1471*7323adacSDevin Teske 1472*7323adacSDevin Teske f_dprintf "Creating struct DEVICE_INFO devinfo_%s" "$dev" 1473*7323adacSDevin Teske f_struct_new DEVICE_INFO devinfo_$dev 1474*7323adacSDevin Teske device_$dev set private devinfo_$dev 1475*7323adacSDevin Teske 1476*7323adacSDevin Teske devinfo_$dev set ipaddr $_ipaddr 1477*7323adacSDevin Teske devinfo_$dev set netmask $_netmask 1478*7323adacSDevin Teske devinfo_$dev set extras $_extras 1479*7323adacSDevin Teske devinfo_$dev set use_rtsol $use_rtsol 1480*7323adacSDevin Teske devinfo_$dev set use_dhcp $use_dhcp 1481*7323adacSDevin Teske 1482*7323adacSDevin Teske if [ "$use_dhcp" -o "$_ipaddr" ]; then 1483*7323adacSDevin Teske if [ "$use_dhcp" ]; then 1484*7323adacSDevin Teske cp="DHCP${extras:+ $extras}" 1485*7323adacSDevin Teske else 1486*7323adacSDevin Teske cp="inet $_ipaddr netmask $_netmask${extras:+ $extras}" 1487*7323adacSDevin Teske fi 1488*7323adacSDevin Teske setvar $VAR_IFCONFIG$dev "$cp" 1489*7323adacSDevin Teske fi 1490*7323adacSDevin Teske [ "$use_rtsol" ] && 1491*7323adacSDevin Teske setvar $VAR_IPV6_ENABLE "YES" 1492*7323adacSDevin Teske 1493*7323adacSDevin Teske [ "$use_dhcp" ] || 1494*7323adacSDevin Teske f_config_resolv # XXX this will do it on the MFS copy 1495*7323adacSDevin Teske 1496*7323adacSDevin Teske return $SUCCESS 1497*7323adacSDevin Teske} 1498*7323adacSDevin Teske 1499*7323adacSDevin Teske# f_device_scan_tcp [$var_to_set] 1500*7323adacSDevin Teske# 1501*7323adacSDevin Teske# Scan for the first active/configured TCP/IP device. The name of the interface 1502*7323adacSDevin Teske# is printed to stderr like other dialog(1)-based functions (stdout is reserved 1503*7323adacSDevin Teske# for dialog(1) interaction) if $var_to_set is missing or NULL. Returns failure 1504*7323adacSDevin Teske# if no active/configured interface 1505*7323adacSDevin Teske# 1506*7323adacSDevin Teskef_device_scan_tcp() 1507*7323adacSDevin Teske{ 1508*7323adacSDevin Teske local __var_to_set="$1" __iface 1509*7323adacSDevin Teske for __iface in $( ifconfig -l ); do 1510*7323adacSDevin Teske if ifconfig $__iface | awk ' 1511*7323adacSDevin Teske BEGIN { 1512*7323adacSDevin Teske has_inet = has_inet6 = is_ethernet = 0 1513*7323adacSDevin Teske is_usable = 1 1514*7323adacSDevin Teske } 1515*7323adacSDevin Teske ( $1 == "status:" && $2 != "active" ) { is_usable = 0; exit } 1516*7323adacSDevin Teske ( $1 == "inet" ) { 1517*7323adacSDevin Teske if ($2 == "0.0.0.0") { is_usable = 0; exit } 1518*7323adacSDevin Teske has_inet++ 1519*7323adacSDevin Teske } 1520*7323adacSDevin Teske ( $1 == "inet6") { has_inet6++ } 1521*7323adacSDevin Teske ( $1 == "media:" ) { 1522*7323adacSDevin Teske if ($2 != "Ethernet") { is_usable = 0; exit } 1523*7323adacSDevin Teske is_ethernet = 1 1524*7323adacSDevin Teske } 1525*7323adacSDevin Teske END { 1526*7323adacSDevin Teske if (!(is_ethernet && (has_inet || has_inet6))) 1527*7323adacSDevin Teske is_usable = 0 1528*7323adacSDevin Teske exit ! is_usable 1529*7323adacSDevin Teske }'; then 1530*7323adacSDevin Teske f_interactive && 1531*7323adacSDevin Teske f_show_msg "$msg_using_interface" "$__iface" 1532*7323adacSDevin Teske f_dprintf "f_device_scan_tcp found %s" "$__iface" 1533*7323adacSDevin Teske if [ "$__var_to_set" ]; then 1534*7323adacSDevin Teske setvar "$__var_to_set" "$__iface" 1535*7323adacSDevin Teske else 1536*7323adacSDevin Teske echo "$__iface" >&2 1537*7323adacSDevin Teske fi 1538*7323adacSDevin Teske return $SUCCESS 1539*7323adacSDevin Teske fi 1540*7323adacSDevin Teske done 1541*7323adacSDevin Teske 1542*7323adacSDevin Teske return $FAILURE 1543*7323adacSDevin Teske} 1544*7323adacSDevin Teske 1545*7323adacSDevin Teske# f_device_select_tcp 1546*7323adacSDevin Teske# 1547*7323adacSDevin Teske# Prompt the user to select network interface to use for TCP/IP access. 1548*7323adacSDevin Teske# Variables from variable.subr that can be used to script user input: 1549*7323adacSDevin Teske# 1550*7323adacSDevin Teske# VAR_NETWORK_DEVICE [Optional] 1551*7323adacSDevin Teske# Either a comma-separated list of network interfaces to try when 1552*7323adacSDevin Teske# setting up network access (e.g., "fxp0,em0") or "ANY" (case- 1553*7323adacSDevin Teske# sensitive) to indicate that the first active and configured 1554*7323adacSDevin Teske# interface is acceptable. If unset, the user is presented with a 1555*7323adacSDevin Teske# menu of all available network interfaces. 1556*7323adacSDevin Teske# 1557*7323adacSDevin Teske# Returns success if a valid network interface has been selected. 1558*7323adacSDevin Teske# 1559*7323adacSDevin Teskef_device_select_tcp() 1560*7323adacSDevin Teske{ 1561*7323adacSDevin Teske local devs dev cnt network_dev 1562*7323adacSDevin Teske f_getvar $VAR_NETWORK_DEVICE network_dev 1563*7323adacSDevin Teske 1564*7323adacSDevin Teske f_dprintf "f_device_select_tcp: %s=[%s]" \ 1565*7323adacSDevin Teske VAR_NETWORK_DEVICE "$network_dev" 1566*7323adacSDevin Teske 1567*7323adacSDevin Teske if [ "$network_dev" ]; then 1568*7323adacSDevin Teske # 1569*7323adacSDevin Teske # This can be set to several types of values. If set to ANY, 1570*7323adacSDevin Teske # scan all network devices looking for a valid link, and go 1571*7323adacSDevin Teske # with the first device found. Can also be specified as a 1572*7323adacSDevin Teske # comma delimited list, with each network device tried in 1573*7323adacSDevin Teske # order. Can also be set to a single network device. 1574*7323adacSDevin Teske # 1575*7323adacSDevin Teske [ "$network_dev" = "ANY" ] && f_device_scan_tcp network_dev 1576*7323adacSDevin Teske 1577*7323adacSDevin Teske while [ "$network_dev" ]; do 1578*7323adacSDevin Teske case "$network_dev" in 1579*7323adacSDevin Teske *,*) dev="${network_dev%%,*}" 1580*7323adacSDevin Teske network_dev="${network_dev#*,}" 1581*7323adacSDevin Teske ;; 1582*7323adacSDevin Teske *) dev="$network_dev" 1583*7323adacSDevin Teske network_dev= 1584*7323adacSDevin Teske esac 1585*7323adacSDevin Teske 1586*7323adacSDevin Teske f_device_find "$dev" $DEVICE_TYPE_NETWORK devs 1587*7323adacSDevin Teske cnt=$( set -- $devs; echo $# ) 1588*7323adacSDevin Teske 1589*7323adacSDevin Teske if [ ${cnt:=0} -gt 0 ]; then 1590*7323adacSDevin Teske dev="${devs%%[$IFS]*}" 1591*7323adacSDevin Teske f_device_dialog_tcp $dev 1592*7323adacSDevin Teske if [ $? -eq $SUCCESS ]; then 1593*7323adacSDevin Teske setvar $VAR_NETWORK_DEVICE $dev 1594*7323adacSDevin Teske return $SUCCESS 1595*7323adacSDevin Teske fi 1596*7323adacSDevin Teske fi 1597*7323adacSDevin Teske done 1598*7323adacSDevin Teske 1599*7323adacSDevin Teske f_interactive && f_dialog_msgbox "$msg_no_network_devices" 1600*7323adacSDevin Teske return $FAILURE 1601*7323adacSDevin Teske 1602*7323adacSDevin Teske fi # $network_dev 1603*7323adacSDevin Teske 1604*7323adacSDevin Teske f_device_find "" $DEVICE_TYPE_NETWORK devs 1605*7323adacSDevin Teske cnt=$( set -- $devs; echo $# ) 1606*7323adacSDevin Teske dev="${devs%%[$IFS]*}" 1607*7323adacSDevin Teske 1608*7323adacSDevin Teske f_quietly f_getvar NETWORK_CONFIGURED # for debugging info 1609*7323adacSDevin Teske if ! f_running_as_init && 1610*7323adacSDevin Teske ! [ "${NETWORK_CONFIGURED+set}" -a "$NETWORK_CONFIGURED" = "NO" ] 1611*7323adacSDevin Teske then 1612*7323adacSDevin Teske trap 'f_interrupt' SIGINT 1613*7323adacSDevin Teske if f_dialog_yesno "$msg_assume_network_is_already_configured" 1614*7323adacSDevin Teske then 1615*7323adacSDevin Teske setvar $VAR_NETWORK_DEVICE $dev 1616*7323adacSDevin Teske return $SUCCESS 1617*7323adacSDevin Teske fi 1618*7323adacSDevin Teske fi 1619*7323adacSDevin Teske 1620*7323adacSDevin Teske local retval=$SUCCESS 1621*7323adacSDevin Teske if [ ${cnt:=0} -eq 0 ]; then 1622*7323adacSDevin Teske f_dialog_msgbox "$msg_no_network_devices" 1623*7323adacSDevin Teske retval=$FAILURE 1624*7323adacSDevin Teske elif [ $cnt -eq 1 ]; then 1625*7323adacSDevin Teske f_device_dialog_tcp $dev 1626*7323adacSDevin Teske retval=$? 1627*7323adacSDevin Teske [ $retval -eq $SUCCESS ] && setvar $VAR_NETWORK_DEVICE $dev 1628*7323adacSDevin Teske else 1629*7323adacSDevin Teske local title="$msg_network_interface_information_required" 1630*7323adacSDevin Teske local prompt="$msg_please_select_ethernet_device_to_configure" 1631*7323adacSDevin Teske local hline="$hline_arrows_tab_enter" 1632*7323adacSDevin Teske 1633*7323adacSDevin Teske dev=$( f_device_menu \ 1634*7323adacSDevin Teske "$title" "$prompt" "$hline" $DEVICE_TYPE_NETWORK \ 1635*7323adacSDevin Teske "$NETWORK_DEVICE_HELPFILE" \ 1636*7323adacSDevin Teske 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD ) 1637*7323adacSDevin Teske retval=$? 1638*7323adacSDevin Teske [ "$dev" ] || return $FAILURE 1639*7323adacSDevin Teske 1640*7323adacSDevin Teske f_device_find "$dev" $DEVICE_TYPE_NETWORK devs 1641*7323adacSDevin Teske [ "$devs" ] || return $FAILURE 1642*7323adacSDevin Teske dev="${devs%%[$IFS]*}" 1643*7323adacSDevin Teske 1644*7323adacSDevin Teske f_device_dialog_tcp $dev 1645*7323adacSDevin Teske retval=$? 1646*7323adacSDevin Teske if [ $retval -eq $SUCCESS ]; then 1647*7323adacSDevin Teske f_struct_copy device_$dev device_network 1648*7323adacSDevin Teske setvar $VAR_NETWORK_DEVICE network 1649*7323adacSDevin Teske else 1650*7323adacSDevin Teske f_struct_free device_network 1651*7323adacSDevin Teske fi 1652*7323adacSDevin Teske fi 1653*7323adacSDevin Teske 1654*7323adacSDevin Teske return $retval 1655*7323adacSDevin Teske} 1656*7323adacSDevin Teske 1657*7323adacSDevin Teske# f_dialog_menu_select_tcp 1658*7323adacSDevin Teske# 1659*7323adacSDevin Teske# Like f_dialog_select_tcp() above, but do it from a menu that doesn't care 1660*7323adacSDevin Teske# about status. In other words, where f_dialog_select_tcp() will not display a 1661*7323adacSDevin Teske# menu if scripted, this function will always display the menu of available 1662*7323adacSDevin Teske# network interfaces. 1663*7323adacSDevin Teske# 1664*7323adacSDevin Teskef_dialog_menu_select_tcp() 1665*7323adacSDevin Teske{ 1666*7323adacSDevin Teske local private use_dhcp name 1667*7323adacSDevin Teske NETWORK_CONFIGURED=NO f_device_select_tcp 1668*7323adacSDevin Teske if f_struct device_network && 1669*7323adacSDevin Teske device_network get private private && 1670*7323adacSDevin Teske f_struct_copy "$private" di && 1671*7323adacSDevin Teske di get use_dhcp use_dhcp && 1672*7323adacSDevin Teske [ ! "$use_dhcp" ] && 1673*7323adacSDevin Teske device_network get name name && 1674*7323adacSDevin Teske f_yesno "$msg_would_you_like_to_bring_interface_up" "$name" 1675*7323adacSDevin Teske then 1676*7323adacSDevin Teske if ! f_device_init network; then 1677*7323adacSDevin Teske f_show_msg "$msg_initialization_of_device_failed" \ 1678*7323adacSDevin Teske "$name" 1679*7323adacSDevin Teske fi 1680*7323adacSDevin Teske fi 1681*7323adacSDevin Teske return $SUCCESS 1682*7323adacSDevin Teske} 1683*7323adacSDevin Teske 1684*7323adacSDevin Teske############################################################ MAIN 1685*7323adacSDevin Teske 1686*7323adacSDevin Teskef_dprintf "%s: Successfully loaded." media/tcpip.subr 1687*7323adacSDevin Teske 1688*7323adacSDevin Teskefi # ! $_MEDIA_TCPIP_SUBR 1689