netaddr 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of netaddr might be problematic. Click here for more details.

data/README CHANGED
@@ -15,188 +15,3 @@ your life easier.
15
15
 
16
16
  Dustin Spinhirne
17
17
 
18
-
19
- =Example Script
20
-
21
- #!/usr/bin/ruby
22
-
23
- # A script to parse static routes from a Cisco router.
24
- # Performs the following tasks:
25
- # - organizes statics by directly connected next-hop interface
26
- # - corrects recursive static routes
27
- # - reports statics with no directly connected next-hop
28
- # - reports duplicate static routes
29
- # - reports static routes that overlap directly connected interfaces
30
- #
31
- # Change the variable 'infile' to that of the name of the router configuration
32
- # file that should be parsed.
33
-
34
- require 'rubygems'
35
- require_gem 'netaddr'
36
-
37
- # change this variable to that of the router config file
38
- infile = 'router_config.txt'
39
-
40
-
41
- ip_interface_count = 0
42
- static_route_count = 0
43
- connected_routes = []
44
- static_routes = []
45
- statics = {}
46
- grouped_routes = {}
47
- duplicates = []
48
- recursives = []
49
- corrected_statics = []
50
- overlapping_statics = []
51
-
52
-
53
- # sort through router config. put connected ip interfaces into 'connected_routes'
54
- # and static routes into 'statics'. Set aside duplicate static routes.
55
- File.open(infile, 'r') do |file|
56
- while line = file.gets
57
- if (line =~/^interface .+/)
58
- interface = line.chomp
59
- elsif (line =~ /^\s*ip address/) # connected interface
60
- ip_interface_count += 1
61
- addr = line.split('ip address ').join # ['x.x.x.x y.y.y.y']
62
- cidr = NetAddr::CIDR.create(addr, :Tag => {:interface => interface})
63
- connected_routes.push(cidr)
64
- elsif (line =~/^ip route/) # static route
65
- static_route_count += 1
66
- elements = line.split(' ') # ['ip','route','x.x.x.x','y.y.y.y','x.x.x.x',]
67
- ip = elements[2]
68
- netmask = elements[3]
69
- nexthop = elements[4]
70
-
71
- # keep all but loopbacks, nulls, or defaults
72
- if ( (nexthop !~ /Loopback/) && (nexthop !~ /Null/) && (ip != '0.0.0.0') )
73
- nexthop_cidr = NetAddr::CIDR.create(nexthop)
74
- cidr = NetAddr::CIDR.create("#{ip} #{netmask}",
75
- :Tag => {:route => line, :nexthop => nexthop_cidr})
76
-
77
- if (!statics.has_key?(cidr.desc))
78
- statics[cidr.desc] = cidr
79
- else
80
- msg = '! overlaps with - ' + statics[cidr.desc].tag[:route] + line + "!\n"
81
- duplicates.push(msg)
82
- end
83
- end
84
- end
85
- end
86
- end
87
-
88
-
89
- # look for statics that overlap with a connected interface, and
90
- # group static routes with their next-hop interface.
91
- statics.each_key do |desc|
92
- cidr = statics[desc]
93
- nexthop = cidr.tag[:nexthop]
94
- route = cidr.tag[:route]
95
-
96
- overlaps_with = nil
97
- nexthop_int = nil
98
- connected_routes.each do |interface|
99
- if (interface.contains?(cidr)) # overlapping static
100
- overlaps_with = interface
101
- break
102
- elsif (interface.contains?(nexthop)) # next-hop directly connected
103
- nexthop_int = interface
104
- break
105
- end
106
- end
107
-
108
- if (nexthop_int)
109
- key = "#{nexthop_int.tag[:interface]} -> #{nexthop_int.desc}"
110
- if (grouped_routes.has_key?(key))
111
- grouped_routes[key].push(route)
112
- else
113
- grouped_routes[key] = [route]
114
- end
115
- static_routes.push(cidr)
116
- elsif (overlaps_with)
117
- overlap = "! overlaps with: #{overlaps_with.tag[:interface]} -> #{overlaps_with.desc}"
118
- overlap << "\n#{route}!\n"
119
- overlapping_statics.push(overlap)
120
- else
121
- recursives.push(cidr)
122
- end
123
- end
124
-
125
-
126
- # process recursive routes. update next-hop so that it points
127
- # to next hop of a directly connected ip. remove any that do not point to a
128
- # directly connected ip. We must continually cycle through the list, as the
129
- # 'static_routes' tree is constantly updated. We do this until our list of
130
- # recursive static routes stops getting any shorter
131
- recursives_count = 0
132
- until (recursives_count == recursives.length)
133
- recursives_count = recursives.length
134
- recursives.each do |cidr|
135
- nexthop = cidr.tag[:nexthop]
136
- route = cidr.tag[:route]
137
-
138
- found = nil
139
- static_routes.each do |static|
140
- if (static.contains?(nexthop))
141
- found = static
142
- break
143
- end
144
- end
145
-
146
- if (found)
147
- updated = 'no ' + route
148
- updated << "ip route #{cidr.network} #{cidr.netmask_ext} #{found.tag[:nexthop].ip}\n"
149
- updated << "!\n"
150
- corrected_statics.push(updated)
151
- static_routes.push(cidr)
152
- recursives.delete(cidr)
153
- end
154
- end
155
- end
156
-
157
-
158
- # print results.
159
- puts "--- STATISTICS ---"
160
- puts "#{ip_interface_count} Connected IP Interfaces\n#{static_route_count} IP Static Routes\n"
161
-
162
- print "\n\n"
163
-
164
- puts "--- OVERLAPPING STATIC ROUTES ---"
165
- overlapping_statics.each do |overlap|
166
- puts overlap
167
- end
168
-
169
- print "\n\n"
170
-
171
- puts "--- DUPLICATE STATIC ROUTES ---"
172
- duplicates.each do |route|
173
- puts route
174
- end
175
-
176
- print "\n\n"
177
-
178
- puts "--- STATIC ROUTES WITH UPDATED NEXT-HOP ---"
179
- corrected_statics.each do |route|
180
- puts route
181
- end
182
-
183
- print "\n\n"
184
-
185
- puts "--- STATIC ROUTES WITH UNKNOWN NEXT-HOP ---"
186
- recursives.each do |cidr|
187
- puts cidr.tag[:route]
188
- end
189
-
190
- print "\n\n"
191
-
192
- puts "--- STATIC ROUTES GROUPED BY NEXT-HOP INTERFACE ---"
193
- grouped_routes.each_key do |interface|
194
- routes = grouped_routes[interface]
195
- puts interface
196
- routes.each do |route|
197
- puts route
198
- end
199
- print "\n"
200
- end
201
-
202
- __END__
@@ -210,7 +210,7 @@ module_function :cidr_make_subnets_from_base_and_ip_count
210
210
 
