class IPAddr

IPAddr provides a set of methods to manipulate an IP address. Both IPv4 and IPv6 are supported.

Example

require'ipaddr'ipaddr1 =IPAddr.new"3ffe:505:2::1"pipaddr1#=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>pipaddr1.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>pipaddr2.to_s#=> "3ffe:505:2::"ipaddr3 =IPAddr.new"192.168.2.0/24"pipaddr3#=> #<IPAddr: IPv4:192.168.2.0/255.255.255.0>

Constants

IN4MASK

32 bit mask for IPv4

IN6FORMAT

Format string for IPv6

IN6MASK

128 bit mask for IPv6

RE_IPV4ADDRLIKE

Regexpinternally used for parsing IPv4 address.

RE_IPV6ADDRLIKE_COMPRESSED

Regexpinternally used for parsing IPv6 address.

RE_IPV6ADDRLIKE_FULL

Regexpinternally used for parsing IPv6 address.

VERSION

Attributes

family[R]

Returns the address family of this IP address.

Public Class Methods

Source
# File lib/ipaddr.rb, line 655definitialize(addr ='::',family =Socket::AF_UNSPEC)@mask_addr =nilif!addr.kind_of?(String)casefamilywhenSocket::AF_INET,Socket::AF_INET6set(addr.to_i,family)@mask_addr = (family==Socket::AF_INET)?IN4MASK:IN6MASKreturnwhenSocket::AF_UNSPECraiseAddressFamilyError,"address family must be specified"elseraiseAddressFamilyError,"unsupported address family: #{family}"endendprefix,prefixlen =addr.split('/',2)ifprefix=~/\A\[(.*)\]\z/iprefix =$1family =Socket::AF_INET6endifprefix=~/\A(.*)(%\w+)\z/prefix =$1zone_id =$2family =Socket::AF_INET6end# 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 =niliffamily==Socket::AF_UNSPEC||family==Socket::AF_INET@addr =in_addr(prefix)if@addr@family =Socket::AF_INETendendif!@addr&& (family==Socket::AF_UNSPEC||family==Socket::AF_INET6)@addr =in6_addr(prefix)@family =Socket::AF_INET6end@zone_id =zone_idiffamily!=Socket::AF_UNSPEC&&@family!=familyraiseAddressFamilyError,"address family mismatch"endifprefixlenmask!(prefixlen)else@mask_addr = (@family==Socket::AF_INET)?IN4MASK:IN6MASKendend

Creates a new ipaddr object either from a human readable IP address representation in string, or from a packedin_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 packedin_addr value and an address family.

TheIPAddr class defines many methods and operators, and some of those, such as &, |, include? and ==, accept a string, or a packedin_addr value instead of anIPAddr object.

Source
# File lib/ipaddr.rb, line 107defself.new_ntoh(addr)returnnew(ntop(addr))end

Creates a new ipaddr containing the given network byte ordered string form of an IP address.

Source
# File lib/ipaddr.rb, line 114defself.ntop(addr)ifaddr.is_a?(String)&&addr.encoding!=Encoding::BINARYraiseInvalidAddressError,"invalid encoding (given #{addr.encoding}, expected BINARY)"endcaseaddr.bytesizewhen4addr.unpack('C4').join('.')when16IN6FORMAT%addr.unpack('n8')elseraiseAddressFamilyError,"unsupported address family"endend

Convert a network byte ordered string form of an IP address into human readable form. It expects the string to be encoded in Encoding::ASCII_8BIT (BINARY).

Public Instance Methods

Source
# File lib/ipaddr.rb, line 130def&(other)returnself.clone.set(@addr&coerce_other(other).to_i)end

Returns a new ipaddr built by bitwise AND.

Source
# File lib/ipaddr.rb, line 155def+(offset)self.clone.set(@addr+offset,@family)end

Returns a new ipaddr greater than the original address by offset

Source
# File lib/ipaddr.rb, line 160def-(offset)self.clone.set(@addr-offset,@family)end

Returns a new ipaddr less than the original address by offset

Source
# File lib/ipaddr.rb, line 145def<<(num)returnself.clone.set(addr_mask(@addr<<num))end

Returns a new ipaddr built by bitwise left shift.

Source
# File lib/ipaddr.rb, line 434def<=>(other)other =coerce_other(other)rescuenilelse@addr<=>other.to_iifother.family==@familyend

Compares the ipaddr with another.

