ipadmin 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (8) hide show
  1. data/README +166 -446
  2. data/lib/cidr.rb +132 -241
  3. data/lib/eui.rb +6 -40
  4. data/lib/methods.rb +28 -99
  5. data/lib/tree.rb +23 -144
  6. data/tests/cidr_test.rb +28 -17
  7. data/tests/tree_test.rb +2 -1
  8. metadata +4 -4
data/README CHANGED
@@ -50,190 +50,6 @@
50
50
  You can see how the CIDR object is based around the entire IP space
51
51
  defined by the provided IP/Netmask pair, and not necessarily the individual
52
52
  IP address itself.
53
-
54
-
55
- ====Examples:
56
-
57
- #!/usr/bin/ruby
58
-
59
- require 'rubygems'
60
- require_gem 'ipadmin'
61
-
62
- puts "IPAdmin::CIDR"
63
- print "\n"
64
-
65
- # new
66
- cidr4 = IPAdmin::CIDR.new('192.168.1.0/24')
67
- cidr4 = IPAdmin::CIDR.new(:CIDR => '192.168.1.1',
68
- :Netmask => '255.255.255.0',
69
- :Tag => {'test' => 'cidr4 tag'})
70
- cidr6 = IPAdmin::CIDR.new('fec0::1/64')
71
-
72
- cidr4_2 = IPAdmin::CIDR.new('192.168.1.0/26')
73
- cidr6_2 = IPAdmin::CIDR.new('fec0::0/96')
74
-
75
- # reader/writer
76
- puts "reader/writer"
77
- puts "cidr4 tag '#{cidr4.tag['test']}'"
78
- cidr4.tag['test'] = 'modified cidr4 tag'
79
- puts "updated cidr4 tag '#{cidr4.tag['test']}'"
80
- puts "cidr4 version #{cidr4.version}"
81
- puts "cidr6 version #{cidr6.version}"
82
- print "\n"
83
-
84
- # arpa
85
- puts "arpa"
86
- puts "arpa for #{cidr4.desc()} is #{cidr4.arpa}"
87
- puts "arpa for #{cidr6.desc(:Short => true)} is #{cidr6.arpa}"
88
- print "\n"
89
-
90
- # bits
91
- puts "bits"
92
- puts "cidr4 netmask in bits #{cidr4.bits()}"
93
- puts "cidr6 netmask in bits #{cidr6.bits()}"
94
- print "\n"
95
-
96
- # contains?
97
- puts "contains"
98
- puts "#{cidr4.desc} contains #{cidr4_2.desc}" if ( cidr4.contains?(cidr4_2) )
99
- puts "#{cidr6.desc} contains #{cidr6_2.desc(:Short => true)}" if ( cidr6.contains?(cidr6_2) )
100
- print "\n"
101
-
102
- # desc
103
- puts "desc"
104
- puts "cidr4 description #{cidr4.desc()}"
105
- puts "cidr6 description #{cidr6.desc()}"
106
- puts "cidr6 short-hand description #{cidr6.desc(:Short => true)}"
107
- print "\n"
108
-
109
- # enumerate
110
- puts "enumerate"
111
- puts "first 4 cidr4 addresses (bitstep 32)"
112
- cidr4.enumerate(:Limit => 4, :Bitstep => 32).each {|x| puts " #{x}"}
113
-
114
- puts "first 4 cidr6 addresses (bitstep 32)"
115
- cidr6.enumerate(:Limit => 4, :Bitstep => 32, :Objectify => true).each {|x| puts " #{x.desc}"}
116
- print "\n"
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
- # hostmask_ext
125
- puts "hostmask_ext"
126
- puts "cidr4 extended hostmask #{cidr4.hostmask_ext()}"
127
- print "\n"
128
-
129
- # ip
130
- puts "ip"
131
- puts "cidr4 ip #{cidr4.ip()}"
132
- puts "cidr6 short-hand ip #{cidr6.ip(:Short => true)}"
133
- print "\n"
134
-
135
- # last
136
- puts "last"
137
- puts "cidr4 last ip #{cidr4.last()}"
138
- puts "cidr6 last ip #{cidr6.last(:Short => true)}"
139
- print "\n"
140
-
141
- # multicast_mac
142
- mcast = IPAdmin::CIDR.new('224.0.0.6')
143
- mcast2 = IPAdmin::CIDR.new('ff00::abcd')
144
- puts "multicast_mac"
145
- puts "#{mcast.ip} multicast mac is #{mcast.multicast_mac()}"
146
- puts "#{mcast2.ip} multicast mac is #{mcast2.multicast_mac()}"
147
- print "\n"
148
-
149
- # netmask
150
- puts "netmask"
151
- puts "cidr4 netmask in CIDR format #{cidr4.netmask()}"
152
- puts "cidr6 netmask in CIDR format #{cidr6.netmask()}"
153
- print "\n"
154
-
155
- # netmask_ext
156
- puts "netmask_ext"
157
- puts "cidr4 extended netmask #{cidr4.netmask_ext()}"
158
- print "\n"
159
-
160
- # network
161
- puts "network"
162
- puts "cidr4 network address #{cidr4.network()}"
163
- puts "cidr6 network address #{cidr6.network(:Short => true)}"
164
- print "\n"
165
-
166
- # next_ip
167
- puts "next_ip"
168
- puts "cidr4 next ip #{cidr4.next_ip()}"
169
- puts "cidr6 next ip #{cidr6.next_ip(:Short => true)}"
170
- print "\n"
171
-
172
- # next_subnet
173
- puts "next_subnet"
174
- puts "cidr4 next subnet #{cidr4.next_subnet()}"
175
- puts "cidr6 next subnet #{cidr6.next_subnet(:Short => true)}"
176
- print "\n"
177
-
178
- # nth
179
- puts "nth"
180
- puts "cidr4 1st ip is #{cidr4.nth(1)}"
181
- puts "cidr6 1st ip is #{(cidr6.nth(:Index => 1, :Objectify => true)).base}"
182
- print "\n"
183
-
184
- # packed_hostmask
185
- puts "packed_hostmask"
186
- puts "cidr4 packed_hostmask is #{cidr4.packed_hostmask.to_s(16)}"
187
- puts "cidr6 packed_hostmask is #{cidr6.packed_hostmask.to_s(16)}"
188
- print "\n"
189
-
190
- # packed_netmask
191
- puts "packed_netmask"
192
- puts "cidr4 packed_netmask is #{cidr4.packed_netmask.to_s(16)}"
193
- puts "cidr6 packed_netmask is #{cidr6.packed_netmask.to_s(16)}"
194
- print "\n"
195
-
196
- # packed_network
197
- puts "packed_network"
198
- puts "cidr4 packed_network is #{cidr4.packed_network.to_s(16)}"
199
- puts "cidr6 packed_network is #{cidr6.packed_network.to_s(16)}"
200
- print "\n"
201
-
202
- # range
203
- puts "range"
204
- cidr4.range(:Indexes => [20,0], :Bitstep => 5).each {|x| puts x}
205
- cidr6.range(:Indexes => [20,0], :Bitstep => 5).each {|x| puts x}
206
- print "\n"
207
-
208
- # remainder
209
- puts "remainder"
210
- cidr4_2 = IPAdmin::CIDR.new('192.168.1.64/26')
211
- puts "The remainder of #{cidr4.desc} after subtracting #{cidr4_2.desc} is:"
212
- cidr4.remainder(cidr4_2).each {|x| puts x}
213
- print "\n"
214
-
215
- # resize!
216
- puts "resize!"
217
- cidr4.resize!(25)
218
- cidr6.resize!(:Netmask => 65)
219
- puts "cidr4 resized is #{cidr4.desc}"
220
- puts "cidr6 resized is #{cidr6.desc}"
221
- print "\n"
222
-
223
- # size
224
- puts "size"
225
- puts "cidr4 size is #{cidr4.size()}"
226
- puts "cidr6 size is #{cidr6.size()}"
227
- print "\n"
228
-
229
- # subnet
230
- puts "subnet"
231
- puts "#{cidr4.desc} subnetted into at least 3 /28 ranges"
232
- cidr4.subnet(:Subnet => 28, :MinCount => 3).each {|x| puts " #{x}"}
233
-
234
- puts "#{cidr6.desc(:Short => true)} subnetted into at least 4 /67 ranges"
235
- cidr6.subnet(:Subnet => 67, :MinCount => 4, :Short => true).each {|x| puts " #{x}"}
236
-
237
53
 