211
211
  # given a list of NetAddr::CIDRs, return them as a sorted list
212
212
  #
213
- def cidr_sort(list)
213
+ def cidr_sort(list, desc=false)
214
214
  # uses simple quicksort algorithm
215
215
  sorted_list = []
216
216
  if (list.length < 1)
@@ -220,19 +220,38 @@ def cidr_sort(list)
220
220
  greater_list = []
221
221
  equal_list = []
222
222
  pivot = list[rand(list.length)]
223
- list.each do |x|
224
- gt_lt = cidr_gt_lt(pivot,x)
225
- if (gt_lt == 1)
226
- less_list.push(x)
227
- elsif (gt_lt == -1)
228
- greater_list.push(x)
229
- else
230
- equal_list.push(x)
223
+ if (desc)
224
+ list.each do |x|
225
+ if ( pivot.to_i(:network) < x.to_i(:network) )
226
+ less_list.push(x)
227
+ elsif ( pivot.to_i(:network) > x.to_i(:network) )
228
+ greater_list.push(x)
229
+ else
230
+ if ( pivot.to_i(:netmask) < x.to_i(:netmask) )
231
+ greater_list.push(x)
232
+ elsif ( pivot.to_i(:netmask) > x.to_i(:netmask) )
233
+ less_list.push(x)
234
+ else
235
+ equal_list.push(x)
236
+ end
237
+ end
238
+ end
239
+ else
240
+ list.each do |x|
241
+ gt_lt = cidr_gt_lt(pivot,x)
242
+ if (gt_lt == 1)
243
+ less_list.push(x)
244
+ elsif (gt_lt == -1)
245
+ greater_list.push(x)
246
+ else
247
+ equal_list.push(x)
248
+ end
231
249
  end
