Class: IPAddress::IPv6
- Inherits:
-
Object
- Object
- IPAddress::IPv6
- Includes:
- Comparable, Enumerable, IPAddress
- Defined in:
- lib/ipaddress_2/ipv6.rb
Overview
Name
IPAddress::IPv6 - IP version 6 address manipulation library
Synopsis
require 'ipaddress'
Description
Class IPAddress::IPv6 is used to handle IPv6 type addresses.
IPv6 addresses
IPv6 addresses are 128 bits long, in contrast with IPv4 addresses which are only 32 bits long. An IPv6 address is generally written as eight groups of four hexadecimal digits, each group representing 16 bits or two octect. For example, the following is a valid IPv6 address:
2001:0db8:0000:0000:0008:0800:200c:417a
Letters in an IPv6 address are usually written downcase, as per RFC. You can create a new IPv6 object using uppercase letters, but they will be converted.
Compression
Since IPv6 addresses are very long to write, there are some semplifications and compressions that you can use to shorten them.
-
Leading zeroes: all the leading zeroes within a group can be omitted: “0008” would become “8”
-
A string of consecutive zeroes can be replaced by the string “::”. This can be only applied once.
Using compression, the IPv6 address written above can be shorten into the following, equivalent, address
2001:db8::8:800:200c:417a
This short version is often used in human representation.
Network Mask
As we used to do with IPv4 addresses, an IPv6 address can be written using the prefix notation to specify the subnet mask:
2001:db8::8:800:200c:417a/64
The /64 part means that the first 64 bits of the address are representing the network portion, and the last 64 bits are the host portion.
Direct Known Subclasses
Defined Under Namespace
Classes: Loopback, Mapped, Unspecified
Constant Summary collapse
- IN6FORMAT =
Format string to pretty print IPv6 addresses
("%.4x:"*8).chop
Constants included from IPAddress
Class Method Summary collapse
-
.compress(str) ⇒ Object
Compress an IPv6 address in its compressed form.
-
.expand(str) ⇒ Object
Expands an IPv6 address in the canocical form.
-
.groups(str) ⇒ Object
Extract 16 bits groups from a string.
-
.parse_data(str) ⇒ Object
Creates a new IPv6 object from binary data, like the one you get from a network stream.
-
.parse_hex(hex, prefix = 128) ⇒ Object
Creates a new IPv6 object from a number expressed in hexdecimal format:.
-
.parse_u128(u128, prefix = 128) ⇒ Object
Creates a new IPv6 object from an unsigned 128 bits integer.
-
.summarize(*args) ⇒ Object
Summarization (or aggregation) is the process when two or more networks are taken together to check if a supernet, including all and only these networks, exists.
Instance Method Summary collapse
-
#+(oth) ⇒ Object
Returns a new IPv6 object which is the result of the summarization, if possible, of the two objects.
-
#<=>(oth) ⇒ Object
Spaceship operator to compare IPv6 objects.
-
#[](index) ⇒ Object
(also: #group)
Returns the 16-bits value specified by index.
-
#[]=(index, value) ⇒ Object
(also: #group=)
Updated the octet specified at index.
-
#address ⇒ Object
Returns the IPv6 address in uncompressed form:.
-
#allocate(skip = 0) ⇒ Object
Allocates a new ip from the current subnet.
-
#as_json ⇒ Object
When serializing to JSON format, just use the string representation.
-
#bits ⇒ Object
Returns the address portion of an IP in binary format, as a string containing a sequence of 0 and 1.
-
#broadcast ⇒ Object
Returns the broadcast address for the given IP.
-
#broadcast_u128 ⇒ Object
Returns the broadcast address in Unsigned 128bits format.
-
#compressed ⇒ Object
Compressed form of the IPv6 address.
-
#data ⇒ Object
Returns the address portion of an IPv6 object in a network byte order format.
-
#each ⇒ Object
Iterates over all the IP addresses for the given network (or IP address).
-
#find_adjacent_subnet ⇒ Object
Finds the adjacent block to a subnet.
-
#first ⇒ Object
Returns a new IPv6 object with the first host IP address in the range.
-
#groups ⇒ Object
Returns an array with the 16 bits groups in decimal format:.
-
#hexs ⇒ Object
Returns an array of the 16 bits groups in hexdecimal format:.
-
#include?(oth) ⇒ Boolean
Checks whether a subnet includes the given IP address.
-
#include_all?(*others) ⇒ Boolean
Checks whether a subnet includes all the given IPv4 objects.
-
#initialize(str) ⇒ IPv6
constructor
Creates a new IPv6 address object.
-
#last ⇒ Object
Like its sibling method IPv4#first, this method returns a new IPv4 object with the last host IP address in the range.
-
#link_local? ⇒ Boolean
Checks if an IPv6 address objects belongs to a link-local network RFC4291.
-
#literal ⇒ Object
Literal version of the IPv6 address.
-
#loopback? ⇒ Boolean
Returns true if the address is a loopback address.
-
#mapped? ⇒ Boolean
Returns true if the address is a mapped address.
-
#network ⇒ Object
Returns a new IPv6 object with the network number for the given IP.
-
#network? ⇒ Boolean
True if the IPv6 address is a network.
-
#network_u128 ⇒ Object
Returns the network number in Unsigned 128bits format.
-
#pred ⇒ Object
Returns the predecessor to the IP address.
-
#prefix ⇒ Object
Returns an instance of the prefix object.
-
#prefix=(num) ⇒ Object
Set a new prefix number for the object.
-
#reverse ⇒ Object
(also: #arpa)
Returns the IPv6 address in a DNS reverse lookup string, as per RFC3172 and RFC2874.
-
#size ⇒ Object
Returns the number of IP addresses included in the network.
-
#split(subnets = 2) ⇒ Object
(also: #/)
Splits a network into different subnets.
-
#subnet(subprefix) ⇒ Object
This method implements the subnetting function similar to the one described in RFC3531.
-
#succ ⇒ Object
(also: #next)
Returns the successor to the IP address.
-
#supernet(new_prefix) ⇒ Object
Returns a new IPv4 object from the supernetting of the instance network.
-
#to_hex ⇒ Object
Returns a Base16 number representing the IPv6 address.
-
#to_i ⇒ Object
(also: #to_u128)
Returns a decimal format (unsigned 128 bit) of the IPv6 address.
-
#to_s ⇒ Object
Returns the IPv6 address in a human readable form, using the compressed address.
-
#to_string ⇒ Object
Returns the IPv6 address in a human readable form, using the compressed address.
-
#to_string_uncompressed ⇒ Object
Unlike its counterpart IPv6#to_string method, IPv6#to_string_uncompressed returns the whole IPv6 address and prefix in an uncompressed form.
-
#unique_local? ⇒ Boolean
Checks if an IPv6 address objects belongs to a unique-local network RFC4193.
-
#unspecified? ⇒ Boolean
Returns true if the address is an unspecified address.
Methods included from IPAddress
demongoize, deprecate, evolve, #ipv4?, #ipv6?, mongoize, #mongoize, ntoa, parse, valid?, valid_ip?, valid_ipv4?, valid_ipv4_netmask?, valid_ipv4_subnet?, valid_ipv6?, valid_ipv6_subnet?
Constructor Details
#initialize(str) ⇒ IPv6
Creates a new IPv6 address object.
An IPv6 address can be expressed in any of the following forms:
-
“2001:0db8:0000:0000:0008:0800:200C:417A”: IPv6 address with no compression
-
“2001:db8:0:0:8:800:200C:417A”: IPv6 address with leading zeros compression
-
“2001:db8::8:800:200C:417A”: IPv6 address with full compression
In all these 3 cases, a new IPv6 address object will be created, using the default subnet mask /128
You can also specify the subnet mask as with IPv4 addresses:
ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/ipaddress_2/ipv6.rb', line 89 def initialize(str) raise ArgumentError, "Nil IP" unless 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 else raise ArgumentError, "Invalid IP #{ip.inspect}" end @prefix = Prefix128.new(netmask ? netmask : 128) @allocator = 0 end |
Class Method Details
.compress(str) ⇒ Object
Compress an IPv6 address in its compressed form
IPAddress::IPv6.compress "2001:0DB8:0000:CD30:0000:0000:0000:0000"
#=> "2001:db8:0:cd30::"
802 803 804 |
# File 'lib/ipaddress_2/ipv6.rb', line 802 def self.compress(str) self.new(str).compressed end |
.expand(str) ⇒ Object
Expands an IPv6 address in the canocical form
IPAddress::IPv6. "2001:0DB8:0:CD30::"
#=> "2001:0DB8:0000:CD30:0000:0000:0000:0000"
792 793 794 |
# File 'lib/ipaddress_2/ipv6.rb', line 792 def self.(str) self.new(str).address end |
.groups(str) ⇒ Object
Extract 16 bits groups from a string
851 852 853 854 855 856 857 858 |
# File 'lib/ipaddress_2/ipv6.rb', line 851 def self.groups(str) l, r = if str =~ /^(.*)::(.*)$/ [$1,$2].map {|i| i.split ":"} else [str.split(":"),[]] end (l + Array.new(8-l.size-r.size, '0') + r).map {|i| i.hex} end |
.parse_data(str) ⇒ Object
Creates a new IPv6 object from binary data, like the one you get from a network stream.
For example, on a network stream the IP
"2001:db8::8:800:200c:417a"
is represented with the binary data
" \001\r\270\000\000\000\000\000\b\b\000 \fAz"
With that data you can create a new IPv6 object:
ip6 = IPAddress::IPv6::parse_data " \001\r\270\000\000\000\000\000\b\b\000 \fAz"
ip6.prefix = 64
ip6.to_s
#=> "2001:db8::8:800:200c:417a/64"
880 881 882 |
# File 'lib/ipaddress_2/ipv6.rb', line 880 def self.parse_data(str) self.new(IN6FORMAT % str.unpack("n8")) end |
.parse_hex(hex, prefix = 128) ⇒ Object
Creates a new IPv6 object from a number expressed in hexdecimal format:
ip6 = IPAddress::IPv6::parse_hex("20010db80000000000080800200c417a")
ip6.prefix = 64
ip6.to_string
#=> "2001:db8::8:800:200c:417a/64"
The prefix parameter is optional:
ip6 = IPAddress::IPv6::parse_hex("20010db80000000000080800200c417a", 64)
ip6.to_string
#=> "2001:db8::8:800:200c:417a/64"
923 924 925 |
# File 'lib/ipaddress_2/ipv6.rb', line 923 def self.parse_hex(hex, prefix=128) self.parse_u128(hex.hex, prefix) end |
.parse_u128(u128, prefix = 128) ⇒ Object
Creates a new IPv6 object from an unsigned 128 bits integer.
ip6 = IPAddress::IPv6::parse_u128(42540766411282592856906245548098208122)
ip6.prefix = 64
ip6.to_string
#=> "2001:db8::8:800:200c:417a/64"
The prefix parameter is optional:
ip6 = IPAddress::IPv6::parse_u128(42540766411282592856906245548098208122, 64)
ip6.to_string
#=> "2001:db8::8:800:200c:417a/64"
901 902 903 904 |
# File 'lib/ipaddress_2/ipv6.rb', line 901 def self.parse_u128(u128, prefix=128) str = IN6FORMAT % (0..7).map{|i| (u128>>(112-16*i))&0xffff} self.new(str + "/#{prefix}") end |
.summarize(*args) ⇒ Object
Summarization (or aggregation) is the process when two or more networks are taken together to check if a supernet, including all and only these networks, exists. If it exists then this supernet is called the summarized (or aggregated) network.
It is very important to understand that summarization can only occur if there are no holes in the aggregated network, or, in other words, if the given networks fill completely the address space of the supernet. So the two rules are:
1) The aggregate network must contain all the IP addresses of the
original networks;
2) The aggregate network must contain only the IP addresses of the
original networks;
A few examples will help clarify the above. Let’s consider for instance the following two networks:
ip1 = IPAddress("2001:db8:8:800::1/64")
ip2 = IPAddress("2001:0db8:8:801::2/64")
These two networks can be expressed using only one IP address network if we change the prefix. Let Ruby do the work:
IPAddress::IPv6::summarize(ip1,ip2).to_s
#=> "2001:db8:8:800::/63"
We note how the network “2001:db8:8:800::/63” includes all the addresses specified in the above networks, and (more important) includes ONLY those addresses.
If we summarized ip1 and ip2 with the following network:
"2001:db8::/32"
we would have satisfied rule #1 above, but not rule #2. So “2001:db8::/32” is not an aggregate network for ip1 and ip2.
If it’s not possible to compute a single aggregated network for all the original networks, the method returns an array with all the aggregate networks found. For example, the following four networks can be aggregated in a single /22:
ip1 = IPAddress("2001:db8:8:800::1/64")
ip2 = IPAddress("2001:db8:8:801::1/64")
ip3 = IPAddress("2001:db8:8:802::1/64")
ip4 = IPAddress("2001:db8:8:803::1/64")
IPAddress::IPv6::summarize(ip1,ip2,ip3,ip4).to_string
#=> "2001:db8:8:800::/62",
But the following networks can’t be summarized in a single network:
ip1 = IPAddress("2001:db8:8:801::1/64")
ip2 = IPAddress("2001:db8:8:802::1/64")
ip3 = IPAddress("2001:db8:8:803::1/64")
ip4 = IPAddress("2001:db8:8:804::1/64")
IPAddress::IPv6::summarize(ip1,ip2,ip3,ip4).map{|i| i.to_string}
#=> ["2001:db8:8:801::/64","2001:db8:8:802::/63","2001:db8:8:804::/64"]
989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 |
# File 'lib/ipaddress_2/ipv6.rb', line 989 def self.summarize(*args) # one network? no need to summarize return [args.first.network] if args.size == 1 args_size = args.size i = 0 result = args.sort.map{|ip| ip.network} while i < result.size-1 sum = result[i] + result[i+1] result[i..i+1] = sum.first if sum.size == 1 i += 1 end result.flatten! if result.size == args_size # nothing more to summarize return result else # keep on summarizing return self.summarize(*result) end end |
Instance Method Details
#+(oth) ⇒ Object
Returns a new IPv6 object which is the result of the summarization, if possible, of the two objects
Example:
ip1 = IPAddress("172.16.10.1/24")
ip2 = IPAddress("172.16.11.2/24")
p (ip1 + ip2).map {|i| i.to_string}
#=> ["172.16.10.0/23"]
If the networks are not contiguous, returns the two network numbers from the objects
ip1 = IPAddress("10.0.0.1/24")
ip2 = IPAddress("10.0.2.1/24")
p (ip1 + ip2).map {|i| i.to_string}
#=> ["10.0.0.0/24","10.0.2.0/24"]
610 611 612 |
# File 'lib/ipaddress_2/ipv6.rb', line 610 def +(oth) aggregate(*[self,oth].sort.map{|i| i.network}) end |
#<=>(oth) ⇒ Object
Spaceship operator to compare IPv6 objects
Comparing IPv6 addresses is useful to ordinate them into lists that match our intuitive perception of ordered IP addresses.
The first comparison criteria is the u128 value. For example, 2001:db8:1::1 will be considered to be less than 2001:db8:2::1, because, in a ordered list, we expect 2001:db8:1::1 to come before 2001:db8:2::1.
The second criteria, in case two IPv6 objects have identical addresses, is the prefix. An higher prefix will be considered greater than a lower prefix. This is because we expect to see 2001:db8:1::1/64 come before 2001:db8:1::1/65
Example:
ip1 = IPAddress "2001:db8:1::1/64"
ip2 = IPAddress "2001:db8:2::1/64"
ip3 = IPAddress "2001:db8:1::1/65"
ip1 < ip2
#=> true
ip1 < ip3
#=> false
[ip1,ip2,ip3].sort.map{|i| i.to_string}
#=> ["2001:db8:1::1/64","2001:db8:1::1/65","2001:db8:2::1/64"]
767 768 769 770 771 |
# File 'lib/ipaddress_2/ipv6.rb', line 767 def <=>(oth) return nil unless oth.is_a?(self.class) return prefix <=> oth.prefix if to_u128 == oth.to_u128 to_u128 <=> oth.to_u128 end |
#[](index) ⇒ Object Also known as: group
Returns the 16-bits value specified by index
ip = IPAddress("2001:db8::8:800:200c:417a/64")
ip[0]
#=> 8193
ip[1]
#=> 3512
ip[2]
#=> 0
ip[3]
#=> 0
320 321 322 |
# File 'lib/ipaddress_2/ipv6.rb', line 320 def [](index) @groups[index] end |
#[]=(index, value) ⇒ Object Also known as: group=
Updated the octet specified at index
328 329 330 331 |
# File 'lib/ipaddress_2/ipv6.rb', line 328 def []=(index, value) @groups[index] = value initialize("#{IN6FORMAT % @groups}/#{prefix}") end |
#address ⇒ Object
Returns the IPv6 address in uncompressed form:
ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
ip6.address
#=> "2001:0db8:0000:0000:0008:0800:200c:417a"
118 119 120 |
# File 'lib/ipaddress_2/ipv6.rb', line 118 def address @address end |
#allocate(skip = 0) ⇒ Object
Allocates a new ip from the current subnet. Optional skip parameter can be used to skip addresses.
Will raise StopIteration exception when all addresses have been allocated
Example:
ip = IPAddress("10.0.0.0/24")
ip.allocate
#=> "10.0.0.1/24"
ip.allocate
#=> "10.0.0.2/24"
ip.allocate(2)
#=> "10.0.0.5/24"
Uses an internal @allocator which tracks the state of allocated addresses.
1032 1033 1034 1035 1036 1037 1038 1039 1040 |
# File 'lib/ipaddress_2/ipv6.rb', line 1032 def allocate(skip=0) @allocator += 1 + skip next_ip = network_u128+@allocator if next_ip > broadcast_u128 raise StopIteration end self.class.parse_u128(next_ip, @prefix) end |
#as_json ⇒ Object
When serializing to JSON format, just use the string representation
ip = IPAddress "2001:db8::8:800:200c:417a/64"
ip.as_json
#=> "2001:db8::8:800:200c:417a/64"
129 130 131 |
# File 'lib/ipaddress_2/ipv6.rb', line 129 def as_json to_string end |
#bits ⇒ Object
Returns the address portion of an IP in binary format, as a string containing a sequence of 0 and 1
ip6 = IPAddress("2001:db8::8:800:200c:417a")
ip6.bits
#=> "0010000000000001000011011011100000 [...] "
782 783 784 |
# File 'lib/ipaddress_2/ipv6.rb', line 782 def bits data.unpack("B*").first end |
#broadcast ⇒ Object
Returns the broadcast address for the given IP. As this is IPv6 it is just the last IP
ip = IPAddress("2001:db8:8:800::/64")
ip.broadcast.to_s
#=> "2001:db8:8:800::"
840 841 842 843 844 845 846 |
# File 'lib/ipaddress_2/ipv6.rb', line 840 def broadcast if prefix == 128 return self else IPAddress::IPv6::parse_u128(broadcast_u128) end end |
#broadcast_u128 ⇒ Object
Returns the broadcast address in Unsigned 128bits format
ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
ip6.broadcast_u128
#=> 42540766411282592875350729025363378175
Please note that there is no Broadcast concept in IPv6 addresses as in IPv4 addresses, and this method is just an helper to other functions.
469 470 471 |
# File 'lib/ipaddress_2/ipv6.rb', line 469 def broadcast_u128 network_u128 + size - 1 end |
#compressed ⇒ Object
Compressed form of the IPv6 address
ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
ip6.compressed
#=> "2001:db8::8:800:200c:417a"
529 530 531 |
# File 'lib/ipaddress_2/ipv6.rb', line 529 def compressed @compressed end |
#data ⇒ Object
Returns the address portion of an IPv6 object in a network byte order format.
ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
ip6.data
#=> " \001\r\270\000\000\000\000\000\b\b\000 \fAz"
It is usually used to include an IP address in a data packet to be sent over a socket
a = Socket.open(params) # socket details here
ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
binary_data = ["Address: "].pack("a*") + ip.data
# Send binary data
a.puts binary_data
365 366 367 |
# File 'lib/ipaddress_2/ipv6.rb', line 365 def data @groups.pack("n8") end |
#each ⇒ Object
Iterates over all the IP addresses for the given network (or IP address).
The object yielded is a new IPv6 object created from the iteration.
ip6 = IPAddress("2001:db8::4/125")
ip6.each do |i|
p i.compressed
end
#=> "2001:db8::"
#=> "2001:db8::1"
#=> "2001:db8::2"
#=> "2001:db8::3"
#=> "2001:db8::4"
#=> "2001:db8::5"
#=> "2001:db8::6"
#=> "2001:db8::7"
WARNING: if the host portion is very large, this method can be very slow and possibly hang your system!
700 701 702 703 704 |
# File 'lib/ipaddress_2/ipv6.rb', line 700 def each (network_u128..broadcast_u128).each do |i| yield self.class.parse_u128(i, @prefix) end end |
#find_adjacent_subnet ⇒ Object
Finds the adjacent block to a subnet.
Example:
ip = IPAddress("2001:db8::/32")
ip.find_adjacent_subnet
#=> "2001:db9::/32"
1051 1052 1053 1054 1055 1056 1057 1058 |
# File 'lib/ipaddress_2/ipv6.rb', line 1051 def find_adjacent_subnet return false if prefix == 0 current_subnet = to_string self.prefix = @prefix - 1 adjacent_subnet = (split.map{|i| i.to_string} - [current_subnet])[0] self.prefix = @prefix + 1 return adjacent_subnet end |
#first ⇒ Object
Returns a new IPv6 object with the first host IP address in the range.
Example: given the 2001:db8:8:800::/64 network, the first
- host IP address is 2001:db8:8:800
-
ip = IPAddress(“2001:db8:8:800::/64”)
ip.first.to_s
#=> "2001:db8:8:800::"
The object IP doesn’t need to be a network: the method automatically gets the network number from it
ip = IPAddress("2001:db8:9:800::2/64")
ip.first.to_s
#=> "2001:db8:9:800::"
269 270 271 272 273 274 275 |
# File 'lib/ipaddress_2/ipv6.rb', line 269 def first if prefix == 128 return self else IPAddress::IPv6::parse_u128(network_u128) end end |
#groups ⇒ Object
Returns an array with the 16 bits groups in decimal format:
ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
ip6.groups
#=> [8193, 3512, 0, 0, 8, 2048, 8204, 16762]
142 143 144 |
# File 'lib/ipaddress_2/ipv6.rb', line 142 def groups @groups end |
#hexs ⇒ Object
Returns an array of the 16 bits groups in hexdecimal format:
ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
ip6.hexs
#=> ["2001", "0db8", "0000", "0000", "0008", "0800", "200c", "417a"]
Not to be confused with the similar IPv6#to_hex method.
380 381 382 |
# File 'lib/ipaddress_2/ipv6.rb', line 380 def hexs @address.split(":") end |
#include?(oth) ⇒ Boolean
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
501 502 503 |
# File 'lib/ipaddress_2/ipv6.rb', line 501 def include?(oth) @prefix <= oth.prefix and network_u128 == self.class.new(oth.address+"/#@prefix").network_u128 end |
#include_all?(*others) ⇒ Boolean
Checks whether a subnet includes all the given IPv4 objects.
ip = IPAddress("2001:db8:8:800::1/64")
addr1 = IPAddress("2001:db8:8:800::2/64")
addr2 = IPAddress("2001:db8:8:800::8/64")
ip.include_all?(addr1,addr2)
#=> true
517 518 519 |
# File 'lib/ipaddress_2/ipv6.rb', line 517 def include_all?(*others) others.all? {|oth| include?(oth)} end |
#last ⇒ Object
Like its sibling method IPv4#first, this method returns a new IPv4 object with the last host IP address in the range.
Example: given the 192.168.100.0/24 network, the last host IP address is 192.168.100.254
ip = IPAddress("2001:db8:8:800::/64")
ip.last.to_s
#=> "2001:db8:8:800:ffff:ffff:ffff:ffff"
The object IP doesn’t need to be a network: the method automatically gets the network number from it
ip = IPAddress("2001:db8:9:800::2/64")
ip.last.to_s
#=> "2001:db8:9:800:ffff:ffff:ffff:ffff"
298 299 300 301 302 303 304 |
# File 'lib/ipaddress_2/ipv6.rb', line 298 def last if prefix == 128 return self else IPAddress::IPv6::parse_u128(broadcast_u128) end end |
#link_local? ⇒ Boolean
Checks if an IPv6 address objects belongs to a link-local network RFC4291
Example:
ip = IPAddress "fe80::1"
ip.link_local?
#=> true
561 562 563 |
# File 'lib/ipaddress_2/ipv6.rb', line 561 def link_local? [self.class.new("fe80::/10")].any? {|i| i.include? self} end |
#literal ⇒ Object
Literal version of the IPv6 address
ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
ip6.literal
#=> "2001-0db8-0000-0000-0008-0800-200c-417a.ipv6-literal.net"
814 815 816 |
# File 'lib/ipaddress_2/ipv6.rb', line 814 def literal @address.gsub(":","-") + ".ipv6-literal.net" end |
#loopback? ⇒ Boolean
Returns true if the address is a loopback address
See IPAddress::IPv6::Loopback for more information
547 548 549 |
# File 'lib/ipaddress_2/ipv6.rb', line 547 def loopback? @prefix == 128 and @compressed == "::1" end |
#mapped? ⇒ Boolean
Returns true if the address is a mapped address
See IPAddress::IPv6::Mapped for more information
584 585 586 |
# File 'lib/ipaddress_2/ipv6.rb', line 584 def mapped? to_u128 >> 32 == 0xffff end |
#network ⇒ Object
Returns a new IPv6 object with the network number for the given IP.
ip = IPAddress "2001:db8:1:1:1:1:1:1/32"
ip.network.to_string
#=> "2001:db8::/32"
827 828 829 |
# File 'lib/ipaddress_2/ipv6.rb', line 827 def network self.class.parse_u128(network_u128, @prefix) end |
#network? ⇒ Boolean
True if the IPv6 address is a network
ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
ip6.network?
#=> false
ip6 = IPAddress "2001:db8:8:800::/64"
ip6.network?
#=> true
245 246 247 |
# File 'lib/ipaddress_2/ipv6.rb', line 245 def network? to_u128 | @prefix.to_u128 == @prefix.to_u128 end |
#network_u128 ⇒ Object
Returns the network number in Unsigned 128bits format
ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
ip6.network_u128
#=> 42540766411282592856903984951653826560
453 454 455 |
# File 'lib/ipaddress_2/ipv6.rb', line 453 def network_u128 to_u128 & @prefix.to_u128 end |
#pred ⇒ Object
Returns the predecessor to the IP address
Example:
ip6 = IPAddress("2001:db8::8:800:200c:417a/64")
ip6.pred.to_string
=> "2001:db8::8:800:200c:4179/64"
731 732 733 |
# File 'lib/ipaddress_2/ipv6.rb', line 731 def pred IPAddress::IPv6.parse_u128(to_u128.pred, prefix) end |
#prefix ⇒ Object
Returns an instance of the prefix object
ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
ip6.prefix
#=> 64
154 155 156 |
# File 'lib/ipaddress_2/ipv6.rb', line 154 def prefix @prefix end |
#prefix=(num) ⇒ Object
Set a new prefix number for the object
This is useful if you want to change the prefix to an object created with IPv6::parse_u128 or if the object was created using the default prefix of 128 bits.
ip6 = IPAddress("2001:db8::8:800:200c:417a")
puts ip6.to_string
#=> "2001:db8::8:800:200c:417a/128"
ip6.prefix = 64
puts ip6.to_string
#=> "2001:db8::8:800:200c:417a/64"
175 176 177 |
# File 'lib/ipaddress_2/ipv6.rb', line 175 def prefix=(num) @prefix = Prefix128.new(num) end |
#reverse ⇒ Object Also known as: arpa
Returns the IPv6 address in a DNS reverse lookup string, as per RFC3172 and RFC2874.
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"
393 394 395 |
# File 'lib/ipaddress_2/ipv6.rb', line 393 def reverse to_hex.reverse.gsub(/./){|c| c+"."} + "ip6.arpa" end |
#size ⇒ Object
Returns the number of IP addresses included in the network. It also counts the network address and the broadcast address.
ip6 = IPAddress("2001:db8::8:800:200c:417a/64")
ip6.size
#=> 18446744073709551616
483 484 485 |
# File 'lib/ipaddress_2/ipv6.rb', line 483 def size 2 ** @prefix.host_prefix end |
#split(subnets = 2) ⇒ Object Also known as: /
Splits a network into different subnets
NOTE: Will allow you to split past /64 against RFC 5375
If the IP Address is a network, it can be divided into multiple networks. If self is not a network, this method will calculate the network from the IP and then subnet it.
If subnets is an power of two number, the resulting networks will be divided evenly from the supernet.
network = IPAddress("2001:db8:8::/48")
network / 4 # implies map{|i| i.to_string}
#=> ["2001:db8:8::/50",
#=> "2001:db8:8:4000::/50",
#=> "2001:db8:8:8000::/50",
#=> "2001:db8:8:c000::/50"]
If num is any other number, the supernet will be divided into some networks with a even number of hosts and other networks with the remaining addresses.
network = IPAddress("2001:db8:8::/48")
network / 3 # implies map{|i| i.to_string}
#=> ["2001:db8:8::/50",
#=> "2001:db8:8:4000::/50",
#=> "2001:db8:8:8000::/49"]
Returns an array of IPv6 objects
433 434 435 436 437 438 439 440 441 442 |
# File 'lib/ipaddress_2/ipv6.rb', line 433 def split(subnets=2) unless (1..(2**@prefix.host_prefix)).include? subnets raise ArgumentError, "Value #{subnets} out of range" end networks = subnet(newprefix(subnets)) until networks.size == subnets networks = sum_first_found(networks) end return networks end |
#subnet(subprefix) ⇒ Object
This method implements the subnetting function similar to the one described in RFC3531.
By specifying a new prefix, the method calculates the network number for the given IPv4 object and calculates the subnets associated to the new prefix.
For example, given the following network:
ip = IPAddress "172.16.10.0/24"
we can calculate the subnets with a /26 prefix
ip.subnet(26).map{&:to_string)
#=> ["172.16.10.0/26", "172.16.10.64/26",
"172.16.10.128/26", "172.16.10.192/26"]
The resulting number of subnets will of course always be a power of two.
666 667 668 669 670 671 672 673 |
# File 'lib/ipaddress_2/ipv6.rb', line 666 def subnet(subprefix) unless ((@prefix.to_i)..128).include? subprefix raise ArgumentError, "New prefix must be between #@prefix and 128" end Array.new(2**(subprefix-@prefix.to_i)) do |i| self.class.parse_u128(network_u128+(i*(2**(128-subprefix))), subprefix) end end |
#succ ⇒ Object Also known as: next
Returns the successor to the IP address
Example:
ip6 = IPAddress("2001:db8::8:800:200c:417a/64")
ip6.succ.to_string
=> "2001:db8::8:800:200c:417b/64"
716 717 718 |
# File 'lib/ipaddress_2/ipv6.rb', line 716 def succ IPAddress::IPv6.parse_u128(to_u128.succ, prefix) end |
#supernet(new_prefix) ⇒ Object
Returns a new IPv4 object from the supernetting of the instance network.
Supernetting is similar to subnetting, except that you getting as a result a network with a smaller prefix (bigger host space). For example, given the network
ip = IPAddress("2001:db8:8:800::1/64")
you can supernet it with a new /32 prefix
ip.supernet(32).to_string
#=> "2001:db8::/32"
However if you supernet it with a /22 prefix, the network address will change:
ip.supernet(22).to_string
#=> "2001:c00::/22"
If new_prefix is less than 1, returns 0000:0000:0000:0000:0000:0000:0000:0000/0
638 639 640 641 642 |
# File 'lib/ipaddress_2/ipv6.rb', line 638 def supernet(new_prefix) raise ArgumentError, "New prefix must be smaller than existing prefix" if new_prefix >= @prefix.to_i return self.class.new("0000:0000:0000:0000:0000:0000:0000:0000/0") if new_prefix < 1 return self.class.new(@address+"/#{new_prefix}").network end |
#to_hex ⇒ Object
Returns a Base16 number representing the IPv6 address
ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
ip6.to_hex
#=> "20010db80000000000080800200c417a"
343 344 345 |
# File 'lib/ipaddress_2/ipv6.rb', line 343 def to_hex hexs.join("") end |
#to_i ⇒ Object Also known as: to_u128
Returns a decimal format (unsigned 128 bit) of the IPv6 address
ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
ip6.to_i
#=> 42540766411282592856906245548098208122
227 228 229 |
# File 'lib/ipaddress_2/ipv6.rb', line 227 def to_i to_hex.hex end |
#to_s ⇒ Object
Returns the IPv6 address in a human readable form, using the compressed address.
ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
ip6.to_s
#=> "2001:db8::8:800:200c:417a"
214 215 216 |
# File 'lib/ipaddress_2/ipv6.rb', line 214 def to_s @compressed end |
#to_string ⇒ Object
Returns the IPv6 address in a human readable form, using the compressed address.
ip6 = IPAddress "2001:0db8:0000:0000:0008:0800:200c:417a/64"
ip6.to_string
#=> "2001:db8::8:800:200c:417a/64"
201 202 203 |
# File 'lib/ipaddress_2/ipv6.rb', line 201 def to_string "#@compressed/#@prefix" end |
#to_string_uncompressed ⇒ Object
Unlike its counterpart IPv6#to_string method, IPv6#to_string_uncompressed returns the whole IPv6 address and prefix in an uncompressed form
ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
ip6.to_string_uncompressed
#=> "2001:0db8:0000:0000:0008:0800:200c:417a/64"
188 189 190 |
# File 'lib/ipaddress_2/ipv6.rb', line 188 def to_string_uncompressed "#@address/#@prefix" end |
#unique_local? ⇒ Boolean
Checks if an IPv6 address objects belongs to a unique-local network RFC4193
Example:
ip = IPAddress "fc00::1"
ip.unique_local?
#=> true
575 576 577 |
# File 'lib/ipaddress_2/ipv6.rb', line 575 def unique_local? [self.class.new("fc00::/7")].any? {|i| i.include? self} end |
#unspecified? ⇒ Boolean
Returns true if the address is an unspecified address
See IPAddress::IPv6::Unspecified for more information
538 539 540 |
# File 'lib/ipaddress_2/ipv6.rb', line 538 def unspecified? @prefix == 128 and @compressed == "::" end |