ospfv2 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. data/bin/ospfv2 +136 -0
  2. data/lib/ie/au_type.rb +79 -0
  3. data/lib/ie/external_route.rb +181 -0
  4. data/lib/ie/id.rb +97 -0
  5. data/lib/ie/interface_mtu.rb +64 -0
  6. data/lib/ie/ls_age.rb +89 -0
  7. data/lib/ie/ls_type.rb +148 -0
  8. data/lib/ie/metric.rb +63 -0
  9. data/lib/ie/mt_metric.rb +119 -0
  10. data/lib/ie/options.rb +356 -0
  11. data/lib/ie/ospf_version.rb +67 -0
  12. data/lib/ie/packet_type.rb +65 -0
  13. data/lib/ie/router_link.rb +167 -0
  14. data/lib/ie/router_link_factory.rb +53 -0
  15. data/lib/ie/router_link_type.rb +86 -0
  16. data/lib/ie/sequence_number.rb +144 -0
  17. data/lib/ie/tos_metric.rb +102 -0
  18. data/lib/infra/ospf_common.rb +291 -0
  19. data/lib/infra/ospf_constants.rb +73 -0
  20. data/lib/infra/ospf_io.rb +133 -0
  21. data/lib/infra/ospf_socket.rb +126 -0
  22. data/lib/infra/parse_options.rb +135 -0
  23. data/lib/infra/timer.rb +104 -0
  24. data/lib/infra/to_s.rb +38 -0
  25. data/lib/ls_db/advertised_routers.rb +78 -0
  26. data/lib/ls_db/common.rb +31 -0
  27. data/lib/ls_db/link_state_database.rb +376 -0
  28. data/lib/ls_db/link_state_database_build.rb +181 -0
  29. data/lib/ls_db/link_state_database_links.rb +178 -0
  30. data/lib/ls_db/links.rb +160 -0
  31. data/lib/lsa/external.rb +347 -0
  32. data/lib/lsa/lsa.rb +438 -0
  33. data/lib/lsa/lsa_factory.rb +59 -0
  34. data/lib/lsa/network.rb +166 -0
  35. data/lib/lsa/router.rb +336 -0
  36. data/lib/lsa/summary.rb +393 -0
  37. data/lib/neighbor/neighbor.rb +298 -0
  38. data/lib/neighbor/neighbor_event_handler.rb +61 -0
  39. data/lib/neighbor/recv_database_description.rb +153 -0
  40. data/lib/neighbor/recv_hello.rb +53 -0
  41. data/lib/neighbor/recv_ospf_packet.rb +68 -0
  42. data/lib/neighbor_sm/attempt_state.rb +44 -0
  43. data/lib/neighbor_sm/down_state.rb +46 -0
  44. data/lib/neighbor_sm/exchange_state.rb +32 -0
  45. data/lib/neighbor_sm/exstart_state.rb +69 -0
  46. data/lib/neighbor_sm/full_state.rb +36 -0
  47. data/lib/neighbor_sm/init_state.rb +43 -0
  48. data/lib/neighbor_sm/loading_state.rb +33 -0
  49. data/lib/neighbor_sm/neighbor_state.rb +87 -0
  50. data/lib/packet/database_description.rb +300 -0
  51. data/lib/packet/hello.rb +327 -0
  52. data/lib/packet/link_state_ack.rb +144 -0
  53. data/lib/packet/link_state_request.rb +153 -0
  54. data/lib/packet/link_state_update.rb +189 -0
  55. data/lib/packet/ospf_packet.rb +306 -0
  56. metadata +116 -0
data/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
@@ -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