#!/bin/sh -efu

if [ -z "${__included_shell_ip_address-}" ]; then
__included_shell_ip_address=1

# Regexp for single byte
readonly regex_byte='([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])'

# Regexp for 4-byte address
readonly regex_ipaddr="$regexp_byte(\.$regexp_byte){3}"

# Regexp for IPv4 address
#
# (http://en.wikipedia.org/wiki/IP_address)
#
# Some first-octet values have special meanings:
#
# * First octet 127 represents the local computer, regardless of what network
#   it is really in. This is useful when testing internal operations.
#
# * First octet 224 and above are reserved for special purposes such as
#   multicasting.
#
# Octets 0 and 255 are not acceptable values in some situations, but 0 can be used
# as the second and/or third octet (e.g. 10.2.0.100).
#
readonly __regex_fbyte='([1-9][0-9]?|1[0-9][0-9]|2[01][0-9]|22[0-3])'
readonly __regex_sbyte='([1]?[0-9][0-9]?|2[0-4][0-9]|25[0-4])'
readonly __regex_lbyte='([1]?[0-9][0-9]?|2[0-4][0-9]|25[0-4])'

readonly regex_ipv4="${__regex_fbyte}(\.${__regex_sbyte}){2}\.${__regex_lbyte}"

# Checks that given option value is a valid IPv4 address.
valid_ipv4() {
	local ipaddr="$1"
	local i=0 byte

	byte="${ipaddr##*.}"
	ipaddr="${ipaddr%.$byte}"

	[ "$byte" -gt 0 -a "$byte" -lt 255 ] 2>/dev/null ||
			return 1

	while [ $i -lt 3 ]; do
		byte="${ipaddr##*.}"

		[ "$byte" != "$ipaddr" ] ||
			break

		ipaddr="${ipaddr%.$byte}"

		[ "$byte" -ge 0 -a "$byte" -lt 255 ] 2>/dev/null ||
			return 1

		i=$(($i+1))
	done

	[ $i -eq 2 -a \
	  "$byte" -ne 127 -a "$byte" -gt 0 -a "$byte" -lt 224 ] 2>/dev/null ||
		return 1
}

fi #__included_shell_ip_address
