ospfv2 0.0.2 → 0.0.3

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 (107) hide show
  1. checksums.yaml +7 -0
  2. data/COPYING +674 -0
  3. data/LICENSE.txt +53 -0
  4. data/README +50 -0
  5. data/bin/ospfv2 +112 -105
  6. data/changelog.txt +7 -0
  7. data/gemspec +17 -0
  8. data/lib/ie/external_route.rb +9 -0
  9. data/lib/ie/id.rb +3 -4
  10. data/lib/ie/ie.rb +12 -0
  11. data/lib/ie/ls_age.rb +35 -5
  12. data/lib/ie/ls_type.rb +40 -37
  13. data/lib/ie/opaque_id.rb +46 -0
  14. data/lib/ie/opaque_type.rb +96 -0
  15. data/lib/ie/options.rb +5 -3
  16. data/lib/ie/router_link.rb +30 -7
  17. data/lib/ie/router_link_type.rb +116 -27
  18. data/lib/ie/sequence_number.rb +7 -3
  19. data/lib/infra/ospf_common.rb +1 -12
  20. data/lib/infra/ospf_io.rb +14 -8
  21. data/lib/infra/ospf_socket.rb +14 -14
  22. data/lib/infra/parse_options.rb +69 -25
  23. data/lib/ls_db/advertised_routers.rb +1 -1
  24. data/lib/ls_db/link_state_database.rb +74 -39
  25. data/lib/ls_db/link_state_database_build.rb +3 -3
  26. data/lib/ls_db/link_state_database_links.rb +7 -2
  27. data/lib/ls_db/lsdb_ios.rb +59 -0
  28. data/lib/lsa/external.rb +35 -2
  29. data/lib/lsa/lsa.rb +128 -35
  30. data/lib/lsa/lsa_factory.rb +20 -7
  31. data/lib/lsa/network.rb +44 -9
  32. data/lib/lsa/router.rb +14 -2
  33. data/lib/lsa/summary.rb +16 -3
  34. data/lib/lsa/tlv/color.rb +47 -0
  35. data/lib/lsa/tlv/link.rb +122 -0
  36. data/lib/lsa/tlv/link_id.rb +55 -0
  37. data/lib/lsa/tlv/link_type.rb +44 -0
  38. data/lib/lsa/tlv/local_interface.rb +56 -0
  39. data/lib/lsa/tlv/maximum_bandwidth.rb +55 -0
  40. data/lib/lsa/tlv/maximum_reservable_bandwidth.rb +52 -0
  41. data/lib/lsa/tlv/remote_interface.rb +58 -0
  42. data/lib/lsa/tlv/router_address.rb +57 -0
  43. data/lib/lsa/tlv/tlv.rb +32 -0
  44. data/lib/lsa/tlv/tlv_factory.rb +72 -0
  45. data/lib/lsa/tlv/traffic_engineering_metric.rb +52 -0
  46. data/lib/lsa/tlv/unreserved_bandwidth.rb +55 -0
  47. data/lib/lsa/traffic_engineering.rb +95 -0
  48. data/lib/neighbor/neighbor.rb +9 -9
  49. data/lib/packet/link_state_update.rb +16 -14
  50. data/lib/packet/ospf_packet.rb +13 -9
  51. data/test/unit/ie/au_type_test.rb +18 -0
  52. data/test/unit/ie/external_route_test.rb +51 -0
  53. data/test/unit/ie/id_test.rb +22 -0
  54. data/test/unit/ie/interface_mtu_test.rb +23 -0
  55. data/test/unit/ie/ls_age_test.rb +46 -0
  56. data/test/unit/ie/ls_type_test.rb +41 -0
  57. data/test/unit/ie/metric_test.rb +24 -0
  58. data/test/unit/ie/mt_metric_test.rb +27 -0
  59. data/test/unit/ie/opaque_id_test.rb +22 -0
  60. data/test/unit/ie/opaque_type_test.rb +22 -0
  61. data/test/unit/ie/options_test.rb +142 -0
  62. data/test/unit/ie/ospf_version_test.rb +0 -0
  63. data/test/unit/ie/packet_type_test.rb +33 -0
  64. data/test/unit/ie/router_link_factory_test.rb +26 -0
  65. data/test/unit/ie/router_link_test.rb +276 -0
  66. data/test/unit/ie/router_link_type_test.rb +24 -0
  67. data/test/unit/ie/sequence_number_test.rb +31 -0
  68. data/test/unit/ie/tos_metric_test.rb +27 -0
  69. data/test/unit/infra/ospf_common_test.rb +42 -0
  70. data/test/unit/infra/parse_options_test.rb +58 -0
  71. data/test/unit/infra/timer_test.rb +94 -0
  72. data/test/unit/ls_db/all +10 -0
  73. data/test/unit/ls_db/link_state_database_build_test.rb +140 -0
  74. data/test/unit/ls_db/link_state_database_links_tests.rb +74 -0
  75. data/test/unit/ls_db/link_state_database_test.rb +444 -0
  76. data/test/unit/ls_db/links_test.rb +49 -0
  77. data/test/unit/lsa/all +10 -0
  78. data/test/unit/lsa/external_test.rb +218 -0
  79. data/test/unit/lsa/lsa_factory_test.rb +314 -0
  80. data/test/unit/lsa/lsa_test.rb +191 -0
  81. data/test/unit/lsa/network_test.rb +107 -0
  82. data/test/unit/lsa/router_test.rb +614 -0
  83. data/test/unit/lsa/summary_test.rb +135 -0
  84. data/test/unit/lsa/tlv/color_test.rb +39 -0
  85. data/test/unit/lsa/tlv/link_id_test.rb +14 -0
  86. data/test/unit/lsa/tlv/link_test.rb +413 -0
  87. data/test/unit/lsa/tlv/link_type_test.rb +16 -0
  88. data/test/unit/lsa/tlv/local_interface_test.rb +15 -0
  89. data/test/unit/lsa/tlv/maximum_bandwidth_test.rb +14 -0
  90. data/test/unit/lsa/tlv/maximum_reservable_bandwidth_test.rb +13 -0
  91. data/test/unit/lsa/tlv/remote_interface_test.rb +14 -0
  92. data/test/unit/lsa/tlv/router_address_test.rb +16 -0
  93. data/test/unit/lsa/tlv/tlv_factory_test.rb +89 -0
  94. data/test/unit/lsa/tlv/traffic_engineering_metric_test.rb +15 -0
  95. data/test/unit/lsa/traffic_engineering_test.rb +65 -0
  96. data/test/unit/neighbor/neighbor_test.rb +82 -0
  97. data/test/unit/packet/all +10 -0
  98. data/test/unit/packet/database_description_test.rb +114 -0
  99. data/test/unit/packet/hello_test.rb +107 -0
  100. data/test/unit/packet/link_state_ack_test.rb +64 -0
  101. data/test/unit/packet/link_state_request_test.rb +168 -0
  102. data/test/unit/packet/link_state_update_test.rb +62 -0
  103. data/test/unit/packet/ospf_packet_test.rb +91 -0
  104. metadata +106 -51
  105. data/lib/infra/to_s.rb +0 -38
  106. data/lib/lsa/lsa_base.rb +0 -430
  107. data/lib/lsa/opaque.rb +0 -143
