ipadmin 0.3.0 → 0.4.0

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.
data/README CHANGED
@@ -1,11 +1,10 @@
1
-
2
1
  =Introduction
3
2
 
4
3
  IPAdmin arose from a work-related project to create a Rails IP
5
4
  Administration package. I needed a back-end module that could easily
6
5
  handle such advanced tasks as automating the subnetting/supernetting
7
6
  of IP space, performing calculations on IP CIDR blocks, and other
8
- various tasks. At the current time there were no modules that could
7
+ various items. At that time there were no modules that could
9
8
  do any of the things that I needed, so I set out to create my own.
10
9
  Since it proved to be fairly useful to me, I decided to share the
11
10
  code with the Ruby community.
@@ -20,14 +19,9 @@
20
19
  your life easier. Comments are also welcome (positive ones in particular).
21
20
 
22
21
  Dustin Spinhirne
23
-
24
-
25
- Copyright (c) 2006 Dustin Spinhirne - http://www.spinhirne.com
26
- Licensed under the same terms as Ruby, No Warranty is provided.
27
22
 
28
-
29
23
 
30
- =CIDR:
24
+ =CIDR - Classless Inter-Domain Routing
31
25
 
32
26
  A class & series of methods for creating and manipulating CIDR network
33
27
  addresses. Both IPv4 and IPv6 are supported.
@@ -43,7 +37,7 @@
43
37
  methods for modifying the CIDR or creating new derivative CIDR's.
44
38
 
45
39
  An example CIDR object is as follows:
46
- IPAdmin::CIDR.new(:CIDR => '192.168.1.20/24')
40
+ IPAdmin::CIDR.new('192.168.1.20/24')
47
41
 
48
42
  This would create a CIDR object (192.168.1.0/24) with the following properties:
49
43
  version = 4
@@ -69,14 +63,14 @@
69
63
  print "\n"
70
64
 
71
65
  # new
72
- cidr4 = IPAdmin::CIDR.new(:CIDR => '192.168.1.0/24')
66
+ cidr4 = IPAdmin::CIDR.new('192.168.1.0/24')
73
67
  cidr4 = IPAdmin::CIDR.new(:CIDR => '192.168.1.1',
74
68
  :Netmask => '255.255.255.0',
75
69
  :Tag => {'test' => 'cidr4 tag'})
76
- cidr6 = IPAdmin::CIDR.new(:CIDR => 'fec0::1/64')
70
+ cidr6 = IPAdmin::CIDR.new('fec0::1/64')
77
71
 
78
- cidr4_2 = IPAdmin::CIDR.new(:CIDR => '192.168.1.0/26')
79
- cidr6_2 = IPAdmin::CIDR.new(:CIDR => 'fec0::0/96')
72
+ cidr4_2 = IPAdmin::CIDR.new('192.168.1.0/26')
73
+ cidr6_2 = IPAdmin::CIDR.new('fec0::0/96')
80
74
 
81
75
  # reader/writer
82
76
  puts "reader/writer"
@@ -121,6 +115,12 @@
121
115
  cidr6.enumerate(:Limit => 4, :Bitstep => 32, :Objectify => true).each {|x| puts " #{x.desc}"}
122
116
  print "\n"
123
117
 
118
+ # fill_in
119
+ puts "fill_in"
120
+ puts "#{cidr4.desc} filled-in is:"
121
+ cidr4.fill_in([cidr4_2]).each {|x| puts x}
122
+ print "\n"
123
+
124
124
  # hostmask_ext
125
125
  puts "hostmask_ext"
126
126
  puts "cidr4 extended hostmask #{cidr4.hostmask_ext()}"
@@ -139,8 +139,8 @@
139
139
  print "\n"
140
140
 
141
141
  # multicast_mac
142
- mcast = IPAdmin::CIDR.new(:CIDR => '224.0.0.6')
143
- mcast2 = IPAdmin::CIDR.new(:CIDR => 'ff00::abcd')
142
+ mcast = IPAdmin::CIDR.new('224.0.0.6')
143
+ mcast2 = IPAdmin::CIDR.new('ff00::abcd')
144
144
  puts "multicast_mac"
