ospfv2 0.0.1

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.
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
data/bin/ospfv2 ADDED
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'neighbor/neighbor'
4
+ require 'packet/ospf_packet'
5
+ require 'ls_db/link_state_database'
6
+ require 'ls_db/link_state_database_links'
7
+ require 'infra/parse_options'
8
+ require 'pp'
9
+
10
+ include OSPFv2
11
+
12
+ Thread.current["name"] = "#{self}"
13
+
14
+ cli = Thread.new do
15
+ Thread.current["name"] = "CLI"
16
+
17
+ # Parse command line
18
+ begin
19
+ options = OptParse.parse(ARGV)
20
+ rescue OptionParser::InvalidOption => e
21
+ STDERR.puts e.to_s.gsub(/at\s*$/,'')
22
+ exit(1)
23
+ end
24
+
25
+ ls_db = OSPFv2::LSDB::LinkStateDatabase.create :columns=> options.grid[0],
26
+ :rows=> options.grid[1],
27
+ :base_prefix => options.base_link_addr,
28
+ :base_router_id=> options.base_router_id
29
+
30
+ # Up all links
31
+ OSPFv2::LSDB::Link.all.each { |id,lnk| ls_db.link lnk, :up }
32
+
33
+
34
+ # Describe the connection to our neighbor
35
+ # It's a p2p connection
36
+ # we need to describe a p2p link and a stub link
37
+ rlsa = Router.new :ls_id=> options.router_id,
38
+ :advertising_router=>options.router_id,
39
+ :options=>0x22
40
+ rlsa << RouterLink.new_point_to_point(:link_id=>options.neighbor_id,
41
+ :link_data=> options.ipaddr,
42
+ :metric=>1)
43
+ rlsa << RouterLink.new_stub_network(:link_id=>options.network,
44
+ :link_data=>options.netmask,
45
+ :metric=>1)
46
+ ls_db << rlsa
47
+
48
+
49
+ rid1 = OSPFv2::LSDB::LinkStateDatabase.router_id(1,1,options.base_router_id)
50
+ rid2 = OSPFv2::LSDB::LinkStateDatabase.router_id(2,1,options.base_router_id)
51
+ rid3 = OSPFv2::LSDB::LinkStateDatabase.router_id(1,1,options.base_router_id)
52
+
53
+ # add a a p2p link between router_id and rid1
54
+ ls_db.new_link :router_id=> options.router_id, :neighbor_id=>rid1
55
+
56
+ # Link.all.values.each { |lnk| @ls_db.link lnk, :down }
57
+
58
+ # Add some Summary LSAs
59
+ [rid1,rid2].each do |rid|
60
+ ls_db.lookup(1,rid).set_abr
61
+ (options.num_sum/2).times { ls_db << OSPFv2::Summary.new_lsdb( :advertising_router=> rid ) }
62
+ end
63
+
64
+ # Add some External LSAs
65
+ ls_db.find_router_lsa(rid3).set_asbr
66
+ options.num_ext.times { \
67
+ ls_db << OSPFv2::AsExternal.new_lsdb(:advertising_router=> rid3,
68
+ :mt_metrics=>[{:mt_id=>10, :metric=>20,
69
+ :tag=>10}])}
70
+
71
+ ls_db << AsbrSummary.new(:advertising_router=> rid3, :ls_id=> rid3)
72
+
73
+
74
+ neighbor = OSPFv2::Neighbor.new :src_addr => options.ipaddr,
75
+ :router_id => options.router_id,
76
+ :area_id=>options.area_id,
77
+ :log_fname => options.log_fname
78
+
79
+ neighbor.hello_int
80
+ neighbor.dead_int
81
+ neighbor.ls_db = ls_db
82
+
83
+ # Add option to parse
84
+ ls_db.ls_refresh_time=2000
85
+ ls_db.ls_refresh_interval=10
86
+
87
+ help= <<-"end;"
88
+ start
89
+ stop
90
+ puts ls_db
91
+ puts ls_db.to_js_unos
92
+ aging :on | :off
93
+ end;
94
+
95
+ def prompt() ; ">> " ; end
96
+
97
+ sleep(1)
98
+ ue=nil
99
+
100
+ def eval_cmd(cmd,binding)
101
+ s = eval(cmd,binding)
102
+ print "=> #{s.inspect}" if s
103
+ puts
104
+ rescue SyntaxError, NameError => e
105
+ puts "% syntax error\n"
106
+ rescue => e
107
+ puts "% error: #{e}\n"
108
+ end
109
+
110
+ def aging(arg)
111
+ OSPFv2::Lsa::LsAge.aging arg
112
+ end
113
+
114
+ loop do
115
+ print prompt() ; $stdout.flush
116
+ cmd = STDIN.gets
117
+ break unless cmd
118
+ next if cmd.size == 0
119
+ ary = cmd.downcase.split(' ')
120
+ case ary[0]
121
+ when 'start' ; aging :on ; neighbor.start
122
+ when 'stop' ; neighbor.stop
123
+ when 'help', '?'
124
+ print help
125
+ when nil
126
+ when /^(exit|quit|x|q|fin|end)$/ ; exit
127
+ else
128
+ eval_cmd cmd, binding()
129
+ end
130
+ end
131
+
132
+ end
133
+
134
+ cli.join
135
+
136
+ exit
data/lib/ie/au_type.rb ADDED
@@ -0,0 +1,79 @@
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
+ # 0 Null authentication 1 Simple password 2 Cryptographic authentication
25
+ module OSPFv2
26
+ class AuType
27
+ def initialize(au_type=0)
28
+ @au_type=0
29
+ case au_type
30
+ when :null, 0 ; @au_type = 0
31
+ when :simple_password, 1 ; @au_type = 1
32
+ when :cryptographic, 2 ; @au_type = 2
33
+ else
34
+ @au_type = au_type if au_type.is_a?(Integer)
35
+ end
36
+ end
37
+
38
+ def to_hash
39
+ to_sym
40
+ end
41
+
42
+ def to_i
43
+ @au_type
44
+ end
45
+
46
+ def to_s
47
+ self.class.to_s.split('::').last + ": #{au_to_s}"
48
+ end
49
+
50
+ def to_sym
51
+ case @au_type
52
+ when 2 ; :cryptographic
53
+ when 1 ; :simple_password
54
+ when 0 ; :null
55
+ else
56
+ :undefined?
57
+ end
58
+ end
59
+
60
+ def encode
61
+ [@au_type].pack('n')
62
+ end
63
+ alias :enc :encode
64
+
65
+ private
66
+
67
+ def au_to_s
68
+ case @au_type
69
+ when 0 ; 'null authentication'
70
+ when 1 ; 'simple password'
71
+ when 2 ; 'cryptographic authentication'
72
+ else
73
+ 'unknown'
74
+ end
75
+ end
76
+
77
+
78
+ end
79
+ end
@@ -0,0 +1,181 @@
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
+ # (RFC 2328)
25
+ #
26
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
27
+ # |E| 0 | metric |
28
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
29
+ # | Forwarding address |
30
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
31
+ # | External Route Tag |
32
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
33
+ #
34
+ #
35
+ #
36
+ # (RFC 4915)
37
+ #
38
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
39
+ # | Network Mask |
40
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41
+ # |E| 0 | metric |
42
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43
+ # | Forwarding address |
44
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45
+ # | External Route Tag |
46
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47
+ # |E| MT-ID | MT-ID metric |
48
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49
+ # | Forwarding address |
50
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
51
+ # | External Route Tag |
52
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53
+ # | ... |
54
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55
+ #
56
+ require 'infra/ospf_common'
57
+ require 'ie/metric'
58
+ require 'ie/tos_metric'
59
+ require 'ie/id'
60
+
61
+
62
+ module OSPFv2
63
+
64
+ class ExternalRoute_Base
65
+ include Common
66
+
67
+ ForwardingAddress = Class.new(OSPFv2::Id)
68
+
69
+ attr_reader :metric, :type, :forwarding_address, :tag, :mt_id
70
+ attr_checked :metric do |x|
71
+ (0..0xffffff).include?(x)
72
+ end
73
+ attr_checked :type do |x|
74
+ [:e1,:e2].include?(x)
75
+ end
76
+ attr_checked :tag do |x|
77
+ (0..0xffffffff).include?(x)
78
+ end
79
+ attr_checked :mt_id do |x|
80
+ (0..0x7f).include?(x)
81
+ end
82
+
83
+ attr_writer_delegate :forwarding_address
84
+
85
+ def initialize(arg={})
86
+ arg = arg.dup
87
+ self.metric=0
88
+ self.type=:e1
89
+ self.tag=0
90
+ self.mt_id=0
91
+ if arg.is_a?(Hash)
92
+ set arg
93
+ elsif arg.is_a?(String)
94
+ parse arg
95
+ elsif arg.is_a?(self.class)
96
+ parse arg.encode
97
+ else
98
+ raise ArgumentError, "Invalid Argument: #{arg.inspect}"
99
+ end
100
+ end
101
+
102
+ def encode
103
+ external =[]
104
+ external << encoded_e_id_metric
105
+ external << forwarding_address.encode
106
+ external << [tag].pack('N')
107
+ external.join
108
+ end
109
+
110
+ def parse(s)
111
+ long1, long2, @tag = s.unpack('NNN')
112
+ @type, @mt_id, @metric = parse_e_id_metric(long1)
113
+ @forwarding_address = ForwardingAddress.new(long2)
114
+ end
115
+
116
+ def to_s
117
+ "#{type.to_s.upcase} (ID #{mt_id}) Metric: #{metric.to_i} Forwarding: #{forwarding_address.to_ip} Tag: #{tag}"
118
+ end
119
+
120
+ private
121
+
122
+ def encoded_e_id_metric
123
+ long = 0
124
+ long = 0x80000000 if type== :e2
125
+ long |= (mt_id << 24)
126
+ long |= metric.to_i
127
+ [long].pack('N')
128
+ end
129
+
130
+ def parse_e_id_metric(long)
131
+ type = :e1
132
+ type = :e2 if (long >> 31) > 0
133
+ metric = long & 0xffffff
134
+ _id = long >> 24 & 0x7f
135
+ [type,_id,metric]
136
+ end
137
+
138
+ def metric_to_s
139
+ "Metric: #{metric}"
140
+ end
141
+
142
+ end
143
+
144
+ class ExternalRoute < ExternalRoute_Base
145
+ def initialize(arg={})
146
+ if arg.is_a?(Hash)
147
+ @forwarding_address = ForwardingAddress.new
148
+ raise ArgumentError, "ID should be 0" if arg[:id] and arg[:mt_id]>0
149
+ end
150
+ super
151
+ end
152
+ def to_hash
153
+ h = super
154
+ h.delete(:mt_id)
155
+ h
156
+ end
157
+
158
+ end
159
+
160
+ class MtExternalRoute < ExternalRoute_Base
161
+ def initialize(arg={})
162
+ if arg.is_a?(Hash)
163
+ @forwarding_address = ForwardingAddress.new
164
+ raise ArgumentError, "MT-ID not set!" unless arg[:mt_id]
165
+ raise ArgumentError, "MT-ID should not be 0!" if arg[:mt_id]==0
166
+ end
167
+ super
168
+ end
169
+ end
170
+
171
+ def ExternalRoute_Base.new_hash(h)
172
+ if h[:mt_metrics]
173
+ MtExternalRoute.new(h)
174
+ else
175
+ ExternalRoute.new(h)
176
+ end
177
+ end
178
+
179
+ end
180
+
181
+ load "../../../test/ospfv2/ie/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
data/lib/ie/id.rb ADDED
@@ -0,0 +1,97 @@
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 'ipaddr'
25
+ require 'infra/ospf_common'
26
+
27
+ module OSPFv2
28
+ class Id
29
+
30
+ def self.new_ntoh(s)
31
+ return unless s.is_a?(String)
32
+ new s.unpack('N')[0]
33
+ end
34
+
35
+ def self.to_i(id)
36
+ return id.to_i unless id.is_a?(String) and id.split('.').size==4
37
+ IPAddr.new(id).to_i
38
+ end
39
+
40
+ def initialize(arg=0)
41
+ self.id = arg
42
+ end
43
+
44
+ def id=(val)
45
+ if val.is_a?(Hash)
46
+ @id = val[:id] if val[:id]
47
+ elsif val.is_a?(IPAddr)
48
+ @id = val.to_i
49
+ elsif val.is_a?(Integer)
50
+ raise ArgumentError, "Invalid Argument #{val}" unless (0..0xffffffff).include?(val)
51
+ @id = val
52
+ elsif val.is_a?(String)
53
+ @id = IPAddr.new(val).to_i
54
+ elsif val.is_a?(Id)
55
+ @id = val.to_i
56
+ else
57
+ raise ArgumentError, "Invalid Argument #{val.inspect}"
58
+ end
59
+ end
60
+
61
+ def encode
62
+ [@id].pack('N')
63
+ end
64
+ alias :enc :encode
65
+
66
+ def to_i
67
+ @id
68
+ end
69
+
70
+ def to_s(verbose=true)
71
+ verbose ? to_s_verbose : to_s_short
72
+ end
73
+
74
+ def to_hash
75
+ to_s_short
76
+ end
77
+
78
+ def to_ip
79
+ to_s(false)
80
+ end
81
+
82
+ private
83
+
84
+ def to_s_short
85
+ IPAddr.new_ntoh([@id].pack('N')).to_s
86
+ end
87
+
88
+ def to_s_verbose
89
+ self.class.to_s.split('::').last + ": " + to_s_short
90
+ end
91
+
92
+ end
93
+
94
+ end
95
+
96
+ load "../../../test/ospfv2/ie/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
97
+
@@ -0,0 +1,64 @@
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 'infra/ospf_common'
24
+ require 'infra/ospf_constants'
25
+
26
+ module OSPFv2
27
+
28
+ class InterfaceMtu
29
+ include Common
30
+
31
+ attr_checked :interface_mtu do |x|
32
+ (0..0xffff).include?(x)
33
+ end
34
+
35
+ def initialize(interface_mtu=1500)
36
+ self.interface_mtu=interface_mtu
37
+ end
38
+
39
+ def to_i
40
+ interface_mtu
41
+ end
42
+
43
+ def number_of_lsa
44
+ @noh ||= ((to_i - OSPFv2::PACKET_HEADER_LEN) / OSPFv2::LSA_HEADER_LEN) - 1
45
+ end
46
+ alias :n0flsa :number_of_lsa
47
+
48
+ def to_s
49
+ self.class.to_s.split('::').last + ": #{to_i}"
50
+ end
51
+
52
+ def encode(fmt='n')
53
+ [interface_mtu].pack(fmt)
54
+ end
55
+ alias :enc :encode
56
+
57
+ def to_hash
58
+ to_i
59
+ end
60
+
61
+ end
62
+ end
63
+
64
+ load "../../../test/ospfv2/ie/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
data/lib/ie/ls_age.rb ADDED
@@ -0,0 +1,89 @@
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 'infra/ospf_constants'
24
+
25
+ module OSPFv2
26
+ class LsAge
27
+ include Comparable
28
+
29
+ class << self
30
+ def aging(state=:off)
31
+ case state
32
+ when :on ; @aging = true
33
+ when :off ; @aging = false
34
+ else
35
+ raise ArgumentError, "Invalid Argument"
36
+ end
37
+ end
38
+ def aging?
39
+ @aging
40
+ end
41
+ end
42
+
43
+ def initialize(age=0)
44
+ raise ArgumentError, "Invalid Argument #{age}" unless age.is_a?(Integer)
45
+ @age=age
46
+ @time = Time.now
47
+ end
48
+
49
+ def to_i
50
+ aging? ? (Time.new - @time + @age).to_int : @age
51
+ end
52
+
53
+ def aging?
54
+ self.class.aging?
55
+ end
56
+
57
+ def maxage
58
+ @age = OSPFv2::MaxAge
59
+ end
60
+
61
+ def maxaged?
62
+ to_i >= OSPFv2::MaxAge
63
+ end
64
+
65
+ def <=>(obj)
66
+ to_i <=> obj.to_i
67
+ end
68
+
69
+ def -(obj)
70
+ to_i - obj.to_i
71
+ end
72
+
73
+ def to_s
74
+ self.class.to_s.split('::').last + ": #{to_i}"
75
+ end
76
+
77
+ def encode
78
+ [@age].pack('n')
79
+ end
80
+ alias :enc :encode
81
+
82
+ def to_hash
83
+ to_i
84
+ end
85
+
86
+ end
87
+ end
88
+
89
+ load "../../../test/ospfv2/ie/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0