@@ -93,7 +93,7 @@ class Network < Lsa
93
93
 
94
94
  def initialize(arg={})
95
95
  @network_mask, @attached_routers = nil, []
96
- @ls_type = LsType.new(:network_lsa)
96
+ @ls_type = LsType.new(:network)
97
97
  super
98
98
  end
99
99
 
@@ -135,20 +135,55 @@ class Network < Lsa
135
135
  # NetworkMask: 255.255.255.0
136
136
  # AttachRouter: 192.168.1.200
137
137
  # AttachRouter: 193.0.0.0
138
- def to_s_default(*args)
138
+ # FIXME:
139
+ # when not verbose, only header is displayed and this is taken care of by parent method
140
+ def to_s_verbose(*args)
139
141
  super +
140
142
  ['', network_mask, *attached_routers].join("\n ")
141
143
  end
142
-
143
- # Network *192.168.1.200 192.168.1.200 0x80000001 98 0x22 0x2dc 32
144
- # mask 255.255.255.0
145
- # attached router 192.168.1.200
146
- # attached router 193.0.0.0
144
+ #
145
+ # R1#show ip ospf database network
147
146
  #
148
- def to_s_junos
149
- super
147
+ # OSPF Router with ID (1.1.1.1) (Process ID 1)
148
+ #
149
+ # Net Link States (Area 0)
150
+ #
151
+ # Routing Bit Set on this LSA
152
+ # LS age: 949
153
+ # Options: (No TOS-capability, DC)
154
+ # LS Type: Network Links
155
+ # Link State ID: 192.168.0.2 (address of Designated Router)
156
+ # Advertising Router: 2.2.2.2
157
+ # LS Seq Number: 8000000E
158
+ # Checksum: 0xF9B3
159
+ # Length: 32
160
+ # Network Mask: /24
161
+ # Attached Router: 2.2.2.2
162
+ # Attached Router: 1.1.1.1
163
+ #
164
+ # R1#
165
+ # def to_s_ios
166
+ # attrs = attached_routers.collect { |ar| " Attached Router #{ar.to_ip}"}
167
+ # s = []
168
+ # s << super
169
+ # s << "Network Mask: " + network_mask.to_s(false)
170
+ # s << attached_routers.collect { |ar| " Attached Router #{ar.to_ip}"}
171
+ # s.join("\n")
172
+ # end
173
+ def to_s_ios_verbose
174
+ attrs = attached_routers.collect { |ar| " Attached Router #{ar.to_ip}"}
175
+ s = []
176
+ s << super
177
+ s << "Network Mask: " + network_mask.to_s(false)
178
+ s << attached_routers.collect { |ar| " Attached Router #{ar.to_ip}"}
179
+ s.join("\n ")
150
180
  end
