ospfv2 0.0.1 → 0.0.2
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/bin/ospfv2 +3 -6
- data/changelog.txt +8 -0
- data/lib/ie/au_type.rb +1 -1
- data/lib/ie/external_route.rb +6 -3
- data/lib/ie/interface_mtu.rb +0 -1
- data/lib/ie/ls_age.rb +2 -16
- data/lib/ie/ls_type.rb +106 -73
- data/lib/ie/metric.rb +13 -0
- data/lib/ie/options.rb +42 -21
- data/lib/ie/ospf_version.rb +0 -8
- data/lib/ie/router_link.rb +7 -28
- data/lib/ie/sequence_number.rb +6 -1
- data/lib/infra/ospf_common.rb +2 -13
- data/lib/infra/ospf_constants.rb +8 -8
- data/lib/infra/ospf_io.rb +1 -1
- data/lib/infra/ospf_socket.rb +12 -20
- data/lib/infra/parse_options.rb +3 -3
- data/lib/infra/timer.rb +2 -1
- data/lib/ls_db/advertised_routers.rb +30 -28
- data/lib/ls_db/link_state_database.rb +8 -50
- data/lib/ls_db/link_state_database_build.rb +5 -5
- data/lib/ls_db/links.rb +1 -4
- data/lib/lsa/external.rb +13 -11
- data/lib/lsa/lsa.rb +81 -43
- data/lib/lsa/lsa_base.rb +430 -0
- data/lib/lsa/lsa_factory.rb +5 -1
- data/lib/lsa/network.rb +7 -2
- data/lib/lsa/opaque.rb +143 -0
- data/lib/lsa/router.rb +17 -25
- data/lib/lsa/summary.rb +17 -171
- data/lib/lsa/tlv/tlv.rb +0 -0
- data/lib/neighbor/neighbor.rb +24 -9
- data/lib/neighbor/recv_hello.rb +0 -5
- data/lib/neighbor/recv_ospf_packet.rb +1 -2
- data/lib/neighbor_sm/exstart_state.rb +9 -12
- data/lib/neighbor_sm/init_state.rb +5 -7
- data/lib/packet/database_description.rb +7 -7
- data/lib/packet/hello.rb +94 -12
- data/lib/packet/link_state_ack.rb +2 -2
- data/lib/packet/link_state_update.rb +1 -1
- data/lib/packet/ospf_packet.rb +4 -5
- metadata +16 -8
data/lib/ie/ospf_version.rb
CHANGED
data/lib/ie/router_link.rb
CHANGED
@@ -30,10 +30,13 @@ module OSPFv2
|
|
30
30
|
|
31
31
|
class RouterLink
|
32
32
|
include Common
|
33
|
+
include CommonMetric
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
unless const_defined?(:LinkId)
|
36
|
+
LinkId = Class.new(Id)
|
37
|
+
LinkData = Class.new(Id)
|
38
|
+
end
|
39
|
+
|
37
40
|
attr_reader :link_id, :link_data, :router_link_type, :metric, :mt_metrics
|
38
41
|
|
39
42
|
attr_writer_delegate :link_id, :link_data, :router_link_type
|
@@ -79,7 +82,6 @@ module OSPFv2
|
|
79
82
|
rlink.join
|
80
83
|
end
|
81
84
|
|
82
|
-
# TODO: if self.class is not RouterLink do not display RouterLinkType info....
|
83
85
|
def to_s(ident=2)
|
84
86
|
encode unless @router_link_type
|
85
87
|
self.class.to_s.split('::').last + ":" +
|
@@ -118,23 +120,12 @@ module OSPFv2
|
|
118
120
|
super arg
|
119
121
|
end
|
120
122
|
define_method(:to_hash) do
|
121
|
-
super.merge :router_link_type => x
|
123
|
+
super().merge :router_link_type => x
|
122
124
|
end
|
123
125
|
end
|
124
126
|
self.const_set(x.to_klass, klassname)
|
125
127
|
}
|
126
128
|
|
127
|
-
# FIXME: same as summary.rb ... mixin candidate
|
128
|
-
def mt_metrics=(val)
|
129
|
-
[val].flatten.each { |x| self << x }
|
130
|
-
end
|
131
|
-
|
132
|
-
def <<(metric)
|
133
|
-
@mt_metrics ||=[]
|
134
|
-
@mt_metrics << MtMetric.new(metric)
|
135
|
-
self
|
136
|
-
end
|
137
|
-
|
138
129
|
def parse(s)
|
139
130
|
@mt_metrics ||=[]
|
140
131
|
link_id, link_data, router_link_type, ntos, metric, mt_metrics = s.unpack('NNCCna*')
|
@@ -148,20 +139,8 @@ module OSPFv2
|
|
148
139
|
end
|
149
140
|
|
150
141
|
end
|
151
|
-
#
|
152
|
-
# require 'pp'
|
153
|
-
# h = {:router_link_type=>1, :metric=>1,:mt_metrics=>[{:id=>20, :metric=>33}, {:id=>255, :metric=>34}], :link_data=>"10.254.233.233",:link_id=>"2.2.2.2"}
|
154
|
-
#
|
155
|
-
# pp RouterLink.new(h)
|
156
|
-
#
|
157
|
-
# puts RouterLink.new(h)
|
158
|
-
# puts RouterLink.new(h).to_shex
|
159
|
-
|
160
|
-
|
161
|
-
|
162
142
|
|
163
143
|
end
|
164
144
|
|
165
145
|
|
166
|
-
|
167
146
|
load "../../../test/ospfv2/ie/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|
data/lib/ie/sequence_number.rb
CHANGED
@@ -82,12 +82,17 @@ module OSPFv2
|
|
82
82
|
self
|
83
83
|
end
|
84
84
|
|
85
|
+
def incr(num=1)
|
86
|
+
seqn = (@seqn.unpack('i')[0]+num)
|
87
|
+
@seqn = [seqn].pack('I')
|
88
|
+
self
|
89
|
+
end
|
90
|
+
|
85
91
|
def -(num)
|
86
92
|
self.+(-num)
|
87
93
|
end
|
88
94
|
|
89
95
|
def encode
|
90
|
-
#FIXME: unit-test and check if 'i' or 'I'
|
91
96
|
[to_i].pack('N')
|
92
97
|
end
|
93
98
|
|
data/lib/infra/ospf_common.rb
CHANGED
@@ -100,16 +100,7 @@ class Object
|
|
100
100
|
""
|
101
101
|
end
|
102
102
|
end
|
103
|
-
def method_missing(method, *args, &block)
|
104
|
-
# puts "COMMON method_missing: #{method}"
|
105
103
|
|
106
|
-
if method.to_s =~ /^to_s(\d+)/
|
107
|
-
to_s($1.to_i)
|
108
|
-
else
|
109
|
-
# p caller
|
110
|
-
super
|
111
|
-
end
|
112
|
-
end
|
113
104
|
def define_to_s
|
114
105
|
if defined?($style)
|
115
106
|
self.class.class_eval { eval("alias :to_s :to_s_#{$style}") }
|
@@ -117,7 +108,7 @@ class Object
|
|
117
108
|
self.class.class_eval { alias :to_s :to_s_default }
|
118
109
|
else
|
119
110
|
puts "You're screwed!"
|
120
|
-
end
|
111
|
+
end
|
121
112
|
end
|
122
113
|
end
|
123
114
|
|
@@ -175,7 +166,7 @@ class IPAddr
|
|
175
166
|
[to_s,mlen].join('/')
|
176
167
|
end
|
177
168
|
|
178
|
-
def IPAddr.
|
169
|
+
def IPAddr.to_arr(prefix)
|
179
170
|
source_address,mlen = prefix.split('/')
|
180
171
|
ip = IPAddr.new(prefix)
|
181
172
|
network = ip.to_s
|
@@ -200,8 +191,6 @@ class IPAddr
|
|
200
191
|
Proc.new { |n| n*(2**(max_len - mlen)) }
|
201
192
|
end
|
202
193
|
|
203
|
-
|
204
|
-
|
205
194
|
end
|
206
195
|
|
207
196
|
|
data/lib/infra/ospf_constants.rb
CHANGED
@@ -23,14 +23,14 @@
|
|
23
23
|
module OSPFv2
|
24
24
|
|
25
25
|
module Constant
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
26
|
+
V2=2
|
27
|
+
V3=3
|
28
|
+
HELLO = 1
|
29
|
+
DATABASE_DESCRIPTION = 2
|
30
|
+
LINK_STATE_REQUEST = 3
|
31
|
+
LINK_STATE_UPDATE = 4
|
32
|
+
LINK_STATE_ACKNOWLEDGEMENT = 5
|
33
|
+
end
|
34
34
|
|
35
35
|
VERSION=2
|
36
36
|
LSRefreshTime = 30*60
|
data/lib/infra/ospf_io.rb
CHANGED
data/lib/infra/ospf_socket.rb
CHANGED
@@ -34,8 +34,7 @@ module OSPFv2
|
|
34
34
|
def initialize(src, options={})
|
35
35
|
@src = src
|
36
36
|
@sock = Socket.open(Socket::PF_INET, Socket::SOCK_RAW, IPPROTO_OSPF)
|
37
|
-
|
38
|
-
add_membership OSPFv2::AllDRouters
|
37
|
+
@sock.setsockopt(::Socket::IPPROTO_IP, ::Socket::IP_MULTICAST_IF, IPAddr.new(src).hton)
|
39
38
|
rescue Errno::EPERM
|
40
39
|
$stderr.puts "#{e}: You are not root, cannot run: #{$0}!"
|
41
40
|
exit(1)
|
@@ -50,25 +49,17 @@ module OSPFv2
|
|
50
49
|
#TODO: use all_spf_routers, all_dr_routers, ...
|
51
50
|
# 8.1 Sending protocol packets .............................. 58
|
52
51
|
|
53
|
-
def send(packet, location={:to=> :all_spf_routers})
|
54
|
-
case location
|
55
|
-
when :all_spf_routers ; send_all_spf_routers(packet)
|
56
|
-
when :all_dr_routers ; send_all_dr_routers(packet)
|
57
|
-
else
|
58
|
-
send_to(packet, location[:to])
|
59
|
-
end
|
60
|
-
end
|
61
52
|
|
62
53
|
def send_all_spf_routers
|
63
|
-
_send_
|
54
|
+
_send_((packet.respond_to?(:encode) ? packet.encode : packet), 0, @sock_addr_all_spf_routers)
|
64
55
|
end
|
65
56
|
|
66
57
|
def send_all_dr_routers
|
67
|
-
_send_
|
58
|
+
_send_((packet.respond_to?(:encode) ? packet.encode : packet), 0, @send_all_dr_routers)
|
68
59
|
end
|
69
60
|
|
70
61
|
def send_to(packet, dest)
|
71
|
-
_send_
|
62
|
+
_send_((packet.respond_to?(:encode) ? packet.encode : packet), 0, Socket.pack_sockaddr_in(0, dest))
|
72
63
|
end
|
73
64
|
|
74
65
|
def send(packet, dest)
|
@@ -84,7 +75,6 @@ module OSPFv2
|
|
84
75
|
|
85
76
|
def add_membership(group)
|
86
77
|
@sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, (IPAddr.new(group).hton + IPAddr.new(@src).hton))
|
87
|
-
puts "*** ADDED #{group} membership to Send Socket ***"
|
88
78
|
rescue Errno::EADDRNOTAVAIL
|
89
79
|
end
|
90
80
|
|
@@ -100,8 +90,8 @@ module OSPFv2
|
|
100
90
|
def initialize(src, options={})
|
101
91
|
@src=src
|
102
92
|
@sock = Socket.open(Socket::PF_INET, Socket::SOCK_RAW,89)
|
103
|
-
add_membership OSPFv2::AllSPFRouters
|
104
|
-
add_membership OSPFv2::AllDRouters
|
93
|
+
add_membership OSPFv2::AllSPFRouters, src
|
94
|
+
add_membership OSPFv2::AllDRouters, src
|
105
95
|
end
|
106
96
|
def recv(size=8192)
|
107
97
|
begin
|
@@ -116,10 +106,12 @@ module OSPFv2
|
|
116
106
|
begin ; @sock.close ; rescue ; end
|
117
107
|
@sock=nil
|
118
108
|
end
|
119
|
-
def add_membership(group)
|
120
|
-
|
121
|
-
|
122
|
-
rescue Errno::EADDRNOTAVAIL
|
109
|
+
def add_membership(group,src)
|
110
|
+
optval = IPAddr.new(group).hton + IPAddr.new(src).hton
|
111
|
+
@sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, optval)
|
112
|
+
rescue Errno::EADDRNOTAVAIL => e
|
113
|
+
p e
|
114
|
+
raise
|
123
115
|
end
|
124
116
|
end
|
125
117
|
|
data/lib/infra/parse_options.rb
CHANGED
@@ -56,7 +56,7 @@ class OptParse
|
|
56
56
|
|
57
57
|
to_ip = lambda { |id| [id].pack('N').unpack('C*').join('.') }
|
58
58
|
to_id = lambda { |x| OSPFv2::Id.to_i(x) }
|
59
|
-
dead_int = lambda {
|
59
|
+
dead_int = lambda { options.dead_int || (options.hello_int * 4) }
|
60
60
|
|
61
61
|
option_help = "blabla ...."
|
62
62
|
hlp_address = "IP Address of the OSPF Interface."
|
@@ -104,7 +104,7 @@ class OptParse
|
|
104
104
|
options.hello_int = int.to_i
|
105
105
|
}
|
106
106
|
opts.on("--dead-interval [INT]", hlp_dead_int) { |int|
|
107
|
-
|
107
|
+
options.dead_int = int.to_i
|
108
108
|
}
|
109
109
|
opts.on("-g", "--grid [colxrow]", hlp_grid) { |grid|
|
110
110
|
options.grid = grid.split('x').collect { |x| x.to_i }
|
@@ -124,7 +124,7 @@ class OptParse
|
|
124
124
|
end
|
125
125
|
|
126
126
|
optparse.parse!(args)
|
127
|
-
options.dead_int
|
127
|
+
options.dead_int ||= (options.hello_int * 4)
|
128
128
|
|
129
129
|
options
|
130
130
|
|
data/lib/infra/timer.rb
CHANGED
@@ -41,6 +41,7 @@ class Timer
|
|
41
41
|
@interval = interval
|
42
42
|
@code = block if block
|
43
43
|
add_observer observer if observer
|
44
|
+
@_timer_thread_ = nil
|
44
45
|
end
|
45
46
|
|
46
47
|
def start _interval=@interval, &block
|
@@ -69,7 +70,7 @@ class Timer
|
|
69
70
|
|
70
71
|
def reset &block
|
71
72
|
cancel
|
72
|
-
start
|
73
|
+
start(&block)
|
73
74
|
end
|
74
75
|
|
75
76
|
private
|
@@ -26,11 +26,10 @@ require 'ie/id'
|
|
26
26
|
module OSPFv2::LSDB
|
27
27
|
class AdvertisedRouters
|
28
28
|
AdvertisedRouter = Class.new(OSPFv2::Id)
|
29
|
-
attr_reader :routers
|
30
29
|
def initialize
|
31
30
|
@set = Set.new
|
32
31
|
end
|
33
|
-
def
|
32
|
+
def <<(id)
|
34
33
|
@set << router_id(id)
|
35
34
|
end
|
36
35
|
def routers
|
@@ -40,6 +39,9 @@ module OSPFv2::LSDB
|
|
40
39
|
def has?(id)
|
41
40
|
routers.include?(router_id(id))
|
42
41
|
end
|
42
|
+
def to_s
|
43
|
+
@set.collect { |r| IPAddr.new_ntoh([r].pack('N')).to_s }
|
44
|
+
end
|
43
45
|
def -(id)
|
44
46
|
@set.delete router_id(id)
|
45
47
|
end
|
@@ -50,29 +52,29 @@ module OSPFv2::LSDB
|
|
50
52
|
end
|
51
53
|
end
|
52
54
|
|
53
|
-
if __FILE__ == $0
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
end
|
55
|
+
# if __FILE__ == $0
|
56
|
+
#
|
57
|
+
# require "test/unit"
|
58
|
+
#
|
59
|
+
# # require "ls_db/advertised_routers"
|
60
|
+
#
|
61
|
+
# class TestLsDbAdvertisedRouters < Test::Unit::TestCase
|
62
|
+
# include OSPFv2::LSDB
|
63
|
+
# def tests
|
64
|
+
# assert AdvertisedRouters.new
|
65
|
+
# routers = AdvertisedRouters.new
|
66
|
+
# routers + 1
|
67
|
+
# routers + '0.0.0.1'
|
68
|
+
# routers + 2
|
69
|
+
# routers + OSPFv2::Id.new(3)
|
70
|
+
# assert_equal [1,2,3], routers.routers
|
71
|
+
# routers -1
|
72
|
+
# assert_equal [2,3], routers.routers
|
73
|
+
# routers -3
|
74
|
+
# assert_equal [2], routers.routers
|
75
|
+
# routers - '0.0.0.2'
|
76
|
+
# assert_equal [], routers.routers
|
77
|
+
# end
|
78
|
+
# end
|
79
|
+
#
|
80
|
+
# end
|
@@ -77,8 +77,7 @@ require 'ls_db/advertised_routers'
|
|
77
77
|
require 'infra/to_s'
|
78
78
|
|
79
79
|
module OSPFv2
|
80
|
-
|
81
|
-
module LSDB
|
80
|
+
module LSDB
|
82
81
|
|
83
82
|
class LinkStateDatabase
|
84
83
|
include OSPFv2
|
@@ -95,7 +94,7 @@ module OSPFv2
|
|
95
94
|
|
96
95
|
def initialize(arg={})
|
97
96
|
@ls_db = Hash.new
|
98
|
-
@area_id =
|
97
|
+
@area_id = AreaId.new
|
99
98
|
@advertised_routers= AdvertisedRouters.new
|
100
99
|
@ls_refresh_interval=180
|
101
100
|
@offset=0
|
@@ -210,12 +209,7 @@ module OSPFv2
|
|
210
209
|
raise ArgumentError, "*** Invalid argument, #{args.inspect}"
|
211
210
|
end
|
212
211
|
end
|
213
|
-
|
214
|
-
|
215
|
-
def refresh
|
216
|
-
all.find_all {|l| l.refresh(ls_refresh_time) }
|
217
|
-
end
|
218
|
-
|
212
|
+
|
219
213
|
def reset
|
220
214
|
each {|lsa| lsa.ack }
|
221
215
|
@offset=0
|
@@ -261,10 +255,6 @@ module OSPFv2
|
|
261
255
|
all.find_all { |l| ! l.ack? }
|
262
256
|
end
|
263
257
|
|
264
|
-
def method_missing(method, *args, &block)
|
265
|
-
super
|
266
|
-
end
|
267
|
-
|
268
258
|
def refresh
|
269
259
|
all.find_all {|l| l.refresh(advertised_routers, ls_refresh_time) }
|
270
260
|
end
|
@@ -277,11 +267,16 @@ module OSPFv2
|
|
277
267
|
def recv_link_state_update(link_state_update)
|
278
268
|
link_state_update.each do |lsa|
|
279
269
|
if advertised_routers.has?(lsa.advertising_router)
|
270
|
+
puts "RECEIVING FROM *OUR* #{lsa.advertising_router}"
|
280
271
|
if @ls_db.key? lsa.key
|
272
|
+
puts "AND WE HAVE KEY #{lsa.key.inspect} ALREADY ...."
|
281
273
|
@ls_db[lsa.key].force_refresh(lsa.sequence_number)
|
282
274
|
else
|
275
|
+
puts "AND WE DO NOT HAVE KEY #{lsa.key.inspect}...."
|
283
276
|
@ls_db.store(lsa.key,lsa)
|
277
|
+
puts "STORE KEY #{lsa.key.inspect}...."
|
284
278
|
lsa.maxage
|
279
|
+
puts "MAXAGE IT #{lsa.key.inspect}...."
|
285
280
|
end
|
286
281
|
else
|
287
282
|
if lsa.maxaged?
|
@@ -331,46 +326,9 @@ module OSPFv2
|
|
331
326
|
|
332
327
|
end
|
333
328
|
|
334
|
-
#
|
335
|
-
# @ls_db = []
|
336
|
-
# @ls_db << {
|
337
|
-
# :sequence_number=>2147483650,
|
338
|
-
# :advertising_router=>"1.2.0.0",
|
339
|
-
# :ls_id=>"0.0.4.5",
|
340
|
-
# :nwveb=>1,
|
341
|
-
# :ls_type=>:router_lsa,
|
342
|
-
# :options=> 0x21,
|
343
|
-
# :ls_age=>10,
|
344
|
-
# :links=>[
|
345
|
-
# {
|
346
|
-
# :link_id=>"1.1.1.1",
|
347
|
-
# :link_data=>"255.255.255.255",
|
348
|
-
# :router_link_type=>:point_to_point,
|
349
|
-
# :metric=>11,
|
350
|
-
# :mt_metrics=>[ {:id=>1, :metric=>11}, {:id=>2, :metric=>22} ]
|
351
|
-
# },
|
352
|
-
# {
|
353
|
-
# :link_id=>"1.1.1.2",
|
354
|
-
# :link_data=>"255.255.255.255",
|
355
|
-
# :router_link_type=>:point_to_point,
|
356
|
-
# :metric=>12,
|
357
|
-
# :mt_metrics=>[]
|
358
|
-
# }
|
359
|
-
# ],
|
360
|
-
# }
|
361
|
-
#
|
362
|
-
#
|
363
|
-
# ls_db = LinkStateDatabase.new :area_id=> 1, :ls_db => @ls_db
|
364
|
-
# puts ""
|
365
|
-
# puts ls_db.to_s_junos
|
366
|
-
#
|
367
|
-
|
368
|
-
|
369
|
-
|
370
329
|
end
|
371
330
|
end
|
372
331
|
|
373
332
|
require 'ls_db/link_state_database_build'
|
374
333
|
|
375
334
|
load "../../../test/ospfv2/ls_db/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|
376
|
-
|