ip 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. data/lib/ip.rb +232 -0
  2. metadata +39 -0
@@ -0,0 +1,232 @@
1
+ #
2
+ # IP - Collection of Tools to work with IP addresses
3
+ #
4
+ # Version:: 0.0.1
5
+ # Author:: Erik Hollensbe
6
+ # License:: BSD
7
+ # Contact:: erik@hollensbe.org
8
+ #
9
+ # IP is, as mentioned above, a collection of tools to work
10
+ # with IP addresses. There are three major classes included
11
+ # in the IP namespace, IP::Address, which works with standard
12
+ # dotted-quad IP addresses, IP::Range, which can calculate and return
13
+ # a range of IP::Address objects, and IP::CIDR, which can work with
14
+ # Classless Inter-Domain Routing address formats.
15
+ #
16
+ # The IP module uses long integers and bit-flipping per <netinet/in.h>
17
+ # to achieve fairly efficient performance, as opposed to a purely
18
+ # iterative approach. This is most true when calculating ranges and
19
+ # netmasks.
20
+ #
21
+ # Please see the documentation for each of these classes for usage
22
+ # information.
23
+ #
24
+ # Note: there is no IPv6 support as of current, but this is planned in
25
+ # perhaps a distant, future release. Any patches that can correct this
26
+ # issue are most welcome.
27
+ #
28
+
29
+ class IP
30
+
31
+ #
32
+ # A IP::AddressException is thrown when an IP address cannot be
33
+ # parsed.
34
+ #
35
+
36
+ class AddressException < Exception
37
+ end
38
+
39
+ #
40
+ # A IP::BoundaryException is thrown when an index is being used out of
41
+ # it's pre-defined boundary. This is most relevant when using the []
42
+ # method in IP::Address.
43
+ #
44
+
45
+ class BoundaryException < Exception
46
+ end
47
+
48
+ #
49
+ # IP::Range - Calculates a range of IP addresses, and returns an
50
+ # Array of IP::Address objects.
51
+ #
52
+ # Usage::
53
+ #
54
+ # IP::Range['10.0.0.1', '10.0.0.2'] => IP::Address objects between
55
+ # 10.0.0.1 and 10.0.0.2 (inclusive)
56
+ #
57
+ # IP::Range can also take two IP::Address objects.
58
+ #
59
+ # Will throw a IP::AddressException if for some reason addresses
60
+ # cannot be parsed.
61
+ #
62
+
63
+ class Range
64
+
65
+ #
66
+ # See the documentation for IP::Range for more information on this
67
+ # method.
68
+ #
69
+
70
+ def Range.[](addr1, addr2)
71
+ raw1, raw2 = [nil, nil]
72
+
73
+ if addr1.kind_of? String
74
+ raw1 = IP::Address.pack(IP::Address.new(addr1))
75
+ elsif addr1.kind_of? IP::Address
76
+ raw1 = IP::Address.pack(addr1)
77
+ else
78
+ raise IP::AddressException("IP Address is not type String or IP::Address")
79
+ end
80
+
81
+ if addr2.kind_of? String
82
+ raw2 = IP::Address.pack(IP::Address.new(addr2))
83
+ elsif addr2.kind_of? IP::Address
84
+ raw2 = IP::Address.pack(addr2)
85
+ else
86
+ raise IP::AddressException("IP Address is not type String or IP::Address")
87
+ end
88
+
89
+ range = []
90
+
91
+ (raw1..raw2).each { |x| range.push(IP::Address.unpack(x)) }
92
+
93
+ return range
94
+ end
95
+ end
96
+
97
+ #
98
+ # IP::CIDR - Works with Classless Inter-Domain Routing formats, such
99
+ # as 10.0.0.1/32.
100
+ #
101
+ # Note: this class does not work with expanded RHS
102
+ # netmasks, such as 10.0.0.1/255.255.255.255. This is to be
103
+ # corrected in a later release.
104
+ #
105
+
106
+ class CIDR
107
+ #
108
+ # Contains the original CIDR you fed it, returned as a string.
109
+ #
110
+ attr_reader :cidr
111
+ #
112
+ # Contains the IP address (LHS) only. Returned as an IP::Address
113
+ # object.
114
+ #
115
+ attr_reader :ip
116
+ #
117
+ # Contains the integer-based netmask (RHS) only. Returned as an
118
+ # integer.
119
+ #
120
+ attr_reader :mask
121
+
122
+ #
123
+ # Given a string of format X.X.X.X/X, in standard CIDR notation,
124
+ # this will construct a IP::CIDR object.
125
+ #
126
+ def initialize(cidr)
127
+ if !cidr.kind_of? String
128
+ raise IP::AddressException("CIDR value is not of type String")
129
+ end
130
+
131
+ @cidr = cidr
132
+ @ip, @mask = cidr.split(/\//)
133
+
134
+ if @mask.length == 0 or @mask.length > 2 or /\D/.match @mask
135
+ raise IP::AddressException("CIDR RHS is not valid - #{@mask}")
136
+ end
137
+
138
+ @ip = IP::Address.new(@ip)
139
+ @mask = @mask.to_i
140
+ end
141
+
142
+ #
143
+ # This produces the netmask of the CIDR in an IP::Address object.
144
+ #
145
+ def netmask
146
+ raw = 0xFFFFFFFF << (32 - @mask)
147
+ return IP::Address.unpack(raw)
148
+ end
149
+
150
+ #
151
+ # This produces a range ala IP::Range, but only for the subnet
152
+ # defined by the CIDR object.
153
+ #
154
+ def range
155
+ rawip = IP::Address.pack(@ip)
156
+ rawnm = 0xFFFFFFFF << (32 - @mask)
157
+ upper = rawip | ~rawnm
158
+ return IP::Range[IP::Address.unpack(rawip), IP::Address.unpack(upper)]
159
+ end
160
+
161
+ end
162
+
163
+ #
164
+ # IP::Address - utility class to work with dotted-quad IP addresses.
165
+ #
166
+ class Address
167
+ #
168
+ # This original IP Address you passed it, returned as a string.
169
+ #
170
+ attr_reader :ip_address
171
+ #
172
+ # This returns an Array of Integer which contains the octets of
173
+ # the IP, in descending order.
174
+ #
175
+ attr_reader :octets
176
+
177
+ #
178
+ # When given a string, constructs an IP::Address object.
179
+ #
180
+ def initialize(ip_address)
181
+ if ! ip_address.kind_of? String
182
+ raise IP::AddressException("Fed IP address is not String")
183
+ end
184
+ @ip_address = ip_address
185
+ @octets = ip_address.split(/\./).collect { |x| x.to_i }
186
+
187
+ # I made a design decision to allow 0.0.0.0 here.
188
+ if @octets.length != 4 or @octets.find_all { |x| x > 255 }.length > 0
189
+ raise IP::AddressException.new("IP address is improperly formed")
190
+ end
191
+ end
192
+
193
+ #
194
+ # Returns an octet given the proper index. The octets returned are
195
+ # Integer types.
196
+ #
197
+ def [](num)
198
+ if num > 3
199
+ raise IP::BoundaryException.new("Max octet number is 3")
200
+ end
201
+ return @octets[num]
202
+ end
203
+
204
+ #
205
+ # See [].
206
+ #
207
+ alias_method :octet, :[]
208
+
209
+ #
210
+ # Class method to pack an IP::Address object into a long integer
211
+ # used for calculation. Returns a 'FixNum' type.
212
+ #
213
+ def Address.pack(ip)
214
+ ret = 0
215
+ myip = ip.octets.reverse
216
+ 4.times { |x| ret = ret | (myip[x] & 0xFF) << 8*x }
217
+ return ret
218
+ end
219
+
220
+ #
221
+ # Class method to take a 'FixNum' type and return an IP::Address
222
+ # object.
223
+ #
224
+ def Address.unpack(ip)
225
+ ret = []
226
+ 4.times { |x| ret.push((ip >> 8*x) & 0xFF) }
227
+ return IP::Address.new(ret.reverse.join("."))
228
+ end
229
+
230
+ end
231
+
232
+ end
metadata ADDED
@@ -0,0 +1,39 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11
3
+ specification_version: 1
4
+ name: ip
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.1
7
+ date: 2005-10-17 00:00:00 -07:00
8
+ summary: "Ruby classes to work with IP address, ranges, and netmasks"
9
+ require_paths:
10
+ - lib
11
+ email: erik@hollensbe.org
12
+ homepage:
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: ip
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ -
22
+ - ">"
23
+ - !ruby/object:Gem::Version
24
+ version: 0.0.0
25
+ version:
26
+ platform: ruby
27
+ signing_key:
28
+ cert_chain:
29
+ authors:
30
+ - Erik Hollensbe
31
+ files:
32
+ - lib/ip.rb
33
+ test_files: []
34
+ rdoc_options: []
35
+ extra_rdoc_files: []
36
+ executables: []
37
+ extensions: []
38
+ requirements: []
39
+ dependencies: []