Class: IP
- Inherits:
-
Object
- Object
- IP
- Includes:
- Comparable
- Defined in:
- lib/ip/base.rb,
lib/ip/cpal.rb,
lib/ip/socket.rb
Overview
Copyright © 2009-2010 Brian Candler <www.deploy2.net/> Licensed under the same terms as ruby. See LICENCE.txt and COPYING.txt
Defined Under Namespace
Constant Summary collapse
- PROTO_TO_CLASS =
{}
Instance Attribute Summary collapse
-
#ctx ⇒ Object
Routing Context indicates the scope of this address (e.g. virtual router).
-
#pfxlen ⇒ Object
Length of prefix (network portion) of address.
Class Method Summary collapse
-
.from_cpal(cpal) ⇒ Object
Create an instance from an alternative array format: [context, protocol, address, prefix_length].
-
.new(src) ⇒ Object
Examples: IP.new(“1.2.3.4”) IP.new(“1.2.3.4/28”) IP.new(“1.2.3.4/28@routing_context”).
- .orig_new ⇒ Object
-
.parse(str) ⇒ Object
Parse a string as an IP address - return a V4/V6 object or nil.
Instance Method Summary collapse
- #&(other) ⇒ Object
- #+(other) ⇒ Object
- #-(other) ⇒ Object
- #<=>(other) ⇒ Object
- #^(other) ⇒ Object
-
#af ⇒ Object
Return the address family, Socket::AF_INET or Socket::AF_INET6.
-
#broadcast(offset = 0) ⇒ Object
Return a new IP object at the top of the subnet, with an optional offset applied.
- #eql?(other) ⇒ Boolean
- #freeze ⇒ Object
- #hash ⇒ Object
-
#initialize(addr, pfxlen = nil, ctx = nil) ⇒ IP
constructor
Examples: IP::V4.new(0x01020304) IP::V4.new(“01020304”) IP::V4.new(0x01020304, 28) IP::V4.new(0x01020304, 28, “routing_context”).
- #inspect ⇒ Object
- #ipv4_compat? ⇒ Boolean
- #ipv4_mapped? ⇒ Boolean
-
#mask ⇒ Object
Return the mask for this pfxlen as an integer.
-
#mask! ⇒ Object
Masks the address such that it is the base of the subnet IP.new(“1.2.3.4/24”).mask! => #<IP::V4 1.2.3.0/24>.
- #native ⇒ Object
-
#netmask ⇒ Object
Return a new IP object representing the netmask IP.new(“1.2.3.4/24”).netmask => #<IP::V4 255.255.255.0>.
-
#network(offset = 0) ⇒ Object
Return a new IP object at the base of the subnet, with an optional offset applied.
-
#offset ⇒ Object
Returns offset from base of subnet to this address IP.new(“1.2.3.4/24”).offset => 4.
-
#offset? ⇒ Boolean
Returns true if this is not the base address of the subnet implied from the prefix length (e.g. 1.2.3.4/24 is offset, because the base is 1.2.3.0/24).
-
#proto ⇒ Object
Return the protocol in string form, “v4” or “v6”.
-
#reset_pfxlen! ⇒ Object
If the address is not on the base, turn it into a single IP.
-
#size ⇒ Object
The number of IP addresses in subnet IP.new(“1.2.3.4/24”).size => 256.
- #succ ⇒ Object
- #succ! ⇒ Object
-
#to_a ⇒ Object
Return an array representation of the address, with 3 or 4 elements depending on whether there is a routing context set.
-
#to_addrlen ⇒ Object
Return the string representation of the IP address and prefix, or just the IP address if it’s a single address.
-
#to_ah ⇒ Object
Return an array representation of the address, with 3 or 4 elements depending on whether there is a routing context set, using hexadecimal.
-
#to_cpal ⇒ Object
Return an alternative 4-element array format with the routing context as the first element.
-
#to_cphl ⇒ Object
As cpal but with a hex string for the address part.
-
#to_hex ⇒ Object
Return the address as a hexadecimal string (8 or 32 digits).
-
#to_i ⇒ Object
Return the address as an Integer.
- #to_irange ⇒ Object
-
#to_range ⇒ Object
QUERY: IPAddr (1.9) turns 1.2.3.0/24 into 1.2.3.0/24..1.2.3.255/24 Here I turn it into 1.2.3.0..1.2.3.255.
-
#to_s ⇒ Object
Return the string representation of the address, x.x.x.x[@ctx].
-
#to_sockaddr(port = 0) ⇒ Object
Convert to a packed sockaddr structure.
-
#wildmask ⇒ Object
Return a new IP object representing the wildmask (inverse netmask) IP.new(“1.2.3.4/24”).netmask => #<IP::V4 0.0.0.255>.
- #|(other) ⇒ Object
- #~ ⇒ Object
Constructor Details
#initialize(addr, pfxlen = nil, ctx = nil) ⇒ IP
52 53 54 55 56 57 |
# File 'lib/ip/base.rb', line 52 def initialize(addr, pfxlen=nil, ctx=nil) @addr = addr.is_a?(String) ? addr.to_i(16) : addr.to_i raise ArgumentError, "Invalid address value" if @addr < 0 || @addr > self.class::MASK self.pfxlen = pfxlen self.ctx = ctx end |
Instance Attribute Details
#ctx ⇒ Object
Routing Context indicates the scope of this address (e.g. virtual router)
45 46 47 |
# File 'lib/ip/base.rb', line 45 def ctx @ctx end |
#pfxlen ⇒ Object
Length of prefix (network portion) of address
42 43 44 |
# File 'lib/ip/base.rb', line 42 def pfxlen @pfxlen end |
Class Method Details
.from_cpal(cpal) ⇒ Object
Create an instance from an alternative array format:
[context, protocol, address, prefix_length]
7 8 9 |
# File 'lib/ip/cpal.rb', line 7 def self.from_cpal(cpal) new([cpal[1], cpal[2], cpal[3], cpal[0]]) end |
.new(src) ⇒ Object
Examples:
IP.new("1.2.3.4")
IP.new("1.2.3.4/28")
IP.new("1.2.3.4/28@routing_context")
Array form (inverse of to_a and to_ah):
IP.new(["v4", 0x01020304])
IP.new(["v4", 0x01020304, 28])
IP.new(["v4", 0x01020304, 28, "routing_context"])
IP.new(["v4", "01020304", 28, "routing_context"])
Note that this returns an instance of IP::V4 or IP::V6. IP is the base class of both of those, but cannot be instantiated itself.
22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/ip/base.rb', line 22 def new(src) case src when String parse(src) || (raise ArgumentError, "invalid address") when Array (PROTO_TO_CLASS[src[0]] || (raise ArgumentError, "invalid protocol")).new(*src[1..-1]) when IP src.dup else raise ArgumentError, "invalid address" end end |
.orig_new ⇒ Object
8 |
# File 'lib/ip/base.rb', line 8 alias :orig_new :new |
Instance Method Details
#&(other) ⇒ Object
205 206 207 |
# File 'lib/ip/base.rb', line 205 def &(other) self.class.new(@addr & other.to_int, @pfxlen, @ctx) end |
#+(other) ⇒ Object
197 198 199 |
# File 'lib/ip/base.rb', line 197 def +(other) self.class.new(@addr + other.to_int, @pfxlen, @ctx) end |
#-(other) ⇒ Object
201 202 203 |
# File 'lib/ip/base.rb', line 201 def -(other) self.class.new(@addr - other.to_int, @pfxlen, @ctx) end |
#<=>(other) ⇒ Object
259 260 261 |
# File 'lib/ip/base.rb', line 259 def <=>(other) to_a <=> other.to_a end |
#^(other) ⇒ Object
213 214 215 |
# File 'lib/ip/base.rb', line 213 def ^(other) self.class.new(@addr ^ other.to_int, @pfxlen, @ctx) end |
#af ⇒ Object
Return the address family, Socket::AF_INET or Socket::AF_INET6
8 9 10 |
# File 'lib/ip/socket.rb', line 8 def af self.class::AF end |
#broadcast(offset = 0) ⇒ Object
Return a new IP object at the top of the subnet, with an optional offset applied.
IP.new("1.2.3.4/24").broadcast => #<IP::V4 1.2.3.255/24>
IP.new("1.2.3.4/24").broadcast(-1) => #<IP::V4 1.2.3.254/24>
134 135 136 |
# File 'lib/ip/base.rb', line 134 def broadcast(offset=0) self.class.new((@addr | mask) + offset, @pfxlen, @ctx) end |
#eql?(other) ⇒ Boolean
255 256 257 |
# File 'lib/ip/base.rb', line 255 def eql?(other) to_a.eql?(other.to_a) end |
#freeze ⇒ Object
250 251 252 253 |
# File 'lib/ip/base.rb', line 250 def freeze mask super end |
#hash ⇒ Object
246 247 248 |
# File 'lib/ip/base.rb', line 246 def hash to_a.hash end |
#inspect ⇒ Object
230 231 232 |
# File 'lib/ip/base.rb', line 230 def inspect res = "#<#{self.class} #{to_s}>" end |
#ipv4_compat? ⇒ Boolean
238 239 240 |
# File 'lib/ip/base.rb', line 238 def ipv4_compat? false end |
#ipv4_mapped? ⇒ Boolean
234 235 236 |
# File 'lib/ip/base.rb', line 234 def ipv4_mapped? false end |
#mask ⇒ Object
Return the mask for this pfxlen as an integer. For example, a V4 /24 address has a mask of 255 (0x000000ff)
118 119 120 |
# File 'lib/ip/base.rb', line 118 def mask @mask ||= (1 << (self.class::ADDR_BITS - @pfxlen)) - 1 end |
#mask! ⇒ Object
Masks the address such that it is the base of the subnet
IP.new("1.2.3.4/24").mask! => #<IP::V4 1.2.3.0/24>
152 153 154 155 |
# File 'lib/ip/base.rb', line 152 def mask! @addr &= ~mask self end |
#native ⇒ Object
242 243 244 |
# File 'lib/ip/base.rb', line 242 def native self end |
#netmask ⇒ Object
Return a new IP object representing the netmask
IP.new("1.2.3.4/24").netmask => #<IP::V4 255.255.255.0>
140 141 142 |
# File 'lib/ip/base.rb', line 140 def netmask self.class.new(self.class::MASK & ~mask) end |
#network(offset = 0) ⇒ Object
Return a new IP object at the base of the subnet, with an optional offset applied.
IP.new("1.2.3.4/24").network => #<IP::V4 1.2.3.0/24>
IP.new("1.2.3.4/24").network(7) => #<IP::V4 1.2.3.7/24>
126 127 128 |
# File 'lib/ip/base.rb', line 126 def network(offset=0) self.class.new((@addr & ~mask) + offset, @pfxlen, @ctx) end |
#offset ⇒ Object
166 167 168 |
# File 'lib/ip/base.rb', line 166 def offset @addr - (@addr & ~mask) end |
#offset? ⇒ Boolean
Returns true if this is not the base address of the subnet implied from the prefix length (e.g. 1.2.3.4/24 is offset, because the base is 1.2.3.0/24)
160 161 162 |
# File 'lib/ip/base.rb', line 160 def offset? @addr != (@addr & ~mask) end |
#proto ⇒ Object
Return the protocol in string form, “v4” or “v6”
60 61 62 |
# File 'lib/ip/base.rb', line 60 def proto self.class::PROTO end |
#reset_pfxlen! ⇒ Object
If the address is not on the base, turn it into a single IP.
IP.new("1.2.3.4/24").reset_pfxlen! => <IP::V4 1.2.3.4>
IP.new("1.2.3.0/24").reset_pfxlen! => <IP::V4 1.2.3.0/24>
173 174 175 176 |
# File 'lib/ip/base.rb', line 173 def reset_pfxlen! self.pfxlen = nil if offset? self end |
#size ⇒ Object
193 194 195 |
# File 'lib/ip/base.rb', line 193 def size mask + 1 end |
#succ ⇒ Object
221 222 223 |
# File 'lib/ip/base.rb', line 221 def succ self.class.new(@addr + size, @pfxlen, @ctx) end |
#succ! ⇒ Object
225 226 227 228 |
# File 'lib/ip/base.rb', line 225 def succ! @addr += size self end |
#to_a ⇒ Object
Return an array representation of the address, with 3 or 4 elements depending on whether there is a routing context set.
["v4", 16909060, 28]
["v4", 16909060, 28, "context"]
(Removing the last element makes them Comparable, as nil.<=> doesn’t exist)
90 91 92 93 |
# File 'lib/ip/base.rb', line 90 def to_a @ctx ? [self.class::PROTO, @addr, @pfxlen, @ctx] : [self.class::PROTO, @addr, @pfxlen] end |
#to_addrlen ⇒ Object
Return the string representation of the IP address and prefix, or just the IP address if it’s a single address
71 72 73 |
# File 'lib/ip/base.rb', line 71 def to_addrlen pfxlen == self.class::ADDR_BITS ? to_addr : "#{to_addr}/#{pfxlen}" end |
#to_ah ⇒ Object
Return an array representation of the address, with 3 or 4 elements depending on whether there is a routing context set, using hexadecimal.
["v4", "01020304", 28]
["v4", "01020304", 28, "context"]
99 100 101 102 |
# File 'lib/ip/base.rb', line 99 def to_ah @ctx ? [self.class::PROTO, to_hex, @pfxlen, @ctx] : [self.class::PROTO, to_hex, @pfxlen] end |
#to_cpal ⇒ Object
Return an alternative 4-element array format with the routing context as the first element. Useful for grouping by context.
cpal = [context, proto, address, prefix_length]
14 15 16 |
# File 'lib/ip/cpal.rb', line 14 def to_cpal [@ctx, self.class::PROTO, @addr, @pfxlen] end |
#to_cphl ⇒ Object
As cpal but with a hex string for the address part
19 20 21 |
# File 'lib/ip/cpal.rb', line 19 def to_cphl [@ctx, self.class::PROTO, to_hex, @pfxlen] end |
#to_hex ⇒ Object
Return the address as a hexadecimal string (8 or 32 digits)
81 82 83 |
# File 'lib/ip/base.rb', line 81 def to_hex @addr.to_s(16).rjust(self.class::ADDR_BITS>>2,"0") end |
#to_i ⇒ Object
Return the address as an Integer
76 77 78 |
# File 'lib/ip/base.rb', line 76 def to_i @addr end |
#to_irange ⇒ Object
178 179 180 181 182 |
# File 'lib/ip/base.rb', line 178 def to_irange a1 = @addr & ~mask a2 = a1 | mask (a1..a2) end |
#to_range ⇒ Object
QUERY: IPAddr (1.9) turns 1.2.3.0/24 into 1.2.3.0/24..1.2.3.255/24 Here I turn it into 1.2.3.0..1.2.3.255. Which is better?
186 187 188 189 |
# File 'lib/ip/base.rb', line 186 def to_range self.class.new(@addr & ~mask, self.class::ADDR_BITS, @ctx) .. self.class.new(@addr | mask, self.class::ADDR_BITS, @ctx) end |
#to_s ⇒ Object
Return the string representation of the address, x.x.x.x[@ctx]
65 66 67 |
# File 'lib/ip/base.rb', line 65 def to_s ctx ? "#{to_addrlen}@#{ctx}" : to_addrlen end |
#to_sockaddr(port = 0) ⇒ Object
Convert to a packed sockaddr structure
13 14 15 |
# File 'lib/ip/socket.rb', line 13 def to_sockaddr(port=0) Socket.pack_sockaddr_in(port, to_addr) end |
#wildmask ⇒ Object
Return a new IP object representing the wildmask (inverse netmask)
IP.new("1.2.3.4/24").netmask => #<IP::V4 0.0.0.255>
146 147 148 |
# File 'lib/ip/base.rb', line 146 def wildmask self.class.new(mask) end |
#|(other) ⇒ Object
209 210 211 |
# File 'lib/ip/base.rb', line 209 def |(other) self.class.new(@addr | other.to_int, @pfxlen, @ctx) end |
#~ ⇒ Object
217 218 219 |
# File 'lib/ip/base.rb', line 217 def ~ self.class.new(~@addr & self.class::MASK, @pfxlen, @ctx) end |