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
data/lib/ie/ls_type.rb
ADDED
@@ -0,0 +1,148 @@
|
|
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
|
+
# LS Type Description
|
25
|
+
# ___________________________________
|
26
|
+
# 1 Router-LSAs
|
27
|
+
# 2 Network-LSAs
|
28
|
+
# 3 Summary-LSAs (IP network)
|
29
|
+
# 4 Summary-LSAs (ASBR)
|
30
|
+
# 5 AS-external-LSAs
|
31
|
+
#
|
32
|
+
module OSPFv2
|
33
|
+
class LsType
|
34
|
+
|
35
|
+
def self.all
|
36
|
+
[:router, :network, :summary, :asbr_summary, :as_external]
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.to_i(arg)
|
40
|
+
return arg unless arg.is_a?(Symbol)
|
41
|
+
case arg.to_s
|
42
|
+
when /^router(_lsa|)$/ ; @ls_type=1
|
43
|
+
when /^network(_lsa|)$/ ; @ls_type=2
|
44
|
+
when /^summary(_lsa|)$/ ; @ls_type=3
|
45
|
+
when /^asbr_summary(_lsa|)$/ ; @ls_type=4
|
46
|
+
when /^as_external(_lsa|)$/ ; @ls_type=5
|
47
|
+
#FIXME: finish and unit-test
|
48
|
+
# when :as_external7_lsa ; @ls_type=7
|
49
|
+
# when :opaque_link ; @ls_type=9
|
50
|
+
# when :opaque_area ; @ls_type=10
|
51
|
+
# when :opaque_as ; @ls_type=11
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.to_sym(arg)
|
56
|
+
return arg unless arg.is_a?(Fixnum)
|
57
|
+
case arg
|
58
|
+
when 1 ; :router_lsa
|
59
|
+
when 2 ; :network_lsa
|
60
|
+
when 3 ; :summary_lsa
|
61
|
+
when 4 ; :asbr_summary_lsa
|
62
|
+
when 5 ; :as_external_lsa
|
63
|
+
when 7 ; :as_external7_lsa
|
64
|
+
when 9 ; :opaque_link
|
65
|
+
when 10 ; :opaque_area
|
66
|
+
when 11 ; :opaque_as
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.to_junos(arg)
|
71
|
+
return arg.to_i unless arg.is_a?(Fixnum)
|
72
|
+
case arg
|
73
|
+
when 1 ; 'Router'
|
74
|
+
when 2 ; 'Network'
|
75
|
+
when 3 ; 'Summary'
|
76
|
+
when 4 ; 'ASBRSum'
|
77
|
+
when 5 ; 'Extern'
|
78
|
+
else
|
79
|
+
'TBD'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def initialize(ls_type=1)
|
84
|
+
case ls_type
|
85
|
+
when 1,:router_lsa ; @ls_type=1
|
86
|
+
when 2,:network_lsa ; @ls_type=2
|
87
|
+
when 3,:summary_lsa ; @ls_type=3
|
88
|
+
when 4,:asbr_summary_lsa ; @ls_type=4
|
89
|
+
when 5,:as_external_lsa ; @ls_type=5
|
90
|
+
when 7,:as_external7_lsa ; @ls_type=7
|
91
|
+
when 9,:opaque_link ; @ls_type=9
|
92
|
+
when 10,:opaque_area ; @ls_type=10
|
93
|
+
when 11,:opaque_as ; @ls_type=11
|
94
|
+
else
|
95
|
+
raise ArgumentError, "Invalid LsType #{ls_type}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
def to_i
|
99
|
+
@ls_type
|
100
|
+
end
|
101
|
+
def to_s
|
102
|
+
self.class.to_s.split('::').last + ": #{to_sym}"
|
103
|
+
end
|
104
|
+
def to_s_short
|
105
|
+
case to_i
|
106
|
+
when 1; 'router'
|
107
|
+
when 2; 'network'
|
108
|
+
when 3; 'summary'
|
109
|
+
when 4; 'asbrSum'
|
110
|
+
when 5; 'external'
|
111
|
+
when 7; 'nssa'
|
112
|
+
when 9; 'opaqLnk'
|
113
|
+
when 10; 'opaqArea'
|
114
|
+
when 11; 'opaqAs'
|
115
|
+
end
|
116
|
+
end
|
117
|
+
def to_sym
|
118
|
+
LsType.to_sym @ls_type
|
119
|
+
end
|
120
|
+
|
121
|
+
def encode
|
122
|
+
[@ls_type].pack('C')
|
123
|
+
end
|
124
|
+
alias :enc :encode
|
125
|
+
|
126
|
+
def to_hash
|
127
|
+
to_sym
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
load "../../../test/ospfv2/ie/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|
134
|
+
|
135
|
+
__END__
|
136
|
+
|
137
|
+
LSA_Header.aging=false
|
138
|
+
LSA_Header.lstype_to_s = Hash.new("unknown")
|
139
|
+
LSA_Header.lstype_to_s.store(1,"Router")
|
140
|
+
LSA_Header.lstype_to_s.store(2,"Network")
|
141
|
+
LSA_Header.lstype_to_s.store(3,"Summary")
|
142
|
+
LSA_Header.lstype_to_s.store(4,"ASBR_Sum")
|
143
|
+
LSA_Header.lstype_to_s.store(5,"External")
|
144
|
+
LSA_Header.lstype_to_s.store(9,"OpaqLink")
|
145
|
+
LSA_Header.lstype_to_s.store(10,"OpaqArea")
|
146
|
+
LSA_Header.lstype_to_s.store(11,"OpaqAS")
|
147
|
+
|
148
|
+
|
data/lib/ie/metric.rb
ADDED
@@ -0,0 +1,63 @@
|
|
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
|
+
|
25
|
+
module OSPFv2
|
26
|
+
|
27
|
+
class Metric
|
28
|
+
include Common
|
29
|
+
|
30
|
+
attr_reader :metric
|
31
|
+
attr_checked :metric do |x|
|
32
|
+
(0..0xffffff).include?(x)
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(metric=0)
|
36
|
+
self.metric=metric
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_i
|
40
|
+
metric
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_s
|
44
|
+
self.class.to_s.split('::').last + ": #{to_i}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_s_junos
|
48
|
+
"Topology default (ID 0) -> Metric: #{to_i}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def encode(fmt='N')
|
52
|
+
[metric].pack(fmt)
|
53
|
+
end
|
54
|
+
alias :enc :encode
|
55
|
+
|
56
|
+
def to_hash
|
57
|
+
to_i
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
load "../../../test/ospfv2/ie/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|
data/lib/ie/mt_metric.rb
ADDED
@@ -0,0 +1,119 @@
|
|
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 metric of this route. Expressed in the same units as the
|
39
|
+
# interface metrics 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 MtMetric
|
57
|
+
|
58
|
+
def initialize(arg={})
|
59
|
+
arg = arg.dup
|
60
|
+
@_id,@_metric=0,0
|
61
|
+
if arg.is_a?(Hash)
|
62
|
+
set arg
|
63
|
+
elsif arg.is_a?(String)
|
64
|
+
parse arg
|
65
|
+
elsif arg.is_a?(self.class)
|
66
|
+
parse arg.encode
|
67
|
+
elsif arg.is_a?(Array) and arg.size==2
|
68
|
+
@_id, @_metric = arg
|
69
|
+
else
|
70
|
+
raise ArgumentError, "Invalid Argument: #{arg.inspect}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def set(arg)
|
75
|
+
@_id = arg[:id] if arg[:id]
|
76
|
+
@_metric = arg[:metric] if arg[:metric]
|
77
|
+
end
|
78
|
+
|
79
|
+
def to_hash
|
80
|
+
{:id=>id, :metric=> metric}
|
81
|
+
end
|
82
|
+
|
83
|
+
def id
|
84
|
+
@_id
|
85
|
+
end
|
86
|
+
def id=(val)
|
87
|
+
@_id=val
|
88
|
+
end
|
89
|
+
def metric
|
90
|
+
@_metric
|
91
|
+
end
|
92
|
+
def metric=(val)
|
93
|
+
@_metric=val
|
94
|
+
end
|
95
|
+
|
96
|
+
def encode
|
97
|
+
m = []
|
98
|
+
m << [id].pack('C')
|
99
|
+
m << [metric].pack('N').unpack('C4')[1..-1].pack('C3')
|
100
|
+
m.join
|
101
|
+
end
|
102
|
+
|
103
|
+
def parse(s)
|
104
|
+
@_id, *metric = s.unpack('C4')
|
105
|
+
@_metric = [0,*metric].pack('C4').unpack('N')[0]
|
106
|
+
end
|
107
|
+
|
108
|
+
def to_s
|
109
|
+
"Topology #{id}, Metric #{metric}"
|
110
|
+
end
|
111
|
+
|
112
|
+
def to_s_junos
|
113
|
+
"Topology (ID #{id}) -> Metric: #{metric}"
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
load "../../../test/ospfv2/ie/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|
data/lib/ie/options.rb
ADDED
@@ -0,0 +1,356 @@
|
|
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
|
+
=begin rdoc
|
25
|
+
|
26
|
+
A.2 The Options field
|
27
|
+
|
28
|
+
The 24-bit OSPF Options field is present in OSPF Hello packets,
|
29
|
+
Database Description packets and certain LSAs (router-LSAs, network-
|
30
|
+
LSAs, inter-area-router-LSAs and link-LSAs). The Options field
|
31
|
+
enables OSPF routers to support (or not support) optional
|
32
|
+
capabilities, and to communicate their capability level to other OSPF
|
33
|
+
routers. Through this mechanism routers of differing capabilities
|
34
|
+
can be mixed within an OSPF routing domain.
|
35
|
+
|
36
|
+
An option mismatch between routers can cause a variety of behaviors,
|
37
|
+
depending on the particular option. Some option mismatches prevent
|
38
|
+
neighbor relationships from forming (e.g., the E-bit below); these
|
39
|
+
mismatches are discovered through the sending and receiving of Hello
|
40
|
+
packets. Some option mismatches prevent particular LSA types from
|
41
|
+
being flooded across adjacencies (e.g., the MC-bit below); these are
|
42
|
+
discovered through the sending and receiving of Database Description
|
43
|
+
packets. Some option mismatches prevent routers from being included
|
44
|
+
in one or more of the various routing calculations because of their
|
45
|
+
reduced functionality (again the MC-bit is an example); these
|
46
|
+
mismatches are discovered by examining LSAs.
|
47
|
+
|
48
|
+
Six bits of the OSPF Options field have been assigned. Each bit is
|
49
|
+
described briefly below. Routers should reset (i.e. clear)
|
50
|
+
unrecognized bits in the Options field when sending Hello packets or
|
51
|
+
Database Description packets and when originating LSAs. Conversely,
|
52
|
+
routers encountering unrecognized Option bits in received Hello
|
53
|
+
Packets, Database Description packets or LSAs should ignore the
|
54
|
+
capability and process the packet/LSA normally.
|
55
|
+
|
56
|
+
|
57
|
+
1 2
|
58
|
+
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
|
59
|
+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--+--+--+--+--+--+
|
60
|
+
| | | | | | | | | | | | | | | | | |DC| R| N|MC| E|V6|
|
61
|
+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--+--+--+--+--+--+
|
62
|
+
|
63
|
+
The Options field
|
64
|
+
|
65
|
+
V6-bit
|
66
|
+
If this bit is clear, the router/link should be excluded from IPv6
|
67
|
+
routing calculations. See Section 3.8 of this memo.
|
68
|
+
|
69
|
+
E-bit
|
70
|
+
This bit describes the way AS-external-LSAs are flooded, as
|
71
|
+
described in Sections 3.6, 9.5, 10.8 and 12.1.2 of [Ref1].
|
72
|
+
|
73
|
+
MC-bit
|
74
|
+
This bit describes whether IP multicast datagrams are forwarded
|
75
|
+
according to the specifications in [Ref7].
|
76
|
+
|
77
|
+
N-bit
|
78
|
+
This bit describes the handling of Type-7 LSAs, as specified in
|
79
|
+
[Ref8].
|
80
|
+
|
81
|
+
R-bit
|
82
|
+
This bit (the `Router' bit) indicates whether the originator is an
|
83
|
+
active router. If the router bit is clear routes which transit the
|
84
|
+
advertising node cannot be computed. Clearing the router bit would
|
85
|
+
be appropriate for a multi-homed host that wants to participate in
|
86
|
+
routing, but does not want to forward non-locally addressed
|
87
|
+
packets.
|
88
|
+
|
89
|
+
DC-bit
|
90
|
+
This bit describes the router's handling of demand circuits, as
|
91
|
+
specified in [Ref10].
|
92
|
+
|
93
|
+
=end
|
94
|
+
|
95
|
+
require 'infra/ospf_common'
|
96
|
+
module OSPFv2
|
97
|
+
|
98
|
+
|
99
|
+
class Options
|
100
|
+
|
101
|
+
attr :options, true
|
102
|
+
|
103
|
+
def initialize(arg={})
|
104
|
+
@options=0
|
105
|
+
if arg.is_a?(Hash) then
|
106
|
+
set(arg)
|
107
|
+
elsif arg.is_a?(String)
|
108
|
+
_parse_(arg)
|
109
|
+
elsif arg.is_a?(Fixnum) and (0..255) === arg
|
110
|
+
@options = arg
|
111
|
+
elsif arg.is_a?(self.class)
|
112
|
+
set(arg.to_hash)
|
113
|
+
else
|
114
|
+
raise ArgumentError, "Invalid argument", caller
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def set(arg)
|
119
|
+
return self unless arg.is_a?(Hash)
|
120
|
+
|
121
|
+
unless arg[:O].nil? and arg[:o].nil?
|
122
|
+
_flag = arg[:O] ||= arg[:o]
|
123
|
+
if _flag.is_a?(TrueClass)
|
124
|
+
setO
|
125
|
+
elsif _flag.is_a?(FalseClass)
|
126
|
+
unsetO
|
127
|
+
elsif _flag.is_a?(Fixnum)
|
128
|
+
if _flag == 0
|
129
|
+
unsetO
|
130
|
+
else
|
131
|
+
setO
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
unless arg[:DC].nil? and arg[:dc].nil?
|
136
|
+
_flag = arg[:DC] ||= arg[:dc]
|
137
|
+
if _flag.is_a?(TrueClass)
|
138
|
+
setDC
|
139
|
+
elsif _flag.is_a?(FalseClass)
|
140
|
+
unsetDC
|
141
|
+
elsif _flag.is_a?(Fixnum)
|
142
|
+
if _flag == 0
|
143
|
+
unsetDC
|
144
|
+
else
|
145
|
+
setDC
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
unless arg[:R].nil? and arg[:r].nil?
|
150
|
+
_flag = arg[:R] ||= arg[:r]
|
151
|
+
if _flag.is_a?(TrueClass)
|
152
|
+
setR
|
153
|
+
elsif _flag.is_a?(FalseClass)
|
154
|
+
unsetR
|
155
|
+
elsif _flag.is_a?(Fixnum)
|
156
|
+
if _flag == 0
|
157
|
+
unsetR
|
158
|
+
else
|
159
|
+
setR
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
unless arg[:N].nil? and arg[:n].nil?
|
164
|
+
_flag = arg[:N] ||= arg[:n]
|
165
|
+
if _flag.is_a?(TrueClass)
|
166
|
+
setN
|
167
|
+
elsif _flag.is_a?(FalseClass)
|
168
|
+
unsetN
|
169
|
+
elsif _flag.is_a?(Fixnum)
|
170
|
+
if _flag == 0
|
171
|
+
unsetN
|
172
|
+
else
|
173
|
+
setN
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
unless arg[:P].nil? and arg[:p].nil?
|
178
|
+
_flag = arg[:P] ||= arg[:p]
|
179
|
+
if _flag.is_a?(TrueClass)
|
180
|
+
setP
|
181
|
+
elsif _flag.is_a?(FalseClass)
|
182
|
+
unsetP
|
183
|
+
elsif _flag.is_a?(Fixnum)
|
184
|
+
if _flag == 0
|
185
|
+
unsetP
|
186
|
+
else
|
187
|
+
setP
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
unless arg[:MC].nil? and arg[:mc].nil?
|
192
|
+
_flag = arg[:MC] ||= arg[:mc]
|
193
|
+
if _flag.is_a?(TrueClass)
|
194
|
+
setMC
|
195
|
+
elsif _flag.is_a?(FalseClass)
|
196
|
+
unsetMC
|
197
|
+
elsif _flag.is_a?(Fixnum)
|
198
|
+
if _flag == 0
|
199
|
+
unsetMC
|
200
|
+
else
|
201
|
+
setMC
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
unless arg[:E].nil? and arg[:e].nil?
|
206
|
+
_flag = arg[:E] ||= arg[:e]
|
207
|
+
if _flag.is_a?(TrueClass)
|
208
|
+
setE
|
209
|
+
elsif _flag.is_a?(FalseClass)
|
210
|
+
unsetE
|
211
|
+
elsif _flag.is_a?(Fixnum)
|
212
|
+
if _flag == 0
|
213
|
+
unsetE
|
214
|
+
else
|
215
|
+
setE
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
unless arg[:V6].nil? and arg[:v6].nil?
|
220
|
+
_flag = arg[:V6] ||= arg[:v6]
|
221
|
+
if _flag.is_a?(TrueClass)
|
222
|
+
setV6
|
223
|
+
elsif _flag.is_a?(FalseClass)
|
224
|
+
unsetV6
|
225
|
+
elsif _flag.is_a?(Fixnum)
|
226
|
+
if _flag == 0
|
227
|
+
unsetV6
|
228
|
+
else
|
229
|
+
setV6
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
self
|
234
|
+
end
|
235
|
+
|
236
|
+
def __setBit(bit)
|
237
|
+
@options = @options | (2 ** (bit-1))
|
238
|
+
end
|
239
|
+
private :__setBit
|
240
|
+
def __unsetBit(bit)
|
241
|
+
@options = @options & ~(2 ** (bit-1))
|
242
|
+
end
|
243
|
+
private :__unsetBit
|
244
|
+
def __isSet(bit)
|
245
|
+
@options & (2**(bit-1))>0
|
246
|
+
end
|
247
|
+
private :__isSet
|
248
|
+
|
249
|
+
def setO ; __setBit(7) ; end
|
250
|
+
def unsetO ; __unsetBit(7) ; end
|
251
|
+
def o? ; __isSet(7) ; end
|
252
|
+
|
253
|
+
def setDC ; __setBit(6) ; end
|
254
|
+
def unsetDC ; __unsetBit(6) ; end
|
255
|
+
def dc? ; __isSet(6) ; end
|
256
|
+
|
257
|
+
def setR ; __setBit(5) ; end
|
258
|
+
def unsetR ; __unsetBit(5) ; end
|
259
|
+
def r? ; __isSet(5) ; end
|
260
|
+
|
261
|
+
# N-bit is used in Hello packets only.
|
262
|
+
# It signals the area is an NSSA area.
|
263
|
+
def setN ; __setBit(4) ; end
|
264
|
+
def unsetN ; __unsetBit(4) ; end
|
265
|
+
def n? ; __isSet(4) ; end
|
266
|
+
|
267
|
+
# P-bit is used in Type-7 LSA Header
|
268
|
+
# It signals the NSSA border to translate the Type-7 into Type-5.
|
269
|
+
def setP ; __setBit(4) ; end
|
270
|
+
def unsetP ; __unsetBit(4) ; end
|
271
|
+
def p? ; __isSet(4) ; end
|
272
|
+
|
273
|
+
def setMC ; __setBit(3) ; end
|
274
|
+
def unsetMC ; __unsetBit(3) ; end
|
275
|
+
def mc? ; __isSet(3) ; end
|
276
|
+
|
277
|
+
def setE ; __setBit(2) ; end
|
278
|
+
def unsetE ; __unsetBit(2) ; end
|
279
|
+
def e? ; __isSet(2) ; end
|
280
|
+
|
281
|
+
def setV6 ; __setBit(1) ; end
|
282
|
+
def unsetV6 ; __unsetBit(1) ; end
|
283
|
+
def v6? ; __isSet(1) ; end
|
284
|
+
|
285
|
+
def setNSSA
|
286
|
+
setN
|
287
|
+
unsetE
|
288
|
+
end
|
289
|
+
|
290
|
+
def encode
|
291
|
+
[@options].pack('C')
|
292
|
+
end
|
293
|
+
|
294
|
+
def _parse_(s)
|
295
|
+
@options = s.unpack('C')[0]
|
296
|
+
end
|
297
|
+
private :_parse_
|
298
|
+
|
299
|
+
# V6-bit
|
300
|
+
# If this bit is clear, the router/link should be excluded from IPv6
|
301
|
+
# routing calculations. See Section 3.8 of this memo.
|
302
|
+
#
|
303
|
+
# E-bit
|
304
|
+
# This bit describes the way AS-external-LSAs are flooded, as
|
305
|
+
# described in Sections 3.6, 9.5, 10.8 and 12.1.2 of [Ref1].
|
306
|
+
#
|
307
|
+
# MC-bit
|
308
|
+
# This bit describes whether IP multicast datagrams are forwarded
|
309
|
+
# according to the specifications in [Ref7].
|
310
|
+
#
|
311
|
+
# N-bit
|
312
|
+
# This bit describes the handling of Type-7 LSAs, as specified in
|
313
|
+
# [Ref8].
|
314
|
+
#
|
315
|
+
# R-bit
|
316
|
+
# This bit (the `Router' bit) indicates whether the originator is an
|
317
|
+
# active router. If the router bit is clear routes which transit the
|
318
|
+
# advertising node cannot be computed. Clearing the router bit would
|
319
|
+
# be appropriate for a multi-homed host that wants to participate in
|
320
|
+
# routing, but does not want to forward non-locally addressed
|
321
|
+
# packets.
|
322
|
+
#
|
323
|
+
# DC-bit
|
324
|
+
# This bit describes the router's handling of demand circuits, as
|
325
|
+
# specified in [Ref10].
|
326
|
+
def to_s
|
327
|
+
self.class.to_s.split('::').last + ": " + format(' 0x%x [%s]', to_i, _to_s_) #[@options].pack('C').unpack('B8')[0][1..7]
|
328
|
+
end
|
329
|
+
|
330
|
+
def to_i
|
331
|
+
@options
|
332
|
+
end
|
333
|
+
|
334
|
+
def to_hash
|
335
|
+
to_i
|
336
|
+
end
|
337
|
+
|
338
|
+
private
|
339
|
+
|
340
|
+
def _to_s_
|
341
|
+
s = []
|
342
|
+
s << 'O' if o?
|
343
|
+
s << 'R' if r?
|
344
|
+
s << 'DC' if dc?
|
345
|
+
s << 'N' if n?
|
346
|
+
s << 'MC' if mc?
|
347
|
+
s << 'E' if e?
|
348
|
+
s << 'V6' if v6?
|
349
|
+
s.join(',')
|
350
|
+
end
|
351
|
+
|
352
|
+
end
|
353
|
+
|
354
|
+
end
|
355
|
+
|
356
|
+
load "../../../test/ospfv2/ie/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|