bug fix / isipv6 complete rewrite
This commit is contained in:
103
profile.d/net.sh
103
profile.d/net.sh
@@ -206,20 +206,21 @@ isipv4()
|
|||||||
for oct in "${ip_arr[@]}"; do
|
for oct in "${ip_arr[@]}"; do
|
||||||
# Reject leading plus/minus or empty entries
|
# Reject leading plus/minus or empty entries
|
||||||
if [[ -z $oct || $oct =~ [^0-9] ]]; then
|
if [[ -z $oct || $oct =~ [^0-9] ]]; then
|
||||||
[[ -t 1 ]] && disp "The given parameter is NOT a valid IPv4."
|
[[ -t 1 ]] && disp E "The given parameter is NOT a valid IPv4."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
if (( oct > 255 )); then
|
# 10# forces base-10 so leading-zero octets (08, 09) are not read as octal
|
||||||
[[ -t 1 ]] && disp "The given parameter is NOT a valid IPv4."
|
if (( 10#$oct > 255 )); then
|
||||||
|
[[ -t 1 ]] && disp E "The given parameter is NOT a valid IPv4."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
[[ -t 1 ]] && disp "The given IPv4 is valid."
|
[[ -t 1 ]] && disp I "The given IPv4 is valid."
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[[ -t 1 ]] && disp "The given parameter is NOT a valid IPv4."
|
[[ -t 1 ]] && disp E "The given parameter is NOT a valid IPv4."
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
export -f isipv4
|
export -f isipv4
|
||||||
@@ -229,19 +230,94 @@ export -f isipv4
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Determine if parameter is a valid IPv6 address
|
# Determine if parameter is a valid IPv6 address
|
||||||
# Usage: isipv6 <ip_address>
|
# Usage: isipv6 <ip_address>
|
||||||
|
# Accepts full and "::"-compressed forms, an embedded IPv4 suffix
|
||||||
|
# (e.g. ::ffff:192.0.2.1) and an optional RFC 4007 zone id (e.g. fe80::1%eth0).
|
||||||
isipv6()
|
isipv6()
|
||||||
{
|
{
|
||||||
local ip="$1"
|
local ip="$1"
|
||||||
local regex='^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$'
|
local valid=0
|
||||||
if [[ $ip =~ $regex ]]; then
|
|
||||||
if [[ -t 1 ]]; then
|
# A single-pass validation; any failing check breaks out with valid=0.
|
||||||
disp "The given IPv6 is valid."
|
while true; do
|
||||||
|
[[ -z $ip ]] && break
|
||||||
|
|
||||||
|
# Strip an optional zone identifier (fe80::1%eth0); reject empty/multiple.
|
||||||
|
if [[ $ip == *%* ]]; then
|
||||||
|
[[ $ip == *%*%* ]] && break
|
||||||
|
[[ -z ${ip#*%} ]] && break
|
||||||
|
ip="${ip%%[%]*}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Reject ':::' and more than one '::' compression.
|
||||||
|
[[ $ip == *:::* ]] && break
|
||||||
|
local compressed=0
|
||||||
|
if [[ $ip == *::* ]]; then
|
||||||
|
[[ ${ip#*::} == *::* ]] && break
|
||||||
|
compressed=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# A lone leading/trailing ':' that is not part of a '::' is invalid.
|
||||||
|
[[ $ip == :* && $ip != ::* ]] && break
|
||||||
|
[[ $ip == *: && $ip != *:: ]] && break
|
||||||
|
|
||||||
|
# An embedded IPv4 is allowed only as the trailing 32 bits. Validate it,
|
||||||
|
# then replace it with two zero hextets so the rest is a clean hextet list.
|
||||||
|
if [[ $ip == *.* ]]; then
|
||||||
|
local v4="${ip##*:}"
|
||||||
|
[[ $v4 == *.*.*.* ]] || break
|
||||||
|
local -a oct=()
|
||||||
|
IFS='.' read -ra oct <<< "$v4"
|
||||||
|
[[ ${#oct[@]} -eq 4 ]] || break
|
||||||
|
local o v4ok=1
|
||||||
|
for o in "${oct[@]}"; do
|
||||||
|
if [[ ! $o =~ ^[0-9]{1,3}$ ]] || (( 10#$o > 255 )); then
|
||||||
|
v4ok=0
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
(( v4ok )) || break
|
||||||
|
ip="${ip%"$v4"}0:0"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Count the hextets on each side of an optional '::'.
|
||||||
|
local left right seg part total=0 ok=1
|
||||||
|
if (( compressed )); then
|
||||||
|
left="${ip%%::*}"
|
||||||
|
right="${ip#*::}"
|
||||||
|
else
|
||||||
|
left="$ip"
|
||||||
|
right=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
for seg in "$left" "$right"; do
|
||||||
|
[[ -z $seg ]] && continue
|
||||||
|
local -a parts=()
|
||||||
|
IFS=':' read -ra parts <<< "$seg"
|
||||||
|
for part in "${parts[@]}"; do
|
||||||
|
[[ $part =~ ^[0-9a-fA-F]{1,4}$ ]] || { ok=0; break; }
|
||||||
|
(( total++ ))
|
||||||
|
done
|
||||||
|
(( ok )) || break
|
||||||
|
done
|
||||||
|
(( ok )) || break
|
||||||
|
|
||||||
|
# Without '::' there must be exactly 8 hextets; with it, fewer than 8
|
||||||
|
# (the '::' expands to at least one zero hextet).
|
||||||
|
if (( compressed )); then
|
||||||
|
(( total <= 7 )) || break
|
||||||
|
else
|
||||||
|
(( total == 8 )) || break
|
||||||
|
fi
|
||||||
|
|
||||||
|
valid=1
|
||||||
|
break
|
||||||
|
done
|
||||||
|
|
||||||
|
if (( valid )); then
|
||||||
|
[[ -t 1 ]] && disp I "The given IPv6 is valid."
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
if [[ -t 1 ]]; then
|
[[ -t 1 ]] && disp E "The given parameter is not a valid IPv6."
|
||||||
disp "The given parameter is not a valid IPv6."
|
|
||||||
fi
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
export -f isipv6
|
export -f isipv6
|
||||||
@@ -256,12 +332,13 @@ urlencode()
|
|||||||
local LANG=C
|
local LANG=C
|
||||||
local str="$*"
|
local str="$*"
|
||||||
local length="${#str}"
|
local length="${#str}"
|
||||||
|
local i
|
||||||
for (( i = 0; i < length; i++ )); do
|
for (( i = 0; i < length; i++ )); do
|
||||||
local c="${str:i:1}"
|
local c="${str:i:1}"
|
||||||
case "$c" in
|
case "$c" in
|
||||||
[a-zA-Z0-9.~_-]) printf '%s' "$c" ;;
|
[a-zA-Z0-9.~_-]) printf '%s' "$c" ;;
|
||||||
' ') printf '+' ;;
|
' ') printf '+' ;;
|
||||||
*) printf '%%%02X' "'$c" #| cut -d' ' -f2 ;;
|
*) printf '%%%02X' "'$c" ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user