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
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
|