232
250
  end
233
- sorted_list.concat( cidr_sort(less_list) )
251
+
252
+ sorted_list.concat( cidr_sort(less_list, desc) )
234
253
  sorted_list.concat(equal_list)
235
- sorted_list.concat( cidr_sort(greater_list) )
254
+ sorted_list.concat( cidr_sort(greater_list, desc) )
236
255
  end
237
256
 
238
257
  return(sorted_list)
@@ -328,6 +347,64 @@ def cidr_summarize(subnet_list)
328
347
  end
329
348
  module_function :cidr_summarize
330
349
 
350
+ #==============================================================================#
351
+ # netmask_sort()
352
+ #==============================================================================#
353
+
354
+ # given a list of NetAddr::CIDRs, return them as a sorted (by netmask) list
355
+ #
356
+ def netmask_sort(list, desc=false)
357
+ # uses simple quicksort algorithm
358
+ sorted_list = []
359
+ if (list.length < 1)
360
+ sorted_list = list
361
+ else
362
+ less_list = []
363
+ greater_list = []
364
+ equal_list = []
365
+ pivot = list[rand(list.length)]
366
+ if (desc)
367
+ list.each do |x|
368
+ if ( pivot.to_i(:netmask) < x.to_i(:netmask) )
369
+ less_list.push(x)
370
+ elsif ( pivot.to_i(:netmask) > x.to_i(:netmask) )
371
+ greater_list.push(x)
372
+ else
373
+ if ( pivot.to_i(:network) < x.to_i(:network) )
374
+ greater_list.push(x)
375
+ elsif ( pivot.to_i(:network) > x.to_i(:network) )
376
+ less_list.push(x)
377
+ else
378
+ equal_list.push(x)
379
+ end
380
+ end
381
+ end
382
+ else
383
+ list.each do |x|
384
+ if ( pivot.to_i(:netmask) < x.to_i(:netmask) )
385
+ greater_list.push(x)
386
+ elsif ( pivot.to_i(:netmask) > x.to_i(:netmask) )
387
+ less_list.push(x)
388
+ else
389
+ if ( pivot.to_i(:network) < x.to_i(:network) )
390
+ greater_list.push(x)
391
+ elsif ( pivot.to_i(:network) > x.to_i(:network) )
392
+ less_list.push(x)
393
+ else
394
+ equal_list.push(x)
395
+ end
396
+ end
397
+ end
398
+ end
399
+
400
+ sorted_list.concat( netmask_sort(less_list, desc) )
401
+ sorted_list.concat(equal_list)
402
+ sorted_list.concat( netmask_sort(greater_list, desc) )
403
+ end
404
+
405
+ return(sorted_list)
406
+ end
407
+ module_function :netmask_sort
331
408
 
332
409
  end # module NetAddr
333
410
 
@@ -51,7 +51,7 @@ def detect_ip_version(ip)
51
51
  elsif (ip =~ /:/)
52
52
  version = 6
53
53
  else
54
- raise ValidationError, "Count not auto-detect IP version for '#{ip}'."
54
+ raise ValidationError, "Could not auto-detect IP version for '#{ip}'."
55
55
  end
56
56
  return(version)
57
57
  end
@@ -601,30 +601,48 @@ module_function :shorten
601
601
  #==============================================================================#
602
602
 
603
603
  #===Synopsis
604
- #Given a list of CIDR addresses or NetAddr::CIDR objects,
605
- #sort them from lowest to highest by Network/Netmask. This method will use the
606
- #base address of any NetAddr::CIDR objects or CIDR addresses provided.
604
+ #Sort a list of CIDR addresses or NetAddr::CIDR objects,
607
605
  #
608
606
  # Example:
609
607
  # cidr1 = NetAddr::CIDR.create('192.168.1.32/27')
610
608
  # cidr2 = NetAddr::CIDR.create('192.168.1.0/27')
611
609
  # NetAddr.sort([cidr1,cidr2])
612
- # NetAddr.sort(['192.168.1.32/27','192.168.1.0/27','192.168.2.0/24'])
610
+ # NetAddr.sort(['192.168.1.32/27','192.168.1.0/27','192.168.2.0/24'], :Desc => true)
613
611
  #
614
612
  #===Arguments:
615
613
  #* list = Array of CIDR addresses as Strings, or Array of NetAddr::CIDR objects