151
181
 
182
+ # FIXME: should be removed and parent take care of it.
183
+ # def to_s_junos
184
+ # super
185
+ # end
186
+
152
187
  def to_s_junos_verbose
153
188
  mask = "mask #{network_mask.to_ip}"
154
189
  attrs = attached_routers.collect { |ar| "attached router #{ar.to_ip}"}
@@ -205,7 +205,7 @@ module OSPFv2
205
205
  super
206
206
  @links=[]
207
207
  @nwveb ||=0
208
- @ls_type = LsType.new(:router_lsa)
208
+ @ls_type = LsType.new(:router)
209
209
 
210
210
  # arg.merge!({:ls_type => 1}) if arg.is_a?(Hash)
211
211
  [[:abr,1],[:asbr,2],[:vl,4],[:wild,8],[:nssa,16]].each { |x| def_bit(*x) } unless respond_to? :set_abr
@@ -242,7 +242,7 @@ module OSPFv2
242
242
  end
243
243
  end
244
244
 
245
- def to_s_default
245
+ def to_s_verbose
246
246
  super +
247
247
  ['', nwveb_to_s, *links.collect {|x| x.to_s }].join("\n ")
248
248
  end
@@ -251,6 +251,18 @@ module OSPFv2
251
251
  super
252
252
  end
253
253
 
254
+ def to_s_ios
255
+ super + links.size.to_s
256
+ end
257
+
258
+ def to_s_ios_verbose
259
+ s = []
260
+ s << super
261
+ s << "Number of Links: #{links.size.to_s}"
262
+ s << links.collect {|l| l.to_s_ios_verbose }.join
263
+ s.join("\n ")
264
+ end
265
+
254
266
  def to_s_junos_verbose
