Module: IPAddress

Included in:
IPv4, IPv6
Defined in:
lib/ipaddress.rb,
lib/ipaddress/ipv4.rb,
lib/ipaddress/ipv6.rb,
lib/ipaddress/prefix.rb

Defined Under Namespace

Classes: IPv4, IPv6, Prefix, Prefix128, Prefix32

Constant Summary collapse

NAME =
"IPAddress"
GEM =
"ipaddress"
AUTHORS =
["Marco Ceresa <[email protected]>"]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.deprecate(message = nil) ⇒ Object

Deprecate method



236
237
238
239
# File 'lib/ipaddress.rb', line 236

def self.deprecate(message = nil) # :nodoc:
  message ||= "You are using deprecated behavior which will be removed from the next major or minor release."
  warn("DEPRECATION WARNING: #{message}")
end

.ntoa(uint) ⇒ Object

Converts a unit32 to IPv4

IPAddress::ntoa(167837953)
  #-> "10.1.1.1"


65
66
67
68
69
70
71
72
73
74
75
# File 'lib/ipaddress.rb', line 65

def self.ntoa(uint)
  unless(uint.is_a? Numeric and uint <= 0xffffffff and uint >= 0)
    raise(::ArgumentError, "not a long integer: #{uint.inspect}")
  end
  ret = []
  4.times do
    ret.unshift(uint & 0xff)
    uint >>= 8
  end
  ret.join('.')
end

.parse(str) ⇒ Object

Parse the argument string to create a new IPv4, IPv6 or Mapped IP object

ip  = IPAddress.parse 167837953 # 10.1.1.1
ip  = IPAddress.parse "172.16.10.1/24"
ip6 = IPAddress.parse "2001:db8::8:800:200c:417a/64"
ip_mapped = IPAddress.parse "::ffff:172.16.10.1/128"

All the object created will be instances of the correct class:

ip.class
  #=> IPAddress::IPv4
ip6.class
  #=> IPAddress::IPv6
ip_mapped.class
  #=> IPAddress::IPv6::Mapped


40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/ipaddress.rb', line 40

def IPAddress::parse(str)

  # Check if an int was passed
  if str.kind_of? Integer
    return IPAddress::IPv4.new(ntoa(str))
  end

  case str
  when /:.+\./
    IPAddress::IPv6::Mapped.new(str)
  when /\./
    IPAddress::IPv4.new(str)
  when /:/
    IPAddress::IPv6.new(str)
  else
    raise ArgumentError, "Unknown IP Address #{str}"
  end
end

.valid?(addr) ⇒ Boolean

Checks if the given string is either a valid IP, either a valid IPv4 subnet

Example:

IPAddress::valid? "10.0.0.0/24"
  #=> true

IPAddress::valid? "2002::1"
  #=> true

IPAddress::valid? "10.0.0.256"
  #=> false

IPAddress::valid? "10.0.0.0/999"
  #=> false

Returns:

  • (Boolean)


119
120
121
# File 'lib/ipaddress.rb', line 119

def self.valid?(addr)
  valid_ip?(addr) || valid_ipv4_subnet?(addr) || valid_ipv6_subnet?(addr)
end

.valid_ip?(addr) ⇒ Boolean

Checks if the given string is a valid IP address, either IPv4 or IPv6

Example:

IPAddress::valid_ip? "2002::1"
  #=> true

IPAddress::valid_ip? "10.0.0.256"
  #=> false

Returns:

  • (Boolean)


135
136
137
# File 'lib/ipaddress.rb', line 135

def self.valid_ip?(addr)
  valid_ipv4?(addr) || valid_ipv6?(addr)
end

.valid_ipv4?(addr) ⇒ Boolean

Checks if the given string is a valid IPv4 address

Example:

IPAddress::valid_ipv4? "2002::1"
  #=> false

IPAddress::valid_ipv4? "172.16.10.1"
  #=> true

