Class: IPAddr::Base

Inherits:
IPAddr show all
Includes:
BetterIpaddr::Constants, BetterIpaddr::InstanceMethods, Comparable, Enumerable
Defined in:
lib/better_ipaddr/classes.rb

Overview

An intermediate superclass for all BetterIpaddr classes

Direct Known Subclasses

MAC, V4, V6

Constant Summary

Constants included from BetterIpaddr::Constants

BetterIpaddr::Constants::FAMILY_TO_BIT_LENGTH, BetterIpaddr::Constants::NETMASK_TO_PREFIX_LENGTH, BetterIpaddr::Constants::PREFIX_LENGTH_TO_NETMASK, BetterIpaddr::Constants::SYMBOL_TO_FAMILY

Instance Attribute Summary

Attributes included from BetterIpaddr::InstanceMethods

#family, #mask_addr

Class Method Summary collapse

Instance Method Summary collapse

Methods included from BetterIpaddr::InstanceMethods

#+, #-, #<=>, #==, #[], #base, #better_to_s, #cidr, #cover?, #each, #first, #grow, #host?, included, #inspect, #last, #netmask, #overlap?, #shrink, #size, #summarize_with, #to_range, #wildcard

Methods inherited from IPAddr

Host

Class Method Details

.[](address, mask = nil, family: self::FAMILY, classful: false) ⇒ IPAddr, Nil

Create an IPAddr from the given object.

Returns nil if the object is of a type that can’t be converted to an IPAddr.

Parameters:

  • address (Integer, IPAddr, String)
  • mask (Integer, IPAddr, String, Nil) (defaults to: nil)
  • family (Integer) (defaults to: self::FAMILY)
  • classful (Boolean) (defaults to: false)

    see Base.from_string

Returns:



23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/better_ipaddr/classes.rb', line 23

def self.[](address, mask = nil, family: self::FAMILY, classful: false)
  prefix_length = mask && object_to_prefix_length(mask, family)

  case address
  when Integer
    from_integer(address, prefix_length, family: family)
  when IPAddr
    from_ipaddr(address, prefix_length, family: family)
  when String
    from_string(address, prefix_length, family: family, classful: classful)
  end
end

.from(address, exception: false, classful: false) ⇒ IPAddr, Nil

Create an IPAddr from the given object, guessing the type of address given based on its type and content.

Note that an Integer that corresponds to an IPv4 address will be converted to an IPAddr::V4, even though all such Integers also correspond to valid IPv6 addresses.

Returns nil if the object can’t be converted based on its type and content.

Parameters:

  • address (Integer, IPAddr, String)
  • exception (Boolean) (defaults to: false)

    If true, then when the given object can’t be converted to an IPAddr, a TypeError will be raise rather than returning nil.

  • classful (Boolean) (defaults to: false)

    see Base.from_string

Returns:



52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/better_ipaddr/classes.rb', line 52

def self.from(address, exception: false, classful: false)
  case address
  when IPAddr
    specialize address
  when Regex::IPV4, 0..V4::MAX_INT
    V4[address, classful: classful]
  when Regex::IPV6, 0..V6::MAX_INT
    V6[address]
  end || (
    if exception
      raise TypeError, "can't convert #{address.inspect} to #{self}"
    end
  )
end

.from_integer(address, prefix_length, family: self::FAMILY) ⇒ IPAddr

Create an IPAddr from an Integer.

Parameters:

  • address (Integer)
  • mask (Integer, String)

    a netmask or prefix length

  • family (Integer, Nil) (defaults to: self::FAMILY)

Returns:



92
93
94
# File 'lib/better_ipaddr/classes.rb', line 92

def self.from_integer(address, prefix_length, family: self::FAMILY)
  new(address, family).mask(prefix_length || FAMILY_TO_BIT_LENGTH[family])
end

.from_ipaddr(address, prefix_length, family: self::FAMILY) ⇒ IPAddr

Create an IPAddr from an IPAddr.