614
+ #* options = Hash with the following keys:
615
+ # :ByMask -- if true, sorts based on the netmask length
616
+ # :Desc -- if true, return results in descending order
616
617
  #
617
618
  #===Returns:
618
619
  #* Array of Strings, or Array of NetAddr::CIDR objects
619
620
  #
620
- def sort(list)
621
-
621
+ def sort(list, options=nil)
622
622
  # make sure list is an array
623
623
  if ( !list.kind_of?(Array) )
624
624
  raise ArgumentError, "Array of NetAddr::CIDR or NetStruct " +
625
625
  "objects expected, but #{list.class} provided."
626
626
  end
627
627
 
628
+ desc = false
629
+ by_mask = false
630
+ # validate options
631
+ if (options)
632
+ known_args = [:Desc, :ByMask]
633
+ raise ArgumentError, "Hash expected for argument 'options' but #{options.class} provided." if (!options.kind_of?(Hash))
634
+ NetAddr.validate_args(options.keys,known_args)
635
+
636
+ if( options.has_key?(:Desc) && options[:Desc] == true )
637
+ desc = true
638
+ end
639
+
640
+ if( options.has_key?(:ByMask) && options[:ByMask] == true )
641
+ by_mask = true
642
+ end
643
+
644
+ end
645
+
628
646
  # make sure all are valid types of the same IP version
629
647
  version = nil
630
648
  cidr_hash = {}
@@ -647,8 +665,12 @@ def sort(list)
647
665
  end
648
666
  end
649
667
 
650
- # sort by network. if networks are equal, sort by netmask.
651
- sorted_list = cidr_sort(cidr_hash.keys)
668
+ # perform sort
669
+ if (by_mask)
670
+ sorted_list = netmask_sort(cidr_hash.keys, desc)
671
+ else
672
+ sorted_list = cidr_sort(cidr_hash.keys, desc)
673
+ end
652
674
 
653
675
  # return original values passed
654
676
  ret_list = []
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
- require '../lib/net_addr.rb'
3
+ require 'lib/netaddr.rb'
4
4
  require 'test/unit'
5
5
 
6
6
 
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
- require '../lib/net_addr.rb'
3
+ require 'lib/netaddr.rb'
4
4
  require 'test/unit'
5
5
 
6
6
 
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
- require '../lib/net_addr.rb'
3
+ require 'lib/netaddr.rb'
4
4
  require 'test/unit'
5
5
 
6
6
 
@@ -161,11 +161,30 @@ class TestMethods < Test::Unit::TestCase
161
161
  cidr6_3 = NetAddr::CIDR.create('fe80::0/10')
162
162
  cidr6_4 = 'fe80::0'
163
163
 
164
+ sort1 = NetAddr.sort(['192.168.1.0/24','192.168.1.128/25','192.168.1.64/26','192.168.1.0/30','192.168.2.0/24'])
165
+ assert_equal(['192.168.1.0/24','192.168.1.0/30','192.168.1.64/26','192.168.1.128/25','192.168.2.0/24'], sort1)
164
166
  sort1 = NetAddr.sort([cidr4_1,cidr4_2,cidr4_3,cidr4_4,cidr4_5])
165
- sort2 = NetAddr.sort([cidr6_1,cidr6_2,cidr6_3,cidr6_4])
166
-
167
167
  assert_equal([cidr4_1,cidr4_4,cidr4_3,cidr4_2,cidr4_5], sort1)
168
+
169
+ sort2 = NetAddr.sort(['fec0::0/64','fec0::0/10','fe80::0/10','fe80::0'])
170
+ assert_equal(['fe80::0/10','fe80::0','fec0::0/10','fec0::0/64'], sort2)
171
+ sort2 = NetAddr.sort([cidr6_1,cidr6_2,cidr6_3,cidr6_4])
168
172
  assert_equal([cidr6_3,cidr6_4,cidr6_2,cidr6_1], sort2)
