ipadmin 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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
+