Class: OSPFv2::Lsa

Inherits:
Object show all
Includes:
Comparable, Common, Constant, TO_S
Defined in:
lib/lsa/lsa.rb,
lib/lsa/lsa_factory.rb,
lib/ls_db/link_state_database_links.rb

Direct Known Subclasses

External_Base, Network, Opaque_Base, Router, Summary_Base

Constant Summary collapse

AdvertisingRouter =
Class.new(Id)
LsId =
Class.new(Id)
LsAge =
Class.new(LsAge)
MODX =
4102

Constants included from Constant

Constant::DATABASE_DESCRIPTION, Constant::HELLO, Constant::LINK_STATE_ACKNOWLEDGEMENT, Constant::LINK_STATE_REQUEST, Constant::LINK_STATE_UPDATE, Constant::V2, Constant::V3

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from TO_S

#to_s

Methods included from Common

#ivar_to_klassname, #ivars, #set

Constructor Details

#initialize(arg = {}) ⇒ Lsa

Returns a new instance of Lsa.



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/lsa/lsa.rb', line 187

def initialize(arg={})
  arg = arg.dup
  @ls_age = LsAge.new
  @sequence_number = SequenceNumber.new
  @options = Options.new
  @ls_id = LsId.new
  @advertising_router = AdvertisingRouter.new
  @_length = 0
  @_rxmt_ = false
  
  # unless @ls_type
  #   # raise if caller[-2].grep(/test\/unit/).empty?
  #   @ls_type = LsType.new(1)
  # end
  
  if arg.is_a?(Hash)
    set arg
  elsif arg.is_a?(String)
    parse arg
  elsif arg.is_a?(self.class)
    parse arg.encode
  else        
    raise ArgumentError, "Invalid Argument: #{arg.inspect}"
  end
  
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object



399
400
401
402
403
404
405
406
407
# File 'lib/lsa/lsa.rb', line 399

def method_missing(method, *args, &block)
  # puts "&&&&&  #{self.class}: method: #{method}"
  # p caller[0]
  if method == :to_s_junos
    :to_s_default
  else
    super
  end
end

Instance Attribute Details

#advertising_routerObject (readonly)

Returns the value of attribute advertising_router.



182
183
184
# File 'lib/lsa/lsa.rb', line 182

def advertising_router
  @advertising_router
end

#ls_ageObject (readonly)

Returns the value of attribute ls_age.



180
181
182
# File 'lib/lsa/lsa.rb', line 180

def ls_age
  @ls_age
end

#ls_idObject (readonly)

Returns the value of attribute ls_id.



181
182
183
# File 'lib/lsa/lsa.rb', line 181

def ls_id
  @ls_id
end

#optionsObject (readonly)

Returns the value of attribute options.



180
181
182
# File 'lib/lsa/lsa.rb', line 180

def options
  @options
end

#sequence_numberObject

Returns the value of attribute sequence_number.



183
184
185
# File 'lib/lsa/lsa.rb', line 183

def sequence_number
  @sequence_number
end

Class Method Details

.factory(arg) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/lsa/lsa_factory.rb', line 32

def factory(arg)
  if arg.is_a?(String)
    return unless (arg.size>=20)
    case arg.slice(3,1).unpack('C')[0]
    when 1 ; OSPFv2::Router.new_ntop(arg)
    when 2 ; OSPFv2::Network.new_ntop(arg)
    when 3 ; OSPFv2::Summary.new_ntop(arg)
    when 4 ; OSPFv2::AsbrSummary.new_ntop(arg)
    when 5 ; OSPFv2::AsExternal.new_ntop(arg)
    when 7 ; OSPFv2::AsExternal7.new_ntop(arg)
    else 
      raise
    end
  elsif arg.is_a?(Hash)
    case arg[:ls_type]
    when :router_lsa        ; OSPFv2::Router.new_hash(arg)
    when :network_lsa       ; OSPFv2::Network.new_hash(arg)
    when :summary_lsa       ; OSPFv2::Summary.new_hash(arg)
    when :asbr_summary_lsa  ; OSPFv2::AsbrSummary.new_hash(arg)
    when :as_external_lsa   ; OSPFv2::AsExternal.new_hash(arg)
    when :as_external7_lsa  ; OSPFv2::AsExternal7.new_hash(arg)
    else
      raise
    end
  elsif arg.is_a?(Lsa)
    factory(arg.encode)
  end
