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/bin/ospfv2
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'neighbor/neighbor'
|
4
|
+
require 'packet/ospf_packet'
|
5
|
+
require 'ls_db/link_state_database'
|
6
|
+
require 'ls_db/link_state_database_links'
|
7
|
+
require 'infra/parse_options'
|
8
|
+
require 'pp'
|
9
|
+
|
10
|
+
include OSPFv2
|
11
|
+
|
12
|
+
Thread.current["name"] = "#{self}"
|
13
|
+
|
14
|
+
cli = Thread.new do
|
15
|
+
Thread.current["name"] = "CLI"
|
16
|
+
|
17
|
+
# Parse command line
|
18
|
+
begin
|
19
|
+
options = OptParse.parse(ARGV)
|
20
|
+
rescue OptionParser::InvalidOption => e
|
21
|
+
STDERR.puts e.to_s.gsub(/at\s*$/,'')
|
22
|
+
exit(1)
|
23
|
+
end
|
24
|
+
|
25
|
+
ls_db = OSPFv2::LSDB::LinkStateDatabase.create :columns=> options.grid[0],
|
26
|
+
:rows=> options.grid[1],
|
27
|
+
:base_prefix => options.base_link_addr,
|
28
|
+
:base_router_id=> options.base_router_id
|
29
|
+
|
30
|
+
# Up all links
|
31
|
+
OSPFv2::LSDB::Link.all.each { |id,lnk| ls_db.link lnk, :up }
|
32
|
+
|
33
|
+
|
34
|
+
# Describe the connection to our neighbor
|
35
|
+
# It's a p2p connection
|
36
|
+
# we need to describe a p2p link and a stub link
|
37
|
+
rlsa = Router.new :ls_id=> options.router_id,
|
38
|
+
:advertising_router=>options.router_id,
|
39
|
+
:options=>0x22
|
40
|
+
rlsa << RouterLink.new_point_to_point(:link_id=>options.neighbor_id,
|
41
|
+
:link_data=> options.ipaddr,
|
42
|
+
:metric=>1)
|
43
|
+
rlsa << RouterLink.new_stub_network(:link_id=>options.network,
|
44
|
+
:link_data=>options.netmask,
|
45
|
+
:metric=>1)
|
46
|
+
ls_db << rlsa
|
47
|
+
|
48
|
+
|
49
|
+
rid1 = OSPFv2::LSDB::LinkStateDatabase.router_id(1,1,options.base_router_id)
|
50
|
+
rid2 = OSPFv2::LSDB::LinkStateDatabase.router_id(2,1,options.base_router_id)
|
51
|
+
rid3 = OSPFv2::LSDB::LinkStateDatabase.router_id(1,1,options.base_router_id)
|
52
|
+
|
53
|
+
# add a a p2p link between router_id and rid1
|
54
|
+
ls_db.new_link :router_id=> options.router_id, :neighbor_id=>rid1
|
55
|
+
|
56
|
+
# Link.all.values.each { |lnk| @ls_db.link lnk, :down }
|
57
|
+
|
58
|
+
# Add some Summary LSAs
|
59
|
+
[rid1,rid2].each do |rid|
|
60
|
+
ls_db.lookup(1,rid).set_abr
|
61
|
+
(options.num_sum/2).times { ls_db << OSPFv2::Summary.new_lsdb( :advertising_router=> rid ) }
|
62
|
+
end
|
63
|
+
|
64
|
+
# Add some External LSAs
|
65
|
+
ls_db.find_router_lsa(rid3).set_asbr
|
66
|
+
options.num_ext.times { \
|
67
|
+
ls_db << OSPFv2::AsExternal.new_lsdb(:advertising_router=> rid3,
|
68
|
+
:mt_metrics=>[{:mt_id=>10, :metric=>20,
|
69
|
+
:tag=>10}])}
|
70
|
+
|
71
|
+
ls_db << AsbrSummary.new(:advertising_router=> rid3, :ls_id=> rid3)
|
72
|
+
|
73
|
+
|
74
|
+
neighbor = OSPFv2::Neighbor.new :src_addr => options.ipaddr,
|
75
|
+
:router_id => options.router_id,
|
76
|
+
:area_id=>options.area_id,
|
77
|
+
:log_fname => options.log_fname
|
78
|
+
|
79
|
+
neighbor.hello_int
|
80
|
+
neighbor.dead_int
|
81
|
+
neighbor.ls_db = ls_db
|
82
|
+
|
83
|
+
# Add option to parse
|
84
|
+
ls_db.ls_refresh_time=2000
|
85
|
+
ls_db.ls_refresh_interval=10
|
86
|
+
|
87
|
+
help= <<-"end;"
|
88
|
+
start
|
89
|
+
stop
|
90
|
+
puts ls_db
|
91
|
+
puts ls_db.to_js_unos
|
92
|
+
aging :on | :off
|
93
|
+
end;
|
94
|
+
|
95
|
+
def prompt() ; ">> " ; end
|
96
|
+
|
97
|
+
sleep(1)
|
98
|
+
ue=nil
|
99
|
+
|
100
|
+
def eval_cmd(cmd,binding)
|
101
|
+
s = eval(cmd,binding)
|
102
|
+
print "=> #{s.inspect}" if s
|
103
|
+
puts
|
104
|
+
rescue SyntaxError, NameError => e
|
105
|
+
puts "% syntax error\n"
|
106
|
+
rescue => e
|
107
|
+
puts "% error: #{e}\n"
|
108
|
+
end
|
109
|
+
|
110
|
+
def aging(arg)
|
111
|
+
OSPFv2::Lsa::LsAge.aging arg
|
112
|
+
end
|
113
|
+
|
114
|
+
loop do
|
115
|
+
print prompt() ; $stdout.flush
|
116
|
+
cmd = STDIN.gets
|
117
|
+
break unless cmd
|
118
|
+
next if cmd.size == 0
|
119
|
+
ary = cmd.downcase.split(' ')
|
120
|
+
case ary[0]
|
121
|
+
when 'start' ; aging :on ; neighbor.start
|
122
|
+
when 'stop' ; neighbor.stop
|
123
|
+
when 'help', '?'
|
124
|
+
print help
|
125
|
+
when nil
|
126
|
+
when /^(exit|quit|x|q|fin|end)$/ ; exit
|
127
|
+
else
|
128
|
+
eval_cmd cmd, binding()
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
cli.join
|
135
|
+
|
136
|
+
exit
|
data/lib/ie/au_type.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2010 Jean-Michel Esnault.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# This file is part of OSPFv2.
|
8
|
+
#
|
9
|
+
# OSPFv2 is free software: you can redistribute it and/or modify
|
10
|
+
# it under the terms of the GNU General Public License as published by
|
11
|
+
# the Free Software Foundation, either version 3 of the License, or
|
12
|
+
# (at your option) any later version.
|
13
|
+
#
|
14
|
+
# OSPFv2 is distributed in the hope that it will be useful,
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
# GNU General Public License for more details.
|
18
|
+
#
|
19
|
+
# You should have received a copy of the GNU General Public License
|
20
|
+
# along with OSPFv2. If not, see <http://www.gnu.org/licenses/>.
|
21
|
+
#++
|
22
|
+
|
23
|
+
|
24
|
+
# 0 Null authentication 1 Simple password 2 Cryptographic authentication
|
25
|
+
module OSPFv2
|
26
|
+
class AuType
|
27
|
+
def initialize(au_type=0)
|
28
|
+
@au_type=0
|
29
|
+
case au_type
|
30
|
+
when :null, 0 ; @au_type = 0
|
31
|
+
when :simple_password, 1 ; @au_type = 1
|
32
|
+
when :cryptographic, 2 ; @au_type = 2
|
33
|
+
else
|
34
|
+
@au_type = au_type if au_type.is_a?(Integer)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_hash
|
39
|
+
to_sym
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_i
|
43
|
+
@au_type
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_s
|
47
|
+
self.class.to_s.split('::').last + ": #{au_to_s}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_sym
|
51
|
+
case @au_type
|
52
|
+
when 2 ; :cryptographic
|
53
|
+
when 1 ; :simple_password
|
54
|
+
when 0 ; :null
|
55
|
+
else
|
56
|
+
:undefined?
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def encode
|
61
|
+
[@au_type].pack('n')
|
62
|
+
end
|
63
|
+
alias :enc :encode
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def au_to_s
|
68
|
+
case @au_type
|
69
|
+
when 0 ; 'null authentication'
|
70
|
+
when 1 ; 'simple password'
|
71
|
+
when 2 ; 'cryptographic authentication'
|
72
|
+
else
|
73
|
+
'unknown'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2010 Jean-Michel Esnault.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# This file is part of OSPFv2.
|
8
|
+
#
|
9
|
+
# OSPFv2 is free software: you can redistribute it and/or modify
|
10
|
+
# it under the terms of the GNU General Public License as published by
|
11
|
+
# the Free Software Foundation, either version 3 of the License, or
|
12
|
+
# (at your option) any later version.
|
13
|
+
#
|
14
|
+
# OSPFv2 is distributed in the hope that it will be useful,
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
# GNU General Public License for more details.
|
18
|
+
#
|
19
|
+
# You should have received a copy of the GNU General Public License
|
20
|
+
# along with OSPFv2. If not, see <http://www.gnu.org/licenses/>.
|
21
|
+
#++
|
22
|
+
|
23
|
+
#
|
24
|
+
# (RFC 2328)
|
25
|
+
#
|
26
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
27
|
+
# |E| 0 | metric |
|
28
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
29
|
+
# | Forwarding address |
|
30
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
31
|
+
# | External Route Tag |
|
32
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
33
|
+
#
|
34
|
+
#
|
35
|
+
#
|
36
|
+
# (RFC 4915)
|
37
|
+
#
|
38
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
39
|
+
# | Network Mask |
|
40
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
41
|
+
# |E| 0 | metric |
|
42
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
43
|
+
# | Forwarding address |
|
44
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
45
|
+
# | External Route Tag |
|
46
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
47
|
+
# |E| MT-ID | MT-ID metric |
|
48
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
49
|
+
# | Forwarding address |
|
50
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
51
|
+
# | External Route Tag |
|
52
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
53
|
+
# | ... |
|
54
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
55
|
+
#
|
56
|
+
require 'infra/ospf_common'
|
57
|
+
require 'ie/metric'
|
58
|
+
require 'ie/tos_metric'
|
59
|
+
require 'ie/id'
|
60
|
+
|
61
|
+
|
62
|
+
module OSPFv2
|
63
|
+
|
64
|
+
class ExternalRoute_Base
|
65
|
+
include Common
|
66
|
+
|
67
|
+
ForwardingAddress = Class.new(OSPFv2::Id)
|
68
|
+
|
69
|
+
attr_reader :metric, :type, :forwarding_address, :tag, :mt_id
|
70
|
+
attr_checked :metric do |x|
|
71
|
+
(0..0xffffff).include?(x)
|
72
|
+
end
|
73
|
+
attr_checked :type do |x|
|
74
|
+
[:e1,:e2].include?(x)
|
75
|
+
end
|
76
|
+
attr_checked :tag do |x|
|
77
|
+
(0..0xffffffff).include?(x)
|
78
|
+
end
|
79
|
+
attr_checked :mt_id do |x|
|
80
|
+
(0..0x7f).include?(x)
|
81
|
+
end
|
82
|
+
|
83
|
+
attr_writer_delegate :forwarding_address
|
84
|
+
|
85
|
+
def initialize(arg={})
|
86
|
+
arg = arg.dup
|
87
|
+
self.metric=0
|
88
|
+
self.type=:e1
|
89
|
+
self.tag=0
|
90
|
+
self.mt_id=0
|
91
|
+
if arg.is_a?(Hash)
|
92
|
+
set arg
|
93
|
+
elsif arg.is_a?(String)
|
94
|
+
parse arg
|
95
|
+
elsif arg.is_a?(self.class)
|
96
|
+
parse arg.encode
|
97
|
+
else
|
98
|
+
raise ArgumentError, "Invalid Argument: #{arg.inspect}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def encode
|
103
|
+
external =[]
|
104
|
+
external << encoded_e_id_metric
|
105
|
+
external << forwarding_address.encode
|
106
|
+
external << [tag].pack('N')
|
107
|
+
external.join
|
108
|
+
end
|
109
|
+
|
110
|
+
def parse(s)
|
111
|
+
long1, long2, @tag = s.unpack('NNN')
|
112
|
+
@type, @mt_id, @metric = parse_e_id_metric(long1)
|
113
|
+
@forwarding_address = ForwardingAddress.new(long2)
|
114
|
+
end
|
115
|
+
|
116
|
+
def to_s
|
117
|
+
"#{type.to_s.upcase} (ID #{mt_id}) Metric: #{metric.to_i} Forwarding: #{forwarding_address.to_ip} Tag: #{tag}"
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
def encoded_e_id_metric
|
123
|
+
long = 0
|
124
|
+
long = 0x80000000 if type== :e2
|
125
|
+
long |= (mt_id << 24)
|
126
|
+
long |= metric.to_i
|
127
|
+
[long].pack('N')
|
128
|
+
end
|
129
|
+
|
130
|
+
def parse_e_id_metric(long)
|
131
|
+
type = :e1
|
132
|
+
type = :e2 if (long >> 31) > 0
|
133
|
+
metric = long & 0xffffff
|
134
|
+
_id = long >> 24 & 0x7f
|
135
|
+
[type,_id,metric]
|
136
|
+
end
|
137
|
+
|
138
|
+
def metric_to_s
|
139
|
+
"Metric: #{metric}"
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
class ExternalRoute < ExternalRoute_Base
|
145
|
+
def initialize(arg={})
|
146
|
+
if arg.is_a?(Hash)
|
147
|
+
@forwarding_address = ForwardingAddress.new
|
148
|
+
raise ArgumentError, "ID should be 0" if arg[:id] and arg[:mt_id]>0
|
149
|
+
end
|
150
|
+
super
|
151
|
+
end
|
152
|
+
def to_hash
|
153
|
+
h = super
|
154
|
+
h.delete(:mt_id)
|
155
|
+
h
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
class MtExternalRoute < ExternalRoute_Base
|
161
|
+
def initialize(arg={})
|
162
|
+
if arg.is_a?(Hash)
|
163
|
+
@forwarding_address = ForwardingAddress.new
|
164
|
+
raise ArgumentError, "MT-ID not set!" unless arg[:mt_id]
|
165
|
+
raise ArgumentError, "MT-ID should not be 0!" if arg[:mt_id]==0
|
166
|
+
end
|
167
|
+
super
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def ExternalRoute_Base.new_hash(h)
|
172
|
+
if h[:mt_metrics]
|
173
|
+
MtExternalRoute.new(h)
|
174
|
+
else
|
175
|
+
ExternalRoute.new(h)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
load "../../../test/ospfv2/ie/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|
data/lib/ie/id.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2010 Jean-Michel Esnault.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# This file is part of OSPFv2.
|
8
|
+
#
|
9
|
+
# OSPFv2 is free software: you can redistribute it and/or modify
|
10
|
+
# it under the terms of the GNU General Public License as published by
|
11
|
+
# the Free Software Foundation, either version 3 of the License, or
|
12
|
+
# (at your option) any later version.
|
13
|
+
#
|
14
|
+
# OSPFv2 is distributed in the hope that it will be useful,
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
# GNU General Public License for more details.
|
18
|
+
#
|
19
|
+
# You should have received a copy of the GNU General Public License
|
20
|
+
# along with OSPFv2. If not, see <http://www.gnu.org/licenses/>.
|
21
|
+
#++
|
22
|
+
|
23
|
+
|
24
|
+
require 'ipaddr'
|
25
|
+
require 'infra/ospf_common'
|
26
|
+
|
27
|
+
module OSPFv2
|
28
|
+
class Id
|
29
|
+
|
30
|
+
def self.new_ntoh(s)
|
31
|
+
return unless s.is_a?(String)
|
32
|
+
new s.unpack('N')[0]
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.to_i(id)
|
36
|
+
return id.to_i unless id.is_a?(String) and id.split('.').size==4
|
37
|
+
IPAddr.new(id).to_i
|
38
|
+
end
|
39
|
+
|
40
|
+
def initialize(arg=0)
|
41
|
+
self.id = arg
|
42
|
+
end
|
43
|
+
|
44
|
+
def id=(val)
|
45
|
+
if val.is_a?(Hash)
|
46
|
+
@id = val[:id] if val[:id]
|
47
|
+
elsif val.is_a?(IPAddr)
|
48
|
+
@id = val.to_i
|
49
|
+
elsif val.is_a?(Integer)
|
50
|
+
raise ArgumentError, "Invalid Argument #{val}" unless (0..0xffffffff).include?(val)
|
51
|
+
@id = val
|
52
|
+
elsif val.is_a?(String)
|
53
|
+
@id = IPAddr.new(val).to_i
|
54
|
+
elsif val.is_a?(Id)
|
55
|
+
@id = val.to_i
|
56
|
+
else
|
57
|
+
raise ArgumentError, "Invalid Argument #{val.inspect}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def encode
|
62
|
+
[@id].pack('N')
|
63
|
+
end
|
64
|
+
alias :enc :encode
|
65
|
+
|
66
|
+
def to_i
|
67
|
+
@id
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_s(verbose=true)
|
71
|
+
verbose ? to_s_verbose : to_s_short
|
72
|
+
end
|
73
|
+
|
74
|
+
def to_hash
|
75
|
+
to_s_short
|
76
|
+
end
|
77
|
+
|
78
|
+
def to_ip
|
79
|
+
to_s(false)
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def to_s_short
|
85
|
+
IPAddr.new_ntoh([@id].pack('N')).to_s
|
86
|
+
end
|
87
|
+
|
88
|
+
def to_s_verbose
|
89
|
+
self.class.to_s.split('::').last + ": " + to_s_short
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
load "../../../test/ospfv2/ie/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|
97
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2010 Jean-Michel Esnault.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# This file is part of OSPFv2.
|
8
|
+
#
|
9
|
+
# OSPFv2 is free software: you can redistribute it and/or modify
|
10
|
+
# it under the terms of the GNU General Public License as published by
|
11
|
+
# the Free Software Foundation, either version 3 of the License, or
|
12
|
+
# (at your option) any later version.
|
13
|
+
#
|
14
|
+
# OSPFv2 is distributed in the hope that it will be useful,
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
# GNU General Public License for more details.
|
18
|
+
#
|
19
|
+
# You should have received a copy of the GNU General Public License
|
20
|
+
# along with OSPFv2. If not, see <http://www.gnu.org/licenses/>.
|
21
|
+
#++
|
22
|
+
|
23
|
+
require 'infra/ospf_common'
|
24
|
+
require 'infra/ospf_constants'
|
25
|
+
|
26
|
+
module OSPFv2
|
27
|
+
|
28
|
+
class InterfaceMtu
|
29
|
+
include Common
|
30
|
+
|
31
|
+
attr_checked :interface_mtu do |x|
|
32
|
+
(0..0xffff).include?(x)
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(interface_mtu=1500)
|
36
|
+
self.interface_mtu=interface_mtu
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_i
|
40
|
+
interface_mtu
|
41
|
+
end
|
42
|
+
|
43
|
+
def number_of_lsa
|
44
|
+
@noh ||= ((to_i - OSPFv2::PACKET_HEADER_LEN) / OSPFv2::LSA_HEADER_LEN) - 1
|
45
|
+
end
|
46
|
+
alias :n0flsa :number_of_lsa
|
47
|
+
|
48
|
+
def to_s
|
49
|
+
self.class.to_s.split('::').last + ": #{to_i}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def encode(fmt='n')
|
53
|
+
[interface_mtu].pack(fmt)
|
54
|
+
end
|
55
|
+
alias :enc :encode
|
56
|
+
|
57
|
+
def to_hash
|
58
|
+
to_i
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
load "../../../test/ospfv2/ie/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|
data/lib/ie/ls_age.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2010 Jean-Michel Esnault.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# This file is part of OSPFv2.
|
8
|
+
#
|
9
|
+
# OSPFv2 is free software: you can redistribute it and/or modify
|
10
|
+
# it under the terms of the GNU General Public License as published by
|
11
|
+
# the Free Software Foundation, either version 3 of the License, or
|
12
|
+
# (at your option) any later version.
|
13
|
+
#
|
14
|
+
# OSPFv2 is distributed in the hope that it will be useful,
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
# GNU General Public License for more details.
|
18
|
+
#
|
19
|
+
# You should have received a copy of the GNU General Public License
|
20
|
+
# along with OSPFv2. If not, see <http://www.gnu.org/licenses/>.
|
21
|
+
#++
|
22
|
+
|
23
|
+
require 'infra/ospf_constants'
|
24
|
+
|
25
|
+
module OSPFv2
|
26
|
+
class LsAge
|
27
|
+
include Comparable
|
28
|
+
|
29
|
+
class << self
|
30
|
+
def aging(state=:off)
|
31
|
+
case state
|
32
|
+
when :on ; @aging = true
|
33
|
+
when :off ; @aging = false
|
34
|
+
else
|
35
|
+
raise ArgumentError, "Invalid Argument"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
def aging?
|
39
|
+
@aging
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def initialize(age=0)
|
44
|
+
raise ArgumentError, "Invalid Argument #{age}" unless age.is_a?(Integer)
|
45
|
+
@age=age
|
46
|
+
@time = Time.now
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_i
|
50
|
+
aging? ? (Time.new - @time + @age).to_int : @age
|
51
|
+
end
|
52
|
+
|
53
|
+
def aging?
|
54
|
+
self.class.aging?
|
55
|
+
end
|
56
|
+
|
57
|
+
def maxage
|
58
|
+
@age = OSPFv2::MaxAge
|
59
|
+
end
|
60
|
+
|
61
|
+
def maxaged?
|
62
|
+
to_i >= OSPFv2::MaxAge
|
63
|
+
end
|
64
|
+
|
65
|
+
def <=>(obj)
|
66
|
+
to_i <=> obj.to_i
|
67
|
+
end
|
68
|
+
|
69
|
+
def -(obj)
|
70
|
+
to_i - obj.to_i
|
71
|
+
end
|
72
|
+
|
73
|
+
def to_s
|
74
|
+
self.class.to_s.split('::').last + ": #{to_i}"
|
75
|
+
end
|
76
|
+
|
77
|
+
def encode
|
78
|
+
[@age].pack('n')
|
79
|
+
end
|
80
|
+
alias :enc :encode
|
81
|
+
|
82
|
+
def to_hash
|
83
|
+
to_i
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
load "../../../test/ospfv2/ie/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|