lib/ipaddress/ipv6.rb in ipaddress-0.6.0 vs lib/ipaddress/ipv6.rb in ipaddress-0.7.0
- old
+ new
@@ -86,10 +86,14 @@
#
# ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
#
def initialize(str)
ip, netmask = str.split("/")
+
+ if str =~ /:.+\./
+ raise ArgumentError, "Please use #{self.class}::Mapped for IPv4 mapped addresses"
+ end
if IPAddress.valid_ipv6?(ip)
@groups = self.class.groups(ip)
@address = IN6FORMAT % @groups
@compressed = compress_address
@@ -99,11 +103,10 @@
@prefix = Prefix128.new(netmask ? netmask : 128)
end # def initialize
-
#
# Returns the IPv6 address in uncompressed form:
#
# ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
#
@@ -301,22 +304,51 @@
#
# Returns the IPv6 address in a DNS reverse lookup
# string, as per RFC3172 and RFC2874.
#
- # ip6 = IPAddress "3ffe:505:2::f")
+ # ip6 = IPAddress "3ffe:505:2::f"
#
# ip6.reverse
# #=> "f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.5.0.5.0.e.f.f.3.ip6.arpa"
#
def reverse
to_hex.reverse.gsub(/./){|c| c+"."} + "ip6.arpa"
end
alias_method :arpa, :reverse
-
#
+ # Returns the network number in Unsigned 128bits format
+ #
+ # ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
+ #
+ # ip6.network_u128
+ # #=> 42540766411282592856903984951653826560
+ #
+ def network_u128
+ to_u128 & @prefix.to_u128
+ end
+
+ #
+ # Checks whether a subnet includes the given IP address.
+ #
+ # Example:
+ #
+ # ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
+ # addr = IPAddress "2001:db8::8:800:200c:1/128"
+ #
+ # ip6.include? addr
+ # #=> true
+ #
+ # ip6.include? IPAddress("2001:db8:1::8:800:200c:417a/76")
+ # #=> false
+ #
+ def include?(oth)
+ @prefix <= oth.prefix and network_u128 == self.class.new(oth.address+"/#@prefix").network_u128
+ end
+
+ #
# Compressed form of the IPv6 address
#
# ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
#
# ip6.compressed
@@ -348,11 +380,11 @@
# Returns true if the address is a mapped address
#
# See IPAddress::IPv6::Mapped for more information
#
def mapped?
- false
+ to_u128 >> 32 == 0xffff
end
#
# Returns the address portion of an IP in binary format,
# as a string containing a sequence of 0 and 1
@@ -672,29 +704,44 @@
# Access the internal IPv4 address
attr_reader :ipv4
#
- # Creates a new IPv6 unspecified address
+ # Creates a new IPv6 IPv4-mapped address
#
# ip6 = IPAddress::IPv6::Mapped.new "::ffff:172.16.10.1/128"
#
+ # ipv6.ipv4.class
+ # #=> IPAddress::IPv4
+ #
+ # An IPv6 IPv4-mapped address can also be created using the
+ # IPv6 only format of the address:
+ #
+ # ip6 = IPAddress::IPv6::Mapped.new "::0d01:4403"
+ #
+ # ip6.to_s
+ # #=> "::ffff:13.1.68.3"
+ #
def initialize(str)
string, netmask = str.split("/")
- @ipv4 = IPAddress::IPv4.extract(string)
+ if string =~ /\./ # IPv4 in dotted decimal form
+ @ipv4 = IPAddress::IPv4.extract(string)
+ else # IPv4 in hex form
+ groups = IPAddress::IPv6.groups(string)
+ @ipv4 = IPAddress::IPv4.parse_u32((groups[-2]<< 16)+groups[-1])
+ end
super("::ffff:#{@ipv4.to_ipv6}/#{netmask}")
end
#
# Similar to IPv6#to_s, but prints out the IPv4 address
# in dotted decimal format
#
- #
# ip6 = IPAddress "::ffff:172.16.10.1/128"
#
# ip6.to_s
- # #=> "::FFFF:172.16.10.1"
+ # #=> "::ffff:172.16.10.1"
#
def to_s
"::ffff:#{@ipv4.address}"
end
@@ -703,11 +750,11 @@
# in dotted decimal format
#
#
# ip6 = IPAddress "::ffff:172.16.10.1/128"
#
- # ip6.to_s
- # #=> "::FFFF:172.16.10.1/128"
+ # ip6.to_string
+ # #=> "::ffff:172.16.10.1/128"
#
def to_string
"::ffff:#{@ipv4.address}/#@prefix"
end