255
267
  link_hdr = " bits 0x#{nwveb.to_i}, link count #{links.size}"
256
268
  links_to_s = links.collect {|link| link.to_s_junos }
@@ -38,7 +38,7 @@ module OSPFv2
38
38
  attr_reader :metric, :netmask, :mt_metrics
39
39
 
40
40
  def initialize(type, arg={})
41
- @netmask=nil
41
+ @netmask=Netmask.new(0)
42
42
  @metric=nil
43
43
  @mt_metrics=[]
44
44
  @ls_type = LsType.new(type)
@@ -68,16 +68,29 @@ module OSPFv2
68
68
  super
69
69
  end
70
70
 
71
- def to_s_default(*args)
71
+ def to_s_verbose
72
72
  super +
73
73
  ['',netmask, metric, *mt_metrics].collect { |x| x.to_s }.join("\n ")
74
74
  end
75
75
 
76
+ def to_s_ios_verbose
77
+ s = []
78
+ s << super
79
+ s << "Network Mask: " + netmask.to_s(false)
80
+ s << " TOS 0 Metrics: #{metric.to_i}"
81
+ s << @mt_metrics.collect { |mt| "\n #{mt.to_s}" }.join unless @mt_metrics.empty?
82
+ s.join("\n ")
83
+ end
84
+
76
85
  def to_s_junos_verbose
77
86
  mask = "mask #{netmask.to_ip}"
78
87
  super +
79
88
  ['', mask, metric.to_s_junos, *mt_metrics.collect{|m| m.to_s_junos}].join("\n ")
89
+ rescue
90
+ p netmask
91
+ p self
80
92
  end
93
+
81
94
  def to_s_junos
82
95
  super
83
96
  end
@@ -117,7 +130,7 @@ module OSPFv2
117
130
  def initialize(arg={})
118
131
  case arg
119
132
  when Hash
120
- arg = fix_hash(arg).merge!({:ls_type => :summary_lsa,})
133
+ arg = fix_hash(arg).merge!({:ls_type => :summary,})
121
134
  end
122
135
  super 3, arg
123
136
  end