173
+
174
+ sort3 = NetAddr.sort([cidr4_1,cidr4_2,cidr4_3,cidr4_4,cidr4_5], :Desc => true)
175
+ assert_equal([cidr4_5,cidr4_2,cidr4_3,cidr4_1,cidr4_4], sort3)
176
+ sort3 = NetAddr.sort(['192.168.1.0/24','192.168.1.128/25','192.168.1.64/26','192.168.1.0/30','192.168.2.0/24'], :Desc => true)
177
+ assert_equal(['192.168.2.0/24','192.168.1.128/25','192.168.1.64/26','192.168.1.0/24','192.168.1.0/30'], sort3)
178
+
179
+ sort4 = NetAddr.sort(['192.168.1.0/24','192.168.1.128/25','192.168.1.64/26','192.168.1.0/30','192.168.2.0/24'], :ByMask => true)
180
+ assert_equal(['192.168.1.0/24','192.168.2.0/24','192.168.1.128/25','192.168.1.64/26','192.168.1.0/30'], sort4)
181
+ sort4 = NetAddr.sort([cidr4_1,cidr4_2,cidr4_3,cidr4_4,cidr4_5], :ByMask => true)
182
+ assert_equal([cidr4_1,cidr4_5,cidr4_2,cidr4_3,cidr4_4], sort4)
183
+
184
+ sort5 = NetAddr.sort(['192.168.1.0/24','192.168.1.128/25','192.168.1.64/26','192.168.1.0/30','192.168.2.0/24'], :ByMask => true, :Desc => true)
185
+ assert_equal(['192.168.1.0/30','192.168.1.64/26','192.168.1.128/25','192.168.1.0/24','192.168.2.0/24'], sort5)
186
+ sort5 = NetAddr.sort([cidr4_1,cidr4_2,cidr4_3,cidr4_4,cidr4_5], :ByMask => true, :Desc => true)
187
+ assert_equal([cidr4_4,cidr4_3,cidr4_2,cidr4_1,cidr4_5], sort5)
169
188
  end
170
189
 
171
190
  def test_unshorten
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
- require '../lib/net_addr.rb'
3
+ require 'lib/netaddr.rb'
4
4
  require 'test/unit'
5
5
 
6
6
 
metadata CHANGED
@@ -1,61 +1,68 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.4
3
- specification_version: 1
4
2
  name: netaddr
5
3
  version: !ruby/object:Gem::Version
6
- version: 1.3.0
7
- date: 2007-07-10 00:00:00 -05:00
8
- summary: A package for manipulating network addresses.
9
- require_paths:
10
- - lib
11
- email:
12
- homepage:
13
- rubyforge_project:
14
- description:
15
- autorequire:
16
- default_executable:
17
- bindir: bin
18
- has_rdoc: true
19
- required_ruby_version: !ruby/object:Gem::Version::Requirement
20
- requirements:
21
- - - ">"
22
- - !ruby/object:Gem::Version
23
- version: 0.0.0
24
- version:
4
+ version: 1.4.0
25
5
  platform: ruby
26
- signing_key:
27
- cert_chain:
28
- post_install_message:
29
6
  authors:
30
7
  - Dustin Spinhirne
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-02-15 00:00:00 -06:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email:
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README
24
+ - Errors
25
+ - changelog
31
26
  files:
32
27
  - lib/cidr_shortcuts.rb
33
28
  - lib/cidr.rb
34
29
  - lib/ip_math.rb
35
- - lib/eui.rb
36
- - lib/methods.rb
37
30
  - lib/validation_shortcuts.rb
31
+ - lib/eui.rb
38
32
  - lib/netaddr.rb
33
+ - lib/methods.rb
39
34
  - lib/tree.rb
40
35
  - README
41
36
  - Errors
42
37
  - changelog
43
- test_files:
44
- - tests/eui_test.rb
45
- - tests/methods_test.rb
46
- - tests/cidr_test.rb
47
- - tests/tree_test.rb
38
+ has_rdoc: true
39
+ homepage:
40
+ post_install_message:
48
41
  rdoc_options: []
49
42
 
50
- extra_rdoc_files:
51
- - README
52
- - Errors
53
- - changelog
54
- executables: []
55
-
56
- extensions: []
57
-
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
58
57
  requirements: []
59
58
 
60
- dependencies: []
61
-
59
+ rubyforge_project:
60
+ rubygems_version: 1.0.1
61
+ signing_key:
62
+ specification_version: 2
63
+ summary: A package for manipulating network addresses.
64
+ test_files:
65
+ - tests/tree_test.rb
66
+ - tests/methods_test.rb
67
+ - tests/cidr_test.rb
68
+ - tests/eui_test.rb