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
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