238
54
 
239
55
 
@@ -254,49 +70,6 @@
254
70
  Link Local addresses use MAC addresses for IP auto-assignment and multicast MAC addresses
255
71
  are determined based on the multicast IP address.
256
72
 
257
- ====Examples:
258
-
259
- #!/usr/bin/ruby
260
-
261
- require 'rubygems'
262
- require_gem 'ipadmin'
263
-
264
- puts "IPAdmin::EUI"
265
- print "\n"
266
-
267
- eui1 = IPAdmin::EUI48.new('aa-bb-cc-dd-ee-ff')
268
- eui2 = IPAdmin::EUI64.new('12-34-56-78-9a-bc-de-f0')
269
-
270
- # oui
271
- puts "oui"
272
- puts "OUI 1 is #{eui1.oui}"
273
- puts "OUI 2 is #{eui2.oui}"
274
- print "\n"
275
-
276
- # ei
277
- puts "ei"
278
- puts "EI 1 is #{eui1.ei}"
279
- puts "EI 2 is #{eui2.ei}"
280
- print "\n"
281
-
282
- # address
283
- puts "address"
284
- puts "address 1 is #{eui1.address(:Delimiter => '.')}"
285
- puts "address 2 is #{eui2.address(:Delimiter => '.')}"
286
- print "\n"
287
-
288
- # link local
289
- puts "link local"
290
- puts "IPv6 link local 1 is #{eui1.link_local(:Short => true)}"
291
- puts "IPv6 link local 2 is #{eui2.link_local(:Short => true)}"
292
- print "\n"
293
-
294
- # type
295
- puts "class"
296
- puts "eui 1 is a #{eui1.class}"
297
- puts "eui 2 is a #{eui2.class}"
298
-
299
-
300
73
 