Parameters:

  • address (IPAddr)
  • mask (Integer, String)

    a netmask or prefix length

  • family (Integer, Nil) (defaults to: self::FAMILY)

Returns:



102
103
104
105
# File 'lib/better_ipaddr/classes.rb', line 102

def self.from_ipaddr(address, prefix_length, family: self::FAMILY)
  address = specialize(address)
  new(address.to_i, family).mask(prefix_length || address.prefix_length)
end

.from_string(address, mask = nil, family: self::FAMILY, classful: false) ⇒ IPAddr

Create an IPAddr from a String.

Parameters:

  • address (String)
  • mask (Integer, String) (defaults to: nil)

    a netmask or prefix length

  • family (Integer, Nil) (defaults to: self::FAMILY)
  • classful (Boolean) (defaults to: false)

    controls the conversion of IPv4 addresses without a prefix length in CIDR notation. When false, these are assumed to be host networks (/32). When true, these are assumed to be classful (rfc791) networks, with an implicit prefix length. Has no effect on IPv6 addresses.

Returns:



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/better_ipaddr/classes.rb', line 118

def self.from_string(
  address,
  mask = nil,
  family: self::FAMILY,
  classful: false
)
  if mask
    new(address, family).mask(mask)
  elsif !classful || address.include?('/')
    new(address, family)
  else
    ipaddr = new(address, family)
    return ipaddr unless ipaddr.ipv4?
    ipaddr.classful || ipaddr
  end
end

.host_from(address, exception: false) ⇒ IPAddr::Host, Nil

Create an IPAddr host subclass from the given object, guessing the type of address given based on its type and content.

Uses .from internally, so the same concerns apply, though the returned object is guaranteed to be of a Host class or nil.

Parameters:

  • address (Integer, IPAddr, String)
  • exception (Boolean) (defaults to: false)

    See IPAddr::Base.from

Returns:

  • (IPAddr::Host, Nil)


77
78
79
80
81
82
83
84
# File 'lib/better_ipaddr/classes.rb', line 77

def self.host_from(address, exception: false)
  ip = from(address, exception: exception)
  if ip && ip.ipv4?
    V4::Host[ip]
  elsif ip && ip.ipv6?
    V6::Host[ip]
  end
end

.integer_to_prefix_length(mask, family = self::FAMILY) ⇒ Integer

Convert an integer to a prefix length.

If the integer is within the range of possible prefix lengths, returns the same integer. Otherwise it assumes that the given integer is the integer representation of a netmask.

Returns nil if the integer can’t be converted.

Parameters:

  • mask (Integer)

Returns:

  • (Integer)


163
164
165
166
167
168
169
170
# File 'lib/better_ipaddr/classes.rb', line 163

def self.integer_to_prefix_length(mask, family = self::FAMILY)
  if valid_prefix_length?(mask)
    mask
  else
    NETMASK_TO_PREFIX_LENGTH[family][mask] ||
      (raise ArgumentError, "Can't convert #{mask} to prefix length")
  end
end

.ipaddr_to_prefix_length(mask, family = self::FAMILY) ⇒ Integer

Convert a netmask represented as an IPAddr to a prefix length.

Returns nil if the IPAddr can’t be converted.

Parameters:

Returns:

  • (Integer)


178
179
180
# File 'lib/better_ipaddr/classes.rb', line 178

def self.ipaddr_to_prefix_length(mask, family = self::FAMILY)
  NETMASK_TO_PREFIX_LENGTH[family][mask.to_i]
end

.object_to_prefix_length(mask, family = self::FAMILY) ⇒ Integer

Convert an object to a prefix length.

Parameters:

  • mask (Integer, String)
  • family (Integer, Nil) (defaults to: self::FAMILY)

Returns:

  • (Integer)


140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/better_ipaddr/classes.rb', line 140

def self.object_to_prefix_length(mask, family = self::FAMILY)
  case mask
  when Integer
    integer_to_prefix_length(mask, family)
  when String
    string_to_prefix_length(mask, family)
  when IPAddr
    ipaddr_to_prefix_length(mask, family)
  else
    raise ArgumentError, "Can't convert #{mask.class} to prefix length"
  end
