1if [ ! "$_NETWORKING_IPADDR_SUBR" ]; then _NETWORKING_IPADDR_SUBR=1 2# 3# Copyright (c) 2006-2013 Devin Teske 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25# SUCH DAMAGE. 26# 27# $FreeBSD$ 28# 29############################################################ INCLUDES 30 31BSDCFG_SHARE="/usr/share/bsdconfig" 32. $BSDCFG_SHARE/common.subr || exit 1 33f_dprintf "%s: loading includes..." networking/ipaddr.subr 34f_include $BSDCFG_SHARE/dialog.subr 35f_include $BSDCFG_SHARE/networking/common.subr 36f_include $BSDCFG_SHARE/strings.subr 37 38BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="120.networking" 39f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr 40 41############################################################ FUNCTIONS 42 43# f_dialog_iperror $error $ipaddr 44# 45# Display a msgbox with the appropriate error message for an error returned by 46# the f_validate_ipaddr function. 47# 48f_dialog_iperror() 49{ 50 local error="$1" ip="$2" 51 52 [ ${error:-0} -ne 0 ] || return $SUCCESS 53 54 case "$error" in 55 1) f_show_msg "$msg_ipv4_addr_octet_contains_invalid_chars" "$ip" ;; 56 2) f_show_msg "$msg_ipv4_addr_octet_is_null" "$ip" ;; 57 3) f_show_msg "$msg_ipv4_addr_octet_exceeds_max_value" "$ip" ;; 58 4) f_show_msg "$msg_ipv4_addr_octet_missing_or_extra" "$ip" ;; 59 esac 60} 61 62# f_dialog_validate_ipaddr $ipaddr 63# 64# Returns zero if the given argument (an IP address) is of the proper format. 65# 66# If the IP address is determined to be invalid, the appropriate error will be 67# displayed using the f_dialog_iperror function above. 68# 69f_dialog_validate_ipaddr() 70{ 71 local ip="$1" 72 73 f_validate_ipaddr "$ip" 74 local retval=$? 75 76 # Produce an appropriate error message if necessary. 77 [ $retval -eq $SUCCESS ] || f_dialog_iperror $retval "$ip" 78 79 return $retval 80} 81 82# f_dialog_ip6error $error $ipv6_addr 83# 84# Display a msgbox with the appropriate error message for an error returned by 85# the f_validate_ipaddr6 function above. 86# 87f_dialog_ip6error() 88{ 89 local error="$1" ip="$2" 90 91 [ ${error:-0} -ne 0 ] || return $SUCCESS 92 93 case "$error" in 94 1) f_show_msg "$msg_ipv6_addr_segment_contains_invalid_chars" "$ip" ;; 95 2) f_show_msg "$msg_ipv6_addr_too_many_null_segments" "$ip" ;; 96 3) f_show_msg "$msg_ipv6_addr_segment_contains_too_many_chars" "$ip" ;; 97 4) f_show_msg "$msg_ipv6_addr_too_few_or_extra_segments" "$ip" ;; 98 *) 99 if [ $(( $error & 0xF )) -eq 5 ]; then 100 # IPv4 at the end of IPv6 address is invalid 101 f_dialog_iperror $(( $error >> 4 )) "$ip" 102 fi 103 esac 104} 105 106# f_dialog_validate_ipaddr6 $ipv6_addr 107# 108# Returns zero if the given argument (an IPv6 address) is of the proper format. 109# 110# If the IP address is determined to be invalid, the appropriate error will be 111# displayed using the f_dialog_ip6error function above. 112# 113f_dialog_validate_ipaddr6() 114{ 115 local ip="$1" 116 117 f_validate_ipaddr6 "$ip" 118 local retval=$? 119 120 # Produce an appropriate error message if necessary. 121 [ $retval -eq $SUCCESS ] || f_dialog_ip6error $retval "$ip" 122 123 return $retval 124} 125 126# f_dialog_input_ipaddr $interface $ipaddr 127# 128# Allows the user to edit a given IP address. If the user does not cancel or 129# press ESC, the $ipaddr environment variable will hold the newly-configured 130# value upon return. 131# 132# Optionally, the user can enter the format "IP_ADDRESS/NBITS" to set the 133# netmask at the same time as the IP address. If such a format is entered by 134# the user, the $netmask environment variable will hold the newly-configured 135# netmask upon return. 136# 137f_dialog_input_ipaddr() 138{ 139 local interface="$1" _ipaddr="$2" _input 140 141 # 142 # Return with-error when there are NFS-mounts currently active. If the 143 # IP address is changed while NFS-exported directories are mounted, the 144 # system may hang (if any NFS mounts are using that interface). 145 # 146 if f_nfs_mounted && ! f_jailed; then 147 local setting="$( printf "$msg_current_ipaddr" \ 148 "$interface" "$_ipaddr" )" 149 f_noyes "$msg_nfs_mounts_may_cause_hang" "$setting" || 150 return $DIALOG_CANCEL 151 fi 152 153 local msg="$( printf "$msg_please_enter_new_ip_addr" "$interface" )" 154 155 # 156 # Loop until the user provides taint-free input. 157 # 158 local retval 159 while :; do 160 # 161 # Return error status if: 162 # - User has either pressed ESC or chosen Cancel/No 163 # - User has not made any changes to the given value 164 # 165 f_dialog_input _input "$msg" "$_ipaddr" \ 166 "$hline_num_punc_tab_enter" || return $? 167 [ "$_ipaddr" = "$_input" ] && return $DIALOG_CANCEL 168 169 # Return success if NULL value was entered 170 [ "$_input" ] || return $DIALOG_OK 171 172 # Take only the first "word" of the user's input 173 _ipaddr="$_input" 174 _ipaddr="${_ipaddr%%[$IFS]*}" 175 176 # Taint-check the user's input 177 f_dialog_validate_ipaddr "${_ipaddr%%/*}" && break 178 done 179 180 # 181 # Support the syntax: IP_ADDRESS/NBITS 182 # 183 local _netmask="" 184 case "$_ipaddr" in 185 */*) 186 local nbits="${_ipaddr#*/}" n=0 187 _ipaddr="${_ipaddr%%/*}" 188 189 # 190 # Taint-check $nbits to be (a) a positive whole-integer, 191 # and (b) to be less than or equal to 32. Otherwise, set 192 # $n so that the below loop never executes. 193 # 194 ( f_isinteger "$nbits" && [ $nbits -ge 0 -a $nbits -le 32 ] ) \ 195 || n=4 196 197 while [ $n -lt 4 ]; do 198 _netmask="$_netmask${_netmask:+.}$(( 199 (65280 >> ($nbits - 8 * $n) & 255) 200 * ((8*$n) < $nbits & $nbits <= (8*($n+1))) 201 + 255 * ($nbits > (8*($n+1))) 202 ))" 203 n=$(( $n + 1 )) 204 done 205 ;; 206 esac 207 208 ipaddr="$_ipaddr" 209 [ "$_netmask" ] && netmask="$_netmask" 210 211 return $DIALOG_OK 212} 213 214############################################################ MAIN 215 216f_dprintf "%s: Successfully loaded." networking/ipaddr.subr 217 218fi # ! $_NETWORKING_IPADDR_SUBR 219