301
74
 
302
75
  =Tree
@@ -321,241 +94,188 @@
321
94
  192.168.1.192/26
322
95
 
323
96
 
324
- ====Examples:
97
+
98
+ =Example Script
325
99
 
326
100
  #!/usr/bin/ruby
327
101
 
102
+ # A script to parse static routes from a Cisco router.
103
+ # Performs the following tasks:
104
+ # - organizes statics by directly connected next-hop interface
105
+ # - corrects recursive static routes
106
+ # - reports statics with no directly connected next-hop
107
+ # - reports duplicate static routes
108
+ # - reports static routes that overlap directly connected interfaces
109
+ #
110
+ # Change the variable 'infile' to that of the name of the router configuration
111
+ # file that should be parsed.
112
+
328
113
  require 'rubygems'
329
114
  require_gem 'ipadmin'
330
-
331
- puts "IPAdmin::Tree"
332
- print "\n"
333
-
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']
343
115
 
344
- # new
345
- tree = IPAdmin::Tree.new()
116
+ # change this variable to that of the router config file
117
+ infile = 'router_config.txt'
118
+
119
+
120
+ ip_interface_count = 0
121
+ static_route_count = 0
122
+ connected_routes = []
123
+ static_routes = []
124
+ statics = {}
125
+ grouped_routes = {}
126
+ duplicates = []
127
+ recursives = []
128
+ corrected_statics = []
129
+ overlapping_statics = []
130
+
131
+
132
+ # sort through router config. put connected ip interfaces into 'connected_routes'
133
+ # and static routes into 'statics'. Set aside duplicate static routes.
134
+ File.open(infile, 'r') do |file|
135
+ while line = file.gets
136
+ if (line =~/^interface .+/)
137
+ interface = line.chomp
138
+ elsif (line =~ /^\s*ip address/) # connected interface
139
+ ip_interface_count += 1
140
+ addr = line.split('ip address ').join # ['x.x.x.x y.y.y.y']
141
+ cidr = IPAdmin::CIDR.new(:CIDR => addr, :Tag => {:interface => interface})
142
+ connected_routes.push(cidr)
143
+ elsif (line =~/^ip route/) # static route
144
+ static_route_count += 1
145
+ elements = line.split(' ') # ['ip','route','x.x.x.x','y.y.y.y','x.x.x.x',]
146
+ ip = elements[2]
147
+ netmask = elements[3]
148
+ nexthop = elements[4]
149
+
150
+ # keep all but loopbacks, nulls, or defaults
151
+ if ( (nexthop !~ /Loopback/) && (nexthop !~ /Null/) && (ip != '0.0.0.0') )
152
+ nexthop_cidr = IPAdmin::CIDR.new(nexthop)
153
+ cidr = IPAdmin::CIDR.new(:CIDR => "#{ip} #{netmask}",
154
+ :Tag => {:route => line, :nexthop => nexthop_cidr})
155
+
156
+ if (!statics.has_key?(cidr.desc))
157
+ statics[cidr.desc] = cidr
158
+ else
159
+ msg = '! overlaps with - ' + statics[cidr.desc].tag[:route] + line + "!\n"
160
+ duplicates.push(msg)
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
346
166
 
