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.
- data/bin/ospfv2 +136 -0
- data/lib/ie/au_type.rb +79 -0
- data/lib/ie/external_route.rb +181 -0
- data/lib/ie/id.rb +97 -0
- data/lib/ie/interface_mtu.rb +64 -0
- data/lib/ie/ls_age.rb +89 -0
- data/lib/ie/ls_type.rb +148 -0
- data/lib/ie/metric.rb +63 -0
- data/lib/ie/mt_metric.rb +119 -0
- data/lib/ie/options.rb +356 -0
- data/lib/ie/ospf_version.rb +67 -0
- data/lib/ie/packet_type.rb +65 -0
- data/lib/ie/router_link.rb +167 -0
- data/lib/ie/router_link_factory.rb +53 -0
- data/lib/ie/router_link_type.rb +86 -0
- data/lib/ie/sequence_number.rb +144 -0
- data/lib/ie/tos_metric.rb +102 -0
- data/lib/infra/ospf_common.rb +291 -0
- data/lib/infra/ospf_constants.rb +73 -0
- data/lib/infra/ospf_io.rb +133 -0
- data/lib/infra/ospf_socket.rb +126 -0
- data/lib/infra/parse_options.rb +135 -0
- data/lib/infra/timer.rb +104 -0
- data/lib/infra/to_s.rb +38 -0
- data/lib/ls_db/advertised_routers.rb +78 -0
- data/lib/ls_db/common.rb +31 -0
- data/lib/ls_db/link_state_database.rb +376 -0
- data/lib/ls_db/link_state_database_build.rb +181 -0
- data/lib/ls_db/link_state_database_links.rb +178 -0
- data/lib/ls_db/links.rb +160 -0
- data/lib/lsa/external.rb +347 -0
- data/lib/lsa/lsa.rb +438 -0
- data/lib/lsa/lsa_factory.rb +59 -0
- data/lib/lsa/network.rb +166 -0
- data/lib/lsa/router.rb +336 -0
- data/lib/lsa/summary.rb +393 -0
- data/lib/neighbor/neighbor.rb +298 -0
- data/lib/neighbor/neighbor_event_handler.rb +61 -0
- data/lib/neighbor/recv_database_description.rb +153 -0
- data/lib/neighbor/recv_hello.rb +53 -0
- data/lib/neighbor/recv_ospf_packet.rb +68 -0
- data/lib/neighbor_sm/attempt_state.rb +44 -0
- data/lib/neighbor_sm/down_state.rb +46 -0
- data/lib/neighbor_sm/exchange_state.rb +32 -0
- data/lib/neighbor_sm/exstart_state.rb +69 -0
- data/lib/neighbor_sm/full_state.rb +36 -0
- data/lib/neighbor_sm/init_state.rb +43 -0
- data/lib/neighbor_sm/loading_state.rb +33 -0
- data/lib/neighbor_sm/neighbor_state.rb +87 -0
- data/lib/packet/database_description.rb +300 -0
- data/lib/packet/hello.rb +327 -0
- data/lib/packet/link_state_ack.rb +144 -0
- data/lib/packet/link_state_request.rb +153 -0
- data/lib/packet/link_state_update.rb +189 -0
- data/lib/packet/ospf_packet.rb +306 -0
- metadata +116 -0
@@ -0,0 +1,67 @@
|
|
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
|
+
module OSPFv2
|
24
|
+
class OspfVersion
|
25
|
+
def initialize(version=2)
|
26
|
+
case version
|
27
|
+
when :v2, 2 ; @ospf_version = 2
|
28
|
+
when :v3, 3 ; @ospf_version = 3
|
29
|
+
else
|
30
|
+
@ospf_version = 0
|
31
|
+
end
|
32
|
+
end
|
33
|
+
def to_s
|
34
|
+
case @ospf_version
|
35
|
+
when 2 ; '2'
|
36
|
+
when 3 ; '3'
|
37
|
+
else
|
38
|
+
'unknown'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
def to_hash
|
42
|
+
to_i
|
43
|
+
end
|
44
|
+
def to_i
|
45
|
+
@ospf_version
|
46
|
+
end
|
47
|
+
def to_s
|
48
|
+
self.class.to_s.split('::').last + ": #{to_sym}"
|
49
|
+
end
|
50
|
+
def to_sym
|
51
|
+
case @ospf_version
|
52
|
+
when 2 ; :v2
|
53
|
+
when 3 ; :v3
|
54
|
+
else
|
55
|
+
':v?'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def encode
|
60
|
+
[@ospf_version].pack('C')
|
61
|
+
end
|
62
|
+
alias :enc :encode
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
load "../../../test/ospfv2/ie/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|
@@ -0,0 +1,65 @@
|
|
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
|
+
module OSPFv2
|
24
|
+
class PacketType
|
25
|
+
def initialize(value=0)
|
26
|
+
case value
|
27
|
+
when 1, :hello ; @packet_type = 1
|
28
|
+
when 2, :dd ; @packet_type = 2
|
29
|
+
when 3, :ls_request ; @packet_type = 3
|
30
|
+
when 4, :ls_update ; @packet_type = 4
|
31
|
+
when 5, :ls_ack ; @packet_type = 5
|
32
|
+
else
|
33
|
+
@packet_type = 0
|
34
|
+
end
|
35
|
+
end
|
36
|
+
def to_hash
|
37
|
+
to_sym
|
38
|
+
end
|
39
|
+
def to_i
|
40
|
+
@packet_type
|
41
|
+
end
|
42
|
+
def to_s
|
43
|
+
self.class.to_s.split('::').last + ": #{to_sym}"
|
44
|
+
end
|
45
|
+
def to_sym
|
46
|
+
case @packet_type
|
47
|
+
when 1 ; :hello
|
48
|
+
when 2 ; :dd
|
49
|
+
when 3 ; :ls_request
|
50
|
+
when 4 ; :ls_update
|
51
|
+
when 5 ; :ls_ack
|
52
|
+
else
|
53
|
+
'unknown'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def encode
|
58
|
+
[@packet_type].pack('C')
|
59
|
+
end
|
60
|
+
alias :enc :encode
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
load "../../../test/ospfv2/ie/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|
@@ -0,0 +1,167 @@
|
|
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 'ie/id'
|
25
|
+
require 'ie/metric'
|
26
|
+
require 'ie/mt_metric'
|
27
|
+
require 'ie/router_link_type'
|
28
|
+
|
29
|
+
module OSPFv2
|
30
|
+
|
31
|
+
class RouterLink
|
32
|
+
include Common
|
33
|
+
|
34
|
+
LinkId = Class.new(Id)
|
35
|
+
LinkData = Class.new(Id)
|
36
|
+
|
37
|
+
attr_reader :link_id, :link_data, :router_link_type, :metric, :mt_metrics
|
38
|
+
|
39
|
+
attr_writer_delegate :link_id, :link_data, :router_link_type
|
40
|
+
|
41
|
+
def initialize(arg={})
|
42
|
+
arg = arg.dup
|
43
|
+
if arg.is_a?(Hash)
|
44
|
+
@link_id, @link_data, @router_link_type, @metric = nil, nil, nil, nil
|
45
|
+
@mt_metrics = []
|
46
|
+
set arg
|
47
|
+
elsif arg.is_a?(String)
|
48
|
+
parse arg
|
49
|
+
elsif arg.is_a?(self.class)
|
50
|
+
parse arg.encode
|
51
|
+
else
|
52
|
+
raise ArgumentError, "Invalid Argument: #{arg.inspect}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
57
|
+
# | Link ID |
|
58
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
59
|
+
# | Link Data |
|
60
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
61
|
+
# | Type | # TOS | metric |
|
62
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
63
|
+
# | ... |
|
64
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
65
|
+
# | TOS | 0 | TOS metric |
|
66
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
67
|
+
def encode
|
68
|
+
@link_id ||= LinkId.new
|
69
|
+
@link_data ||= LinkData.new
|
70
|
+
@router_link_type ||= RouterLinkType.new
|
71
|
+
@metric ||= Metric.new
|
72
|
+
rlink =[]
|
73
|
+
rlink << link_id.encode
|
74
|
+
rlink << link_data.encode
|
75
|
+
rlink << router_link_type.encode
|
76
|
+
rlink << [mt_metrics.size].pack('C')
|
77
|
+
rlink << metric.encode('n')
|
78
|
+
rlink << mt_metrics.collect { |x| x.encode }
|
79
|
+
rlink.join
|
80
|
+
end
|
81
|
+
|
82
|
+
# TODO: if self.class is not RouterLink do not display RouterLinkType info....
|
83
|
+
def to_s(ident=2)
|
84
|
+
encode unless @router_link_type
|
85
|
+
self.class.to_s.split('::').last + ":" +
|
86
|
+
['',link_id, link_data, router_link_type, metric, *mt_metrics].compact.collect { |x| x.to_s }.join("\n"+" "*ident)
|
87
|
+
end
|
88
|
+
|
89
|
+
def to_s_junos_style
|
90
|
+
s = " id #{id}, data #{data}, Type #{RouterLink.type_to_s_junos_style[@type]} (#{@type})"
|
91
|
+
s +="\n Topology count: #{@mt_id.size}, Default metric: #{@metric}"
|
92
|
+
s += @mt_id.collect { |mt| "\n #{mt.to_s_junos_style}" }.join
|
93
|
+
s
|
94
|
+
end
|
95
|
+
|
96
|
+
def to_s_junos
|
97
|
+
s = " id #{link_id.to_ip}, data #{link_data.to_ip}, Type #{RouterLinkType.to_junos(router_link_type.to_i)} (#{router_link_type.to_i})"
|
98
|
+
s +="\n Topology count: #{@mt_metrics.size}, Default metric: #{metric.to_i}"
|
99
|
+
s += @mt_metrics.collect { |mt| "\n #{mt.to_s}" }.join
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
class << self
|
104
|
+
class_eval {
|
105
|
+
RouterLinkType.each { |x|
|
106
|
+
define_method "new_#{x}" do |*args|
|
107
|
+
OSPFv2::RouterLink.const_get(x.to_klass).send :new, *args
|
108
|
+
end
|
109
|
+
}
|
110
|
+
}
|
111
|
+
end
|
112
|
+
|
113
|
+
RouterLinkType.each { |x|
|
114
|
+
klassname = Class.new(self) do
|
115
|
+
define_method(:initialize) do |arg|
|
116
|
+
arg ||={}
|
117
|
+
arg[:router_link_type] = x if arg.is_a?(Hash)
|
118
|
+
super arg
|
119
|
+
end
|
120
|
+
define_method(:to_hash) do
|
121
|
+
super.merge :router_link_type => x
|
122
|
+
end
|
123
|
+
end
|
124
|
+
self.const_set(x.to_klass, klassname)
|
125
|
+
}
|
126
|
+
|
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
|
+
def parse(s)
|
139
|
+
@mt_metrics ||=[]
|
140
|
+
link_id, link_data, router_link_type, ntos, metric, mt_metrics = s.unpack('NNCCna*')
|
141
|
+
@link_id = LinkId.new link_id
|
142
|
+
@link_data = LinkData.new link_data
|
143
|
+
@router_link_type = RouterLinkType.new router_link_type
|
144
|
+
@metric = Metric.new metric
|
145
|
+
while mt_metrics.size>0
|
146
|
+
self << MtMetric.new(mt_metrics.slice!(0,4))
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
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
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
|
167
|
+
load "../../../test/ospfv2/ie/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|
@@ -0,0 +1,53 @@
|
|
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 'ie/router_link'
|
25
|
+
|
26
|
+
module OSPFv2
|
27
|
+
class RouterLink
|
28
|
+
def self.factory(arg)
|
29
|
+
if arg.is_a?(Hash)
|
30
|
+
raise ArgumentError, "no link type specified" unless arg[:router_link_type]
|
31
|
+
case arg[:router_link_type]
|
32
|
+
when 1,:point_to_point ; PointToPoint.new(arg)
|
33
|
+
when 2,:transit_network ; TransitNetwork.new(arg)
|
34
|
+
when 3,:stub_network ; StubNetwork.new(arg)
|
35
|
+
when 4,:virtual_link ; VirtualLink.new(arg)
|
36
|
+
end
|
37
|
+
elsif arg.is_a?(String)
|
38
|
+
case arg[8,1].unpack('C')[0]
|
39
|
+
when 1 ; PointToPoint.new(arg)
|
40
|
+
when 2 ; TransitNetwork.new(arg)
|
41
|
+
when 3 ; StubNetwork.new(arg)
|
42
|
+
when 4 ; VirtualLink.new(arg)
|
43
|
+
else
|
44
|
+
raise ArgumentError, "Invalid Argument: #{arg[8,1].unpack('C')[0]} #{arg.inspect}/#{arg.unpack('H*')}"
|
45
|
+
end
|
46
|
+
elsif arg.is_a?(RouterLink)
|
47
|
+
factory(arg.encode)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
load "../../../test/ospfv2/ie/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|
@@ -0,0 +1,86 @@
|
|
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
|
+
# Router Link:
|
24
|
+
# Type Description
|
25
|
+
# __________________________________________________
|
26
|
+
# 1 Point-to-point connection to another router
|
27
|
+
# 2 Connection to a transit network
|
28
|
+
# 3 Connection to a stub network
|
29
|
+
# 4 Virtual link
|
30
|
+
|
31
|
+
module OSPFv2
|
32
|
+
class RouterLinkType
|
33
|
+
def self.each
|
34
|
+
[:point_to_point, :transit_network, :stub_network, :virtual_link].each { |x| yield(x) } if block_given?
|
35
|
+
end
|
36
|
+
def self.to_i(arg)
|
37
|
+
return arg unless arg.is_a?(Symbol)
|
38
|
+
[:point_to_point, :transit_network, :stub_network, :virtual_link].index(arg)+1
|
39
|
+
end
|
40
|
+
def self.to_junos(type)
|
41
|
+
case type.to_i
|
42
|
+
when 1 ; 'Point-to-point'
|
43
|
+
when 2 ; 'Transit'
|
44
|
+
when 3 ; 'Stub'
|
45
|
+
when 4 ; 'Virtual-link'
|
46
|
+
else ; type.to_i
|
47
|
+
end
|
48
|
+
end
|
49
|
+
def initialize(router_link_type=1)
|
50
|
+
case router_link_type
|
51
|
+
when 1, :point_to_point ; @router_link_type=1
|
52
|
+
when 2, :transit_network ; @router_link_type=2
|
53
|
+
when 3, :stub_network ; @router_link_type=3
|
54
|
+
when 4, :virtual_link ; @router_link_type=4
|
55
|
+
else
|
56
|
+
raise ArgumentError, "Invalid RouterLinkType #{router_link_type}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
def to_i
|
60
|
+
@router_link_type
|
61
|
+
end
|
62
|
+
def to_s
|
63
|
+
self.class.to_s.split('::').last + ": #{to_sym}"
|
64
|
+
end
|
65
|
+
def to_sym
|
66
|
+
case @router_link_type
|
67
|
+
when 1 ; :point_to_point
|
68
|
+
when 2 ; :transit_network
|
69
|
+
when 3 ; :stub_network
|
70
|
+
when 4 ; :virtual_link
|
71
|
+
end
|
72
|
+
end
|
73
|
+
def encode
|
74
|
+
[@router_link_type].pack('C')
|
75
|
+
end
|
76
|
+
alias :enc :encode
|
77
|
+
|
78
|
+
def to_hash
|
79
|
+
to_sym
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
load "../../../test/ospfv2/ie/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|
86
|
+
|
@@ -0,0 +1,144 @@
|
|
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
|
+
|
27
|
+
class SequenceNumber
|
28
|
+
include OSPFv2
|
29
|
+
include Comparable
|
30
|
+
|
31
|
+
def SequenceNumber.initial
|
32
|
+
[N + 1].pack('I').unpack('i')[0]
|
33
|
+
end
|
34
|
+
|
35
|
+
def SequenceNumber.max
|
36
|
+
[N - 1].pack('I').unpack('i')[0]
|
37
|
+
end
|
38
|
+
|
39
|
+
def SequenceNumber.N
|
40
|
+
[N].pack('I').unpack('i')[0]
|
41
|
+
end
|
42
|
+
|
43
|
+
def SequenceNumber.to_s(seqn)
|
44
|
+
new(seqn).to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
def initialize(seqn=:init)
|
48
|
+
if seqn.is_a?(Symbol)
|
49
|
+
if seqn == :max
|
50
|
+
@seqn= MaxSequenceNumber
|
51
|
+
elsif seqn == :init
|
52
|
+
@seqn = InitialSequenceNumber
|
53
|
+
elsif seqn == :reserved
|
54
|
+
@seqn = N
|
55
|
+
end
|
56
|
+
elsif seqn.is_a?(self.class)
|
57
|
+
@seqn = seqn.to_I
|
58
|
+
else
|
59
|
+
@seqn=seqn
|
60
|
+
end
|
61
|
+
@seqn = [@seqn].pack('I')
|
62
|
+
end
|
63
|
+
|
64
|
+
def <=>(o)
|
65
|
+
to_i <=> o.to_i
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_i
|
69
|
+
@seqn.unpack('i')[0]
|
70
|
+
end
|
71
|
+
def to_I
|
72
|
+
@seqn.unpack('I')[0]
|
73
|
+
end
|
74
|
+
|
75
|
+
def to_s
|
76
|
+
"0x"+ sprintf("%08.8x", to_I)
|
77
|
+
end
|
78
|
+
|
79
|
+
def +(num)
|
80
|
+
seqn = (@seqn.unpack('i')[0]+num)
|
81
|
+
@seqn = [seqn].pack('I')
|
82
|
+
self
|
83
|
+
end
|
84
|
+
|
85
|
+
def -(num)
|
86
|
+
self.+(-num)
|
87
|
+
end
|
88
|
+
|
89
|
+
def encode
|
90
|
+
#FIXME: unit-test and check if 'i' or 'I'
|
91
|
+
[to_i].pack('N')
|
92
|
+
end
|
93
|
+
|
94
|
+
def to_hash
|
95
|
+
to_I
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
load "../../../test/ospfv2/ie/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|
103
|
+
|
104
|
+
__END__
|
105
|
+
|
106
|
+
|
107
|
+
=begin rdoc
|
108
|
+
12.1.6. LS sequence number
|
109
|
+
|
110
|
+
The sequence number field is a signed 32-bit integer. It is
|
111
|
+
used to detect old and duplicate LSAs. The space of
|
112
|
+
sequence numbers is linearly ordered. The larger the
|
113
|
+
sequence number (when compared as signed 32-bit integers)
|
114
|
+
the more recent the LSA. To describe to sequence number
|
115
|
+
space more precisely, let N refer in the discussion below to
|
116
|
+
the constant 2**31.
|
117
|
+
|
118
|
+
The sequence number -N (0x80000000) is reserved (and
|
119
|
+
unused). This leaves -N + 1 (0x80000001) as the smallest
|
120
|
+
(and therefore oldest) sequence number; this sequence number
|
121
|
+
is referred to as the constant InitialSequenceNumber. A
|
122
|
+
router uses InitialSequenceNumber the first time it
|
123
|
+
originates any LSA. Afterwards, the LSA's sequence number
|
124
|
+
is incremented each time the router originates a new
|
125
|
+
instance of the LSA. When an attempt is made to increment
|
126
|
+
the sequence number past the maximum value of N - 1
|
127
|
+
(0x7fffffff; also referred to as MaxSequenceNumber), the
|
128
|
+
current instance of the LSA must first be flushed from the
|
129
|
+
routing domain. This is done by prematurely aging the LSA
|
130
|
+
(see Section 14.1) and reflooding it. As soon as this flood
|
131
|
+
has been acknowledged by all adjacent neighbors, a new
|
132
|
+
instance can be originated with sequence number of
|
133
|
+
InitialSequenceNumber.
|
134
|
+
|
135
|
+
The router may be forced to promote the sequence number of
|
136
|
+
one of its LSAs when a more recent instance of the LSA is
|
137
|
+
unexpectedly received during the flooding process. This
|
138
|
+
should be a rare event. This may indicate that an out-of-
|
139
|
+
date LSA, originated by the router itself before its last
|
140
|
+
restart/reload, still exists in the Autonomous System. For
|
141
|
+
more information see Section 13.4.
|
142
|
+
|
143
|
+
|
144
|
+
=end
|
@@ -0,0 +1,102 @@
|
|
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 | metric |
|
25
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
26
|
+
# | TOS | TOS metric |
|
27
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
28
|
+
# | ... |
|
29
|
+
#
|
30
|
+
# Network Mask
|
31
|
+
# For Type 3 summary-LSAs, this indicates the destination
|
32
|
+
# network's IP address mask. For example, when advertising the
|
33
|
+
# location of a class A network the value 0xff000000 would be
|
34
|
+
# used. This field is not meaningful and must be zero for Type 4
|
35
|
+
# summary-LSAs.
|
36
|
+
#
|
37
|
+
# metric
|
38
|
+
# The cost of this route. Expressed in the same units as the
|
39
|
+
# interface costs in the router-LSAs.
|
40
|
+
#
|
41
|
+
# Additional TOS-specific information may also be included, for
|
42
|
+
# backward compatibility with previous versions of the OSPF
|
43
|
+
# specification ([Ref9]). For each desired TOS, TOS-specific
|
44
|
+
# information is encoded as follows:
|
45
|
+
#
|
46
|
+
# TOS IP Type of Service that this metric refers to. The encoding of
|
47
|
+
# TOS in OSPF LSAs is described in Section 12.3.
|
48
|
+
#
|
49
|
+
# TOS metric
|
50
|
+
# TOS-specific metric information.
|
51
|
+
#
|
52
|
+
|
53
|
+
require 'infra/ospf_common'
|
54
|
+
module OSPFv2
|
55
|
+
|
56
|
+
class TosMetric
|
57
|
+
include Common
|
58
|
+
|
59
|
+
attr_reader :tos, :cost
|
60
|
+
|
61
|
+
def initialize(arg={})
|
62
|
+
arg = arg.dup
|
63
|
+
@tos,@cost=0,0
|
64
|
+
if arg.is_a?(Hash)
|
65
|
+
set arg
|
66
|
+
elsif arg.is_a?(String)
|
67
|
+
parse arg
|
68
|
+
elsif arg.is_a?(self.class)
|
69
|
+
parse arg.encode
|
70
|
+
elsif arg.is_a?(Array) and arg.size==2
|
71
|
+
@tos, @cost = arg
|
72
|
+
else
|
73
|
+
raise ArgumentError, "Invalid Argument: #{arg.inspect}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
alias :id :tos
|
78
|
+
|
79
|
+
def encode
|
80
|
+
m = []
|
81
|
+
m << [tos].pack('C')
|
82
|
+
m << [cost].pack('N').unpack('C4')[1..-1].pack('C3')
|
83
|
+
m.join
|
84
|
+
end
|
85
|
+
|
86
|
+
def parse(s)
|
87
|
+
@tos, *cost = s.unpack('C4')
|
88
|
+
@cost = [0,*cost].pack('C4').unpack('N')[0]
|
89
|
+
end
|
90
|
+
|
91
|
+
def to_s
|
92
|
+
self.class.to_s.split('::').last + ": tos: #{tos} cost: #{cost}"
|
93
|
+
end
|
94
|
+
|
95
|
+
def to_s_junos_style
|
96
|
+
"Topology (ID #{id}) -> Metric: #{cost}"
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
load "../../../test/ospfv2/ie/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|