@@ -0,0 +1,47 @@
1
+ #--
2
+ # Copyright 2011 Jean-Michel Esnault.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #
6
+ #
7
+ # This file is part of OSPFv2.
8
+ #
9
+ #++
10
+
11
+ require_relative 'tlv'
12
+
13
+ module OSPFv2
14
+
15
+ class Color_Tlv
16
+ include SubTlv
17
+ include Common
18
+
19
+ attr_reader :tlv_type, :color
20
+
21
+ def initialize(arg={})
22
+ @tlv_type = 9
23
+ @color = 0
24
+
25
+ if arg.is_a?(Hash) then
26
+ set(arg.dup)
27
+ elsif arg.is_a?(String)
28
+ __parse(arg)
29
+ else
30
+ raise ArgumentError, "Invalid argument", caller
31
+ end
32
+ end
33
+
34
+ def encode
35
+ [@tlv_type, 4, @color].pack('nnN')
36
+ end
37
+
38
+ def __parse(s)
39
+ @tlv_type, _, @color = s.unpack('nnN')
40
+ end
41
+
42
+ def to_s
43
+ self.class.to_s + ": " + color.to_s
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,122 @@
1
+ #--
2
+ # Copyright 2011 Jean-Michel Esnault.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #
6
+ #
7
+ # This file is part of OSPFv2.
8
+ #
9
+ #++
10
+
11
+ require_relative 'tlv'
12
+
13
+ module OSPFv2
14
+
15
+ class Link_Tlv
16
+ include Tlv
17
+ include Tlv::Common
18
+ include Common
19
+
20
+ attr_reader :tlv_type, :_length, :tlvs
21
+
22
+ def initialize(arg={})
23
+ @tlv_type = 2
24
+ @tlvs = []
25
+ if arg.is_a?(Hash) then
26
+ if arg.has_key?(:tlvs)
27
+ @tlvs = arg[:tlvs].collect { |h| SubTlv.factory(h) }
28
+ end
29
+ elsif arg.is_a?(String)
30
+ __parse(arg)
31
+ else
32
+ raise ArgumentError, "Invalid argument", caller
33
+ end
34
+ end
35
+
36
+ def has?(klass=nil)
37
+ if klass.nil?
38
+ return tlvs.collect { |tlv| tlv.class }
39
+ else
40
+ return tlvs.find { |tlv| tlv.is_a?(klass) }.nil? ? false : true
41
+ end
42
+ end
43
+
44
+ def find(klass)
45
+ tlvs.find { |a| a.is_a?(klass) }
46
+ end
47
+
48
+ def __index(klass)
49
+ i=-1
50
+ tlvs.find { |a| i +=1 ; a.is_a?(klass) }
51
+ i
52
+ end
53
+ private :__index
54
+
55
+ def replace(*objs)
56
+ objs.each do |obj|
57
+ if has?(obj.class)
58
+ index = __index(obj.class)
59
+ tlvs[index]=obj
60
+ else
61
+ add(obj)
62
+ end
63
+ end
64
+ self
65
+ end
66
+
67
+ def remove(klass)
68
+ tlvs.delete_if { |a| a.is_a?(klass) }
69
+ end
70
+
71
+ def [](klass)
72
+ find(klass)
73
+ end
74
+
75
+ def add(obj)
76
+ if obj.is_a?(OSPFv2::SubTlv)
77
+ @tlvs << obj
78
+ else
79
+ raise
80
+ end
81
+ self
82
+ end
83
+
84
+ def <<(obj)
85
+ add(obj)
86
+ end
87
+
88
+ def encode
89
+ tlvs = encoded_tlvs
90
+ [@tlv_type, tlvs.size, tlvs].pack('nna*')
91
+ end
92
+
93
+ def __parse(s)
94
+ @tlv_type, @_length, tlvs = s.unpack('nna*')
95
+ while tlvs.size>0
96
+ _, len = tlvs.unpack('nn')
97
+ @tlvs << SubTlv.factory(tlvs.slice!(0,stlv_len(len)))
98
+ end
99
+ end
100
+
101
+ def encoded_tlvs
102
+ tlvs.collect { |tlv| tlv.encode }.join
103
+ end
104
+
105
+ def _length
106
+ encoded_tlvs.size
107
+ end
108
+
109
+ def to_s_ios
110
+ #TODO
111
+ tlvs.collect { |tlv| tlv.to_s }.join("\n ")
112
+ end
113
+
114
+ def to_s(args={})
115
+ ident = [' ']* (args[:ident] || 0)
116
+ "Link TLV (#{tlv_type}), length: #{encoded_tlvs.size}" +
117
+ ['',tlvs].flatten.collect { |tlv| tlv.to_s }.join("\n#{ident}")
118
+ end
119
+
120
+ end
121
+ end
122
+
@@ -0,0 +1,55 @@
1
+ #--
2
+ # Copyright 2011 Jean-Michel Esnault.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #
6
+ #
7
+ # This file is part of OSPFv2.
8
+ #
9
+ #++
10
+
11
+ require_relative 'tlv'
12
+
13
+ module OSPFv2
14
+
15
+ class LinkId_Tlv
16
+ include SubTlv
17
+ include Common
18
+
19
+ LinkId = Class.new(Id) unless const_defined?(:LinkId)
20
+ attr_reader :tlv_type, :link_id
21
+
22
+ attr_writer_delegate :link_id
23
+
24
+ def initialize(arg={})
25
+ @tlv_type = 2
26
+ @link_id = LinkId.new
27
+
28
+ if arg.is_a?(Hash) then
29
+ set(arg.dup)
30
+ elsif arg.is_a?(String)
31
+ __parse(arg)
32
+ else
33
+ raise ArgumentError, "Invalid argument", caller
34
+ end
35
+ end
36
+
37
+ def encode
38
+ [@tlv_type, 4, @link_id.encode].pack('nna*')
39
+ end
40
+
41
+ def __parse(s)
42
+ @tlv_type, _, link_id = s.unpack('nna*')
43
+ @link_id = LinkId.new_ntoh(link_id)
44
+ end
45
+
46
+ def to_s
47
+ "Link ID : " + link_id.to_ip
48
+ end
49
+
50
+ def to_s_junos_style(ident=0)
51
+ " "*ident + "RtrAddr (1), length #{@length}: #{router_id.to_ip}"
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,44 @@
1
+ #--
2
+ # Copyright 2011 Jean-Michel Esnault.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #
6
+ #
7
+ # This file is part of OSPFv2.
8
+ #
9
+ #++
10
+
11
+ require_relative 'tlv'
12
+
13
+ module OSPFv2
14
+ class LinkType_Tlv
15
+ @link_type = { 1=> :p2p, 2=> :multiaccess }
16
+ class << self
17
+ def type_to_s(arg)
18
+ "#{@link_type[arg]}"
19
+ end
20
+ end
21
+ include SubTlv
22
+ include Common
23
+ attr_reader :tlv_type, :link_type
24
+ def initialize(arg={})
25
+ @tlv_type, @link_type = 1,1
26
+ if arg.is_a?(Hash) then
27
+ set(arg.dup)
28
+ elsif arg.is_a?(String)
29
+ __parse(arg)
30
+ else
31
+ raise ArgumentError, "Invalid argument", caller
32
+ end
33
+ end
34
+ def encode
35
+ [@tlv_type, 1, @link_type,0,0,0].pack('nnCC3')
36
+ end
37
+ def __parse(s)
38
+ @tlv_type, _, @link_type= s.unpack('nnC')
39
+ end
40
+ def to_s
41
+ "Link Type : #{LinkType_Tlv.type_to_s(link_type)}"
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,56 @@
1
+ #--
2
+ # Copyright 2011 Jean-Michel Esnault.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #
6
+ #
7
+ # This file is part of OSPFv2.
8
+ #
9
+ #++
10
+
11
+ require_relative 'tlv'
12
+
13
+ module OSPFv2
14
+
15
+ class LocalInterfaceIpAddress_Tlv
16
+ include SubTlv
17
+ include Common
18
+
19
+ IpAddress = Class.new(Id) unless const_defined?(:IpAddress)
20
+ attr_reader :tlv_type, :ip_address
21
+
22
+ attr_writer_delegate :ip_address
23
+
24
+ def initialize(arg={})
25
+ @tlv_type = 3
26
+ @ip_address = IpAddress.new
27
+
28
+ if arg.is_a?(Hash) then
29
+ set(arg.dup)
30
+ elsif arg.is_a?(String)
31
+ __parse(arg)
32
+ else
33
+ raise ArgumentError, "Invalid argument", caller
34
+ end
35
+ end
36
+
37
+ def encode
38
+ [@tlv_type, 4, @ip_address.encode].pack('nna*')
39
+ end
40
+
41
+ def __parse(s)
42
+ @tlv_type, _, ip_address = s.unpack('nna*')
43
+ @ip_address = IpAddress.new_ntoh(ip_address)
44
+ end
45
+
46
+
47
+ def to_s
48
+ "Interface Address : #{ip_address.to_ip}"
49
+ end
50
+
51
+ def to_s_junos_style(ident=0)
52
+ " "*ident + "RtrAddr (1), length #{@length}: #{router_id.to_ip}"
53
+ end
54
+
55
+ end
56
+ end