summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordteske <dteske@FreeBSD.org>2012-11-25 10:37:10 +0000
committerdteske <dteske@FreeBSD.org>2012-11-25 10:37:10 +0000
commit048b91382659be160e79eb9adfed66923c00a572 (patch)
treeeb6dd105503c5c1ff1b71de1f4f489071115c3fc
parent5d9b3f284b13ac492326e05f6ba4c00e98adf05c (diff)
downloadFreeBSD-src-048b91382659be160e79eb9adfed66923c00a572.zip
FreeBSD-src-048b91382659be160e79eb9adfed66923c00a572.tar.gz
Split IP address validation routines and improve error detection for dotted-
quad notation in IPv6 addresses. Approved by: adrian (co-mentor) (implicit)
-rw-r--r--usr.sbin/bsdconfig/networking/include/messages.subr8
-rw-r--r--usr.sbin/bsdconfig/networking/share/ipaddr.subr120
2 files changed, 91 insertions, 37 deletions
diff --git a/usr.sbin/bsdconfig/networking/include/messages.subr b/usr.sbin/bsdconfig/networking/include/messages.subr
index d430505..3a3d1bc 100644
--- a/usr.sbin/bsdconfig/networking/include/messages.subr
+++ b/usr.sbin/bsdconfig/networking/include/messages.subr
@@ -55,10 +55,10 @@ msg_hostname_label_is_null="ERROR! One or more individual labels within the host
msg_hostname_label_starts_or_ends_with_hyphen="ERROR! One or more individual labels within the hostname\n(separated by dots) starts or ends with a hyphen (hyphens\nare allowed, but a label cannot begin or end with a hyphen).\n\nInvalid Hostname: %s"
msg_internal_error_nsindex_value="FATAL! dialog_input_nameserver_edit_awk: variable\nnsindex must be a whole positive integer greater-\nthan or equal-to zero.\n\nInvalid nsindex: %s"
msg_ipaddr4="ipaddr"
-msg_ipv4_addr_octet_contains_invalid_chars="ERROR! One or more individual octets within the IP address\n(separated by dots) contains one or more invalid characters.\nOctets must contain only the characters 0-9.\n\nInvalid IP Address: %s"
-msg_ipv4_addr_octet_exceeds_max_value="ERROR! One or more individual octets within the IP address\n(separated by dots) exceeds the maximum of 255.\n\nInvalid IP Address: %s"
-msg_ipv4_addr_octet_is_null="ERROR! One or more individual octets within the IP address\n(separated by dots) are null and/or missing.\n\nInvalid IP Address: %s"
-msg_ipv4_addr_octet_missing_or_extra="ERROR! The IP address entered has either too few (less than\nfour) or too many (more than four) octets, separated by dots.\n\nInvalid IP Address: %s"
+msg_ipv4_addr_octet_contains_invalid_chars="ERROR! One or more individual octets within the IPv4 address\n(separated by dots) contains one or more invalid characters.\nOctets must contain only the characters 0-9.\n\nInvalid IP Address: %s"
+msg_ipv4_addr_octet_exceeds_max_value="ERROR! One or more individual octets within the IPv4 address\n(separated by dots) exceeds the maximum of 255.\n\nInvalid IP Address: %s"
+msg_ipv4_addr_octet_is_null="ERROR! One or more individual octets within the IPv4 address\n(separated by dots) are null and/or missing.\n\nInvalid IP Address: %s"
+msg_ipv4_addr_octet_missing_or_extra="ERROR! The IPv4 address entered has either too few (less than\nfour) or too many (more than four) octets, separated by dots.\n\nInvalid IP Address: %s"
msg_ipv6_addr_segment_contains_invalid_chars="ERROR! One or more individual segments within the IP address\n(separated by colons) contains one or more invalid characters.\nSegments must contain only combinations of the characters 0-9,\nA-F, or a-f.\n\nInvalid IPv6 Address: %s"
msg_ipv6_addr_segment_contains_too_many_chars="ERROR! One or more individual segments within the IP address\n(separated by colons) exceeds the length of 4 hex-digits.\n\nInvalid IPv6 Address: %s"
msg_ipv6_addr_too_few_or_extra_segments="ERROR! The IP address entered has either too few (less than 3), too\nmany (more than 8), or not enough segments, separated by colons.\n\nInvalid IPv6 Address: %s"
diff --git a/usr.sbin/bsdconfig/networking/share/ipaddr.subr b/usr.sbin/bsdconfig/networking/share/ipaddr.subr
index c64cfb9..23e2218 100644
--- a/usr.sbin/bsdconfig/networking/share/ipaddr.subr
+++ b/usr.sbin/bsdconfig/networking/share/ipaddr.subr
@@ -60,7 +60,7 @@ f_ifconfig_inet()
'
}
-# f_dialog_validate_ipaddr $ipaddr
+# f_validate_ipaddr $ipaddr
#
# Returns zero if the given argument (an IP address) is of the proper format.
#
@@ -73,10 +73,7 @@ f_ifconfig_inet()
# maximum of 255 (or 2^8, being an octet comprised of 8 bits).
# 4 The IP address has either too few or too many octets.
#
-# If the IP address is determined to be invalid, the appropriate error will be
-# displayed using the f_dialog_msgbox function.
-#
-f_dialog_validate_ipaddr()
+f_validate_ipaddr()
{
local ip="$1"
@@ -106,12 +103,19 @@ f_dialog_validate_ipaddr()
[ $noctets -eq 4 ] || exit 4
)
+}
+# f_dialog_iperror $error $ipaddr
+#
+# Display a msgbox with the appropriate error message for an error returned by
+# f_validate_ipaddr above.
+#
+f_dialog_iperror()
+{
+ local error="$1" ip="$2"
- #
- # Produce an appropriate error message if necessary.
- #
- local retval=$?
- case $retval in
+ [ ${error:-0} -ne 0 ] || return $SUCCESS
+
+ case "$error" in
1) f_dialog_msgbox "$( printf \
"$msg_ipv4_addr_octet_contains_invalid_chars" "$ip" )";;
2) f_dialog_msgbox "$( printf \
@@ -121,34 +125,57 @@ f_dialog_validate_ipaddr()
4) f_dialog_msgbox "$( printf \
"$msg_ipv4_addr_octet_missing_or_extra" "$ip" )";;
esac
+}
+
+# f_dialog_validate_ipaddr $ipaddr
+#
+# Returns zero if the given argument (an IP address) is of the proper format.
+#
+# If the IP address is determined to be invalid, the appropriate error will be
+# displayed using the f_dialog_iperror function above.
+#
+f_dialog_validate_ipaddr()
+{
+ local ip="$1"
+
+ f_validate_ipaddr "$ip"
+ local retval=$?
+
+ # Produce an appropriate error message if necessary.
+ [ $retval -eq $SUCCESS ] || f_dialog_iperror $retval "$ip"
return $retval
}
-# f_dialog_validate_ipaddr6 $ipv6_addr
+# f_validate_ipaddr6 $ipv6_addr
#
# Returns zero if the given argument (an IPv6 address) is of the proper format.
#
# The return status for invalid IP address is one of:
# 1 One or more individual segments within the IP address
# (separated by colons) contains one or more invalid characters.
-# 2 More than two segments within the IP address are null or the
-# the second null segment is not at the end of the address.
-# 3 One or more individual segments within the IP address exceeds
-# the word length of 32-bits (segments are always hexadecimal).
-# 4 The IP address has either too few or too many segments.
-# 5 The IPv4 address at the end of the IPv6 address is invalid.
+# Segments must contain only combinations of the characters 0-9,
+# A-F, or a-f.
+# 2 Too many/incorrect null segments. A single null segment is
+# allowed within the IP address (separated by colons) but not
+# allowed at the beginning or end (unless a double-null segment;
+# i.e., "::*" or "*::").
+# 3 One or more individual segments within the IP address
+# (separated by colons) exceeds the length of 4 hex-digits.
+# 4 The IP address entered has either too few (less than 3), too
+# many (more than 8), or not enough segments, separated by
+# colons.
+# 5* The IPv4 address at the end of the IPv6 address is invalid.
+# * When there is an error with the dotted-quad IPv4 address at the
+# end of the IPv6 address, the return value of 5 is OR'd with a
+# bit-shifted (<< 4) return of f_validate_ipaddr.
#
-# If the IP address is determined to be invalid, the appropriate error will be
-# displayed using the f_dialog_msgbox function.
-#
-f_dialog_validate_ipaddr6()
+f_validate_ipaddr6()
{
local ip="$1"
( # Operate within a sub-shell to protect the parent environment
- oldIFS="$IFS"
IFS=":" # Split on `colon'
set -- $ip:
@@ -216,9 +243,8 @@ f_dialog_validate_ipaddr6()
contains_ipv4_segment=1
# Validate the IPv4 address
- IFS="$oldIFS"
- f_dialog_validate_ipaddr "$segment" || exit 5
- IFS=":"
+ f_validate_ipaddr "$segment" ||
+ exit $(( 5 | $? << 4 ))
;;
*)
# Segment characters are all valid but too many
@@ -254,12 +280,20 @@ f_dialog_validate_ipaddr6()
exit $SUCCESS
)
+}
- #
- # Produce an appropriate error message if necessary.
- #
- local retval=$?
- case $retval in
+# f_dialog_ip6error $error $ipv6_addr
+#
+# Display a msgbox with the appropriate error message for an error returned by
+# f_validate_ipaddr6 above.
+#
+f_dialog_ip6error()
+{
+ local error="$1" ip="$2"
+
+ [ ${error:-0} -ne 0 ] || return $SUCCESS
+
+ case "$error" in
1) f_dialog_msgbox "$( printf \
"$msg_ipv6_addr_segment_contains_invalid_chars" "$ip" )";;
2) f_dialog_msgbox "$( printf \
@@ -268,10 +302,30 @@ f_dialog_validate_ipaddr6()
"$msg_ipv6_addr_segment_contains_too_many_chars" "$ip" )";;
4) f_dialog_msgbox "$( printf \
"$msg_ipv6_addr_too_few_or_extra_segments" "$ip" )";;
- 5) : IPv4 at the end of IPv6 address is invalid ;;
- # Don't display an error because f_dialog_validate_ipaddr
- # already displayed one for the particular issue encountered.
+ *)
+ if [ $(( $error & 0xF )) -eq 5 ]; then
+ # IPv4 at the end of IPv6 address is invalid
+ f_dialog_iperror $(( $error >> 4 )) "$ip"
+ fi
esac
+}
+
+# f_dialog_validate_ipaddr6 $ipv6_addr
+#
+# Returns zero if the given argument (an IPv6 address) is of the proper format.
+#
+# If the IP address is determined to be invalid, the appropriate error will be
+# displayed using the f_dialog_ip6error function above.
+#
+f_dialog_validate_ipaddr6()
+{
+ local ip="$1"
+
+ f_validate_ipaddr6 "$ip"
+ local retval=$?
+
+ # Produce an appropriate error message if necessary.
+ [ $retval -eq $SUCCESS ] || f_dialog_ip6error $retval "$ip"
return $retval
}
OpenPOWER on IntegriCloud