Class: IP::CIDR
- Inherits:
-
Object
- Object
- IP::CIDR
- Defined in:
- lib/ip/cidr.rb
Overview
IP::CIDR - Works with Classless Inter-Domain Routing formats, such as 10.0.0.1/32 or 10.0.0.1/255.255.255.255
Instance Attribute Summary collapse
-
#cidr ⇒ Object
readonly
Contains the original CIDR you fed it, returned as a string.
-
#ip ⇒ Object
readonly
Contains the IP address (LHS) only.
-
#mask ⇒ Object
readonly
Contains the integer-based (short) netmask (RHS) only.
Instance Method Summary collapse
-
#first_ip ⇒ Object
This returns the first ip address of the cidr as an IP::Address object.
-
#includes?(address) ⇒ Boolean
Given an IP::Address object, will determine if it is included in the current subnet.
-
#initialize(cidr) ⇒ CIDR
constructor
Given a string of format X.X.X.X/X, in standard CIDR notation, this will construct a IP::CIDR object.
-
#last_ip ⇒ Object
This returns the last ip address of the cidr as an IP::Address object.
-
#long_netmask ⇒ Object
This produces the long netmask (eg. 255.255.255.255) of the CIDR in an IP::Address object.
- #netmask ⇒ Object
-
#overlaps?(other_cidr) ⇒ Boolean
This will take another IP::CIDR object as an argument and check to see if it overlaps with this cidr object.
-
#range ⇒ Object
This produces a range ala IP::Range, but only for the subnet defined by the CIDR object.
-
#short_netmask ⇒ Object
This produces the short netmask (eg. 32) of the CIDR in an IP::Address object.
Constructor Details
#initialize(cidr) ⇒ CIDR
Given a string of format X.X.X.X/X, in standard CIDR notation, this will construct a IP::CIDR object.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/ip/cidr.rb', line 26 def initialize(cidr) if !cidr.kind_of? String raise IP::AddressException.new("CIDR value is not of type String") end @cidr = cidr @ip, @mask = cidr.split(/\//, 2) @ip = IP::Address::Util.string_to_ip(@ip) if @ip.nil? or @mask.nil? raise IP::AddressException.new("CIDR is not valid - invalid format") end if @mask.length == 0 or /[^0-9.]/.match @mask or (@ip.kind_of? IP::Address::IPv6 and @mask.to_i.to_s != @mask) raise IP::AddressException.new("CIDR RHS is not valid - #{@mask}") end if @ip.kind_of? IP::Address::IPv4 and @mask.length > 2 # get the short netmask for IPv4 - this will throw an exception if the netmask is malformed. @mask = IP::Address::Util.short_netmask(IP::Address::IPv4.new(@mask)) end @mask = @mask.to_i end |
Instance Attribute Details
#cidr ⇒ Object (readonly)
Contains the original CIDR you fed it, returned as a string.
10 11 12 |
# File 'lib/ip/cidr.rb', line 10 def cidr @cidr end |
#ip ⇒ Object (readonly)
Contains the IP address (LHS) only. Returned as an IP::Address object.
15 16 17 |
# File 'lib/ip/cidr.rb', line 15 def ip @ip end |
#mask ⇒ Object (readonly)
Contains the integer-based (short) netmask (RHS) only. Returned as an integer.
20 21 22 |
# File 'lib/ip/cidr.rb', line 20 def mask @mask end |
Instance Method Details
#first_ip ⇒ Object
This returns the first ip address of the cidr as an IP::Address object.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/ip/cidr.rb', line 92 def first_ip rawip = @ip.pack # # since our actual mask calculation is done with the full 128 bits, # we have to shift calculations that we want in IPv4 to the left to # get proper return values. # if @ip.kind_of? IP::Address::IPv4 rawip = rawip << 96 end rawnm = (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) << (128 - @mask) lower = rawip & rawnm if @ip.kind_of? IP::Address::IPv4 lower = lower & (0xFFFFFFFF000000000000000000000000) lower = lower >> 96 end case @ip.class.object_id when IP::Address::IPv4.object_id return IP::Address::IPv4.new(lower) when IP::Address::IPv6.object_id return IP::Address::IPv6.new(lower) else raise IP::AddressException.new("Cannot determine type of IP address") end end |
#includes?(address) ⇒ Boolean
Given an IP::Address object, will determine if it is included in the current subnet. This does not generate a range and is comparatively much faster.
This will not generate an exception when IPv4 objects are compared to IPv6, and vice-versa. This is intentional.
182 183 184 185 186 187 188 189 190 |
# File 'lib/ip/cidr.rb', line 182 def includes?(address) raise TypeError.new("Expected type of IP::Address or derived") unless (address.kind_of? IP::Address) raw = address.pack first = first_ip.pack last = last_ip.pack return (raw >= first) && (raw <= last) end |
#last_ip ⇒ Object
This returns the last ip address of the cidr as an IP::Address object.
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/ip/cidr.rb', line 127 def last_ip rawip = @ip.pack # see #first_ip for the reason that we shift this way for IPv4. if @ip.kind_of? IP::Address::IPv4 rawip = rawip << 96 end rawnm = (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) << (128 - @mask) upper = rawip | ~rawnm if @ip.kind_of? IP::Address::IPv4 upper = upper & (0xFFFFFFFF000000000000000000000000) upper = upper >> 96 end case @ip.class.object_id when IP::Address::IPv4.object_id return IP::Address::IPv4.new(upper) when IP::Address::IPv6.object_id return IP::Address::IPv6.new(upper) else raise IP::AddressException.new("Cannot determine type of IP address") end end |
#long_netmask ⇒ Object
This produces the long netmask (eg. 255.255.255.255) of the CIDR in an IP::Address object.
This will throw an exception for IPv6 addresses.
64 65 66 67 68 69 70 |
# File 'lib/ip/cidr.rb', line 64 def long_netmask if @ip.kind_of? IP::Address::IPv6 raise IP::AddressException.new("IPv6 does not support a long netmask.") end return IP::Address::Util.long_netmask_ipv4(@mask) end |
#netmask ⇒ Object
53 54 55 56 |
# File 'lib/ip/cidr.rb', line 53 def netmask warn "IP::CIDR#netmask is deprecated. Please use IP::CIDR#long_netmask instead." return self.long_netmask end |
#overlaps?(other_cidr) ⇒ Boolean
This will take another IP::CIDR object as an argument and check to see if it overlaps with this cidr object. Returns true/false on overlap.
This also throws a TypeError if passed invalid data.
159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/ip/cidr.rb', line 159 def overlaps?(other_cidr) raise TypeError.new("Expected object of type IP::CIDR") unless(other_cidr.kind_of?(IP::CIDR)) myfirst = self.first_ip.pack mylast = self.last_ip.pack otherfirst = other_cidr.first_ip.pack otherlast = other_cidr.last_ip.pack return ((myfirst >= otherfirst && myfirst <= otherlast) || (mylast <= otherlast && mylast >= otherfirst) || (otherfirst >= myfirst && otherfirst <= mylast)) ? true : false; end |
#range ⇒ Object
This produces a range ala IP::Range, but only for the subnet defined by the CIDR object.
85 86 87 |
# File 'lib/ip/cidr.rb', line 85 def range return IP::Range[self.first_ip, self.last_ip] end |
#short_netmask ⇒ Object
This produces the short netmask (eg. 32) of the CIDR in an IP::Address object.
77 78 79 |
# File 'lib/ip/cidr.rb', line 77 def short_netmask return @mask end |