ospfv2 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|