Class: IPAddress::IPv4
- Inherits:
-
Object
- Object
- IPAddress::IPv4
- Includes:
- Comparable, Enumerable, IPAddress
- Defined in:
- lib/ipaddress_2/ipv4.rb
Overview
Name
IPAddress::IPv4 - IP version 4 address manipulation library
Synopsis
require 'ipaddress'
Description
Class IPAddress::IPv4 is used to handle IPv4 type addresses.
Constant Summary collapse
- CLASSFUL =
This Hash contains the prefix values for Classful networks
Note that classes C, D and E will all have a default prefix of /24 or 255.255.255.0
{ /^0../ => 8, # Class A, from 0.0.0.0 to 127.255.255.255 /^10./ => 16, # Class B, from 128.0.0.0 to 191.255.255.255 /^110/ => 24 # Class C, D and E, from 192.0.0.0 to 255.255.255.254 }
- REGEXP =
Regular expression to match an IPv4 address
Regexp.new(/((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)/)
Constants included from IPAddress
Class Method Summary collapse
-
.extract(str) ⇒ Object
Extract an IPv4 address from a string and returns a new object.
-
.parse_classful(ip) ⇒ Object
Creates a new IPv4 address object by parsing the address in a classful way.
-
.parse_data(str, prefix = 32) ⇒ Object
Creates a new IPv4 object from binary data, like the one you get from a network stream.
-
.parse_u32(u32, prefix = 32) ⇒ Object
Creates a new IPv4 object from an unsigned 32bits 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 IPv4 object which is the result of the summarization, if possible, of the two objects.
-
#-(oth) ⇒ Object
Returns the difference between two IP addresses in unsigned int 32 bits format Example:.
-
#<=>(oth) ⇒ Object
Spaceship operator to compare IPv4 objects.
-
#[](index) ⇒ Object
(also: #octet)
Returns the octet specified by index.
-
#[]=(index, value) ⇒ Object
(also: #octet=)
Updated the octet specified at index.
-
#a? ⇒ Boolean
Checks whether the ip address belongs to a RFC 791 CLASS A network, no matter what the subnet mask is.
-
#add(oth, validating = true) ⇒ Object
Returns a new IPv4 object which is the result of advancing this IP address by a given value.
-
#address ⇒ Object
Returns the address portion of the IPv4 object as a string.
-
#advance_network(amount) ⇒ Object
Returns the network address of the n-th network succeeding this one.
-
#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.
-
#b? ⇒ Boolean
Checks whether the ip address belongs to a RFC 791 CLASS B network, no matter what the subnet mask is.
-
#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_u32 ⇒ Object
Returns the broadcast address in Unsigned 32bits format.
-
#c? ⇒ Boolean
Checks whether the ip address belongs to a RFC 791 CLASS C network, no matter what the subnet mask is.
-
#data ⇒ Object
Returns the address portion of an IPv4 object in a network byte order format.
-
#each ⇒ Object
Iterates over all the IP addresses for the given network (or IP address).
-
#each_host ⇒ Object
Iterates over all the hosts 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 IPv4 object with the first host IP address in the range.
-
#hex(space = true) ⇒ Object
(also: #to_h, #to_hex)
Returns the address portion in hex.
-
#hostpart ⇒ Object
Returns a new IPv4 object containing only the host part of this IP.
-
#hostpart_u32 ⇒ Object
Returns this address’ host part in unsigned 32bits format.
-
#hosts ⇒ Object
Returns an array with the IP addresses of all the hosts in the network.
-
#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) ⇒ IPv4
constructor
Creates a new IPv4 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 IPv4 address objects belongs to a link-local network RFC3927.
-
#loopback? ⇒ Boolean
Checks if an IPv4 address objects belongs to a loopback network RFC1122.
-
#multicast? ⇒ Boolean
Checks if an IPv4 address objects belongs to a multicast network RFC3171.
-
#netmask ⇒ Object
Returns the prefix as a string in IP format.
-
#netmask=(addr) ⇒ Object
Like IPv4#prefix=, this method allow you to change the prefix / netmask of an IP address object.
-
#network ⇒ Object
Returns a new IPv4 object with the network number for the given IP.
-
#network? ⇒ Boolean
Checks if the IP address is actually a network.
-
#network_u32 ⇒ Object
Returns the network number in Unsigned 32bits format.
-
#next_network ⇒ Object
Returns the network address of the network succeeding this one.
-
#octets ⇒ Object
Returns the address as an array of decimal values.
-
#pred ⇒ Object
Returns the predecessor to the IP address.
-
#prefix ⇒ Object
Returns the prefix portion of the IPv4 object as a IPAddress::Prefix32 object.
-
#prefix=(num) ⇒ Object
Set a new prefix number for the object.
-
#previous_network ⇒ Object
Returns the network address of the network preceeding this one.
-
#private? ⇒ Boolean
Checks if an IPv4 address objects belongs to a private network RFC1918.
-
#regress_network(amount) ⇒ Object
Returns the network address of the n-th network preceeding this one.
-
#reverse ⇒ Object
(also: #arpa)
Returns the IP address in in-addr.arpa format for DNS lookups.
-
#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.
-
#subtract(oth, validating = true) ⇒ Object
Returns a new IPv4 object which is the result of decreasing this IP address by a given value.
-
#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(e) ⇒ Object
Return a list of IP’s between @address and the supplied IP.
-
#to_ipv6 ⇒ Object
Return the ip address in a format compatible with the IPv6 Mapped IPv4 addresses.
-
#to_s ⇒ Object
Returns a string with the address portion of the IPv4 object.
-
#to_string ⇒ Object
Returns a string with the IP address in canonical form.
-
#u32 ⇒ Object
(also: #to_i, #to_u32)
Returns the address portion in unsigned 32 bits integer format.
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) ⇒ IPv4
Creates a new IPv4 address object.
An IPv4 address can be expressed in any of the following forms:
-
“10.1.1.1/24”: ip
addressandprefix. This is the common and
suggested way to create an object .
-
“10.1.1.1/255.255.255.0”: ip
addressandnetmask. Although
convenient sometimes, this format is less clear than the previous one.
-
“10.1.1.1”: if the address alone is specified, the prefix will be
set as default 32, also known as the host prefix
Examples:
# These two are the same
ip = IPAddress::IPv4.new("10.0.0.1/24")
ip = IPAddress("10.0.0.1/24")
# These two are the same
IPAddress::IPv4.new "10.0.0.1/8"
IPAddress::IPv4.new "10.0.0.1/255.0.0.0"
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/ipaddress_2/ipv4.rb', line 63 def initialize(str) raise ArgumentError, "Nil IP" unless str ip, netmask = str.split("/") # Check the ip and remove white space if IPAddress.valid_ipv4?(ip) @address = ip.strip else raise ArgumentError, "Invalid IP #{ip.inspect}" end # Check the netmask if netmask # netmask is defined netmask.strip! if netmask =~ /^\d{1,2}$/ # netmask in cidr format @prefix = Prefix32.new(netmask.to_i) elsif IPAddress.valid_ipv4_netmask?(netmask) # netmask in IP format @prefix = Prefix32.parse_netmask(netmask) else # invalid netmask raise ArgumentError, "Invalid netmask #{netmask}" end else # netmask is nil, reverting to defaul classful mask @prefix = Prefix32.new(32) end # Array formed with the IP octets @octets = @address.split(".").map{|i| i.to_i} # 32 bits interger containing the address @u32 = (@octets[0]<< 24) + (@octets[1]<< 16) + (@octets[2]<< 8) + (@octets[3]) @allocator = 0 end |
Class Method Details
.extract(str) ⇒ Object
1118 1119 1120 |
# File 'lib/ipaddress_2/ipv4.rb', line 1118 def self.extract(str) self.new REGEXP.match(str).to_s end |
.parse_classful(ip) ⇒ Object
Creates a new IPv4 address object by parsing the address in a classful way.
Classful addresses have a fixed netmask based on the class they belong to:
-
Class A, from 0.0.0.0 to 127.255.255.255
-
Class B, from 128.0.0.0 to 191.255.255.255
-
Class C, D and E, from 192.0.0.0 to 255.255.255.254
Example:
ip = IPAddress::IPv4.parse_classful "10.0.0.1"
ip.netmask
#=> "255.0.0.0"
ip.a?
#=> true
Note that classes C, D and E will all have a default prefix of /24 or 255.255.255.0
1229 1230 1231 1232 1233 1234 1235 1236 1237 |
# File 'lib/ipaddress_2/ipv4.rb', line 1229 def self.parse_classful(ip) if IPAddress.valid_ipv4?(ip) address = ip.strip else raise ArgumentError, "Invalid IP #{ip.inspect}" end prefix = CLASSFUL.find{|h,k| h === ("%.8b" % address.to_i)}.last self.new "#{address}/#{prefix}" end |
.parse_data(str, prefix = 32) ⇒ Object
1102 1103 1104 |
# File 'lib/ipaddress_2/ipv4.rb', line 1102 def self.parse_data(str, prefix=32) self.new(str.unpack("C4").join(".")+"/#{prefix}") end |
.parse_u32(u32, prefix = 32) ⇒ Object
1085 1086 1087 |
# File 'lib/ipaddress_2/ipv4.rb', line 1085 def self.parse_u32(u32, prefix=32) self.new([u32].pack("N").unpack("C4").join(".")+"/#{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("172.16.10.0/24")
ip2 = IPAddress("172.16.11.0/24")
These two networks can be expressed using only one IP address network if we change the prefix. Let Ruby do the work:
IPAddress::IPv4::summarize(ip1,ip2).to_s
#=> "172.16.10.0/23"
We note how the network “172.16.10.0/23” 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:
"172.16.0.0/16"
we would have satisfied rule #1 above, but not rule #2. So “172.16.0.0/16” 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("10.0.0.1/24")
ip2 = IPAddress("10.0.1.1/24")
ip3 = IPAddress("10.0.2.1/24")
ip4 = IPAddress("10.0.3.1/24")
IPAddress::IPv4::summarize(ip1,ip2,ip3,ip4).to_string
#=> "10.0.0.0/22",
But the following networks can’t be summarized in a single network:
ip1 = IPAddress("10.0.1.1/24")
ip2 = IPAddress("10.0.2.1/24")
ip3 = IPAddress("10.0.3.1/24")
ip4 = IPAddress("10.0.4.1/24")
IPAddress::IPv4::summarize(ip1,ip2,ip3,ip4).map{|i| i.to_string}
#=> ["10.0.1.0/24","10.0.2.0/23","10.0.4.0/24"]
1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 |
# File 'lib/ipaddress_2/ipv4.rb', line 1184 def self.summarize(*args) # one network? no need to summarize return [args.first.network] if args.size == 1 i = 0 result = args.dup.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 IPv4 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"]
910 911 912 |
# File 'lib/ipaddress_2/ipv4.rb', line 910 def +(oth) aggregate(*[self,oth].sort.map{|i| i.network}) end |
#-(oth) ⇒ Object
884 885 886 |
# File 'lib/ipaddress_2/ipv4.rb', line 884 def -(oth) return (to_u32 - oth.to_u32).abs end |
#<=>(oth) ⇒ Object
Spaceship operator to compare IPv4 objects
Comparing IPv4 addresses is useful to ordinate them into lists that match our intuitive perception of ordered IP addresses.
The first comparison criteria is the u32 value. For example, 10.100.100.1 will be considered to be less than 172.16.0.1, because, in a ordered list, we expect 10.100.100.1 to come before 172.16.0.1.
The second criteria, in case two IPv4 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 10.100.100.0/24 come before 10.100.100.0/25.
Example:
ip1 = IPAddress "10.100.100.1/8"
ip2 = IPAddress "172.16.0.1/16"
ip3 = IPAddress "10.100.100.1/16"
ip1 < ip2
#=> true
ip1 > ip3
#=> false
[ip1,ip2,ip3].sort.map{|i| i.to_string}
#=> ["10.100.100.1/8","10.100.100.1/16","172.16.0.1/16"]
566 567 568 569 570 |
# File 'lib/ipaddress_2/ipv4.rb', line 566 def <=>(oth) return nil unless oth.is_a?(self.class) return prefix <=> oth.prefix if to_u32 == oth.to_u32 to_u32 <=> oth.to_u32 end |
#[](index) ⇒ Object Also known as: octet
Returns the octet specified by index
ip = IPAddress("172.16.100.50/24")
ip[0]
#=> 172
ip[1]
#=> 16
ip[2]
#=> 100
ip[3]
#=> 50
299 300 301 |
# File 'lib/ipaddress_2/ipv4.rb', line 299 def [](index) @octets[index] end |
#[]=(index, value) ⇒ Object Also known as: octet=
Updated the octet specified at index
ip = IPAddress("172.16.100.50/24")
ip[2] = 200
#=> #<IPAddress::IPv4:0x00000000000000 @address="172.16.200.1",
#=> @prefix=32, @octets=[172, 16, 200, 1], @u32=2886780929>
313 314 315 316 |
# File 'lib/ipaddress_2/ipv4.rb', line 313 def []=(index, value) @octets[index] = value.to_i initialize("#{@octets.join('.')}/#{prefix}") end |
#a? ⇒ Boolean
Checks whether the ip address belongs to a RFC 791 CLASS A network, no matter what the subnet mask is.
Example:
ip = IPAddress("10.0.0.1/24")
ip.a?
#=> true
1017 1018 1019 |
# File 'lib/ipaddress_2/ipv4.rb', line 1017 def a? CLASSFUL.key(8) === bits end |
#add(oth, validating = true) ⇒ Object
Returns a new IPv4 object which is the result of advancing this IP address by a given value. In other words, this arithmetically adds IP addresses.
Will raise an error if the resulting address is in a different subnet, except validating is set to false.
Example:
ip = IPAddress::IPv4.new("172.16.10.1/24")
ip.add(5).to_string
#=> "172.16.10.6/24"
927 928 929 930 931 932 933 934 935 936 937 |
# File 'lib/ipaddress_2/ipv4.rb', line 927 def add(oth, validating=true) oth = oth.to_i if oth.kind_of? IPAddress::IPv4 # oth shall be integer new_obj = self.class.parse_u32(self.to_i + oth, prefix) if validating and self.network_u32 != new_obj.network_u32 raise RuntimeError, "Subnet (/#{@prefix}) is not large enough." end new_obj end |
#address ⇒ Object
Returns the address portion of the IPv4 object as a string.
ip = IPAddress("172.16.100.4/22")
ip.address
#=> "172.16.100.4"
105 106 107 |
# File 'lib/ipaddress_2/ipv4.rb', line 105 def address @address end |
#advance_network(amount) ⇒ Object
965 966 967 |
# File 'lib/ipaddress_2/ipv4.rb', line 965 def advance_network(amount) IPAddress::IPv4.parse_u32(self.network.u32 + amount*self.size, @prefix) 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.
1259 1260 1261 1262 1263 1264 1265 1266 1267 |
# File 'lib/ipaddress_2/ipv4.rb', line 1259 def allocate(skip=0) @allocator += 1 + skip next_ip = network_u32+@allocator if next_ip > broadcast_u32+1 raise StopIteration end self.class.parse_u32(network_u32+@allocator, @prefix) end |
#as_json ⇒ Object
When serializing to JSON format, just use the string representation
ip = IPAddress("172.16.100.4/22")
ip.as_json
#=> "172.16.100.4/22"
117 118 119 |
# File 'lib/ipaddress_2/ipv4.rb', line 117 def as_json to_string end |
#b? ⇒ Boolean
Checks whether the ip address belongs to a RFC 791 CLASS B network, no matter what the subnet mask is.
Example:
ip = IPAddress("172.16.10.1/24")
ip.b?
#=> true
1033 1034 1035 |
# File 'lib/ipaddress_2/ipv4.rb', line 1033 def b? CLASSFUL.key(16) === bits end |
#bits ⇒ Object
Returns the address portion of an IP in binary format, as a string containing a sequence of 0 and 1
ip = IPAddress("127.0.0.1")
ip.bits
#=> "01111111000000000000000000000001"
328 329 330 |
# File 'lib/ipaddress_2/ipv4.rb', line 328 def bits data.unpack("B*").first end |
#broadcast ⇒ Object
Returns the broadcast address for the given IP.
ip = IPAddress("172.16.10.64/24")
ip.broadcast.to_s
#=> "172.16.10.255"
340 341 342 343 344 345 346 347 348 349 |
# File 'lib/ipaddress_2/ipv4.rb', line 340 def broadcast case when prefix <= 30 self.class.parse_u32(broadcast_u32, @prefix) when prefix == 31 self.class.parse_u32(-1, @prefix) when prefix == 32 return self end end |
#broadcast_u32 ⇒ Object
Returns the broadcast address in Unsigned 32bits format
ip = IPaddress("10.0.0.1/29")
ip.broadcast_u32
#=> 167772167
636 637 638 |
# File 'lib/ipaddress_2/ipv4.rb', line 636 def broadcast_u32 network_u32 + size - 1 end |
#c? ⇒ Boolean
Checks whether the ip address belongs to a RFC 791 CLASS C network, no matter what the subnet mask is.
Example:
ip = IPAddress("192.168.1.1/30")
ip.c?
#=> true
1049 1050 1051 |
# File 'lib/ipaddress_2/ipv4.rb', line 1049 def c? CLASSFUL.key(24) === bits end |
#data ⇒ Object
Returns the address portion of an IPv4 object in a network byte order format.
ip = IPAddress("172.16.10.1/24")
ip.data
#=> "\254\020\n\001"
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
ip = IPAddress("10.1.1.0/24")
binary_data = ["Address: "].pack("a*") + ip.data
# Send binary data
a.puts binary_data
281 282 283 |
# File 'lib/ipaddress_2/ipv4.rb', line 281 def data [@u32].pack("N") end |
#each ⇒ Object
Iterates over all the IP addresses for the given network (or IP address).
The object yielded is a new IPv4 object created from the iteration.
ip = IPAddress("10.0.0.1/29")
ip.each do |i|
p i.address
end
#=> "10.0.0.0"
#=> "10.0.0.1"
#=> "10.0.0.2"
#=> "10.0.0.3"
#=> "10.0.0.4"
#=> "10.0.0.5"
#=> "10.0.0.6"
#=> "10.0.0.7"
499 500 501 502 503 |
# File 'lib/ipaddress_2/ipv4.rb', line 499 def each (network_u32..broadcast_u32).each do |i| yield self.class.parse_u32(i, @prefix) end end |
#each_host ⇒ Object
Iterates over all the hosts IP addresses for the given network (or IP address).
ip = IPAddress("10.0.0.1/29")
ip.each_host do |i|
p i.to_s
end
#=> "10.0.0.1"
#=> "10.0.0.2"
#=> "10.0.0.3"
#=> "10.0.0.4"
#=> "10.0.0.5"
#=> "10.0.0.6"
472 473 474 475 476 |
# File 'lib/ipaddress_2/ipv4.rb', line 472 def each_host (network_u32+1..broadcast_u32-1).each do |i| yield self.class.parse_u32(i, @prefix) end end |
#find_adjacent_subnet ⇒ Object
Finds the adjacent block to a subnet.
Example:
ip = IPAddress("10.0.0.0/24")
ip.find_adjacent_subnet
#=> "10.0.1.0/24"
1278 1279 1280 1281 1282 1283 1284 1285 |
# File 'lib/ipaddress_2/ipv4.rb', line 1278 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 IPv4 object with the first host IP address in the range.
Example: given the 192.168.100.0/24 network, the first host IP address is 192.168.100.1.
ip = IPAddress("192.168.100.0/24")
ip.first.to_s
#=> "192.168.100.1"
The object IP doesn’t need to be a network: the method automatically gets the network number from it
ip = IPAddress("192.168.100.50/24")
ip.first.to_s
#=> "192.168.100.1"
413 414 415 416 417 418 419 420 421 422 |
# File 'lib/ipaddress_2/ipv4.rb', line 413 def first case when prefix <= 30 self.class.parse_u32(network_u32+1, @prefix) when prefix == 31 self.class.parse_u32(network_u32, @prefix) when prefix == 32 return self end end |
#hex(space = true) ⇒ Object Also known as: to_h, to_hex
Returns the address portion in hex
ip = IPAddress("10.0.0.0")
ip.to_h
#=> 0a000000
256 257 258 |
# File 'lib/ipaddress_2/ipv4.rb', line 256 def hex(space=true) "%.4x%.4x" % [to_u32].pack("N").unpack("nn") end |
#hostpart ⇒ Object
Returns a new IPv4 object containing only the host part of this IP.
ip = IPAddress("172.16.10.64/24")
ip.hostpart.to_s
#=> "0.0.0.64"
389 390 391 |
# File 'lib/ipaddress_2/ipv4.rb', line 389 def hostpart self.class.parse_u32(hostpart_u32, 32) end |
#hostpart_u32 ⇒ Object
Returns this address’ host part in unsigned 32bits format
ip = IPAddress("10.0.0.42/24")
ip.host_u32
#=> 42
624 625 626 |
# File 'lib/ipaddress_2/ipv4.rb', line 624 def hostpart_u32 @u32 & ~@prefix.to_u32 end |
#hosts ⇒ Object
Returns an array with the IP addresses of all the hosts in the network.
ip = IPAddress("10.0.0.1/29")
ip.hosts.map {|i| i.address}
#=> ["10.0.0.1",
#=> "10.0.0.2",
#=> "10.0.0.3",
#=> "10.0.0.4",
#=> "10.0.0.5",
#=> "10.0.0.6"]
600 601 602 |
# File 'lib/ipaddress_2/ipv4.rb', line 600 def hosts to_a[1..-2] end |
#include?(oth) ⇒ Boolean
655 656 657 |
# File 'lib/ipaddress_2/ipv4.rb', line 655 def include?(oth) @prefix <= oth.prefix and network_u32 == (oth.to_u32 & @prefix.to_u32) end |
#include_all?(*others) ⇒ Boolean
671 672 673 |
# File 'lib/ipaddress_2/ipv4.rb', line 671 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("192.168.100.0/24")
ip.last.to_s
#=> "192.168.100.254"
The object IP doesn’t need to be a network: the method automatically gets the network number from it
ip = IPAddress("192.168.100.50/24")
ip.last.to_s
#=> "192.168.100.254"
445 446 447 448 449 450 451 452 453 454 |
# File 'lib/ipaddress_2/ipv4.rb', line 445 def last case when prefix <= 30 self.class.parse_u32(broadcast_u32-1, @prefix) when prefix == 31 self.class.parse_u32(broadcast_u32, @prefix) when prefix == 32 return self end end |
#link_local? ⇒ Boolean
Checks if an IPv4 address objects belongs to a link-local network RFC3927
Example:
ip = IPAddress "169.254.0.1"
ip.link_local?
#=> true
729 730 731 |
# File 'lib/ipaddress_2/ipv4.rb', line 729 def link_local? [self.class.new("169.254.0.0/16")].any? {|i| i.include? self} end |
#loopback? ⇒ Boolean
Checks if an IPv4 address objects belongs to a loopback network RFC1122
Example:
ip = IPAddress "127.0.0.1"
ip.loopback?
#=> true
715 716 717 |
# File 'lib/ipaddress_2/ipv4.rb', line 715 def loopback? [self.class.new("127.0.0.0/8")].any? {|i| i.include? self} end |
#multicast? ⇒ Boolean
Checks if an IPv4 address objects belongs to a multicast network RFC3171
Example:
ip = IPAddress "224.0.0.0/4"
ip.multicast?
#=> true
701 702 703 |
# File 'lib/ipaddress_2/ipv4.rb', line 701 def multicast? [self.class.new("224.0.0.0/4")].any? {|i| i.include? self} end |
#netmask ⇒ Object
Returns the prefix as a string in IP format
ip = IPAddress("172.16.100.4/22")
ip.netmask
#=> "255.255.252.0"
205 206 207 |
# File 'lib/ipaddress_2/ipv4.rb', line 205 def netmask @prefix.to_ip end |
#netmask=(addr) ⇒ Object
Like IPv4#prefix=, this method allow you to change the prefix / netmask of an IP address object.
ip = IPAddress("172.16.100.4")
puts ip
#=> 172.16.100.4/16
ip.netmask = "255.255.252.0"
puts ip
#=> 172.16.100.4/22
224 225 226 |
# File 'lib/ipaddress_2/ipv4.rb', line 224 def netmask=(addr) @prefix = Prefix32.parse_netmask(addr) end |
#network ⇒ Object
Returns a new IPv4 object with the network number for the given IP.
ip = IPAddress("172.16.10.64/24")
ip.network.to_s
#=> "172.16.10.0"
377 378 379 |
# File 'lib/ipaddress_2/ipv4.rb', line 377 def network self.class.parse_u32(network_u32, @prefix) end |
#network? ⇒ Boolean
364 365 366 |
# File 'lib/ipaddress_2/ipv4.rb', line 364 def network? (@prefix < 32) && (@u32 | @prefix.to_u32 == @prefix.to_u32) end |
#network_u32 ⇒ Object
Returns the network number in Unsigned 32bits format
ip = IPAddress("10.0.0.1/29")
ip.network_u32
#=> 167772160
612 613 614 |
# File 'lib/ipaddress_2/ipv4.rb', line 612 def network_u32 @u32 & @prefix.to_u32 end |
#next_network ⇒ Object
977 978 979 |
# File 'lib/ipaddress_2/ipv4.rb', line 977 def next_network advance_network 1 end |
#octets ⇒ Object
Returns the address as an array of decimal values
ip = IPAddress("172.16.100.4")
ip.octets
#=> [172, 16, 100, 4]
167 168 169 |
# File 'lib/ipaddress_2/ipv4.rb', line 167 def octets @octets end |
#pred ⇒ Object
Returns the predecessor to the IP address
Example:
ip = IPAddress("192.168.45.23/16")
ip.pred.to_string
=> "192.168.45.22/16"
530 531 532 |
# File 'lib/ipaddress_2/ipv4.rb', line 530 def pred self.class.new("#{IPAddress.ntoa(to_u32.pred % 0x100000000)}/#{prefix}") end |
#prefix ⇒ Object
Returns the prefix portion of the IPv4 object as a IPAddress::Prefix32 object
ip = IPAddress("172.16.100.4/22")
ip.prefix
#=> 22
ip.prefix.class
#=> IPAddress::Prefix32
133 134 135 |
# File 'lib/ipaddress_2/ipv4.rb', line 133 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 IPv4::parse_u32 or if the object was created using the classful mask.
ip = IPAddress("172.16.100.4")
puts ip
#=> 172.16.100.4/16
ip.prefix = 22
puts ip
#=> 172.16.100.4/22
155 156 157 |
# File 'lib/ipaddress_2/ipv4.rb', line 155 def prefix=(num) @prefix = Prefix32.new(num) end |
#previous_network ⇒ Object
1001 1002 1003 |
# File 'lib/ipaddress_2/ipv4.rb', line 1001 def previous_network regress_network 1 end |
#private? ⇒ Boolean
Checks if an IPv4 address objects belongs to a private network RFC1918
Example:
ip = IPAddress "10.1.1.1/24"
ip.private?
#=> true
685 686 687 688 689 |
# File 'lib/ipaddress_2/ipv4.rb', line 685 def private? [self.class.new("10.0.0.0/8"), self.class.new("172.16.0.0/12"), self.class.new("192.168.0.0/16")].any? {|i| i.include? self} end |
#regress_network(amount) ⇒ Object
989 990 991 |
# File 'lib/ipaddress_2/ipv4.rb', line 989 def regress_network(amount) advance_network(-amount) end |
#reverse ⇒ Object Also known as: arpa
Returns the IP address in in-addr.arpa format for DNS lookups
ip = IPAddress("172.16.100.50/24")
ip.reverse
#=> "50.100.16.172.in-addr.arpa"
742 743 744 |
# File 'lib/ipaddress_2/ipv4.rb', line 742 def reverse @octets.reverse.join(".") + ".in-addr.arpa" end |
#size ⇒ Object
Returns the number of IP addresses included in the network. It also counts the network address and the broadcast address.
ip = IPAddress("10.0.0.1/29")
ip.size
#=> 8
582 583 584 |
# File 'lib/ipaddress_2/ipv4.rb', line 582 def size 2 ** @prefix.host_prefix end |
#split(subnets = 2) ⇒ Object Also known as: /
Splits a network into different subnets
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("172.16.10.0/24")
network / 4 # implies map{|i| i.to_string}
#=> ["172.16.10.0/26",
#=> "172.16.10.64/26",
#=> "172.16.10.128/26",
#=> "172.16.10.192/26"]
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("172.16.10.0/24")
network / 3 # implies map{|i| i.to_string}
#=> ["172.16.10.0/26",
#=> "172.16.10.64/26",
#=> "172.16.10.128/25"]
Returns an array of IPv4 objects
799 800 801 802 803 804 805 806 807 808 |
# File 'lib/ipaddress_2/ipv4.rb', line 799 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.
863 864 865 866 867 868 869 870 |
# File 'lib/ipaddress_2/ipv4.rb', line 863 def subnet(subprefix) unless ((@prefix.to_i)..32).include? subprefix raise ArgumentError, "New prefix must be between #@prefix and 32" end Array.new(2**(subprefix-@prefix.to_i)) do |i| self.class.parse_u32(network_u32+(i*(2**(32-subprefix))), subprefix) end end |
#subtract(oth, validating = true) ⇒ Object
Returns a new IPv4 object which is the result of decreasing this IP address by a given value. In other words, this arithmetically subtracts IP addresses.
Will raise an error if the resulting address is in a different subnet, except validating is set to false.
Example:
ip = IPAddress::IPv4.new("172.16.10.10/24")
ip.subtract(5).to_string
#=> "172.16.10.5/24"
952 953 954 955 |
# File 'lib/ipaddress_2/ipv4.rb', line 952 def subtract(oth, validating=true) oth = oth.to_i if oth.kind_of? IPAddress::IPv4 # oth shall be integer add(-oth, validating) end |
#succ ⇒ Object Also known as: next
Returns the successor to the IP address
Example:
ip = IPAddress("192.168.45.23/16")
ip.succ.to_string
=> "192.168.45.24/16"
515 516 517 |
# File 'lib/ipaddress_2/ipv4.rb', line 515 def succ self.class.new("#{IPAddress.ntoa(to_u32.succ % 0x100000000)}/#{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("172.16.10.0/24")
you can supernet it with a new /23 prefix
ip.supernet(23).to_string
#=> "172.16.10.0/23"
However if you supernet it with a /22 prefix, the network address will change:
ip.supernet(22).to_string
#=> "172.16.8.0/22"
If new_prefix is less than 1, returns 0.0.0.0/0
835 836 837 838 839 |
# File 'lib/ipaddress_2/ipv4.rb', line 835 def supernet(new_prefix) raise ArgumentError, "New prefix must be smaller than existing prefix" if new_prefix >= @prefix.to_i return self.class.new("0.0.0.0/0") if new_prefix < 1 return self.class.new(@address+"/#{new_prefix}").network end |
#to(e) ⇒ Object
Return a list of IP’s between @address and the supplied IP
ip = IPAddress("172.16.100.51/32")
ip.to("172.16.100.100")
#=> ["172.16.100.51",
#=> "172.16.100.52",
#=> ...
#=> "172.16.100.99",
#=> "172.16.100.100"]
760 761 762 763 764 765 766 |
# File 'lib/ipaddress_2/ipv4.rb', line 760 def to(e) unless e.is_a? IPAddress::IPv4 e = IPv4.new(e) end Range.new(@u32, e.to_u32).map{|i| IPAddress.ntoa(i) } end |
#to_ipv6 ⇒ Object
Return the ip address in a format compatible with the IPv6 Mapped IPv4 addresses
Example:
ip = IPAddress("172.16.10.1/24")
ip.to_ipv6
#=> "ac10:0a01"
1064 1065 1066 |
# File 'lib/ipaddress_2/ipv4.rb', line 1064 def to_ipv6 "%.4x:%.4x" % [to_u32].pack("N").unpack("nn") end |
#to_s ⇒ Object
Returns a string with the address portion of the IPv4 object
ip = IPAddress("172.16.100.4/22")
ip.to_s
#=> "172.16.100.4"
180 181 182 |
# File 'lib/ipaddress_2/ipv4.rb', line 180 def to_s @address end |
#to_string ⇒ Object
Returns a string with the IP address in canonical form.
ip = IPAddress("172.16.100.4/22")
ip.to_string
#=> "172.16.100.4/22"
193 194 195 |
# File 'lib/ipaddress_2/ipv4.rb', line 193 def to_string "#@address/#@prefix" end |
#u32 ⇒ Object Also known as: to_i, to_u32
Returns the address portion in unsigned 32 bits integer format.
This method is identical to the C function inet_pton to create a 32 bits address family structure.
ip = IPAddress("10.0.0.0/8")
ip.to_i
#=> 167772160
241 242 243 |
# File 'lib/ipaddress_2/ipv4.rb', line 241 def u32 @u32 end |