145
145
  puts "#{mcast.ip} multicast mac is #{mcast.multicast_mac()}"
146
146
  puts "#{mcast2.ip} multicast mac is #{mcast2.multicast_mac()}"
@@ -177,7 +177,7 @@
177
177
 
178
178
  # nth
179
179
  puts "nth"
180
- puts "cidr4 1st ip is #{cidr4.nth(:Index => 1)}"
180
+ puts "cidr4 1st ip is #{cidr4.nth(1)}"
181
181
  puts "cidr6 1st ip is #{(cidr6.nth(:Index => 1, :Objectify => true)).base}"
182
182
  print "\n"
183
183
 
@@ -207,15 +207,15 @@
207
207
 
208
208
  # remainder
209
209
  puts "remainder"
210
- cidr4_2 = IPAdmin::CIDR.new(:CIDR => '192.168.1.64/26')
210
+ cidr4_2 = IPAdmin::CIDR.new('192.168.1.64/26')
211
211
  puts "The remainder of #{cidr4.desc} after subtracting #{cidr4_2.desc} is:"
212
- cidr4.remainder(:Exclude => cidr4_2).each {|x| puts x}
212
+ cidr4.remainder(cidr4_2).each {|x| puts x}
213
213
  print "\n"
214
214
 
215
215
  # resize!
216
216
  puts "resize!"
217
- cidr4.resize!(:Subnet => 25)
218
- cidr6.resize!(:Subnet => 65)
217
+ cidr4.resize!(25)
218
+ cidr6.resize!(:Netmask => 65)
219
219
  puts "cidr4 resized is #{cidr4.desc}"
220
220
  puts "cidr6 resized is #{cidr6.desc}"
221
221
  print "\n"
@@ -234,12 +234,11 @@
234
234
  puts "#{cidr6.desc(:Short => true)} subnetted into at least 4 /67 ranges"
235
235
  cidr6.subnet(:Subnet => 67, :MinCount => 4, :Short => true).each {|x| puts " #{x}"}
236
236
 
237
-
238
-
239
-
240
-
241
- =EUI:
242
237
 
238
+
239
+
240
+ =EUI - Extended Unique Identifier
241
+
243
242
  A class & series of methods for creating and manipulating Extended Unique Identifier
244
243
  (EUI) addresses. Two types of address formats are supported EUI-48 and EUI-64. The
