ruby-ip 0.9.1 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/README.rdoc +19 -0
  3. data/lib/ip/base.rb +80 -6
  4. data/test/ip_test.rb +65 -1
  5. metadata +20 -39
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 97b94276cb0106a57dda469aa8d5ac6b930c6c48
4
+ data.tar.gz: 1597755efb6569844d8b0d659f9b836a155eaf99
5
+ SHA512:
6
+ metadata.gz: 68be79249a2c3e1bdca7574e7c2006b6d6dc503fedb408a71da4eedfd765ef65d0feb08ee1b5c893f2e073a29060d3d040395f48744730368bc7c041a7c8c9ea
7
+ data.tar.gz: f25236b45eb5a3fad698935032ed79c1e490dc7a91512a7b3fbcb789b711f31d40cda38788b59afc15d045b1f0de5778d1715b6c0ed00521a88b4d1d052e608a
@@ -16,8 +16,10 @@ Docs:: http://deploy2.github.com/ruby-ip/
16
16
  ip = IP.new("192.0.2.53/24")
17
17
  ip.to_s # "192.0.2.53/24"
18
18
  ip.to_i # 3221226037
19
+ ip.to_b # 11000000000000000000001000110101
19
20
  ip.to_hex # "c0000235"
20
21
  ip.to_addr # "192.0.2.53"
22
+ ip.to_arpa # "53.2.0.192.in-addr.arpa."
21
23
  ip.pfxlen # 24
22
24
 
23
25
  * Qualify IP address with "routing context" (VRF)
@@ -67,6 +69,23 @@ Docs:: http://deploy2.github.com/ruby-ip/
67
69
  ip ^ 7 #<IP::V4 192.0.2.50/24>
68
70
  ~ip #<IP::V4 63.255.253.202/24>
69
71
 
