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