ospfv2 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/bin/ospfv2 +136 -0
  2. data/lib/ie/au_type.rb +79 -0
  3. data/lib/ie/external_route.rb +181 -0
  4. data/lib/ie/id.rb +97 -0
  5. data/lib/ie/interface_mtu.rb +64 -0
  6. data/lib/ie/ls_age.rb +89 -0
  7. data/lib/ie/ls_type.rb +148 -0
  8. data/lib/ie/metric.rb +63 -0
  9. data/lib/ie/mt_metric.rb +119 -0
  10. data/lib/ie/options.rb +356 -0
  11. data/lib/ie/ospf_version.rb +67 -0
  12. data/lib/ie/packet_type.rb +65 -0
  13. data/lib/ie/router_link.rb +167 -0
  14. data/lib/ie/router_link_factory.rb +53 -0
  15. data/lib/ie/router_link_type.rb +86 -0
  16. data/lib/ie/sequence_number.rb +144 -0
  17. data/lib/ie/tos_metric.rb +102 -0
  18. data/lib/infra/ospf_common.rb +291 -0
  19. data/lib/infra/ospf_constants.rb +73 -0
  20. data/lib/infra/ospf_io.rb +133 -0
  21. data/lib/infra/ospf_socket.rb +126 -0
  22. data/lib/infra/parse_options.rb +135 -0
  23. data/lib/infra/timer.rb +104 -0
  24. data/lib/infra/to_s.rb +38 -0
  25. data/lib/ls_db/advertised_routers.rb +78 -0
  26. data/lib/ls_db/common.rb +31 -0
  27. data/lib/ls_db/link_state_database.rb +376 -0
  28. data/lib/ls_db/link_state_database_build.rb +181 -0
  29. data/lib/ls_db/link_state_database_links.rb +178 -0
  30. data/lib/ls_db/links.rb +160 -0
  31. data/lib/lsa/external.rb +347 -0
  32. data/lib/lsa/lsa.rb +438 -0
  33. data/lib/lsa/lsa_factory.rb +59 -0
  34. data/lib/lsa/network.rb +166 -0
  35. data/lib/lsa/router.rb +336 -0
  36. data/lib/lsa/summary.rb +393 -0
  37. data/lib/neighbor/neighbor.rb +298 -0
  38. data/lib/neighbor/neighbor_event_handler.rb +61 -0
  39. data/lib/neighbor/recv_database_description.rb +153 -0
  40. data/lib/neighbor/recv_hello.rb +53 -0
  41. data/lib/neighbor/recv_ospf_packet.rb +68 -0
  42. data/lib/neighbor_sm/attempt_state.rb +44 -0
  43. data/lib/neighbor_sm/down_state.rb +46 -0
  44. data/lib/neighbor_sm/exchange_state.rb +32 -0
  45. data/lib/neighbor_sm/exstart_state.rb +69 -0
  46. data/lib/neighbor_sm/full_state.rb +36 -0
  47. data/lib/neighbor_sm/init_state.rb +43 -0
  48. data/lib/neighbor_sm/loading_state.rb +33 -0
  49. data/lib/neighbor_sm/neighbor_state.rb +87 -0
  50. data/lib/packet/database_description.rb +300 -0
  51. data/lib/packet/hello.rb +327 -0
  52. data/lib/packet/link_state_ack.rb +144 -0
  53. data/lib/packet/link_state_request.rb +153 -0
  54. data/lib/packet/link_state_update.rb +189 -0
  55. data/lib/packet/ospf_packet.rb +306 -0
  56. metadata +116 -0