72
+ * Advanced Subnet Operations
73
+ sn = IP.new('192.168.0.0/24')
74
+ ip = IP.new('192.168.0.48/32')
75
+ sn.split [#<IP::V4 192.168.0.0/25>,
76
+ #<IP::V4 192.168.0.128/25>] (2 evenly divided subnets)
77
+ sn.divide_by_subnets(3) [#<IP::V4 192.168.0.0/26>,
78
+ #<IP::V4 192.168.0.64/26>,
79
+ #<IP::V4 192.168.0.128/26>,
80
+ #<IP::V4 192.168.0.192/26>] (4 evenly divided subnets)
81
+ #keep in mind this always takes into account a network and broadcast address
82
+ sn.divide_by_hosts(100) [#<IP::V4 192.168.0.0/25>,
83
+ #<IP::V4 192.168.0.128/25>] (128 hosts each)
84
+ ip = IP.new('192.168.0.48/32')
85
+ ip.is_in?(sn)
86
+ => true
87
+
88
+
70
89
  * Convert to and from a compact Array representation
71
90
 
72
91
  ip1 = IP.new("192.0.2.53/24@cust1")
@@ -76,7 +76,10 @@ class IP
76
76
  def to_i
77
77
  @addr
78
78
  end
79
-
79
+ # returns the address in Binary
80
+ def to_b
81
+ @addr.to_s(2).to_i
82
+ end
80
83
  # Return the address as a hexadecimal string (8 or 32 digits)
81
84
  def to_hex
82
85
  @addr.to_s(16).rjust(self.class::ADDR_BITS>>2,"0")
@@ -187,6 +190,55 @@ class IP
187
190
  self.class.new(@addr & ~mask, self.class::ADDR_BITS, @ctx) ..
188
191
  self.class.new(@addr | mask, self.class::ADDR_BITS, @ctx)
189
192
  end
193
+ # test if the address is in the provided subnet
194
+ def is_in?(subnet)
195
+ return subnet.network.to_i <= self.network.to_i &&
196
+ subnet.broadcast.to_i >= self.broadcast.to_i
197
+ end
198
+ #this function sub-divides a subnet into two subnets of equal size
199
+ def split
200
+ nets = Array.new
201
+ if self.pfxlen < self.class::ADDR_BITS
202
+ if self.class::ADDR_BITS == 32
203
+ new_base = IP::V4.new(self.network.to_i, (self.pfxlen + 1))
204
+ nets = [new_base, IP::V4.new((new_base.broadcast + 1).to_i, (self.pfxlen + 1))]
205
+ end
206
+ if self.class::ADDR_BITS == 128
207
+ new_base = IP::V6.new(self.network.to_i, (self.pfxlen + 1))
208
+ nets = [new_base, IP::V6.new((new_base.broadcast + 1).to_i, (self.pfxlen + 1))]
209
+ end
210
+ end
211
+ return nets
212
+ end
213
+
214
+ # subdivide a larger subnet into smaller subnets by number of subnets of equal size,
215
+ # stop when subnets reach their smallest possible size (i.e. 31 for IP4)
216
+ def divide_by_subnets(number_subnets)
217
+ nets = Array.new
218
+ nets << self
219
+ begin
220
+ new_nets = Array.new
221
+ nets.each do |net|
222
+ new_nets = new_nets | net.split
223
+ end
224
+ nets = new_nets
225
+ end until number_subnets <= nets.length && nets[0].pfxlen <= (self.class::ADDR_BITS - 1)
226
+ return nets
227
+ end
228
+
229
+ # subdivide a larger subnet into smaller subnets by number of hosts
230
+ def divide_by_hosts(number_hosts)
231
+ nets = Array.new
232
+ nets << self
233
+ while number_hosts <= (nets[0].split[0].size - 2) && nets[0].pfxlen <= (self.class::ADDR_BITS - 1)
234
+ new_nets = Array.new
235
+ nets.each do |net|
236
+ new_nets = new_nets | net.split
237
+ end
238
+ nets = new_nets
239
+ end
240
+ return nets
241
+ end
190
242
 
191
243
  # The number of IP addresses in subnet
192
244
  # IP.new("1.2.3.4/24").size => 256
@@ -195,23 +247,23 @@ class IP
195
247
  end
196
248
 
197
249
  def +(other)
198
- self.class.new(@addr + other.to_int, @pfxlen, @ctx)
250
+ self.class.new(@addr + other.to_i, @pfxlen, @ctx)
199
251
  end
200
252
 
201
253
  def -(other)
202
- self.class.new(@addr - other.to_int, @pfxlen, @ctx)
254
+ self.class.new(@addr - other.to_i, @pfxlen, @ctx)
203
255
  end
204
256
 
205
257
  def &(other)
206
- self.class.new(@addr & other.to_int, @pfxlen, @ctx)
258
+ self.class.new(@addr & other.to_i, @pfxlen, @ctx)
207
259
  end
208
260
 
209
261
  def |(other)
210
- self.class.new(@addr | other.to_int, @pfxlen, @ctx)
262
+ self.class.new(@addr | other.to_i, @pfxlen, @ctx)
211
263
  end
212
264
 
213
265
  def ^(other)
214
- self.class.new(@addr ^ other.to_int, @pfxlen, @ctx)
266
+ self.class.new(@addr ^ other.to_i, @pfxlen, @ctx)
215
267
  end
216
268
 
217
269
  def ~
@@ -286,6 +338,11 @@ class IP
286
338
  sprintf("%d.%d.%d.%d",
287
339
  (@addr>>24)&0xff, (@addr>>16)&0xff, (@addr>>8)&0xff, @addr&0xff)
288
340
  end
341
+ #return the arpa version of the address for reverse DNS: http://en.wikipedia.org/wiki/Reverse_DNS_lookup
342
+ def to_arpa
343
+ sprintf("%d.%d.%d.%d.in-addr.arpa.",
344
+ @addr&0xff, (@addr>>8)&0xff, (@addr>>16)&0xff,(@addr>>24)&0xff)
345
+ end
289
346
  end
290
347
 
291
348
  class V6 < IP
@@ -357,6 +414,23 @@ class IP
357
414
  end
358
415
  end
359
416
 
417
+ # Return just the address in non-compact form, required for reverse IP.
418
+ def to_addr_full
419
+ if ipv4_compat?
420
+ "::#{native.to_addr}"
421
+ elsif ipv4_mapped?
422
+ "::ffff:#{native.to_addr}"
423
+ elsif @addr.zero?
424
+ "::"
425
+ else
426
+ return to_hex.scan(/..../).join(':')
427
+ end
428
+ end
429
+ #return the arpa version of the address for reverse DNS: http://en.wikipedia.org/wiki/Reverse_DNS_lookup
430
+ def to_arpa
431
+ return self.to_addr_full.reverse.gsub(':','').split(//).join('.') + ".ip6.arpa"
432
+ end
433
+
360
434
  def ipv4_mapped?
361
435
  (@addr >> 32) == 0xffff
362
436
  end
@@ -9,6 +9,7 @@ class IPTest < Test::Unit::TestCase
9
9
  assert_equal "1.2.3.4/26", res.to_s
10
10
  assert_equal "1.2.3.4/26", res.to_addrlen
11
11
  assert_equal 0x01020304, res.to_i
12
+ assert_equal 1000000100000001100000100, res.to_b
12
13
  assert_equal 26, res.pfxlen
13
14
  assert_nil res.ctx
14
15
  end
@@ -75,7 +76,22 @@ class IPTest < Test::Unit::TestCase
75
76
  should "disallow invalid pfxlen" do
76
77
  assert_raises(ArgumentError) { IP.new("1.2.3.4/33") }
77
78
  end
78
-
79
+
80
+ context "ip math" do
81
+ setup do
82
+ @addr1 = IP.new("1.2.3.4/24@foo")
83
+ @addr2 = IP.new("1.2.3.5/24@foo")
84
+ end
85
+
86
+ should "add to ip address" do
87
+ assert_equal @addr2, (@addr1 + 1)
88
+ end
89
+
90
+ should "subtract from ip address" do
91
+ assert_equal @addr1, (@addr2 - 1)
92
+ end
93
+ end
94
+
79
95
  context "address not on subnet boundary" do
80
96
  setup do
81
97
  @addr = IP.new("1.2.3.4/24@foo")
@@ -93,6 +109,10 @@ class IPTest < Test::Unit::TestCase
93
109
  assert_equal "1.2.3.4", @addr.to_addr
94
110
  end
95
111
 
112
+ should "have to_arpa" do
113
+ assert_equal "4.3.2.1.in-addr.arpa.", @addr.to_arpa
114
+ end
115
+
96
116
  should "have to_i" do
97
117
  assert_equal 0x01020304, @addr.to_i
98
118
  end
@@ -128,6 +148,47 @@ class IPTest < Test::Unit::TestCase
128
148
  should "have to_range" do
129
149
  assert_equal IP.new("1.2.3.0@foo")..IP.new("1.2.3.255@foo"), @addr.to_range
130
150
  end
151
+
152
+ should "have is_in?" do
153
+ assert_equal IP.new("1.2.3.0/25").is_in?(IP.new("1.2.3.0/24")), true
154
+ end
155
+
156
+ should "find whether an IP is included in a range" do
157
+ assert_equal IP.new("1.2.3.1").is_in?(IP.new("1.2.3.0/24")), true
158
+ end
159
+
160
+ should "find whether an IP is not included a range" do
161
+ assert_equal IP.new("1.2.4.1").is_in?(IP.new("1.2.3.0/24")), false
162
+ end
163
+
164
+ should "find when a subnet is included in a range" do
165
+ assert_equal IP.new("1.2.3.0/30").is_in?(IP.new("1.2.3.0/24")), true
166
+ end
167
+
168
+ should "find when a subnet is not included in a range" do
169
+ assert_equal IP.new("1.2.4.0/30").is_in?(IP.new("1.2.3.0/24")), false
170
+ end
171
+
172
+ should "have split" do
173
+ assert_equal IP.new("1.2.3.0/24").split, [IP.new("1.2.3.0/25"), IP.new("1.2.3.128/25")]
174
+ end
175
+
176
+ should "have divide_by_subnets be exact" do
177
+ assert_equal IP.new("1.2.3.0/24").divide_by_subnets(4), [IP.new("1.2.3.0/26"), IP.new("1.2.3.64/26"),IP.new("1.2.3.128/26"), IP.new("1.2.3.192/26")]
178
+ end
179
+
180
+ should "have divide_by_subnets choose next largest" do
181
+ assert_equal IP.new("1.2.3.0/24").divide_by_subnets(3), [IP.new("1.2.3.0/26"), IP.new("1.2.3.64/26"),IP.new("1.2.3.128/26"), IP.new("1.2.3.192/26")]
182
+ end
183
+ should "have divide_by_hosts subnet boundary" do
184
+ assert_equal IP.new("1.2.3.0/24").divide_by_hosts(128), [IP.new("1.2.3.0/24")]
185
+ end
186
+ should "have divide_by_hosts full subnet" do
187
+ assert_equal IP.new("1.2.3.0/24").divide_by_hosts(126), [IP.new("1.2.3.0/25"), IP.new("1.2.3.128/25")]
188
+ end
189
+ should "have divide_by_hosts partial subnet" do
190
+ assert_equal IP.new("1.2.3.0/24").divide_by_hosts(68), [IP.new("1.2.3.0/25"), IP.new("1.2.3.128/25")]
191
+ end
131
192
 
132
193
  should "have size" do
133
194
  assert_equal 256, @addr.size
@@ -486,7 +547,10 @@ class IPTest < Test::Unit::TestCase
486
547
  @addr.to_s
487
548
  @addr.to_addrlen
488
549
  @addr.to_addr
550
+ @addr.to_arpa
489
551
  @addr.to_i
552
+ @addr.to_b
553
+ @addr.split
490
554
  @addr.to_a
491
555
  @addr.to_ah
492
556
  @addr.to_hex
metadata CHANGED
@@ -1,32 +1,22 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ruby-ip
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 9
8
- - 1
9
- version: 0.9.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.3
10
5
  platform: ruby
11
- authors:
6
+ authors:
12
7
  - Brian Candler
13
8
  autorequire:
14
9
  bindir: bin
15
10
  cert_chain: []
16
-
17
- date: 2011-12-13 00:00:00 +00:00
18
- default_executable:
11
+ date: 2011-12-13 00:00:00.000000000 Z
19
12
  dependencies: []
20
-
21
13
  description: IP address manipulation library
22
14
  email: b.candler@pobox.com
23
15
  executables: []
24
-
25
16
  extensions: []
26
-
27
- extra_rdoc_files:
17
+ extra_rdoc_files:
28
18
  - README.rdoc
29
- files:
19
+ files:
30
20
  - lib/ip/base.rb
31
21
  - lib/ip/cpal.rb
32
22
  - lib/ip/socket.rb
@@ -38,38 +28,29 @@ files:
38
28
  - Rakefile
39
29
  - LICENSE.txt
40
30
  - COPYING.txt
41
- has_rdoc: true
42
31
  homepage: http://github.com/deploy2/ruby-ip
43
32
  licenses: []
44
-
33
+ metadata: {}
45
34
  post_install_message:
46
- rdoc_options:
35
+ rdoc_options:
47
36
  - --inline-source
48
37
  - --charset=UTF-8
49
- require_paths:
38
+ require_paths:
50
39
  - lib
51
- required_ruby_version: !ruby/object:Gem::Requirement
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- segments:
56
- - 0
57
- version: "0"
58
- required_rubygems_version: !ruby/object:Gem::Requirement
59
- requirements:
60
- - - ">="
61
- - !ruby/object:Gem::Version
62
- segments:
63
- - 1
64
- - 3
65
- - 6
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - '>='
48
+ - !ruby/object:Gem::Version
66
49
  version: 1.3.6
67
50
  requirements: []
68
-
69
51
  rubyforge_project: ruby-ip
70
- rubygems_version: 1.3.6
52
+ rubygems_version: 2.0.14
71
53
  signing_key:
72
54
  specification_version: 2
73
55
  summary: IP address manipulation library
74
56
  test_files: []
75
-