Class: IPAddr::Base

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

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, #last, #netmask, #overlap?, #shrink, #size, #summarize_with, #to_range, #wildcard

Methods inherited from IPAddr

Host

Methods included from BetterIpaddr::ClassMethods

#[]

Class Method Details

.[](address, mask = nil, family: self::FAMILY) ⇒ 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.



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

def self.[](address, mask = nil, family: self::FAMILY)
  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)
  end
end

.from(address) ⇒ 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.



46
47
48
49
50
51
52
53
54
55
# File 'lib/better_ipaddr/classes.rb', line 46

def self.from(address)
  case address
  when IPAddr
    specialize address
  when Regex::IPV4, 0..V4::MAX_INT
    V4[address]
  when Regex::IPV6, 0..V6::MAX_INT
    V6[address]
  end
end

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

Create an IPAddr from an Integer.



78
79
80
# File 'lib/better_ipaddr/classes.rb', line 78

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.



88
89
90
91
# File 'lib/better_ipaddr/classes.rb', line 88

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) ⇒ IPAddr

Create an IPAddr from a String.



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

def self.from_string(address, mask = nil, family: self::FAMILY)
  if mask
    new(address, family).mask(mask)
  else
    new(address, family)
  end
end

.host_from(address) ⇒ Object

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.



63
64
65
66
67
68
69
70
# File 'lib/better_ipaddr/classes.rb', line 63

def self.host_from(address)
  ip = from(address)
  if ip.ipv4?
    V4::Host[ip]
  elsif 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.



135
136
137
138
139
140
141
142
# File 'lib/better_ipaddr/classes.rb', line 135

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.



150
151
152
# File 'lib/better_ipaddr/classes.rb', line 150

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.



112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/better_ipaddr/classes.rb', line 112

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.



183
184
185
# File 'lib/better_ipaddr/classes.rb', line 183

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.



192
193
194
195
196
197
198
199
200
201
202
# File 'lib/better_ipaddr/classes.rb', line 192

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



204
205
206
207
208
209
210
211
212
213
214
# File 'lib/better_ipaddr/classes.rb', line 204

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.



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

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.



175
176
177
# File 'lib/better_ipaddr/classes.rb', line 175

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



216
217
218
# File 'lib/better_ipaddr/classes.rb', line 216

def address_family_bit_length
  self.class::BIT_LENGTH
end

#network?Boolean



220
221
222
# File 'lib/better_ipaddr/classes.rb', line 220

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

#prefix_lengthObject



224
225
226
# File 'lib/better_ipaddr/classes.rb', line 224

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

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



228
229
230
# File 'lib/better_ipaddr/classes.rb', line 228

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