Returns:

  • (Boolean)


194
195
196
197
198
199
# File 'lib/ipaddress.rb', line 194

def self.valid_ipv4?(addr)
  if /^(0|[1-9]{1}\d{0,2})\.(0|[1-9]{1}\d{0,2})\.(0|[1-9]{1}\d{0,2})\.(0|[1-9]{1}\d{0,2})$/ =~ addr
    return $~.captures.all? {|i| i.to_i < 256}
  end
  false
end

.valid_ipv4_netmask?(addr) ⇒ Boolean

Checks if the argument is a valid IPv4 netmask expressed in dotted decimal format.

IPAddress.valid_ipv4_netmask? "255.255.0.0"
  #=> true

Returns:

  • (Boolean)


208
209
210
211
212
213
# File 'lib/ipaddress.rb', line 208

def self.valid_ipv4_netmask?(addr)
  arr = addr.split(".").map{|i| i.to_i}.pack("CCCC").unpack("B*").first.scan(/01/)
  arr.empty? && valid_ipv4?(addr)
rescue
  return false
end

.valid_ipv4_subnet?(addr) ⇒ Boolean

Checks if the given string is a valid IPv4 subnet

Example:

IPAddress::valid_ipv4_subnet? "10.0.0.0/24"
  #=> true

IPAddress::valid_ipv4_subnet? "10.0.0.0/255.255.255.0"
  #=> true

IPAddress::valid_ipv4_subnet? "10.0.0.0/64"
  #=> false

Returns:

  • (Boolean)


153
154
155
156
157
# File 'lib/ipaddress.rb', line 153

def self.valid_ipv4_subnet?(addr)
  ip, netmask = addr.split("/")

  valid_ipv4?(ip) && (!(netmask =~ /\A([12]?\d|3[0-2])\z/).nil? || valid_ipv4_netmask?(netmask))
end

.valid_ipv6?(addr) ⇒ Boolean

Checks if the given string is a valid IPv6 address

Example:

IPAddress::valid_ipv6? "2002::1"
  #=> true

IPAddress::valid_ipv6? "2002::DEAD::BEEF"
  #=> false

Returns:

  • (Boolean)


226
227
228
229
230
231
# File 'lib/ipaddress.rb', line 226

def self.valid_ipv6?(addr)
  # https://gist.github.com/cpetschnig/294476
  # http://forums.intermapper.com/viewtopic.php?t=452
  return true if /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/ =~ addr
  false
end

.valid_ipv6_subnet?(addr) ⇒ Boolean

Checks if the given string is a valid IPv6 subnet

Example:

IPAddress::valid_ipv6_subnet? "::/0"
  #=> true

IPAddress::valid_ipv6_subnet? "dead:beef:cafe:babe::/64"
  #=> true

IPAddress::valid_ipv6_subnet? "2001::1/129"
  #=> false

Returns:

  • (Boolean)


173
174
175
176
177
178
179
180
181
# File 'lib/ipaddress.rb', line 173

def self.valid_ipv6_subnet?(addr)
  ip, netmask = addr.split("/")

  netmask = Integer(netmask, 10)

  valid_ipv6?(ip) && netmask >= 0 && netmask <= 128
rescue ArgumentError
  false
end

Instance Method Details

#ipv4?Boolean

True if the object is an IPv4 address

ip = IPAddress("192.168.10.100/24")

ip.ipv4?
  #-> true

Returns:

  • (Boolean)


85
86
87
# File 'lib/ipaddress.rb', line 85

def ipv4?
  self.kind_of? IPAddress::IPv4
end

#ipv6?Boolean

True if the object is an IPv6 address

ip = IPAddress("192.168.10.100/24")

ip.ipv6?
  #-> false

Returns:

  • (Boolean)


97
98
99
# File 'lib/ipaddress.rb', line 97

def ipv6?
  self.kind_of? IPAddress::IPv6
end