module UsefulUtilities::IP
Provides a bunch of convinient methods to deal with ip addresses The module rely on stdlib ipaddr
Constants
- IPV4
- IPV6
- IPVERSIONS
- MAX_NET_MASK_IPV4
- MAX_NET_MASK_IPV6
- MIN_NET_MASK
- PRIVATE_RANGE_10_END
integer representing ip '10.255.255.255', end of '10.0.0.0/8'
- PRIVATE_RANGE_10_START
integer representing ip '10.0.0.0', start of '10.0.0.0/8'
- PRIVATE_RANGE_172_END
integer representing ip '172.31.255.255', end of '172.16.0.0/12'
- PRIVATE_RANGE_172_START
integer representing ip '172.16.0.0', start of '172.16.0.0/12'
- PRIVATE_RANGE_192_END
integer representing ip '192.168.255.255', end of '192.168.0.0/16'
- PRIVATE_RANGE_192_START
integer representing ip '192.168.0.0', start of '192.168.0.0/16'
- PRIVATE_RANGE_FC_END
integer representing ip 'fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', end of 'fc00::/7'
- PRIVATE_RANGE_FC_START
integer representing ip 'fc00::', start of 'fc00::/7'
- ZERO_IP_INTEGER
Public Instance Methods
@param network_mask [Integer] @param version [Integer] @return [Boolean] ArgumentError raises if version is not equal 4 or 6. @example
UsefulUtilities::IP.acceptable_network_mask?('not int', version: 4) #=> false UsefulUtilities::IP.acceptable_network_mask?(24, version: 4) #=> true
# File lib/useful_utilities/ip.rb, line 177 def acceptable_network_mask?(network_mask, version:) return false unless network_mask.is_a? Integer network_mask >= MIN_NET_MASK && network_mask <= max_network_mask(version) end
@param address [Integer] @param version. If version is not equal 4 or 6 ArgumentError raises. If supplied address can not be converted into ip address string then ArgumentError raises. @return string as human readable ip address. @example
UsefulUtilities::IP.integer_to_ip_string(1,version: 4) #=> '0.0.0.1' UsefulUtilities::IP.integer_to_ip_string(1,version: 6) #=> '::1'
# File lib/useful_utilities/ip.rb, line 97 def integer_to_ip_string(address, version:) unless address.is_a? Integer raise ArgumentError, 'Supplied address is not integer!' end IPAddr.new(address, ip_address_family(version)).to_s rescue IPAddr::InvalidAddressError, IPAddr::AddressFamilyError raise ArgumentError, 'Invalid address!' end
@param ip_string [String] @return integer representation of supplied ip string. ArgumentError raises if ip string can not be parsed as ip address. @example
UsefulUtilities::IP.ip_string_to_integer('0.0.0.2') #=> 2 UsefulUtilities::IP.ip_string_to_integer('::2') #=> 2
# File lib/useful_utilities/ip.rb, line 113 def ip_string_to_integer(ip_string) IPAddr.new(ip_string).to_i rescue IPAddr::InvalidAddressError, IPAddr::AddressFamilyError raise ArgumentError, 'Invalid ip address string supplied!' end
@param ip_string [String] @return array of 2 elements, the first: integer representation of supplied ip string, the second: version of ip protocol 4 or 6. ArgumentError raises if ip string can not be parsed as ip address. @example
UsefulUtilities::IP.ip_string_to_integer_with_version('0.0.0.1') #=> [1, 4] UsefulUtilities::IP.ip_string_to_integer_with_version('::1') #=> [1, 6]
# File lib/useful_utilities/ip.rb, line 127 def ip_string_to_integer_with_version(ip_string) ip = IPAddr.new(ip_string) version = IPV4 if ip.ipv4? version = IPV6 if ip.ipv6? [ip.to_i, version] rescue IPAddr::InvalidAddressError, IPAddr::AddressFamilyError raise ArgumentError, 'Invalid ip address string supplied!' end
@param ip_string [String] @param network_mask [Integer] @return [String] value representing network address derived from supplied ip address and it's network mask @example
UsefulUtilities::IP.network_address('10.10.15.33', 24) #=> "10.10.15.0"
# File lib/useful_utilities/ip.rb, line 143 def network_address(ip_string, network_mask) ip = IPAddr.new(ip_string) version = if ip.ipv4? IPV4 elsif ip.ipv6? IPV6 else raise ArgumentError, 'Unsupported ip address version!' end unless acceptable_network_mask?(network_mask, version: version) raise ArgumentError, "Invalid network mask: '#{network_mask}' for address: '#{ip_string}'" end ip_network_address = IPAddr.new(ZERO_IP_INTEGER, ip_address_family(version)) .~ .<<(max_network_mask(version) - network_mask) .&(ip) ip_network_address.to_s rescue IPAddr::InvalidAddressError, IPAddr::AddressFamilyError raise ArgumentError, 'Invalid ip address string supplied!' end
@param ip_string [String] @return [Boolean] true if ip_string represent private ip address. If ip_sting is non-parsable ip address ArgumentError raises. It is a wrapper on the private? method of IPAddr class instance. IPv4 addresses in 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16 as defined in RFC 1918 and IPv6 Unique Local Addresses in fc00::/7 as defined in RFC 4193 are considered private. @example
UsefulUtilities::IP.private_ip?('10.10.10.10') #=> true UsefulUtilities::IP.private_ip?('8.10.10.10') #=> false
# File lib/useful_utilities/ip.rb, line 77 def private_ip?(ip_string) ip = IPAddr.new(ip_string) # starting from ruby 2.5.0 an IPAddr instance has built-in private? method # use the built-in method if exists return ip.private? if ip.respond_to?(:private?) check_private_ip(ip) rescue IPAddr::InvalidAddressError, IPAddr::AddressFamilyError raise ArgumentError, 'Invalid ip address string supplied!' end
@param ip_string [String] @return [Boolean] true if supplied string is parsable ip address string and false otherwise @example
UsefulUtilities::IP.valid_ip('10.10.0.1') #=> true UsefulUtilities::IP.valid_ip('non-parsable-ip') #=> false
# File lib/useful_utilities/ip.rb, line 60 def valid_ip?(ip_string) IPAddr.new(ip_string) true rescue IPAddr::InvalidAddressError, IPAddr::AddressFamilyError false end
Private Instance Methods
# File lib/useful_utilities/ip.rb, line 203 def check_private_ip(ip) return true if ip.ipv4? && in_private_ipv4?(ip.to_i) return true if ip.ipv6? && in_private_ipv6?(ip.to_i) false end
# File lib/useful_utilities/ip.rb, line 210 def in_private_ipv4?(integer_ip) [ (PRIVATE_RANGE_10_START..PRIVATE_RANGE_10_END), (PRIVATE_RANGE_172_START..PRIVATE_RANGE_172_END), (PRIVATE_RANGE_192_START..PRIVATE_RANGE_192_END) ].any? { |range| range.include?(integer_ip) } end
# File lib/useful_utilities/ip.rb, line 218 def in_private_ipv6?(integer_ip) (PRIVATE_RANGE_FC_START..PRIVATE_RANGE_FC_END).include?(integer_ip) end
# File lib/useful_utilities/ip.rb, line 185 def ip_address_family(ip_version) return Socket::AF_INET if ip_version == IPV4 return Socket::AF_INET6 if ip_version == IPV6 raise ArgumentError, 'Unsupported ip address version! '\ "Supported argument values: #{IPV4} or #{IPV6}." end
# File lib/useful_utilities/ip.rb, line 194 def max_network_mask(ip_version) return MAX_NET_MASK_IPV4 if ip_version == IPV4 return MAX_NET_MASK_IPV6 if ip_version == IPV6 raise ArgumentError, 'Unsupported version supplied! '\ "Supported version values: #{IPV4} or #{IPV6}." end