@@ -0,0 +1,393 @@
1
+ #--
2
+ # Copyright 2010 Jean-Michel Esnault.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #
6
+ #
7
+ # This file is part of OSPFv2.
8
+ #
9
+ # OSPFv2 is free software: you can redistribute it and/or modify
10
+ # it under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation, either version 3 of the License, or
12
+ # (at your option) any later version.
13
+ #
14
+ # OSPFv2 is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ # GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License
20
+ # along with OSPFv2. If not, see <http://www.gnu.org/licenses/>.
21
+ #++
22
+
23
+ require 'lsa/lsa'
24
+
25
+ require 'ie/metric'
26
+ require 'ie/mt_metric'
27
+ require 'ie/id'
28
+
29
+
30
+ module OSPFv2
31
+
32
+ Netmask = Class.new(Id)
33
+
34
+ class Summary_Base < Lsa
35
+
36
+ attr_reader :metric, :netmask, :mt_metrics
37
+
38
+ def initialize(arg={})
39
+ @netmask=nil
40
+ @metric=nil
41
+ @mt_metrics=[]
42
+ super
43
+ end
44
+
45
+ def mt_metrics=(val)
46
+ [val].flatten.each { |x| self << x }
47
+ end
48
+
49
+ def <<(metric)
50
+ @mt_metrics ||=[]
51
+ @mt_metrics << MtMetric.new(metric)
52
+ end
53
+
54
+ def encode
55
+ @netmask ||= Netmask.new
56
+ @metric ||= Metric.new
57
+ summary =[]
58
+ summary << netmask.encode
59
+ summary << metric.encode
60
+ summary << mt_metrics.collect { |x| x.encode } if mt_metrics
61
+ super summary.join
62
+ end
63
+
64
+ def parse(s)
65
+ netmask, metric, mt_metrics = super(s).unpack('NNa*')
66
+ @netmask = Netmask.new netmask
67
+ @metric = Metric.new metric
68
+ while mt_metrics.size>0
69
+ self << MtMetric.new(mt_metrics.slice!(0,4))
70
+ end
71
+ end
72
+
73
+ def to_hash
74
+ super
75
+ end
76
+
77
+ def to_s_default(*args)
78
+ super +
79
+ ['',netmask, metric, *mt_metrics].collect { |x| x.to_s }.join("\n ")
80
+ end
81
+
82
+ def to_s_junos_verbose
83
+ mask = "mask #{netmask.to_ip}"
84
+ super +
85
+ ['', mask, metric.to_s_junos, *mt_metrics.collect{|m| m.to_s_junos}].join("\n ")
86
+ end
87
+ def to_s_junos
88
+ super
89
+ end
90
+
91
+ end
92
+
93
+ class Summary < Summary_Base
94
+ class << self
95
+ def count
96
+ @count ||= 0
97
+ end
98
+
99
+ def incr_count
100
+ self.count
101
+ @count += 1
102
+ end
103
+
104
+ def reset
105
+ @count = nil
106
+ end
107
+
108
+ def base_ip_addr(addr=SUMMARY_BASE_ADDRESS)
109
+ @base_addr ||= IPAddr.new(addr)
110
+ end
111
+
112
+ def network
113
+ @base_addr + count
114
+ end
115
+
116
+ def new_lsdb(arg={})
117
+ new({:network=> base_ip_addr ^ incr_count}.merge(arg))
118
+ end
119
+
120
+ end
121
+
122
+
123
+ def initialize(arg={})
124
+ if arg.is_a?(Hash)
125
+ arg = fix_hash(arg).merge!({:ls_type => :summary_lsa,})
126
+ end
127
+ super
128
+ end
129
+
130
+ private
131
+
132
+ def fix_hash(arg)
133
+ if arg[:network]
134
+ addr = IPAddr.new arg[:network]
135
+ arg.delete :network
136
+ arg.store :netmask, addr.netmask
137
+ arg.store :ls_id, addr.to_s
138
+ end
139
+ arg
140
+ end
141
+
142
+ end
143
+
144
+ class AsbrSummary < Summary_Base
145
+ def initialize(arg={})
146
+ arg.merge!({:ls_type => :asbr_summary_lsa,}) if arg.is_a?(Hash)
147
+ super
148
+ end
149
+ end
150
+
151
+ class Summary_Base
152
+ def self.new_hash(hash)
153
+ raise ArgumentError, "Invalid argument" unless hash.is_a?(Hash)
154
+ new(hash)
155
+ end
156
+ end
157
+
158
+ end
159
+
160
+
161
+ load "../../../test/ospfv2/lsa/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
162
+
163
+ __END__
164
+
165
+ # if arg.is_a?(Hash)
166
+ # arg.merge!({:ls_type=> :summary_lsa}) unless arg.has_key?(:ls_type)
167
+ # set arg
168
+ # super
169
+ # elsif arg.is_a?(String)
170
+ # parse arg
171
+ # elsif arg.is_a?(self.class)
172
+ # parse arg.encode
173
+ # else
174
+ # raise ArgumentError, "Invalid argument", caller
175
+ # end
176
+
177
+ =begin rdoc
178
+
179
+
180
+ A.4.4 Summary-LSAs
181
+
182
+ Summary-LSAs are the Type 3 and 4 LSAs. These LSAs are originated
183
+ by area border routers. Summary-LSAs describe inter-area
184
+ destinations. For details concerning the construction of summary-
185
+ LSAs, see Section 12.4.3.
186
+
187
+ Type 3 summary-LSAs are used when the destination is an IP network.
188
+ In this case the LSA's Link State ID field is an IP network number
189
+ (if necessary, the Link State ID can also have one or more of the
190
+ network's "host" bits set; see Appendix E for details). When the
191
+ destination is an AS boundary router, a Type 4 summary-LSA is used,
192
+ and the Link State ID field is the AS boundary router's OSPF Router
193
+ ID. (To see why it is necessary to advertise the location of each
194
+ ASBR, consult Section 16.4.) Other than the difference in the Link
195
+ State ID field, the format of Type 3 and 4 summary-LSAs is
196
+ identical.
197
+
198
+
199
+ 0 1 2 3
200
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
201
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
202
+ | LS age | Options | 3 or 4 |
203
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
204
+ | Link State ID |
205
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
206
+ | Advertising Router |
207
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
208
+ | LS sequence number |
209
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
210
+ | LS checksum | length |
211
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
212
+ | Network Mask |
213
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
214
+ | 0 | metric |
215
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
216
+ | TOS | TOS metric |
217
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
218
+ | ... |
219
+
220
+
221
+ For stub areas, Type 3 summary-LSAs can also be used to describe a
222
+ (per-area) default route. Default summary routes are used in stub
223
+ areas instead of flooding a complete set of external routes. When
224
+ describing a default summary route, the summary-LSA's Link State ID
225
+ is always set to DefaultDestination (0.0.0.0) and the Network Mask
226
+ is set to 0.0.0.0.
227
+
228
+ Network Mask
229
+ For Type 3 summary-LSAs, this indicates the destination
230
+ network's IP address mask. For example, when advertising the
231
+ location of a class A network the value 0xff000000 would be
232
+ used. This field is not meaningful and must be zero for Type 4
233
+ summary-LSAs.
234
+
235
+ metric
236
+ The cost of this route. Expressed in the same units as the
237
+ interface costs in the router-LSAs.
238
+
239
+ Additional TOS-specific information may also be included, for
240
+ backward compatibility with previous versions of the OSPF
241
+ specification ([Ref9]). For each desired TOS, TOS-specific
242
+ information is encoded as follows:
243
+
244
+ TOS IP Type of Service that this metric refers to. The encoding of
245
+ TOS in OSPF LSAs is described in Section 12.3.
246
+
247
+ TOS metric
248
+ TOS-specific metric information.
249
+
250
+
251
+ =end
252
+
253
+
254
+ module Ospf
255
+ module Summary_Shared
256
+ private
257
+ def __to_s_junos_style__(sum_type, rtype=' ')
258
+ enc
259
+ s = @header.to_s_junos_style(sum_type,rtype)
260
+ s +="\n mask #{netmask}"
261
+ s +="\n Topology default (ID #{@mt_id[0].id}) -> Metric: #{@mt_id[0].metric}"
262
+ s += @mt_id[1..-1].collect { |mt| "\n #{mt.to_s_junos_style}" }.join
263
+ s
264
+ end
265
+ def __to_hash__(sum_type)
266
+ enc
267
+ h = @header.to_hash.merge({:lsa_type=>sum_type, :netmask => netmask,})
268
+ if @mt_id.size > 1 or @mt_id[0].id != 0
269
+ h[:mt_id] = @mt_id.collect { |mt_id| mt_id.to_hash } unless @mt_id.nil?
270
+ else
271
+ h[:metric] = @mt_id[0].metric
272
+ end
273
+ h
274
+ end
275
+ private :__to_s_junos_style__, :__to_hash__
276
+
277
+ end
278
+ end
279
+
280
+ require 'lsa_header'
281
+
282
+ module Ospf
283
+
284
+ class SummaryLSAs < LSA
285
+ include Ospf
286
+ include Ospf::Ip
287
+ include Ospf::Summary_Shared
288
+
289
+ attr :header
290
+ attr_accessor :mt_id
291
+
292
+ def initialize(arg={})
293
+ @netmask, @mt_id = 0, []
294
+ if arg.is_a?(Hash) then
295
+ arg[:lstype]=3 if arg[:lstype].nil?
296
+ @header = LSA_Header.new(arg)
297
+ set(arg)
298
+ elsif arg.is_a?(String)
299
+ __parse(arg)
300
+ else
301
+ raise ArgumentError, "Invalid argument", caller
302
+ end
303
+ end
304
+
305
+ def set(arg)
306
+ return self unless arg.is_a?(Hash)
307
+ @header.set(arg)
308
+ unless arg[:netmask].nil?
309
+ _netmask = arg[:netmask]
310
+ @netmask = _netmask.is_a?(String) ? ip2long(_netmask) : _netmask
311
+ end
312
+
313
+ unless arg[:metric].nil?
314
+ metric=arg[:metric]
315
+ @mt_id << MT.new({:metric=>metric})
316
+ end
317
+ unless arg[:mt_id].nil?
318
+ arg[:mt_id].each { |mt_id|
319
+ mt_id.is_a?(MT) ? @mt_id << mt_id : @mt_id << MT.new(mt_id)
320
+ }
321
+ end
322
+ self
323
+ end
324
+
325
+ def <<(arg)
326
+ append_metric(arg)
327
+ end
328
+
329
+ def enc
330
+ packet = @header.enc
331
+ packet+= __enc([[@netmask,'N'],])
332
+ packet +=@mt_id.collect {|mt_id| mt_id.enc}.join
333
+ packet_size(packet,@header)
334
+ packet_fletchsum(packet)
335
+ end
336
+
337
+ def __parse(s)
338
+ @header = LSA_Header.new(s)
339
+ arr = s[20..24].unpack("N")
340
+ @netmask = arr[0]
341
+ mt_ids = s[24..-1]
342
+ while mt_ids.size>0
343
+ @mt_id << MT.new(mt_ids.slice!(0,4))
344
+ end
345
+ end
346
+ private :__parse
347
+
348
+ def to_s
349
+ enc
350
+ s = @header.to_s
351
+ s += "\n netmask #{netmask}"
352
+ s += "\n " if @mt_id.size>0
353
+ s += @mt_id.collect { |mt| mt.to_s }.join("\n ")
354
+ end
355
+
356
+ def metric
357
+ @mt_id[0].metric
358
+ end
359
+
360
+ end
361
+
362
+ class SummaryLSA < SummaryLSAs
363
+ def initialize(arg={})
364
+ arg.merge!({:lstype => 3,}) if arg.is_a?(Hash)
365
+ super
366
+ end
367
+ def to_s_junos_style(rtype=' ')
368
+ __to_s_junos_style__('Summary', rtype)
369
+ end
370
+ def to_hash
371
+ __to_hash__('Summary')
372
+ end
373
+ end
374
+
375
+ class ASBR_SummaryLSA < SummaryLSAs
376
+ def initialize(arg={})
377
+ arg.merge!({:lstype => 4, :metric=>0}) if arg.is_a?(Hash)
378
+ super(arg)
379
+ end
380
+ def to_s_junos_style(rtype=' ')
381
+ __to_s_junos_style__('ASBRSum', rtype)
382
+ end
383
+ def to_hash
384
+ __to_hash__('ASBRSum')
385
+ end
386
+ end
387
+ end
388
+
389
+ if __FILE__ == $0
390
+ load '../test/lsa_summary_test.rb'
391
+ end
392
+
393
+
@@ -0,0 +1,298 @@
1
+ #--
2
+ # Copyright 2010 Jean-Michel Esnault.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #
6
+ #
7
+ # This file is part of OSPFv2.
8
+ #
9
+ # OSPFv2 is free software: you can redistribute it and/or modify
10
+ # it under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation, either version 3 of the License, or
12
+ # (at your option) any later version.
13
+ #
14
+ # OSPFv2 is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ # GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License
20
+ # along with OSPFv2. If not, see <http://www.gnu.org/licenses/>.
21
+ #++
22
+
23
+
24
+ require 'thread'
25
+ require 'logger'
26
+ require 'infra/ospf_common'
27
+ require 'neighbor_sm/neighbor_state'
28
+ require 'infra/ospf_socket'
29
+ require 'infra/ospf_io'
30
+ require 'packet/ospf_packet'
31
+ require 'infra/timer'
32
+ require 'infra/ospf_constants'
33
+ require 'ls_db/link_state_database'
34
+
35
+ require 'neighbor/neighbor_event_handler'
36
+
37
+ module OSPFv2
38
+
39
+ class Neighbor
40
+
41
+ class Trace
42
+ def initialize(io=$stdout)
43
+ @logger = Logger.new(io)
44
+ end
45
+ def trace(s)
46
+ "{Time.to_ts} #{s}"
47
+ @logger << s
48
+ end
49
+ end
50
+
51
+ include OSPFv2::Common
52
+ include OSPFv2::NeighborState
53
+ include OSPFv2
54
+ attr_reader :address, :inactivity_timer, :hello, :dd_rxmt_interval
55
+
56
+ InactivityTimer = Class.new(Timer)
57
+ HelloTimer = Class.new(PeriodicTimer)
58
+ RxmtIntervalTimer = Class.new(PeriodicTimer)
59
+ RefreshTimer = Class.new(PeriodicTimer)
60
+ RouterId = Class.new(Id)
61
+ AreadId = Class.new(Id)
62
+
63
+ attr_writer :hello_int, :dead_int
64
+
65
+ def initialize(arg={})
66
+ #TODO: accept prefix arg and set @address and @netmask in hello...
67
+ @address = arg[:src_addr] || '127.0.0.1'
68
+ @state = NeighborState::Down.new
69
+ @inactivity_timer = InactivityTimer.new(self.dead_int)
70
+ @periodic_hellos = HelloTimer.new(self.hello_int)
71
+ @router_id= RouterId.new arg[:router_id] || '1.1.1.1'
72
+ @area_id= AreaId.new arg[:aread_id] || '0.0.0.0'
73
+ @lsa_request_list = {}
74
+ @ls_db=nil
75
+ if arg[:log_fname]
76
+ @trace = Trace.new(arg[:log_fname])
77
+ else
78
+ @trace = Trace.new
79
+ end
80
+ end
81
+
82
+ def hello_int
83
+ @hello_int ||= 10
84
+ end
85
+ def dead_int
86
+ @dead_int ||= hello_int*4
87
+ end
88
+
89
+ def state
90
+ @state.class.to_s.split('::').last.downcase.to_sym
91
+ end
92
+
93
+ def in_state?(*states)
94
+ if states.size==0
95
+ state
96
+ else
97
+ states.include? state
98
+ end
99
+ end
100
+
101
+ def ls_db=(val)
102
+ raise ArgumentError, "expecting a LinkStateDatabase object!" unless val.is_a?(LSDB::LinkStateDatabase)
103
+ @ls_db=val
104
+ end
105
+
106
+ def log(ev, obj)
107
+ if obj.is_a?(String)
108
+ @trace.trace "\n#{Time.to_ts} #{ev}: #{obj}"
109
+ else
110
+ s = []
111
+ s << "\n#{Time.to_ts} (#{state}) #{ev} #{obj.name.to_camel}:\n#{obj}"
112
+ s << obj.encode.hexlify.join("\n ") if defined?($debug) and $debug == 1
113
+ s << "\n"
114
+ @trace.trace s.join
115
+ end
116
+ end
117
+
118
+ def debug(obj)
119
+ log :debug, obj if defined? $debug and $debug ==1
120
+ end
121
+
122
+ def clear_lsa_request_list
123
+ @lsa_request_list={}
124
+ end
125
+
126
+ def router_id
127
+ hello.router_id
128
+ end
129
+
130
+ def change_state(new_state, event=nil)
131
+ @num ||=0
132
+ @num +=1
133
+ log 'state change', "#{@num}\# [#{event}]: #{state} -> #{new_state.class.to_s.split('::').last}"
134
+ @state = new_state
135
+ end
136
+ alias :new_state :change_state
137
+
138
+ def dd_sequence_number
139
+ @dd_sequence_number = DatabaseDescription.seqn
140
+ end
141
+ def start
142
+ unless @ev
143
+ @ev = NeighborEventHandler.new(self)
144
+ @evQ = Queue.new
145
+ end
146
+ @dd_rxmt_interval = RxmtIntervalTimer.new(5,@ev)
147
+ @periodic_rxmt = RxmtIntervalTimer.new(5,@ev)
148
+ @periodic_refresh = RefreshTimer.new(60,@ev)
149
+ init_sockets @address
150
+ init_io
151
+ start_io
152
+ start_periodic_hellos
153
+ @state.start(self)
154
+ self
155
+ end
156
+
157
+ def stop
158
+ debug "*** stopping #{router_id}"
159
+ @periodic_hellos.cancel
160
+ @periodic_rxmt.cancel
161
+ @periodic_refresh.cancel
162
+ stop_io
163
+ close_sockets
164
+ rescue Exception => e
165
+ debug "#{e} while stopping neighor"
166
+ ensure
167
+ @state.kill_nbr(self)
168
+ self
169
+ end
170
+
171
+ def update(*args)
172
+ @evQ.enq *args
173
+ end
174
+ def send(packet, dest=OSPFv2::AllSPFRouters)
175
+ return unless @output
176
+ [packet].flatten.each { |p|
177
+ log :snd, p
178
+ @output.enq [p,dest]
179
+ }
180
+ end
181
+
182
+ # AllSPFRouters = "224.0.0.5"
183
+ # AllDRouters = "224.0.0.6"
184
+ def flood(lsas, dest=AllSPFRouters)
185
+ # return unless @output
186
+ send (LinkStateUpdate.new_lsas lsas), dest
187
+ end
188
+
189
+ def start_periodic_hellos
190
+ @periodic_hellos.cancel
191
+ hh = {
192
+ :router_id=> @router_id,
193
+ :netmask=> 0xffffff00,
194
+ :designated_router_id=> '0.0.0.0',
195
+ :backup_designated_router_id=> '0.0.0.0',
196
+ :helloInt=>hello_int,
197
+ :options=>2,
198
+ :rtr_pri=>0,
199
+ :deadInt=>dead_int,
200
+ }
201
+ @hello = Hello.new(hh)
202
+ @periodic_hellos.start {
203
+ send(@hello)
204
+ }
205
+ end
206
+
207
+ def start_periodic_rxmt
208
+ debug "*** about to start periodic rxmt timer ***"
209
+ @periodic_rxmt.start {
210
+ if @ls_req_list
211
+ debug "There are #{@ls_req_list.size} LS Request to re-transmit!"
212
+ send LinkStateRequest.new :area_id => @area_id, :router_id=> @router_id, :requests=> @ls_req_list.keys \
213
+ unless @ls_req_list.empty?
214
+ end
215
+ if @ls_db
216
+ lsas = @ls_db.all_not_acked
217
+ debug "There are #{lsas.size} LSA to re-transmit!"
218
+ send LinkStateUpdate.new_lsas :router_id=> @router_id,
219
+ :area_id => @area_id, :lsas => lsas unless lsas.empty?
220
+ end
221
+ }
222
+ end
223
+
224
+ def start_ls_refresh
225
+ return unless @ls_db
226
+ debug "*** about to start periodic refresh timer ***"
227
+ @periodic_refresh.start {
228
+ @ls_db.refresh if in_state? :full, :loading, :exchange
229
+ }
230
+ nil
231
+ end
232
+
233
+
234
+ def negotiation_done
235
+ @state.negotiation_done
236
+ end
237
+ def exchange_done
238
+ @state.exchange_done(self)
239
+ end
240
+
241
+ def send_dd(dd, rxmt=false)
242
+ dd_rxmt_interval.cancel
243
+ dd_rxmt_interval.start { debug "\n\n\n*** re-transmitting #{dd} ***\n\n\n" ; send dd } if rxmt
244
+ send dd, @neighbor_ip
245
+ @sent_dd = dd
246
+ end
247
+
248
+ def method_missing(method, *args, &block)
249
+ if method.to_s =~ /^(recv|unpack)/
250
+ puts %{
251
+
252
+ Method missing : #{method} !!!! #{@neighbor_state}
253
+
254
+ }
255
+ puts caller.reverse.join("\n")
256
+ raise
257
+ else
258
+ super
259
+ end
260
+ end
261
+
262
+ private
263
+
264
+ def init_sockets(src_addr)
265
+ begin
266
+ @rsock = RecvSocket.new(src_addr)
267
+ @ssock = SendSocket.new(src_addr)
268
+ rescue(Errno::EPERM) => e
269
+ STDERR.puts "\n**** root permission required, neighbor cannot be started.\n"
270
+ return
271
+ end
272
+ end
273
+
274
+ def close_sockets
275
+ @rsock.close
276
+ @ssock.close
277
+ rescue
278
+ end
279
+
280
+ def init_io
281
+ @input = Input.new(@rsock,self, @ev)
282
+ @output = OutputQ.new(@ssock,self, @ev)
283
+ end
284
+ def start_io
285
+ @input.start
286
+ @output.start
287
+ end
288
+ def stop_io
289
+ @input.stop
290
+ @output.stop
291
+ end
292
+
293
+ end
294
+
295
+ end
296
+
297
+ require 'neighbor/recv_ospf_packet'
298
+