end

.new_ntop(arg) ⇒ Object



151
152
153
154
155
156
157
158
159
160
161
# File 'lib/lsa/lsa.rb', line 151

def new_ntop(arg)
  lsa = new
  if arg.is_a?(String)
    lsa.parse(arg)
  elsif arg.is_a?(self)
    lsa.parse arg.encode
  else
    raise ArgumentError, "Invalid Argument: #{arg.inspect}"
  end
  lsa
end

Instance Method Details

#<=>(other) ⇒ Object

-1 self older than other

0  self equivalent to other

+1 self newer than other TODO: compare advr router id.

Raises:

  • (RuntimeError)


338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
# File 'lib/lsa/lsa.rb', line 338

def <=>(other)
  raise RuntimeError unless self.key == other.key
  if self.sequence_number < other.sequence_number
    # puts "*** jme: our lsa older than other: our seq less than other seq ***"        
    -1
  elsif self.sequence_number > other.sequence_number
    # puts "*** jme: our lsa newer than other: our seq greater than other seq ***"        
    +1
  else
    if self.csum_to_i < other.csum_to_i
      # puts "*** jme: our lsa older than other: our csum less than other csum ***"        
      -1
    elsif self.csum_to_i > other.csum_to_i
      # puts "*** jme: our lsa newer than other: our csum greater than other csum ***"        
      +1
    else
      if (self.ls_age != other.ls_age and other.ls_age >= MaxAge) or
        ((other.ls_age - self.ls_age) > OSPFv2::MaxAgeDiff)
        # puts "*** jme: our lsa newer than other: age diff < maxage diff: #{(other.ls_age - self.ls_age)} ***"
        +1
      else
        # puts "*** jme: same lsa: age diff < maxage diff: #{(other.ls_age - self.ls_age)} ***"
        0
      end
    end
  end
end

#ackObject

FIXME: when adding LSA in LSDB should be acked when init, rxmt otherwise .…



168
169
170
# File 'lib/lsa/lsa.rb', line 168

def ack
  @_rxmt_=false
end

#encode(content = '') ⇒ Object



295
296
297
298
299
300
301
302
303
# File 'lib/lsa/lsa.rb', line 295

def encode(content='')
  lsa = []
  lsa << encode_header
  lsa << content
  lsa = lsa.join
  lsa[18..19]= @_size = [lsa.size].pack('n')
  lsa[16..17]= self.csum = cheksum(lsa[2..-1], 15).pack('CC')
  lsa
end

#encode_headerObject Also known as: header_encode



267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# File 'lib/lsa/lsa.rb', line 267

def encode_header
  header = []
  header << ls_age.encode
  header << [options.to_i].pack('C')
  header << ls_type.encode
  if is_opaque?
    header << [(@opaque_type << 24) + @opaque_id].pack('N')
  else
    header << ls_id.encode
  end
  header << advertising_router.encode
  header << sequence_number.encode
  header << [''].pack('a4')
  header.join
rescue => e
  p ls_age
  p ls_type
  p ls_id
  p advertising_router
  p sequence_number
  raise
end

#encode_requestObject



305
306
307
308
309
310
311
# File 'lib/lsa/lsa.rb', line 305

def encode_request
  req=[]
  req << ls_id.encode
  req << ls_type.encode
  req << @advertising_router.encode
  req.join
end


37
38
39
# File 'lib/ls_db/link_state_database_links.rb', line 37

def find_lsa_from_link(id)
  all.find_all { |l| l.lsdb_link_id==id  }
end

#force_refresh(seqn) ⇒ Object



376
377
378
379
380
381
382
# File 'lib/lsa/lsa.rb', line 376

def force_refresh(seqn)
  @sequence_number = SequenceNumber.new(seqn) if seqn
  @sequence_number.incr
  @ls_age = LsAge.new
  retransmit
  self
end

#header_lsaObject



291
292
293
# File 'lib/lsa/lsa.rb', line 291

def header_lsa
  self.class.new self
end

#is_acked?Boolean Also known as: acked?

Returns:

  • (Boolean)


174
175
176
# File 'lib/lsa/lsa.rb', line 174

def is_acked?
  @_rxmt_ == false
end

#is_opaque?Boolean

Returns:

  • (Boolean)