347
167
 
348
- # add!
349
- puts "add!"
350
- cidr4.each do |x|
351
- puts "adding #{x}..."
352
- tree.add!(x)
168
+ # look for statics that overlap with a connected interface, and
169
+ # group static routes with their next-hop interface.
170
+ statics.each_key do |desc|
171
+ cidr = statics[desc]
172
+ nexthop = cidr.tag[:nexthop]
173
+ route = cidr.tag[:route]
174
+
175
+ overlaps_with = nil
176
+ nexthop_int = nil
177
+ connected_routes.each do |interface|
178
+ if (interface.contains?(cidr)) # overlapping static
179
+ overlaps_with = interface
180
+ break
181
+ elsif (interface.contains?(nexthop)) # next-hop directly connected
182
+ nexthop_int = interface
183
+ break
184
+ end
185
+ end
186
+
187
+ if (nexthop_int)
188
+ key = "#{nexthop_int.tag[:interface]} -> #{nexthop_int.desc}"
189
+ if (grouped_routes.has_key?(key))
190
+ grouped_routes[key].push(route)
191
+ else
192
+ grouped_routes[key] = [route]
193
+ end
194
+ static_routes.push(cidr)
195
+ elsif (overlaps_with)
196
+ overlap = "! overlaps with: #{overlaps_with.tag[:interface]} -> #{overlaps_with.desc}"
197
+ overlap << "\n#{route}!\n"
198
+ overlapping_statics.push(overlap)
199
+ else
200
+ recursives.push(cidr)
201
+ end
353
202
  end
354
- cidr6.each do |x|
355
- puts "adding #{x}..."
356
- tree.add!(x)
203
+
204
+
205
+ # process recursive routes. update next-hop so that it points
206
+ # to next hop of a directly connected ip. remove any that do not point to a
207
+ # directly connected ip. We must continually cycle through the list, as the
208
+ # 'static_routes' tree is constantly updated. We do this until our list of
209
+ # recursive static routes stops getting any shorter
210
+ recursives_count = 0
211
+ until (recursives_count == recursives.length)
212
+ recursives_count = recursives.length
213
+ recursives.each do |cidr|
214
+ nexthop = cidr.tag[:nexthop]
215
+ route = cidr.tag[:route]
216
+
217
+ found = nil
218
+ static_routes.each do |static|
219
+ if (static.contains?(nexthop))
220
+ found = static
221
+ break
222
+ end
223
+ end
224
+
225
+ if (found)
226
+ updated = 'no ' + route
227
+ updated << "ip route #{cidr.network} #{cidr.netmask_ext} #{found.tag[:nexthop].ip}\n"
228
+ updated << "!\n"
229
+ corrected_statics.push(updated)
230
+ static_routes.push(cidr)
231
+ recursives.delete(cidr)
232
+ end
233
+ end
357
234
  end
358
- print "\n"
359
-
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
385
- puts "dump"
386
- puts "dumping & printing tree"
387
- dumped = tree.dump()
388
- dumped.each do |val|
389
- cidr = val[:CIDR]
390
- depth = val[:Depth]
391
- if (depth > 0)
392
- indent = " " * (depth*3)
393
- puts indent << cidr.desc()
394
- else
395
- puts cidr.desc()
396
- end
235
+
236
+
237
+ # print results.
238
+ puts "--- STATISTICS ---"
239
+ puts "#{ip_interface_count} Connected IP Interfaces\n#{static_route_count} IP Static Routes\n"
240
+
241
+ print "\n\n"
242
+
243
+ puts "--- OVERLAPPING STATIC ROUTES ---"
244
+ overlapping_statics.each do |overlap|
245
+ puts overlap
397
246
  end
398
- print "\n"
399
247
 
