lib/ipaddress/ipv4.rb in ipaddress-0.8.0 vs lib/ipaddress/ipv4.rb in ipaddress-0.8.2
- old
+ new
@@ -229,10 +229,25 @@
end
alias_method :to_i, :u32
alias_method :to_u32, :u32
#
+ # Returns the address portion in
+ # hex
+ #
+ # ip = IPAddress("10.0.0.0")
+ #
+ # ip.to_h
+ # #=> 0a000000
+ #
+ def hex(space=true)
+ "%.4x%.4x" % [to_u32].pack("N").unpack("nn")
+ end
+ alias_method :to_h, :hex
+ alias_method :to_hex, :hex
+
+ #
# Returns the address portion of an IPv4 object
# in a network byte order format.
#
# ip = IPAddress("172.16.10.1/24")
#
@@ -269,10 +284,25 @@
#
def [](index)
@octets[index]
end
alias_method :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>
+ #
+ def []=(index, value)
+ @octets[index] = value.to_i
+ initialize("#{@octets.join('.')}/#{prefix}")
+ end
+ alias_method :octet=, :[]=
#
# Returns the address portion of an IP in binary format,
# as a string containing a sequence of 0 and 1
#
@@ -292,11 +322,18 @@
#
# ip.broadcast.to_s
# #=> "172.16.10.255"
#
def broadcast
- self.class.parse_u32(broadcast_u32, @prefix)
+ 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
#
# Checks if the IP address is actually a network
#
@@ -309,11 +346,11 @@
#
# ip.network?
# #=> true
#
def network?
- @u32 | @prefix.to_u32 == @prefix.to_u32
+ (@prefix < 32) && (@u32 | @prefix.to_u32 == @prefix.to_u32)
end
#
# Returns a new IPv4 object with the network number
# for the given IP.
@@ -346,11 +383,18 @@
#
# ip.first.to_s
# #=> "192.168.100.1"
#
def first
- self.class.parse_u32(network_u32+1, @prefix)
+ 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
#
# Like its sibling method IPv4#first, this method
# returns a new IPv4 object with the
@@ -371,11 +415,18 @@
#
# ip.last.to_s
# #=> "192.168.100.254"
#
def last
- self.class.parse_u32(broadcast_u32-1, @prefix)
+ 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
#
# Iterates over all the hosts IP addresses for the given
# network (or IP address).
@@ -568,10 +619,52 @@
self.class.new("172.16.0.0/12"),
self.class.new("192.168.0.0/16")].any? {|i| i.include? self}
end
#
+ # Checks if an IPv4 address objects belongs
+ # to a multicast network RFC3171
+ #
+ # Example:
+ #
+ # ip = IPAddress "224.0.0.0/4"
+ # ip.multicast?
+ # #=> true
+ #
+ def multicast?
+ [self.class.new("224.0.0.0/4")].any? {|i| i.include? self}
+ end
+
+ #
+ # Checks if an IPv4 address objects belongs
+ # to a multicast network RFC3171
+ #
+ # Example:
+ #
+ # ip = IPAddress "224.0.0.0/4"
+ # ip.multicast?
+ # #=> true
+ #
+ def multicast?
+ [self.class.new("224.0.0.0/4")].any? {|i| i.include? self}
+ end
+
+ #
+ # Checks if an IPv4 address objects belongs
+ # to a loopback network RFC1122
+ #
+ # Example:
+ #
+ # ip = IPAddress "127.0.0.1"
+ # ip.loopback?
+ # #=> true
+ #
+ def loopback?
+ [self.class.new("127.0.0.0/8")].any? {|i| i.include? self}
+ end
+
+ #
# Returns the IP address in in-addr.arpa format
# for DNS lookups
#
# ip = IPAddress("172.16.100.50/24")
#
@@ -582,10 +675,30 @@
@octets.reverse.join(".") + ".in-addr.arpa"
end
alias_method :arpa, :reverse
#
+ # 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"]
+ #
+ 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
+ #
# 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
@@ -596,24 +709,24 @@
#
# 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"]
+ # #=> "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"]
+ # #=> "172.16.10.64/26",
+ # #=> "172.16.10.128/25"]
#
# Returns an array of IPv4 objects
#
def split(subnets=2)
unless (1..(2**@prefix.host_prefix)).include? subnets
@@ -967,15 +1080,12 @@
#
# private methods
#
private
+ # Tweaked to remove the #upto(32)
def newprefix(num)
- num.upto(32) do |i|
- if (a = Math::log2(i).to_i) == Math::log2(i)
- return @prefix + a
- end
- end
+ return @prefix + (Math::log2(num).ceil )
end
def sum_first_found(arr)
dup = arr.dup.reverse
dup.each_with_index do |obj,i|