245
244
  most common use for this class will be to manipulate MAC addresses (which are essentially
@@ -254,8 +253,7 @@
254
253
  is to help automate certain address assignments within IP. For example, IPv6
255
254
  Link Local addresses use MAC addresses for IP auto-assignment and multicast MAC addresses
256
255
  are determined based on the multicast IP address.
257
-
258
-
256
+
259
257
  ====Examples:
260
258
 
261
259
  #!/usr/bin/ruby
@@ -266,8 +264,8 @@
266
264
  puts "IPAdmin::EUI"
267
265
  print "\n"
268
266
 
269
- eui1 = IPAdmin::EUI.new(:EUI => 'aa-bb-cc-dd-ee-ff')
270
- eui2 = IPAdmin::EUI.new(:EUI => '12-34-56-78-9a-bc-de-f0')
267
+ eui1 = IPAdmin::EUI48.new('aa-bb-cc-dd-ee-ff')
268
+ eui2 = IPAdmin::EUI64.new('12-34-56-78-9a-bc-de-f0')
271
269
 
272
270
  # oui
273
271
  puts "oui"
@@ -294,38 +292,33 @@
294
292
  print "\n"
295
293
 
296
294
  # type
297
- puts "type"
298
- puts "eui 1 type is #{eui1.type}"
299
- puts "eui 2 type is #{eui2.type}"
300
-
295
+ puts "class"
296
+ puts "eui 1 is a #{eui1.class}"
297
+ puts "eui 2 is a #{eui2.class}"
298
+
299
+
301
300
 
302
301
 
303
- =Tree:
302
+ =Tree
304
303
 
305
304
  A class & series of methods for creating and manipulating IP-based
306
305
  heirarchical trees. Both IPv4 and IPv6 are supported.
307
-
308
- Tree's are useful for creating mini 'routing tables' of CIDR address space.
309
- Using a tree, you can quickly determine the 'route' of another CIDR via
310
- the standard longest-match algorithm.
311
-
312
- Tree's are not dynamic, in that if you modify any of the CIDR objects
313
- contained within, the Tree will not automatically adjust itself accordingly.
314
- For example if you have a tree like the following:
315
-
316
- 192.168.0.0/24
317
- 192.168.0.0/26
318
- 192.168.1.0/24
319
-
320
- You decide to resize 192.168.0.0/24 to 192.168.0.0/23. The tree will now
321
- be incorrect:
322
-
323
- 192.168.0.0/23
324
- 192.168.0.0/26
325
- 192.168.1.0/24
326
306
 
327
- You would need to remove and re-add the CIDR 192.168.0.0/23 in order for the
328
- tree to rebuild itself properly.
307
+ A sample tree would look like:
308
+ 192.168.1.0/24
309
+ 192.168.1.0/26
310
+ 192.168.1.0/27
311
+ 192.168.1.0/28
312
+ 192.168.1.16/29
313
+ 192.168.1.16/30
314
+ 192.168.1.24/30
315
+ 192.168.1.25/32
316
+ 192.168.1.28/30
317
+ 192.168.1.32/27
318
+ 192.168.1.64/26
319
+ 192.168.1.64/27
320
+ 192.168.1.128/26
321
+ 192.168.1.192/26
329
322
 
330
323
 
331
324
  ====Examples:
@@ -338,124 +331,154 @@
338
331
  puts "IPAdmin::Tree"
339
332
  print "\n"
340
333
 
341
- cidr4 = [IPAdmin::CIDR.new(:CIDR => '192.168.1.0/24'),
342
- IPAdmin::CIDR.new(:CIDR => '192.168.1.0/26'),
343
- IPAdmin::CIDR.new(:CIDR => '192.168.1.64/26'),
344
- IPAdmin::CIDR.new(:CIDR => '192.168.1.128/26'),
345
- IPAdmin::CIDR.new(:CIDR => '192.168.1.192/26'),
346
- IPAdmin::CIDR.new(:CIDR => '192.168.1.0/27'),
347
- IPAdmin::CIDR.new(:CIDR => '192.168.1.0/28'),
348
- IPAdmin::CIDR.new(:CIDR => '192.168.1.16/28'),
349
- IPAdmin::CIDR.new(:CIDR => '192.168.1.16/29'),
350
- IPAdmin::CIDR.new(:CIDR => '192.168.1.32/27')]
351
-
352
- cidr6 = [IPAdmin::CIDR.new(:CIDR => 'fec0::/64'),
353
- IPAdmin::CIDR.new(:CIDR => 'fec0::/66'),
354
- IPAdmin::CIDR.new(:CIDR => 'fec0::4000:0:0:0/66'),
355
- IPAdmin::CIDR.new(:CIDR => 'fec0::8000:0:0:0/66'),
356
- IPAdmin::CIDR.new(:CIDR => 'fec0::c000:0:0:0/66'),
357
- IPAdmin::CIDR.new(:CIDR => 'fec0::c000:0:0:0/67'),
358
- IPAdmin::CIDR.new(:CIDR => 'fec0::/67'),
359
- IPAdmin::CIDR.new(:CIDR => 'fec0::2000:0:0:0/67')]
334
+ cidr4 = ['192.168.1.0/24','192.168.1.0/26','192.168.1.64/26',
335
+ '192.168.1.128/26','192.168.1.192/26','192.168.1.0/27',
336
+ '192.168.1.0/28','192.168.1.16/30','192.168.1.16/29',
337
+ '192.168.1.32/27','192.168.1.24/30','192.168.1.28/30',
338
+ '192.168.1.64/27','192.168.1.25']
339
+
340
+ cidr6 = ['fec0::/60','fec0::/66','fec0::4000:0:0:0/66',
341
+ 'fec0::8000:0:0:0/66','fec0::c000:0:0:0/66','fec0::c000:0:0:0/67',
342
+ 'fec0::/67','fec0::2000:0:0:0/67','fec0::8000:0:0:0/67','fec0::4000:0:0:0/69']
360
343
 
361
344
  # new
362
- tree4 = IPAdmin::Tree.new(:Version => 4)
363
- tree6 = IPAdmin::Tree.new(:Version => 6)
345
+ tree = IPAdmin::Tree.new()
346
+
364
347
 
365
- # add
366
- puts "add"
348
+ # add!
349
+ puts "add!"
367
350
  cidr4.each do |x|
368
- puts "adding #{x.desc}..."
369
- tree4.add(x)
351
+ puts "adding #{x}..."
352
+ tree.add!(x)
370
353
  end
371
354
  cidr6.each do |x|
372
- puts "adding #{x.desc}..."
373
- tree6.add(x)
355
+ puts "adding #{x}..."
356
+ tree.add!(x)
374
357
  end
375
358
  print "\n"
376
359
 
377
- # dump
360
+ # ancestors
361
+ puts "ancestors"
362
+ puts "ancestors for 192.168.1.16/28 are..."
363
+ tree.ancestors('192.168.1.16/28').each {|x| puts x.desc}
364
+ print "\n"
365
+
366
+ # children
367
+ puts "children"
368
+ puts "children of 192.168.1.0/24 are..."
369
+ tree.children('192.168.1.0/24').each {|x| puts x.desc}
370
+ print "\n"
371
+
372
+ # delete!
373
+ puts "delete!"
374
+ puts "deleting 192.168.1.16/29"
375
+ tree.delete!('192.168.1.16/29')
376
+ print "\n"
377
+
378
+ # descendants
379
+ puts "descendants"
380
+ puts "descendants of 192.168.1.0/26 are..."
381
+ tree.descendants('192.168.1.0/26').each {|x| puts x.desc}
382
+ print "\n"
383
+
384
+ # dump
378
385
  puts "dump"
379
- puts "dumping & printing tree4"
380
- dumped = tree4.dump()
386
+ puts "dumping & printing tree"
387
+ dumped = tree.dump()
381
388
  dumped.each do |val|
382
- obj = val[:Object]
389
+ cidr = val[:CIDR]
383
390
  depth = val[:Depth]
384
391
  if (depth > 0)
385
392
  indent = " " * (depth*3)
386
- puts indent << obj.desc()
393
+ puts indent << cidr.desc()
387
394
  else
388
- puts obj.desc()
395
+ puts cidr.desc()
389
396
  end
390
397
  end
398
+ print "\n"
399
+
400
+ # exists?
401
+ puts "exists?"
402
+ puts "192.168.1.32/27 is in the tree." if tree.exists?('192.168.1.32/27')
391
403
  print "\n"
392
- puts "dumping & printing tree6"
393
- dumped = tree6.dump()
394
- dumped.each do |val|
395
- obj = val[:Object]
396
- depth = val[:Depth]
397
- if (depth > 0)
398
- indent = " " * (depth*3)
399
- puts indent << obj.desc()
400
- else
401
- puts obj.desc()
402
- end
403
- end
404
+
405
+ # fill_in
406
+ puts "fill_in!"
407
+ puts "filling in subnets of 192.168.1.64/26."
408
+ tree.fill_in!('192.168.1.64/26')
409
+ tree.children('192.168.1.64/26').each {|x| puts x.desc}
404
410
  print "\n"
405
-
406
- # find space
407
- puts "find_space with at least 28 IP's in it"
408
- puts "available space with at least 28 IPs"
409
- space = tree4.find_space(:IPCount => 28)
410
- space.each do |obj|
411
- puts " #{obj.desc}"
412
- end
411
+
412
+ # find
413
+ puts "find"
414
+ puts "finding and setting a tag for 192.168.1.64/26..."
415
+ tree.find('192.168.1.64/26').tag[:test] = 'testing'
413
416
  print "\n"
414
- puts "available /67 space"
415
- space = tree6.find_space(:Subnet => 67)
416
- space.each do |obj|
417
- puts " #{obj.desc}"
418
- end
417
+
418
+ # find_space
419
+ puts "find_space"
420
+ puts "finding version 4 subnets with at least 16 ips..."
421
+ tree.find_space(:IPCount => 16, :Version => 4).each {|x| puts x.desc}
422
+ print "\n"
423
+
424
+ # longest_match
425
+ puts "longest_match"
426
+ puts "192.168.1.33 belongs in #{tree.longest_match('192.168.1.33').desc}"
427
+ print "\n"
428
+
429
+ # merge_subnets
430
+ puts "merge_subnets!"
431
+ puts "merging the subnets of 192.168.1.0/27"
432
+ tree.merge_subnets!('192.168.1.0/27')
433
+ puts tree.show
434
+ print "\n"
435
+
436
+ # prune
437
+ puts "prune!"
438
+ puts "pruning subnets of 192.168.1.0/27"
439
+ tree.prune!('192.168.1.0/27')
419
440
  print "\n"
420
441
 
421
442
  # remove
422
- puts "remove"
423
- puts "removing #{cidr4[8].desc}"
424
- tree4.remove(cidr4[8])
425
- puts tree4.show()
443
+ puts "remove!"
444
+ puts "removing fec0::c000:0:0:0/67, and all of its subnets"
445
+ tree.remove!('fec0::c000:0:0:0/67')
426
446
  print "\n"
427
- puts "removing #{cidr6[5].desc}"
428
- tree6.remove(cidr6[5])
429
- puts tree6.show()
447
+
448
+ # resize
449
+ puts "resize!"
450
+ puts "resizing fec0::/60 into a /65"
451
+ tree.resize!('fec0::/60', 65)
430
452
  print "\n"
431
453
 
432
- # prune
433
- puts "prune"
434
- puts "pruning #{cidr4[4].desc}"
435
- tree4.prune(cidr4[4])
436
- puts tree4.show()
454
+ # root
455
+ puts "root"
456
+ puts "root of 192.168.1.32/27 is #{tree.root('192.168.1.32/27').desc}"
437
457
  print "\n"
438
- puts "pruning #{cidr6[1].desc}"
439
- tree6.prune(cidr6[1])
440
- puts tree6.show()
458
+
459
+ # siblings
460
+ puts "siblings"
461
+ puts "siblings of 192.168.1.0/26 are..."
462
+ tree.siblings('192.168.1.0/26').each {|x| puts x.desc}
441
463
  print "\n"
442
464
 
443
- # collapse
444
- puts "collapse"
445
- puts "collapsed tree4 is..."
446
- new_tree4 = tree4.collapse()
447
- puts new_tree4.show()
465
+ # supernets
466
+ puts "supernets"
467
+ puts "supernets of this tree are..."
468
+ tree.supernets.each {|x| puts x.desc}
448
469
  print "\n"
449
- puts "collapsed tree6 is..."
450
- new_tree6 = tree6.collapse()
451
- puts new_tree6.show()
452
-
470
+
471
+ # show
472
+ puts "show"
473
+ puts "showing tree..."
474
+ puts tree.show
475
+
453
476
 
454
477
 
455
- = IPAdmin General Methods
478
+ =General Methods
456
479
 
457
480
  A collection of general purpose methods that dont really fit within
458
- a particular class.
481
+ any particular class.
459
482
 
460
483
 
461
484
  ====Examples:
@@ -470,22 +493,22 @@
470
493
 
471
494
  # validate ip
472
495
  puts "validate ip"
473
- puts "192.168.1.0 is valid" if ( IPAdmin.validate_ip_addr(:IP => '192.168.1.0') )
474
- puts "fec0::0 is valid" if ( IPAdmin.validate_ip_addr(:IP => 'fec0::0') )
475
- puts "::ffff:10.1.0.1 is valid" if ( IPAdmin.validate_ip_addr(:IP => '::ffff:10.1.0.1') )
496
+ puts "192.168.1.0 is valid" if ( IPAdmin.validate_ip_addr('192.168.1.0') )
497
+ puts "fec0::0 is valid" if ( IPAdmin.validate_ip_addr('fec0::0') )
498
+ puts "::ffff:10.1.0.1 is valid" if ( IPAdmin.validate_ip_addr('::ffff:10.1.0.1') )
476
499
  print "\n"
477
500
 
478
501
  # validate netmask
479
502
  puts "validate netmask"
480
- puts "255.255.255.0 is valid" if (IPAdmin.validate_ip_netmask(:Netmask => '255.255.255.0') )
481
- puts "/24 is valid" if ( IPAdmin.validate_ip_netmask(:Netmask => '/24') )
503
+ puts "255.255.255.0 is valid" if (IPAdmin.validate_ip_netmask('255.255.255.0') )
504
+ puts "/24 is valid" if ( IPAdmin.validate_ip_netmask('/24') )
482
505
  puts "/64 is valid" if ( IPAdmin.validate_ip_netmask(:Netmask => 64, :Version => 6) )
483
506
 
484
- cidr4_1 = IPAdmin::CIDR.new(:CIDR => '192.168.1.0/24')
485
- cidr4_2 = IPAdmin::CIDR.new(:CIDR => '192.168.1.0/25')
486
- cidr4_3 = IPAdmin::CIDR.new(:CIDR => '192.168.1.50')
487
- cidr6_1 = IPAdmin::CIDR.new(:CIDR => 'fec0::0/10')
488
- cidr6_2 = IPAdmin::CIDR.new(:CIDR => 'fec0::0/64')
507
+ cidr4_1 = IPAdmin::CIDR.new('192.168.1.0/24')
508
+ cidr4_2 = IPAdmin::CIDR.new('192.168.1.0/25')
509
+ cidr4_3 = IPAdmin::CIDR.new('192.168.1.50')
510
+ cidr6_1 = IPAdmin::CIDR.new('fec0::0/10')
511
+ cidr6_2 = IPAdmin::CIDR.new('fec0::0/64')
489
512
  print "\n"
490
513
 
491
514
  # compare
@@ -500,6 +523,17 @@
500
523
  cidr6_1 = IPAdmin::CIDR.new(:CIDR => 'fec0::0/128')
501
524
  cidr6_2 = IPAdmin::CIDR.new(:CIDR => 'fec0::1/128')
502
525
  print "\n"
526
+
527
+ # merge
528
+ puts "merge"
529
+ puts "merging 192.168.1.0/27, 192.168.1.32/27, 192.168.1.64/26, and 192.168.1.128/25..."
530
+ IPAdmin.merge(['192.168.1.0/27','192.168.1.32/27','192.168.1.64/26','192.168.1.128/25']).each {|x| puts x}
531
+ print "\n"
532
+
533
+ # minimum_size
534
+ puts "minimum_size"
535
+ puts "The subnet size (in bits) for IPv4 that would fit 22 addresses is /#{IPAdmin.minimum_size(22)}"
536
+ print "\n"
503
537
 
504
538
  # range
505
539
  puts "range"
@@ -510,6 +544,12 @@
510
544
  end
511
545
  print "\n"
512
546
 
547
+ # sort
548
+ puts "sort"
549
+ puts " 192.168.1.0/24, 192.168.1.0/30, 192.168.2.0/32, 10.10.10.10 sorted are..."
550
+ IPAdmin.sort(['192.168.1.0/24','192.168.1.0/30','192.168.2.0/32','10.10.10.10']).each {|x| puts x}
551
+ print "\n"
552
+
513
553
  # shorten
514
554
  puts "shorten"
515
555
  puts "shorthand notation for #{cidr6_1.network()} is #{IPAdmin.shorten(cidr6_1.network)}"
@@ -518,5 +558,4 @@
518
558
  # unshorten
519
559
  puts "unshorten"
520
560
  puts "expanded notation for fec0:: is #{IPAdmin.unshorten('fec0::')}"
521
-
522
-
561
+