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
Attributes
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.
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
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
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 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