Source
# File lib/ipaddr.rb, line 165def==(other)other =coerce_other(other)rescuefalseelse@family==other.family&&@addr==other.to_iend

Returns true if two ipaddrs are equal.

Alias for:include?
Source
# File lib/ipaddr.rb, line 140def>>(num)returnself.clone.set(@addr>>num)end

Returns a new ipaddr built by bitwise right-shift.

Source
# File lib/ipaddr.rb, line 135def|(other)returnself.clone.set(@addr|coerce_other(other).to_i)end

Returns a new ipaddr built by bitwise OR.

Source
# File lib/ipaddr.rb, line 150def~returnself.clone.set(addr_mask(~@addr))end

Returns a new ipaddr built by bitwise negation.

Source
# File lib/ipaddr.rb, line 241defas_json(*)ifipv4?&&prefix==32to_selsifipv6?&&prefix==128to_selsecidrendend

Returns a string containing the IP address representation with prefix.

Source
# File lib/ipaddr.rb, line 258defcidr"#{to_s}/#{prefix}"end

Returns a string containing the IP address representation in cidr notation

Source
# File lib/ipaddr.rb, line 444defeql?(other)returnself.class==other.class&&self.hash==other.hash&&self==otherend

Checks equality used byHash.

Source
# File lib/ipaddr.rb, line 449defhashreturn ([@addr,@mask_addr,@zone_id].hash<<1)| (ipv4??0:1)end

Returns a hash value used byHash, Set, andArray classes

Source
# File lib/ipaddr.rb, line 263defhtoncase@familywhenSocket::AF_INETreturn [@addr].pack('N')whenSocket::AF_INET6return (0..7).map {|i|      (@addr>> (112-16*i))&0xffff    }.pack('n8')elseraiseAddressFamilyError,"unsupported address family"endend

Returns a network byte ordered string form of the IP address.

Source
# File lib/ipaddr.rb, line 191definclude?(other)other =coerce_other(other)returnfalseunlessother.family==familybegin_addr<=other.begin_addr&&end_addr>=other.end_addrend

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")net4 =IPAddr.new("192.168.2.0/16")pnet1.include?(net2)#=> truepnet1.include?(net3)#=> falsepnet1.include?(net4)#=> falsepnet4.include?(net1)#=> true
Also aliased as:===
Source
# File lib/ipaddr.rb, line 489definspectcase@familywhenSocket::AF_INETaf ="IPv4"whenSocket::AF_INET6af ="IPv6"zone_id =@zone_id.to_selseraiseAddressFamilyError,"unsupported address family"endreturnsprintf("#<%s: %s:%s%s/%s>",self.class.name,af,_to_string(@addr),zone_id,_to_string(@mask_addr))end