end

.parse(address) ⇒ IPAddr::V4, ...

Convert the given string to an IPAddr subclass.

Parameters:

  • address (String)

    the string to convert

Returns:



211
212
213
# File 'lib/better_ipaddr/classes.rb', line 211

def self.parse(address)
  specialize IPAddr.new(address)
end

.specialize(address) ⇒ IPAddr::V4, ...

Return the given address as an instance of a class specific to its address family.

Parameters:

  • address (IPAddr)

    the address to convert

Returns:



220
221
222
223
224
225
226
227
228
229
230
# File 'lib/better_ipaddr/classes.rb', line 220

def self.specialize(address)
  return address unless address.class == IPAddr
  case address.family
  when Family::IPV4
    IPAddr::V4[address.to_i, address.instance_variable_get(:@mask_addr)]
  when Family::IPV6
    IPAddr::V6[address.to_i, address.instance_variable_get(:@mask_addr)]
  when Family::EUI48
    IPAddr::MAC[address.to_i, address.instance_variable_get(:@mask_addr)]
  end
end

.specialize_constants(family) ⇒ Object



232
233
234
235
236
237
238
239
240
241
242
# File 'lib/better_ipaddr/classes.rb', line 232

def self.specialize_constants(family)
  const_set(:FAMILY, family)
  const_set(:BIT_LENGTH, FAMILY_TO_BIT_LENGTH.fetch(self::FAMILY))
  const_set(:NETMASK_TO_PREFIX_LENGTH,
            NETMASK_TO_PREFIX_LENGTH.fetch(self::FAMILY))
  const_set(:PREFIX_LENGTH_TO_NETMASK,
            PREFIX_LENGTH_TO_NETMASK.fetch(self::FAMILY))
  const_set(:MAX_INT, 2**self::BIT_LENGTH - 1)
  const_set(:HOST_NETMASK,
            self::PREFIX_LENGTH_TO_NETMASK.fetch(self::BIT_LENGTH))
end

.string_to_prefix_length(mask, family = self::FAMILY) ⇒ Integer

Convert a string to a prefix length.

Accepts the decimal representations of integers as well as netmasks in dotted quad notation.

Returns nil if the string can’t be converted.

Parameters:

  • mask (String)

Returns:

  • (Integer)


191
192
193
194
195
196
197
# File 'lib/better_ipaddr/classes.rb', line 191

def self.string_to_prefix_length(mask, family = self::FAMILY)
  if mask =~ /^\d+$/
    integer_to_prefix_length(mask.to_i, family)
  else
    NETMASK_TO_PREFIX_LENGTH[family][new(mask).to_i]
  end
end

.valid_prefix_length?(prefix_length, family: self::FAMILY) ⇒ Boolean

Return true if the given number is a valid prefix length, false otherwise.

Parameters:

  • prefix_length (Integer)

Returns:

  • (Boolean)


203
204
205
# File 'lib/better_ipaddr/classes.rb', line 203

def self.valid_prefix_length?(prefix_length, family: self::FAMILY)
  0 <= prefix_length && prefix_length <= FAMILY_TO_BIT_LENGTH[family]
end

Instance Method Details

#address_family_bit_lengthObject



244
245
246
# File 'lib/better_ipaddr/classes.rb', line 244

def address_family_bit_length
  self.class::BIT_LENGTH
end

#network?Boolean

Returns:

  • (Boolean)


248
249
250
# File 'lib/better_ipaddr/classes.rb', line 248

def network?
  prefix_length < self.class::BIT_LENGTH
end

#prefix_lengthObject



252
253
254
# File 'lib/better_ipaddr/classes.rb', line 252

def prefix_length
  self.class::NETMASK_TO_PREFIX_LENGTH[mask_addr]
end

#to_s(cidr: false, full: false) ⇒ Object



256
257
258
# File 'lib/better_ipaddr/classes.rb', line 256

def to_s(cidr: false, full: false)
  better_to_s(cidr: cidr, full: full)
end