263
264
265
# File 'lib/lsa/lsa.rb', line 263

def is_opaque?
  ls_type.is_opaque?
end

#keyObject



330
331
332
# File 'lib/lsa/lsa.rb', line 330

def key
  [ls_type.to_i, ls_id.to_i, advertising_router.to_i]
end

#ls_typeObject



214
215
216
# File 'lib/lsa/lsa.rb', line 214

def ls_type
  @ls_type ||= LsType.new(1)
end


31
32
33
# File 'lib/ls_db/link_state_database_links.rb', line 31

def lsdb_link_id
  @_lsdb_link_id
end


34
35
36
# File 'lib/ls_db/link_state_database_links.rb', line 34

def lsdb_link_id=(val)
  @_lsdb_link_id= val
end

#maxageObject



384
385
386
387
# File 'lib/lsa/lsa.rb', line 384

def maxage
  ls_age.maxage and retransmit
  self
end

#maxaged?Boolean

Returns:

  • (Boolean)


389
390
391
# File 'lib/lsa/lsa.rb', line 389

def maxaged?
  @ls_age.maxaged?
end

#parse(s) ⇒ Object



313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
# File 'lib/lsa/lsa.rb', line 313

def parse(s)
  validate_checksum(s)
  ls_age, options, ls_type, ls_id, advr, seqn, csum, length, lsa = s.unpack('nCCNNNnna*')
  @ls_type = LsType.new ls_type
  @options = Options.new options
  @ls_age = LsAge.new ls_age
  @sequence_number = SequenceNumber.new seqn
  @advertising_router = AdvertisingRouter.new advr
  if is_opaque?
    @opaque_id   = ls_id >> 24
    @opaque_type = ls_id & 0xffffff
  else
    @ls_id = LsId.new ls_id
  end
  lsa
end

#refresh(advertised_routers, refresh_time, seqn = nil) ⇒ Object



366
367
368
369
370
371
372
373
374
# File 'lib/lsa/lsa.rb', line 366

def refresh(advertised_routers, refresh_time, seqn=nil)
  return unless advertised_routers.has?(advertising_router)
  return unless refresh?(refresh_time)
  @sequence_number = SequenceNumber.new(seqn) if seqn
  @sequence_number.incr
  @ls_age = LsAge.new
  retransmit
  self
end

#retransmitObject



171
172
173
# File 'lib/lsa/lsa.rb', line 171

def retransmit
  @_rxmt_=true
end

#to_hashObject



393
394
395
396
397
# File 'lib/lsa/lsa.rb', line 393

def to_hash
  h = super
  h.delete(:time)
  h
end

#to_s_defaultObject Also known as: to_s_dd



222
223
224
225
226
227
228
229
# File 'lib/lsa/lsa.rb', line 222

def to_s_default
  len = encode.size
  if is_opaque?
  else
    sprintf("%-4.0d  0x%2.2x  %-8s  %-15.15s %-15.15s 0x%8.8x  0x%4.4x   %-7d", 
    ls_age.to_i, options.to_i, ls_type.to_s_short, ls_id.to_ip, advertising_router.to_ip, seqn.to_I,csum_to_i,len)
  end
end

#to_s_junosObject Also known as: to_s_junos_verbose



253
254
255
256
257
258
259
# File 'lib/lsa/lsa.rb', line 253

def to_s_junos
  len = encode.size
  if is_opaque?
  else
    sprintf("%-7s %-1.1s%-15.15s  %-15.15s  0x%8.8x  %4.0d  0x%2.2x 0x%4.4x %3d", ls_type.to_junos, '', ls_id.to_ip, advertising_router.to_ip, seqn.to_I, ls_age.to_i, options.to_i, csum_to_i, len)
  end
end

#to_s_verboseObject



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/lsa/lsa.rb', line 232

def to_s_verbose
  len = encode.size
  s=[]
  s << self.class.to_s.split('::').last + ":"
  s << ls_age.to_s
  s << options.to_s
  s << ls_type.to_s
  s << advertising_router.to_s
  if is_opaque?
    # s << ls_id.to_s
  else
    s << ls_id.to_s
  end
  s << "SequenceNumber: " + sequence_number.to_s
  s << "LS checksum: #{format "%4x", csum_to_i}" if @_csum
  s << "length: #{@_size.unpack('n')}" if @_size
  s.join("\n   ")
end