Extended maintenance of Ruby 1.9.3 ended on February 23, 2015. Read more
Object
IPAddr provides a set of methods to manipulate an IP address. Both IPv4 and IPv6 are supported.
require 'ipaddr' ipaddr1 = IPAddr.new "3ffe:505:2::1" p ipaddr1 #=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff> p ipaddr1.to_s #=> "3ffe:505:2::1" ipaddr2 = ipaddr1.mask(48) #=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0000/ffff:ffff:ffff:0000:0000:0000:0000:0000> p ipaddr2.to_s #=> "3ffe:505:2::" ipaddr3 = IPAddr.new "192.168.2.0/24" p ipaddr3 #=> #<IPAddr: IPv4:192.168.2.0/255.255.255.0>
32 bit mask for IPv4
Format string for IPv6
128 bit mask for IPv4
Regexp internally used for parsing IPv4 address.
Regexp internally used for parsing IPv6 address.
Regexp internally used for parsing IPv6 address.
Creates a new ipaddr object either from a human readable IP address representation in string, or from a packed in_addr value followed by an address family.
In the former case, the following are the valid formats that will be recognized: “address”, “address/prefixlen” and “address/mask”, where IPv6 address may be enclosed in square brackets (`[‘ and `]’). If a prefixlen or a mask is specified, it returns a masked IP address. Although the address family is determined automatically from a specified string, you can specify one explicitly by the optional second argument.
Otherwise an IP address is generated from a packed in_addr value and an address family.
The IPAddr class defines many methods and operators, and some of those, such as &, |, include? and ==, accept a string, or a packed in_addr value instead of an IPAddr object.
# File ipaddr.rb, line 452
def initialize(addr = '::', family = Socket::AF_UNSPEC)
if !addr.kind_of?(String)
case family
when Socket::AF_INET, Socket::AF_INET6
set(addr.to_i, family)
@mask_addr = (family == Socket::AF_INET) ? IN4MASK : IN6MASK
return
when Socket::AF_UNSPEC
raise ArgumentError, "address family must be specified"
else
raise ArgumentError, "unsupported address family: #{family}"
end
end
prefix, prefixlen = addr.split('/')
if prefix =~ /^\[(.*)\]$/i
prefix = $1
family = Socket::AF_INET6
end
# It seems AI_NUMERICHOST doesn't do the job.
#Socket.getaddrinfo(left, nil, Socket::AF_INET6, Socket::SOCK_STREAM, nil,
# Socket::AI_NUMERICHOST)
@addr = @family = nil
if family == Socket::AF_UNSPEC || family == Socket::AF_INET
@addr = in_addr(prefix)
if @addr
@family = Socket::AF_INET
end
end
if !@addr && (family == Socket::AF_UNSPEC || family == Socket::AF_INET6)
@addr = in6_addr(prefix)
@family = Socket::AF_INET6
end
if family != Socket::AF_UNSPEC && @family != family
raise ArgumentError, "address family mismatch"
end
if prefixlen
mask!(prefixlen)
else
@mask_addr = (@family == Socket::AF_INET) ? IN4MASK : IN6MASK
end
end
Creates a new ipaddr containing the given network byte ordered string form of an IP address.
# File ipaddr.rb, line 90
def IPAddr::new_ntoh(addr)
return IPAddr.new(IPAddr::ntop(addr))
end
Convert a network byte ordered string form of an IP address into human readable form.
# File ipaddr.rb, line 96
def IPAddr::ntop(addr)
case addr.size
when 4
s = addr.unpack('C4').join('.')
when 16
s = IN6FORMAT % addr.unpack('n8')
else
raise ArgumentError, "unsupported address family"
end
return s
end
Returns a new ipaddr built by bitwise AND.
# File ipaddr.rb, line 109
def &(other)
return self.clone.set(@addr & coerce_other(other).to_i)
end
Returns a new ipaddr built by bitwise left shift.
# File ipaddr.rb, line 124
def <<(num)
return self.clone.set(addr_mask(@addr << num))
end
Compares the ipaddr with another.
# File ipaddr.rb, line 320
def <=>(other)
other = coerce_other(other)
return nil if other.family != @family
return @addr <=> other.to_i
end
Returns true if two ipaddrs are equal.
# File ipaddr.rb, line 134
def ==(other)
other = coerce_other(other)
return @family == other.family && @addr == other.to_i
end
Returns a new ipaddr built by bitwise right-shift.
# File ipaddr.rb, line 119
def >>(num)
return self.clone.set(@addr >> num)
end
Checks equality used by Hash.
# File ipaddr.rb, line 330
def eql?(other)
return self.class == other.class && self.hash == other.hash && self == other
end
Returns a hash value used by Hash, Set, and Array classes
# File ipaddr.rb, line 335
def hash
return ([@addr, @mask_addr].hash << 1) | (ipv4? ? 0 : 1)
end
Returns a network byte ordered string form of the IP address.
# File ipaddr.rb, line 220
def hton
case @family
when Socket::AF_INET
return [@addr].pack('N')
when Socket::AF_INET6
return (0..7).map { |i|
(@addr >> (112 - 16 * i)) & 0xffff
}.pack('n8')
else
raise "unsupported address family"
end
end
Returns true if the given ipaddr is in the range.
e.g.:
require 'ipaddr' net1 = IPAddr.new("192.168.2.0/24") net2 = IPAddr.new("192.168.2.100") net3 = IPAddr.new("192.168.3.0") p net1.include?(net2) #=> true p net1.include?(net3) #=> false
# File ipaddr.rb, line 154
def include?(other)
other = coerce_other(other)
if ipv4_mapped?
if (@mask_addr >> 32) != 0xffffffffffffffffffffffff
return false
end
mask_addr = (@mask_addr & IN4MASK)
addr = (@addr & IN4MASK)
family = Socket::AF_INET
else
mask_addr = @mask_addr
addr = @addr
family = @family
end
if other.ipv4_mapped?
other_addr = (other.to_i & IN4MASK)
other_family = Socket::AF_INET
else
other_addr = other.to_i
other_family = other.family
end
if family != other_family
return false
end
return ((addr & mask_addr) == (other_addr & mask_addr))
end
Returns a string containing a human-readable representation of the ipaddr. (“#<IPAddr: family:address/mask>”)
# File ipaddr.rb, line 357
def inspect
case @family
when Socket::AF_INET
af = "IPv4"
when Socket::AF_INET6
af = "IPv6"
else
raise "unsupported address family"
end
return sprintf("#<%s: %s:%s/%s>", self.class.name,
af, _to_string(@addr), _to_string(@mask_addr))
end
Returns a string for DNS reverse lookup compatible with RFC3172.
# File ipaddr.rb, line 299
def ip6_arpa
if !ipv6?
raise ArgumentError, "not an IPv6 address"
end
return _reverse + ".ip6.arpa"
end
Returns a string for DNS reverse lookup compatible with RFC1886.
# File ipaddr.rb, line 307
def ip6_int
if !ipv6?
raise ArgumentError, "not an IPv6 address"
end
return _reverse + ".ip6.int"
end
Returns true if the ipaddr is an IPv4 address.
# File ipaddr.rb, line 234
def ipv4?
return @family == Socket::AF_INET
end
Returns a new ipaddr built by converting the native IPv4 address into an IPv4-compatible IPv6 address.
# File ipaddr.rb, line 268
def ipv4_compat
if !ipv4?
raise ArgumentError, "not an IPv4 address"
end
return self.clone.set(@addr, Socket::AF_INET6)
end
Returns true if the ipaddr is an IPv4-compatible IPv6 address.
# File ipaddr.rb, line 249
def ipv4_compat?
if !ipv6? || (@addr >> 32) != 0
return false
end
a = (@addr & IN4MASK)
return a != 0 && a != 1
end
Returns a new ipaddr built by converting the native IPv4 address into an IPv4-mapped IPv6 address.
# File ipaddr.rb, line 259
def ipv4_mapped
if !ipv4?
raise ArgumentError, "not an IPv4 address"
end
return self.clone.set(@addr | 0xffff00000000, Socket::AF_INET6)
end
Returns true if the ipaddr is an IPv4-mapped IPv6 address.
# File ipaddr.rb, line 244
def ipv4_mapped?
return ipv6? && (@addr >> 32) == 0xffff
end
Returns true if the ipaddr is an IPv6 address.
# File ipaddr.rb, line 239
def ipv6?
return @family == Socket::AF_INET6
end
Returns a new ipaddr built by masking IP address with the given prefixlen/netmask. (e.g. 8, 64, “255.255.255.0”, etc.)
# File ipaddr.rb, line 141
def mask(prefixlen)
return self.clone.mask!(prefixlen)
end
Returns a new ipaddr built by converting the IPv6 address into a native IPv4 address. If the IP address is not an IPv4-mapped or IPv4-compatible IPv6 address, returns self.
# File ipaddr.rb, line 278
def native
if !ipv4_mapped? && !ipv4_compat?
return self
end
return self.clone.set(@addr & IN4MASK, Socket::AF_INET)
end
Returns a string for DNS reverse lookup. It returns a string in RFC3172 form for an IPv6 address.
# File ipaddr.rb, line 287
def reverse
case @family
when Socket::AF_INET
return _reverse + ".in-addr.arpa"
when Socket::AF_INET6
return ip6_arpa
else
raise "unsupported address family"
end
end
Returns the successor to the ipaddr.
# File ipaddr.rb, line 315
def succ
return self.clone.set(@addr + 1, @family)
end
Returns the integer representation of the ipaddr.
# File ipaddr.rb, line 184
def to_i
return @addr
end
Creates a Range object for the network address.
# File ipaddr.rb, line 340
def to_range
begin_addr = (@addr & @mask_addr)
case @family
when Socket::AF_INET
end_addr = (@addr | (IN4MASK ^ @mask_addr))
when Socket::AF_INET6
end_addr = (@addr | (IN6MASK ^ @mask_addr))
else
raise "unsupported address family"
end
return clone.set(begin_addr, @family)..clone.set(end_addr, @family)
end
Returns a string containing the IP address representation.
# File ipaddr.rb, line 189
def to_s
str = to_string
return str if ipv4?
str.gsub!(/\b0{1,3}([\da-f]+)\b/i, '\1')
loop do
break if str.sub!(/\A0:0:0:0:0:0:0:0\z/, '::')
break if str.sub!(/\b0:0:0:0:0:0:0\b/, ':')
break if str.sub!(/\b0:0:0:0:0:0\b/, ':')
break if str.sub!(/\b0:0:0:0:0\b/, ':')
break if str.sub!(/\b0:0:0:0\b/, ':')
break if str.sub!(/\b0:0:0\b/, ':')
break if str.sub!(/\b0:0\b/, ':')
break
end
str.sub!(/:{3,}/, '::')
if /\A::(ffff:)?([\da-f]{1,4}):([\da-f]{1,4})\z/i =~ str
str = sprintf('::%s%d.%d.%d.%d', $1, $2.hex / 256, $2.hex % 256, $3.hex / 256, $3.hex % 256)
end
str
end
Returns a string containing the IP address representation in canonical form.
# File ipaddr.rb, line 215
def to_string
return _to_string(@addr)
end
Set current netmask to given mask.
# File ipaddr.rb, line 396
def mask!(mask)
if mask.kind_of?(String)
if mask =~ /^\d+$/
prefixlen = mask.to_i
else
m = IPAddr.new(mask)
if m.family != @family
raise ArgumentError, "address family is not same"
end
@mask_addr = m.to_i
@addr &= @mask_addr
return self
end
else
prefixlen = mask
end
case @family
when Socket::AF_INET
if prefixlen < 0 || prefixlen > 32
raise ArgumentError, "invalid length"
end
masklen = 32 - prefixlen
@mask_addr = ((IN4MASK >> masklen) << masklen)
when Socket::AF_INET6
if prefixlen < 0 || prefixlen > 128
raise ArgumentError, "invalid length"
end
masklen = 128 - prefixlen
@mask_addr = ((IN6MASK >> masklen) << masklen)
else
raise "unsupported address family"
end
@addr = ((@addr >> masklen) << masklen)
return self
end
Set +@addr+, the internal stored ip address, to given addr.
The parameter addr is validated using the first
family member, which is Socket::AF_INET or
Socket::AF_INET6.
# File ipaddr.rb, line 375
def set(addr, *family)
case family[0] ? family[0] : @family
when Socket::AF_INET
if addr < 0 || addr > IN4MASK
raise ArgumentError, "invalid address"
end
when Socket::AF_INET6
if addr < 0 || addr > IN6MASK
raise ArgumentError, "invalid address"
end
else
raise ArgumentError, "unsupported address family"
end
@addr = addr
if family[0]
@family = family[0]
end
return self
end
Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.
If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.
If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.
If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.