Returns a string containing a human-readable representation of the ipaddr. (“#<IPAddr: family:address/mask>”)

Source
# File lib/ipaddr.rb, line 413defip6_arpaif!ipv6?raiseInvalidAddressError,"not an IPv6 address: #{@addr}"endreturn_reverse+".ip6.arpa"end

Returns a string for DNS reverse lookup compatible with RFC3172.

Source
# File lib/ipaddr.rb, line 421defip6_intif!ipv6?raiseInvalidAddressError,"not an IPv6 address: #{@addr}"endreturn_reverse+".ip6.int"end

Returns a string for DNS reverse lookup compatible with RFC1886.

Source
# File lib/ipaddr.rb, line 277defipv4?return@family==Socket::AF_INETend

Returns true if the ipaddr is an IPv4 address.

Source
# File lib/ipaddr.rb, line 379defipv4_compatwarn"IPAddr\##{__callee__} is obsolete",uplevel:1if$VERBOSEif!ipv4?raiseInvalidAddressError,"not an IPv4 address: #{@addr}"endclone =self.clone.set(@addr,Socket::AF_INET6)clone.instance_variable_set(:@mask_addr,@mask_addr|0xffffffffffffffffffffffff00000000)cloneend

Returns a new ipaddr built by converting the native IPv4 address into an IPv4-compatible IPv6 address.

Source
# File lib/ipaddr.rb, line 351defipv4_compat?warn"IPAddr\##{__callee__} is obsolete",uplevel:1if$VERBOSE_ipv4_compat?end

Returns true if the ipaddr is an IPv4-compatible IPv6 address.

Source
# File lib/ipaddr.rb, line 368defipv4_mappedif!ipv4?raiseInvalidAddressError,"not an IPv4 address: #{@addr}"endclone =self.clone.set(@addr|0xffff00000000,Socket::AF_INET6)clone.instance_variable_set(:@mask_addr,@mask_addr|0xffffffffffffffffffffffff00000000)cloneend

Returns a new ipaddr built by converting the native IPv4 address into an IPv4-mapped IPv6 address.

Source
# File lib/ipaddr.rb, line 346defipv4_mapped?returnipv6?&& (@addr>>32)==0xffffend

Returns true if the ipaddr is an IPv4-mapped IPv6 address.

Source
# File lib/ipaddr.rb, line 282defipv6?return@family==Socket::AF_INET6end

Returns true if the ipaddr is an IPv6 address.

Source
# File lib/ipaddr.rb, line 331deflink_local?case@familywhenSocket::AF_INET@addr&0xffff0000==0xa9fe0000# 169.254.0.0/16whenSocket::AF_INET6@addr&0xffc0_0000_0000_0000_0000_0000_0000_0000==0xfe80_0000_0000_0000_0000_0000_0000_0000||# fe80::/10      (@addr&0xffff_0000_0000==0xffff_0000_0000&& (@addr&0xffff0000==0xa9fe0000# ::ffff:169.254.0.0/16      ))elseraiseAddressFamilyError,"unsupported address family"endend

Returns true if the ipaddr is a link-local address. IPv4 addresses in 169.254.0.0/16 reserved by RFC 3927 and link-local IPv6 Unicast Addresses in fe80::/10 reserved by RFC 4291 are considered link-local. Link-local IPv4 addresses in the IPv4-mapped IPv6 address range are also considered link-local.

Source
# File lib/ipaddr.rb, line 289defloopback?case@familywhenSocket::AF_INET@addr&0xff000000==0x7f000000# 127.0.0.1/8whenSocket::AF_INET6@addr==1||# ::1      (@addr&0xffff_0000_0000==0xffff_0000_0000&& (@addr&0xff000000==0x7f000000# ::ffff:127.0.0.1/8      ))elseraiseAddressFamilyError,"unsupported address family"endend

Returns true if the ipaddr is a loopback address. Loopback IPv4 addresses in the IPv4-mapped IPv6 address range are also considered as loopback addresses.

Source
# File lib/ipaddr.rb, line 175defmask(prefixlen)returnself.clone.mask!(prefixlen)end

Returns a new ipaddr built by masking IP address with the given prefixlen/netmask. (e.g. 8, 64, “255.255.255.0”, etc.)

Source
# File lib/ipaddr.rb, line 392defnativeif!ipv4_mapped?&&!_ipv4_compat?returnselfendreturnself.clone.set(@addr&IN4MASK,Socket::AF_INET)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.

Source
# File lib/ipaddr.rb, line 504defnetmask_to_string(@mask_addr)end

Returns the netmask in string format e.g. 255.255.0.0

Source
# File lib/ipaddr.rb, line 459defprefixcase@familywhenSocket::AF_INETn =IN4MASK^@mask_addri =32whenSocket::AF_INET6n =IN6MASK^@mask_addri =128elseraiseAddressFamilyError,"unsupported address family"endwhilen.positive?n>>=1i-=1endiend

Returns the prefix length in bits for the ipaddr.

Source
# File lib/ipaddr.rb, line 478defprefix=(prefix)caseprefixwhenIntegermask!(prefix)elseraiseInvalidPrefixError,"prefix must be an integer"endend

Sets the prefix length in bits

Source
# File lib/ipaddr.rb, line 308defprivate?case@familywhenSocket::AF_INET@addr&0xff000000==0x0a000000||# 10.0.0.0/8@addr&0xfff00000==0xac100000||# 172.16.0.0/12@addr&0xffff0000==0xc0a80000# 192.168.0.0/16whenSocket::AF_INET6@addr&0xfe00_0000_0000_0000_0000_0000_0000_0000==0xfc00_0000_0000_0000_0000_0000_0000_0000||      (@addr&0xffff_0000_0000==0xffff_0000_0000&& (@addr&0xff000000==0x0a000000||# ::ffff:10.0.0.0/8@addr&0xfff00000==0xac100000||# ::ffff::172.16.0.0/12@addr&0xffff0000==0xc0a80000# ::ffff::192.168.0.0/16      ))elseraiseAddressFamilyError,"unsupported address family"endend

Returns true if the ipaddr is a private address. IPv4 addresses in 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16 as defined in RFC 1918 and IPv6 Unique Local Addresses in fc00::/7 as defined in RFC 4193 are considered private. Private IPv4 addresses in the IPv4-mapped IPv6 address range are also considered private.

Source
# File lib/ipaddr.rb, line 401defreversecase@familywhenSocket::AF_INETreturn_reverse+".in-addr.arpa"whenSocket::AF_INET6returnip6_arpaelseraiseAddressFamilyError,"unsupported address family"endend

Returns a string for DNS reverse lookup. It returns a string in RFC3172 form for an IPv6 address.

Source
# File lib/ipaddr.rb, line 429defsuccreturnself.clone.set(@addr+1,@family)end

Returns the successor to the ipaddr.

Source
# File lib/ipaddr.rb, line 199defto_ireturn@addrend

Returns the integer representation of the ipaddr.

Source
# File lib/ipaddr.rb, line 252defto_json(*a)%Q{"#{as_json(*a)}"}end

Returns a json string containing the IP address representation.

Source
# File lib/ipaddr.rb, line 454defto_rangeself.class.new(begin_addr,@family)..self.class.new(end_addr,@family)end

Creates aRange object for the network address.

Source
# File lib/ipaddr.rb, line 204defto_sstr =to_stringreturnstrifipv4?str.gsub!(/\b0{1,3}([\da-f]+)\b/i,'\1')loopdobreakifstr.sub!(/\A0:0:0:0:0:0:0:0\z/,'::')breakifstr.sub!(/\b0:0:0:0:0:0:0\b/,':')breakifstr.sub!(/\b0:0:0:0:0:0\b/,':')breakifstr.sub!(/\b0:0:0:0:0\b/,':')breakifstr.sub!(/\b0:0:0:0\b/,':')breakifstr.sub!(/\b0:0:0\b/,':')breakifstr.sub!(/\b0:0\b/,':')breakendstr.sub!(/:{3,}/,'::')if/\A::(ffff:)?([\da-f]{1,4}):([\da-f]{1,4})\z/i=~strstr =sprintf('::%s%d.%d.%d.%d',$1,$2.hex/256,$2.hex%256,$3.hex/256,$3.hex%256)endstrend

Returns a string containing the IP address representation.

Source
# File lib/ipaddr.rb, line 230defto_stringstr =_to_string(@addr)if@family==Socket::AF_INET6str<<zone_id.to_sendreturnstrend

Returns a string containing the IP address representation in canonical form.

Source
# File lib/ipaddr.rb, line 509defwildcard_maskcase@familywhenSocket::AF_INETmask =IN4MASK^@mask_addrwhenSocket::AF_INET6mask =IN6MASK^@mask_addrelseraiseAddressFamilyError,"unsupported address family"end_to_string(mask)end

Returns the wildcard mask in string format e.g. 0.0.255.255

Source
# File lib/ipaddr.rb, line 524defzone_idif@family==Socket::AF_INET6@zone_idelseraiseInvalidAddressError,"not an IPv6 address"endend

Returns the IPv6 zone identifier, if present. RaisesInvalidAddressError if not an IPv6 address.

Source
# File lib/ipaddr.rb, line 534defzone_id=(zid)if@family==Socket::AF_INET6casezidwhennil,/\A%(\w+)\z/@zone_id =zidelseraiseInvalidAddressError,"invalid zone identifier for address"endelseraiseInvalidAddressError,"not an IPv6 address"endend

Returns the IPv6 zone identifier, if present. RaisesInvalidAddressError if not an IPv6 address.

Protected Instance Methods

Source
# File lib/ipaddr.rb, line 549defbegin_addr@addr&@mask_addrend
Source
# File lib/ipaddr.rb, line 553defend_addrcase@familywhenSocket::AF_INET@addr| (IN4MASK^@mask_addr)whenSocket::AF_INET6@addr| (IN6MASK^@mask_addr)elseraiseAddressFamilyError,"unsupported address family"endend
Source
# File lib/ipaddr.rb, line 591defmask!(mask)casemaskwhenStringcasemaskwhen/\A(0|[1-9]+\d*)\z/prefixlen =mask.to_iwhen/\A\d+\z/raiseInvalidPrefixError,"leading zeros in prefix"elsem =IPAddr.new(mask)ifm.family!=@familyraiseInvalidPrefixError,"address family is not same"end@mask_addr =m.to_in =@mask_addr^m.instance_variable_get(:@mask_addr)unless ((n+1)&n).zero?raiseInvalidPrefixError,"invalid mask #{mask}"end@addr&=@mask_addrreturnselfendelseprefixlen =maskendcase@familywhenSocket::AF_INETifprefixlen<0||prefixlen>32raiseInvalidPrefixError,"invalid length"endmasklen =32-prefixlen@mask_addr = ((IN4MASK>>masklen)<<masklen)whenSocket::AF_INET6ifprefixlen<0||prefixlen>128raiseInvalidPrefixError,"invalid length"endmasklen =128-prefixlen@mask_addr = ((IN6MASK>>masklen)<<masklen)elseraiseAddressFamilyError,"unsupported address family"end@addr = ((@addr>>masklen)<<masklen)returnselfend

Set current netmask to given mask.

Source
# File lib/ipaddr.rb, line 567defset(addr,*family)casefamily[0]?family[0]:@familywhenSocket::AF_INETifaddr<0||addr>IN4MASKraiseInvalidAddressError,"invalid address: #{addr}"endwhenSocket::AF_INET6ifaddr<0||addr>IN6MASKraiseInvalidAddressError,"invalid address: #{addr}"endelseraiseAddressFamilyError,"unsupported address family"end@addr =addriffamily[0]@family =family[0]if@family==Socket::AF_INET@mask_addr&=IN4MASKendendreturnselfend

Set +@addr+, the internal stored ip address, to givenaddr. The parameteraddr is validated using the firstfamily member, which isSocket::AF_INET orSocket::AF_INET6.

Private Instance Methods

Source
# File lib/ipaddr.rb, line 356def_ipv4_compat?if!ipv6?|| (@addr>>32)!=0returnfalseenda = (@addr&IN4MASK)returna!=0&&a!=1end
Source
# File lib/ipaddr.rb, line 778def_reversecase@familywhenSocket::AF_INETreturn (0..3).map {|i|      (@addr>> (8*i))&0xff    }.join('.')whenSocket::AF_INET6return ("%.32x"%@addr).reverse!.gsub!(/.(?!$)/,'\&.')elseraiseAddressFamilyError,"unsupported address family"endend
Source
# File lib/ipaddr.rb, line 791def_to_string(addr)case@familywhenSocket::AF_INETreturn (0..3).map {|i|      (addr>> (24-8*i))&0xff    }.join('.')whenSocket::AF_INET6return (("%.32x"%addr).gsub!(/.{4}(?!$)/,'\&:'))elseraiseAddressFamilyError,"unsupported address family"endend
Source
# File lib/ipaddr.rb, line 767defaddr_mask(addr)case@familywhenSocket::AF_INETreturnaddr&IN4MASKwhenSocket::AF_INET6returnaddr&IN6MASKelseraiseAddressFamilyError,"unsupported address family"endend
Source
# File lib/ipaddr.rb, line 704defcoerce_other(other)caseotherwhenIPAddrotherwhenStringself.class.new(other)elseself.class.new(other,@family)endend
Source
# File lib/ipaddr.rb, line 730defin6_addr(left)caseleftwhenRE_IPV6ADDRLIKE_FULLif$2addr =in_addr($~[2,4])left =$1+':'elseaddr =0endright =''whenRE_IPV6ADDRLIKE_COMPRESSEDif$4left.count(':')<=6orraiseInvalidAddressError,"invalid address: #{@addr}"addr =in_addr($~[4,4])left =$1right =$3+'0:0'elseleft.count(':')<= ($1.empty?||$2.empty??8:7)orraiseInvalidAddressError,"invalid address: #{@addr}"left =$1right =$2addr =0endelseraiseInvalidAddressError,"invalid address: #{@addr}"endl =left.split(':')r =right.split(':')rest =8-l.size-r.sizeifrest<0returnnilend  (l+Array.new(rest,'0')+r).inject(0) {|i,s|i<<16|s.hex  }|addrend
Source
# File lib/ipaddr.rb, line 715defin_addr(addr)caseaddrwhenArrayoctets =addrelseRE_IPV4ADDRLIKE.match?(addr)orreturnniloctets =addr.split('.')endoctets.inject(0) {|i,s|    (n =s.to_i)<256orraiseInvalidAddressError,"invalid address: #{addr}"    (s!='0')&&s.start_with?('0')andraiseInvalidAddressError,"zero-filled number in IPv4 address is ambiguous: #{addr}"i<<8|n  }end