400
- # exists?
401
- puts "exists?"
402
- puts "192.168.1.32/27 is in the tree." if tree.exists?('192.168.1.32/27')
403
- print "\n"
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}
410
- print "\n"
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'
416
- print "\n"
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')
440
- print "\n"
441
-
442
- # remove
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')
446
- print "\n"
447
-
448
- # resize
449
- puts "resize!"
450
- puts "resizing fec0::/60 into a /65"
451
- tree.resize!('fec0::/60', 65)
452
- print "\n"
453
-
454
- # root
455
- puts "root"
456
- puts "root of 192.168.1.32/27 is #{tree.root('192.168.1.32/27').desc}"
457
- print "\n"
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}
463
- print "\n"
464
-
465
- # supernets
466
- puts "supernets"
467
- puts "supernets of this tree are..."
468
- tree.supernets.each {|x| puts x.desc}
469
- print "\n"
470
-
471
- # show
472
- puts "show"
473
- puts "showing tree..."
474
- puts tree.show
475
-
248
+ print "\n\n"
476
249
 
250
+ puts "--- DUPLICATE STATIC ROUTES ---"
251
+ duplicates.each do |route|
252
+ puts route
253
+ end
477
254
 
478
- =General Methods
255
+ print "\n\n"
479
256
 
480
- A collection of general purpose methods that dont really fit within
481
- any particular class.
482
-
257
+ puts "--- STATIC ROUTES WITH UPDATED NEXT-HOP ---"
258
+ corrected_statics.each do |route|
259
+ puts route
260
+ end
483
261
 
484
- ====Examples:
262
+ print "\n\n"
485
263
 
486
- #!/usr/bin/ruby
264
+ puts "--- STATIC ROUTES WITH UNKNOWN NEXT-HOP ---"
265
+ recursives.each do |cidr|
266
+ puts cidr.tag[:route]
267
+ end
487
268
 
488
- require 'rubygems'
489
- require_gem 'ipadmin'
490
-
491
- puts "IPAdmin Methods"
492
- print "\n"
493
-
494
- # validate ip
495
- puts "validate ip"
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') )
499
- print "\n"
500
-
501
- # validate netmask
502
- puts "validate netmask"
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') )
505
- puts "/64 is valid" if ( IPAdmin.validate_ip_netmask(:Netmask => 64, :Version => 6) )
506
-
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')
512
- print "\n"
513
-
514
- # compare
515
- puts "compare"
516
- comp1 = IPAdmin.compare(cidr4_1,cidr4_2)
517
- comp2 = IPAdmin.compare(cidr6_1,cidr6_2)
518
- puts "#{(comp1[0]).desc} is the supernet of #{(comp1[1]).desc}"
519
- puts "#{(comp2[0]).desc} is the supernet of #{(comp2[1]).desc}"
520
-
521
- cidr4_1 = IPAdmin::CIDR.new(:CIDR => '192.168.1.0/24')
522
- cidr4_2 = IPAdmin::CIDR.new(:CIDR => '192.168.0.0/24')
523
- cidr6_1 = IPAdmin::CIDR.new(:CIDR => 'fec0::0/128')
524
- cidr6_2 = IPAdmin::CIDR.new(:CIDR => 'fec0::1/128')
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"
537
-
538
- # range
539
- puts "range"
540
- list = IPAdmin.range(:Boundaries => [cidr4_1,cidr4_3], :Bitstep => 20 )
541
- puts "ip's between #{cidr4_1.base} and #{cidr4_3.base} (bitstep of 20)"
542
- list.each do |x|
543
- puts " #{x}"
269
+ print "\n\n"
270
+
271
+ puts "--- STATIC ROUTES GROUPED BY NEXT-HOP INTERFACE ---"
272
+ grouped_routes.each_key do |interface|
273
+ routes = grouped_routes[interface]
274
+ puts interface
275
+ routes.each do |route|
276
+ puts route
277
+ end
278
+ print "\n"
544
279
  end
545
- print "\n"
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
-
553
- # shorten
554
- puts "shorten"
555
- puts "shorthand notation for #{cidr6_1.network()} is #{IPAdmin.shorten(cidr6_1.network)}"
556
- print "\n"
557
-
558
- # unshorten
559
- puts "unshorten"
560
- puts "expanded notation for fec0:: is #{IPAdmin.unshorten('fec0::')}"
561
-
280
+
281
+ __END__