bgp4r 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. data/README.rdoc +1 -10
  2. data/bgp/io.rb +4 -2
  3. data/bgp/messages/capability.rb +176 -0
  4. data/bgp/messages/keepalive.rb +30 -0
  5. data/bgp/messages/markers.rb +10 -0
  6. data/bgp/messages/message.rb +85 -0
  7. data/bgp/messages/messages.rb +17 -0
  8. data/bgp/messages/notification.rb +116 -0
  9. data/bgp/messages/open.rb +117 -0
  10. data/bgp/messages/route_refresh.rb +181 -0
  11. data/bgp/messages/update.rb +148 -0
  12. data/bgp/neighbor.rb +20 -11
  13. data/bgp/nlris/inet.rb +18 -0
  14. data/bgp/{label.rb → nlris/label.rb} +1 -1
  15. data/bgp/nlris/labeled.rb +39 -0
  16. data/bgp/nlris/nlri.rb +154 -0
  17. data/bgp/{attributes.rb → nlris/nlris.rb} +11 -13
  18. data/bgp/nlris/prefix.rb +33 -0
  19. data/bgp/{rd.rb → nlris/rd.rb} +1 -1
  20. data/bgp/nlris/vpn.rb +68 -0
  21. data/bgp/optional_parameters/as4.rb +59 -0
  22. data/bgp/optional_parameters/capabilities.rb +13 -0
  23. data/bgp/optional_parameters/capability.rb +145 -0
  24. data/bgp/optional_parameters/dynamic.rb +37 -0
  25. data/bgp/optional_parameters/graceful_restart.rb +116 -0
  26. data/bgp/optional_parameters/mbgp.rb +97 -0
  27. data/bgp/optional_parameters/optional_parameter.rb +76 -0
  28. data/bgp/optional_parameters/orf.rb +90 -0
  29. data/bgp/optional_parameters/route_refresh.rb +36 -0
  30. data/bgp/{prefix_orf.rb → orfs/prefix_orf.rb} +4 -10
  31. data/bgp/{aggregator.rb → path_attributes/aggregator.rb} +2 -2
  32. data/bgp/{as_path.rb → path_attributes/as_path.rb} +2 -2
  33. data/bgp/{atomic_aggregate.rb → path_attributes/atomic_aggregate.rb} +2 -2
  34. data/bgp/{attribute.rb → path_attributes/attribute.rb} +2 -2
  35. data/bgp/path_attributes/attributes.rb +21 -0
  36. data/bgp/{cluster_list.rb → path_attributes/cluster_list.rb} +2 -2
  37. data/bgp/{communities.rb → path_attributes/communities.rb} +2 -2
  38. data/bgp/{extended_communities.rb → path_attributes/extended_communities.rb} +3 -3
  39. data/bgp/{extended_community.rb → path_attributes/extended_community.rb} +1 -1
  40. data/bgp/{local_pref.rb → path_attributes/local_pref.rb} +2 -2
  41. data/bgp/{mp_reach.rb → path_attributes/mp_reach.rb} +3 -69
  42. data/bgp/path_attributes/mp_unreach.rb +97 -0
  43. data/bgp/{multi_exit_disc.rb → path_attributes/multi_exit_disc.rb} +2 -2
  44. data/bgp/{next_hop.rb → path_attributes/next_hop.rb} +2 -2
  45. data/bgp/{origin.rb → path_attributes/origin.rb} +2 -2
  46. data/bgp/{originator_id.rb → path_attributes/originator_id.rb} +2 -2
  47. data/bgp/{path_attribute.rb → path_attributes/path_attribute.rb} +6 -7
  48. data/bgp4r.gemspec +127 -67
  49. data/bgp4r.rb +5 -25
  50. data/examples/routegen +1 -1
  51. data/examples/routegen.yml +21 -5
  52. data/examples/simple.rb +4 -4
  53. data/examples/unit-testing/malformed_update.rb +1 -1
  54. data/examples/unit-testing/unknown_transitive_attr.rb +18 -10
  55. data/test/messages/capability_test.rb +113 -0
  56. data/test/messages/keepalive_test.rb +34 -0
  57. data/test/messages/markers_test.rb +33 -0
  58. data/test/messages/message_test.rb +43 -0
  59. data/test/messages/notification_test.rb +49 -0
  60. data/test/messages/open_test.rb +98 -0
  61. data/test/messages/route_refresh_test.rb +77 -0
  62. data/test/messages/update_test.rb +133 -0
  63. data/test/neighbor_test.rb +8 -9
  64. data/test/nlris/inet_test.rb +43 -0
  65. data/test/{label_test.rb → nlris/labeled_test.rb} +1 -1
  66. data/test/{nlri_test.rb → nlris/nlri_test.rb} +5 -1
  67. data/test/{rd_test.rb → nlris/rd_test.rb} +1 -2
  68. data/test/optional_parameters/as4_test.rb +34 -0
  69. data/test/optional_parameters/capability_test.rb +69 -0
  70. data/test/optional_parameters/dynamic_test.rb +34 -0
  71. data/test/optional_parameters/graceful_restart_test.rb +23 -0
  72. data/test/optional_parameters/mbgp_test.rb +35 -0
  73. data/test/optional_parameters/optional_parameter_test.rb +51 -0
  74. data/test/optional_parameters/orf_test.rb +42 -0
  75. data/test/optional_parameters/route_refresh_test.rb +32 -0
  76. data/test/{prefix_orf_test.rb → orfs/prefix_orf_test.rb} +2 -1
  77. data/test/{aggregator_test.rb → path_attributes/aggregator_test.rb} +1 -1
  78. data/test/{as_path_test.rb → path_attributes/as_path_test.rb} +1 -1
  79. data/test/{atomic_aggregate_test.rb → path_attributes/atomic_aggregate_test.rb} +1 -1
  80. data/test/{attribute_test.rb → path_attributes/attribute_test.rb} +2 -2
  81. data/test/{cluster_list_test.rb → path_attributes/cluster_list_test.rb} +1 -1
  82. data/test/{communities_test.rb → path_attributes/communities_test.rb} +1 -1
  83. data/test/{extended_communities_test.rb → path_attributes/extended_communities_test.rb} +1 -1
  84. data/test/{extended_community_test.rb → path_attributes/extended_community_test.rb} +1 -1
  85. data/test/{local_pref_test.rb → path_attributes/local_pref_test.rb} +1 -1
  86. data/test/{mp_reach_test.rb → path_attributes/mp_reach_test.rb} +1 -37
  87. data/test/path_attributes/mp_unreach_test.rb +67 -0
  88. data/test/{multi_exit_disc_test.rb → path_attributes/multi_exit_disc_test.rb} +1 -1
  89. data/test/{next_hop_test.rb → path_attributes/next_hop_test.rb} +1 -1
  90. data/test/{origin_test.rb → path_attributes/origin_test.rb} +2 -1
  91. data/test/{originator_id_test.rb → path_attributes/originator_id_test.rb} +1 -1
  92. data/test/{path_attribute_test.rb → path_attributes/path_attribute_test.rb} +2 -2
  93. metadata +122 -67
  94. data/bgp/message.rb +0 -921
  95. data/bgp/nlri.rb +0 -303
  96. data/bgp/version.rb +0 -3
  97. data/examples/unit-testing/keepalive_set_to_zeo.rb +0 -64
  98. data/test/message_test.rb +0 -347
  99. /data/bgp/{orf.rb → orfs/orf.rb} +0 -0
data/bgp/nlris/vpn.rb ADDED
@@ -0,0 +1,68 @@
1
+
2
+ module BGP
3
+ class Vpn
4
+ attr_reader :prefix, :rd
5
+ def initialize(*args)
6
+ if args.size>0 and args[0].is_a?(String) and args[0].is_packed?
7
+ parse(*args)
8
+ else
9
+ prefix, *rd = args
10
+ self.prefix=(prefix)
11
+ self.rd=rd
12
+ end
13
+ end
14
+ def prefix=(arg)
15
+ if arg.is_a?(Prefix)
16
+ @prefix=arg
17
+ else
18
+ @prefix=Prefix.new(arg)
19
+ end
20
+ end
21
+ def rd=(args)
22
+ args.flatten!
23
+ if args.empty?
24
+ @rd=Rd.new
25
+ elsif args.size==1 and args[0].is_a?(BGP::Rd)
26
+ @rd=args[0]
27
+ else
28
+ @rd=Rd.new(*args)
29
+ end
30
+ end
31
+ # len_included arg is used by labeled encode()
32
+ def encode_next_hop
33
+ Rd.new.encode + @prefix.encode(false)
34
+ end
35
+ def encode(len_included=true)
36
+ if len_included
37
+ [bit_length, @rd.encode, @prefix.encode(false)].pack('Ca*a*')
38
+ else
39
+ @rd.encode + @prefix.encode(false)
40
+ end
41
+ end
42
+ def bit_length
43
+ @rd.bit_length + @prefix.mlen
44
+ end
45
+ def ipv4?
46
+ @prefix.ipv4?
47
+ end
48
+ def afi
49
+ @prefix.afi
50
+ end
51
+ def ipv6?
52
+ @prefix.ipv6?
53
+ end
54
+ def parse(s, afi=1)
55
+ nbits = s.slice!(0,1).unpack('C')[0]
56
+ rd,vpn = s.slice!(0,(7+nbits)/8).unpack("a8a*")
57
+ @rd = Rd.new(rd.is_packed)
58
+ @prefix= Prefix.new([nbits-64,vpn].pack('Ca*'), afi)
59
+ end
60
+ def nexthop
61
+ @prefix.nexthop
62
+ end
63
+ def to_s
64
+ #Label Stack=5806 (bottom) RD=3215:317720610, IPv4=10.45.142.64/32
65
+ "#{@rd.to_s(false)}, #{@prefix.ipv4? ? 'IPv4' : 'IPv6'}=#{@prefix.to_s}"
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,59 @@
1
+ #--
2
+ # Copyright 2008, 2009 Jean-Michel Esnault.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #
6
+ #
7
+ # This file is part of BGP4R.
8
+ #
9
+ # BGP4R 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
+ # BGP4R 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 BGP4R. If not, see <http://www.gnu.org/licenses/>.
21
+ #++
22
+
23
+ require 'bgp/optional_parameters/capability'
24
+
25
+ module BGP
26
+ module OPT_PARM
27
+ module CAP
28
+
29
+ class As4 < OPT_PARM::Capability
30
+ def initialize(s)
31
+ if s.is_a?(String) and s.is_packed?
32
+ parse(s)
33
+ else
34
+ super(OPT_PARM::CAP_AS4)
35
+ @as=s
36
+ end
37
+ end
38
+
39
+ def encode()
40
+ super([@as].pack('N'))
41
+ end
42
+
43
+ def parse(s)
44
+ @as = super(s).unpack('N')[0]
45
+ end
46
+
47
+ def to_s
48
+ super + "\n Capability(#{CAP_AS4}): 4-octet AS number: " + @as.to_s
49
+ end
50
+
51
+ def to_hash
52
+ super({:as => @as})
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ load "../../test/optional_parameters/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
@@ -0,0 +1,13 @@
1
+ require 'bgp/optional_parameters/capability'
2
+
3
+ %w{ mbgp orf route_refresh as4 graceful_restart dynamic }.each do |c|
4
+ BGP::OPT_PARM::CAP.autoload "#{c}".capitalize.to_sym,"bgp/optional_parameters/#{c}"
5
+ end
6
+
7
+ module BGP::OPT_PARM
8
+ module DYN_CAP
9
+ BGP::OPT_PARM::CAP.constants.each do |kl|
10
+ const_set(kl, Class.new(::BGP::OPT_PARM::CAP.const_get(kl)))
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,145 @@
1
+ #--
2
+ # Copyright 2008, 2009 Jean-Michel Esnault.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #
6
+ #
7
+ # This file is part of BGP4R.
8
+ #
9
+ # BGP4R 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
+ # BGP4R 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 BGP4R. If not, see <http://www.gnu.org/licenses/>.
21
+ #++
22
+
23
+
24
+ require 'bgp/optional_parameters/optional_parameter'
25
+
26
+ module BGP::OPT_PARM
27
+
28
+ class Capability < Optional_parameter
29
+ include BGP
30
+
31
+ unless const_defined? :Unknown
32
+ Unknown = Class.new(self) do
33
+ def initialize(s)
34
+ if s.is_a?(String) and s.is_packed?
35
+ parse(s)
36
+ else
37
+ raise ArgumentError
38
+ end
39
+ end
40
+ def encode
41
+ super @value
42
+ end
43
+ def parse(s)
44
+ @value = super(s)
45
+ end
46
+ end
47
+ end
48
+
49
+ include BGP::OPT_PARM
50
+ def initialize(code)
51
+ super(OPT_PARM::CAPABILITY)
52
+ @code=code
53
+ end
54
+ def encode(value='')
55
+ if self.class.to_s =~ /BGP::OPT_PARM::DYN_CAP/
56
+ [@code,value.size, value].pack("Cna*")
57
+ else
58
+ super([@code,value.size, value].pack("CCa*"))
59
+ end
60
+ end
61
+
62
+ def parse(_s)
63
+ s = _s
64
+ if self.class.to_s =~ /BGP::OPT_PARM::DYN_CAP/
65
+ @code, len = _s.slice!(0,3).unpack('Cn')
66
+ else
67
+ s = super(_s)
68
+ @code, len = s.slice!(0,2).unpack('CC')
69
+ end
70
+ s.slice!(0,len).is_packed
71
+ end
72
+ def to_s
73
+ "Option Capabilities Advertisement (#{@parm_type}): [#{to_shex}]"
74
+ end
75
+ def to_hash(h={})
76
+ if h.empty?
77
+ {:code=> @code}
78
+ else
79
+ {:code=> @code, :capability=> h}
80
+ end
81
+ end
82
+
83
+ def method_missing()
84
+ if name == :to_s_brief
85
+ "#{self.class.to_s.split('::').last}"
86
+ else
87
+ super
88
+ end
89
+ end
90
+
91
+ end
92
+ end
93
+
94
+ module BGP
95
+ module OPT_PARM
96
+ module CAP
97
+ end
98
+ end
99
+ end
100
+
101
+ # require 'bgp4r'
102
+
103
+ module BGP::OPT_PARM
104
+ def Capability.factory(s)
105
+ code = s.slice(2,1).unpack('C')[0]
106
+ case code
107
+ when CAP_AS4
108
+ CAP::As4.new(s)
109
+ when CAP_MBGP
110
+ CAP::Mbgp.new(s)
111
+ when CAP_ROUTE_REFRESH, CAP_ROUTE_REFRESH_CISCO
112
+ CAP::Route_refresh.new(code)
113
+ when CAP_ORF,CAP_ORF_CISCO
114
+ CAP::Orf.new(s)
115
+ when CAP_GR
116
+ CAP::Graceful_restart.new(s)
117
+ when CAP_DYNAMIC
118
+ CAP::Dynamic.new(s)
119
+ else
120
+ Capability::Unknown.new(s)
121
+ end
122
+ end
123
+ end
124
+
125
+ module BGP::OPT_PARM
126
+ def Capability.dynamic_factory(s)
127
+ code = s.slice(0,1).unpack('C')[0]
128
+ case code
129
+ when CAP_AS4
130
+ DYN_CAP::As4.new(s)
131
+ when CAP_MBGP
132
+ DYN_CAP::Mbgp.new(s)
133
+ when CAP_ROUTE_REFRESH, CAP_ROUTE_REFRESH_CISCO
134
+ DYN_CAP::Route_refresh.new(code)
135
+ when CAP_ORF,CAP_ORF_CISCO
136
+ DYN_CAP::Orf.new(s)
137
+ when CAP_GR
138
+ DYN_CAP::Graceful_restart.new(s)
139
+ else
140
+ Capability::Unknown.new(s)
141
+ end
142
+ end
143
+ end
144
+
145
+ load "../../test/optional_parameters/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
@@ -0,0 +1,37 @@
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 BGP4R.
8
+ #
9
+ # BGP4R 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
+ # BGP4R 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 BGP4R. If not, see <http://www.gnu.org/licenses/>.
21
+ #++
22
+
23
+ require 'bgp/optional_parameters/capability'
24
+
25
+ module BGP::OPT_PARM::CAP
26
+
27
+ class Dynamic < BGP::OPT_PARM::Capability
28
+ def initialize(code=BGP::OPT_PARM::CAP_DYNAMIC)
29
+ super(code)
30
+ end
31
+ def to_s
32
+ super + "\n Dynamic Capability #{@code}, length: 2"
33
+ end
34
+ end
35
+ end
36
+
37
+ load "../../test/optional_parameters/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
@@ -0,0 +1,116 @@
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 BGP4R.
8
+ #
9
+ # BGP4R 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
+ # BGP4R 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 BGP4R. If not, see <http://www.gnu.org/licenses/>.
21
+ #++
22
+
23
+ require 'bgp/optional_parameters/capability'
24
+
25
+ module BGP::OPT_PARM::CAP
26
+
27
+ class Graceful_restart < BGP::OPT_PARM::Capability
28
+
29
+ def initialize(*args)
30
+ if args.size>1
31
+ @restart_state, @restart_time = args
32
+ @address_families = []
33
+ super(OPT_PARM::CAP_GR)
34
+ else
35
+ parse(*args)
36
+ end
37
+ end
38
+
39
+ def add(afi,safi,flags)
40
+ @address_families << [_afi(afi), _safi(safi), flags]
41
+ end
42
+
43
+ def parse(s)
44
+ @address_families = []
45
+ o1, families = super(s).unpack('na*')
46
+ @restart_state = o1 >> 12
47
+ @restart_time = o1 & 0xfff
48
+ while families.size>0
49
+ @address_families << families.slice!(0,4).unpack('nCC')
50
+ end
51
+ end
52
+
53
+
54
+ def encode
55
+ s = []
56
+ s << [(@restart_state << 12) + @restart_time].pack('n')
57
+ s << @address_families.collect { |af| af.pack('nCC') }
58
+ super s.join
59
+ end
60
+ def to_s
61
+ s = []
62
+ s << "\n Graceful Restart Extension (#{CAP_GR}), length: 4"
63
+ s << " Restart Flags: #{restart_flag}, Restart Time #{@restart_time}s"
64
+ s = s.join("\n ")
65
+ super + (s + (['']+@address_families.collect { |af| address_family(*af)}).join("\n "))
66
+ end
67
+
68
+ private
69
+
70
+ def address_family(afi, safi, flags)
71
+ "AFI #{IANA.afi(afi)} (#{afi}), SAFI #{IANA.safi(safi)} (#{safi}), #{address_family_flags(flags)}"
72
+ end
73
+
74
+ def restart_flag
75
+ if @restart_state == 0
76
+ '[none]'
77
+ else
78
+ "0x#{@restart_state}"
79
+ end
80
+ end
81
+
82
+ def address_family_flags(flags)
83
+ if flags & 1 == 0
84
+ "Forwarding state not preserved (0x#{flags.to_s(16)})"
85
+ elsif flags & 1 == 1
86
+ "Forwarding state preserved (0x#{flags.to_s(16)})"
87
+ end
88
+ end
89
+
90
+ def _afi(val)
91
+ if val.is_a?(Fixnum)
92
+ val
93
+ elsif val == :ipv4
94
+ 1
95
+ elsif val == :ipv6
96
+ 2
97
+ end
98
+ end
99
+
100
+ def _safi(val)
101
+ if val.is_a?(Fixnum)
102
+ val
103
+ elsif val == :unicast
104
+ 1
105
+ elsif val == :multicast
106
+ 2
107
+ end
108
+ end
109
+
110
+
111
+ end
112
+ end
113
+
114
+ load "../../test/optional_parameters/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
115
+
116
+
@@ -0,0 +1,97 @@
1
+ #--
2
+ # Copyright 2008, 2009 Jean-Michel Esnault.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #
6
+ #
7
+ # This file is part of BGP4R.
8
+ #
9
+ # BGP4R 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
+ # BGP4R 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 BGP4R. If not, see <http://www.gnu.org/licenses/>.
21
+ #++
22
+
23
+ require 'bgp/optional_parameters/capability'
24
+
25
+ module BGP::OPT_PARM::CAP
26
+
27
+ class Mbgp < BGP::OPT_PARM::Capability
28
+
29
+ def self.ipv4_unicast
30
+ Mbgp.new(1,1)
31
+ end
32
+
33
+ def self.ipv4_multicast
34
+ Mbgp.new(1,2)
35
+ end
36
+
37
+ def self.ipv6_unicast
38
+ Mbgp.new(2,2)
39
+ end
40
+
41
+ def self.ipv6_multicast
42
+ Mbgp.new(2,2)
43
+ end
44
+
45
+ def initialize(afi,safi=nil)
46
+ if safi.nil? and afi.is_a?(String) and afi.is_packed?
47
+ parse(afi)
48
+ else
49
+ super(OPT_PARM::CAP_MBGP)
50
+ self.safi, self.afi = safi, afi
51
+ end
52
+ end
53
+
54
+ def afi=(val)
55
+ @afi = if val.is_a?(Fixnum)
56
+ val
57
+ elsif val == :ipv4
58
+ 1
59
+ elsif val == :ipv6
60
+ 2
61
+ end
62
+ end
63
+
64
+ def safi=(val)
65
+ @safi = if val.is_a?(Fixnum)
66
+ val
67
+ elsif val == :unicast
68
+ 1
69
+ elsif val == :multicast
70
+ 2
71
+ end
72
+ end
73
+
74
+ def encode
75
+ super([@afi,0,@safi].pack('nCC'))
76
+ end
77
+
78
+ def parse(s)
79
+ @afi, ignore, @safi = super(s).unpack('nCC')
80
+ end
81
+
82
+ def to_s
83
+ super + "\n Multiprotocol Extensions (#{CAP_MBGP}), length: 4" +
84
+ "\n AFI #{IANA.afi(@afi)} (#{@afi}), SAFI #{IANA.safi(@safi)} (#{@safi})"
85
+ end
86
+
87
+ def to_s_brief
88
+ "MBGP #{IANA.afi(@afi)}, #{IANA.safi(@safi)}"
89
+ end
90
+
91
+ def to_hash
92
+ super({:afi => @afi, :safi => @safi, })
93
+ end
94
+ end
95
+ end
96
+
97
+ load "../../test/optional_parameters/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
@@ -0,0 +1,76 @@
1
+ #--
2
+ # Copyright 2008, 2009 Jean-Michel Esnault.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #
6
+ #
7
+ # This file is part of BGP4R.
8
+ #
9
+ # BGP4R 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
+ # BGP4R 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 BGP4R. If not, see <http://www.gnu.org/licenses/>.
21
+ #++
22
+
23
+ module BGP
24
+
25
+ class UnknownBgpCapability < RuntimeError
26
+ end
27
+
28
+ module OPT_PARM
29
+
30
+ unless const_defined? :CAPABILITY
31
+ CAPABILITY = 2
32
+
33
+ CAP_MBGP = 1
34
+ CAP_ROUTE_REFRESH = 2
35
+ CAP_ORF = 3
36
+ CAP_GR = 64
37
+ CAP_AS4 = 65
38
+ CAP_DYNAMIC = 67
39
+ CAP_ROUTE_REFRESH_CISCO = 128
40
+ CAP_ORF_CISCO = 130
41
+
42
+ ORF_NLRI = 1
43
+ ORF_COMMUNITIES = 2
44
+ ORF_EXTENDED_COMMUNITIES = 3
45
+ ORF_PREFIX_LIST = 129
46
+ end
47
+
48
+ class Optional_parameter
49
+
50
+ def initialize(parm_type)
51
+ @parm_type=parm_type
52
+ end
53
+
54
+ def encode(value)
55
+ [@parm_type, value.size, value].pack('CCa*')
56
+ end
57
+
58
+ def parse(s)
59
+ @parm_type, len = s.slice!(0,2).unpack('CC')
60
+ s.slice!(0,len).is_packed
61
+ end
62
+
63
+ def self.factory(s)
64
+ parm_type, len = s.unpack('CC')
65
+ opt_parm = s.slice!(0,len+2).is_packed
66
+ case parm_type
67
+ when CAPABILITY
68
+ Capability.factory(opt_parm)
69
+ else
70
+ raise RuntimeError, "Optional parameter type '#{parm_type}' not implemented"
71
+ end
72
+ end
73
+
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,90 @@
1
+ #--
2
+ # Copyright 2008, 2009 Jean-Michel Esnault.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #
6
+ #
7
+ # This file is part of BGP4R.
8
+ #
9
+ # BGP4R 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
+ # BGP4R 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 BGP4R. If not, see <http://www.gnu.org/licenses/>.
21
+ #++
22
+
23
+ require 'bgp/optional_parameters/capability'
24
+
25
+ module BGP::OPT_PARM::CAP
26
+
27
+ class Orf < BGP::OPT_PARM::Capability
28
+
29
+ class Entry
30
+
31
+ def initialize(*args)
32
+ if args.size==1 and args[0].is_a?(String) and args[0].is_packed?
33
+ parse(args[0])
34
+ elsif args[0].is_a?(Hash)
35
+ else
36
+ @afi, @safi, *@types = *args
37
+ end
38
+ end
39
+
40
+ def encode
41
+ [@afi, 0, @safi, @types.size,@types.collect { |e| e.pack('CC')}.join].pack('nCCCa*')
42
+ end
43
+
44
+ def parse(s)
45
+ @afi, __, @safi, n = s.slice!(0,5).unpack('nCCC')
46
+ @types=[]
47
+ types = s.slice!(0, 2*n)
48
+ while types.size>0
49
+ @types<< types. slice!(0,2).unpack('CC')
50
+ end
51
+ end
52
+
53
+ def to_s
54
+ "AFI #{IANA.afi(@afi)} (#{@afi}), SAFI #{IANA.safi(@safi)} (#{@safi}): #{@types.inspect}"
55
+ end
56
+ end
57
+
58
+ def initialize(*args)
59
+ @entries=[]
60
+ if args.size==1 and args[0].is_a?(String) and args[0].is_packed?
61
+ parse(args[0])
62
+ else
63
+ super(OPT_PARM::CAP_ORF)
64
+ end
65
+ end
66
+
67
+ def add(entry)
68
+ @entries << entry
69
+ end
70
+
71
+ def encode
72
+ super(@entries.collect { |e| e.encode }.join)
73
+ end
74
+
75
+ def parse(s)
76
+ entries = super(s)
77
+ while entries.size>0
78
+ @entries << Entry.new(entries)
79
+ end
80
+ end
81
+
82
+ def to_s
83
+ super + "\n Outbound Route Filtering (#{@code}), length: #{encode.size}" +
84
+ (['']+@entries.collect { |e| e.to_s }).join("\n ")
85
+ end
86
+
87
+ end
88
+ end
89
+
90
+ load "../../test/optional_parameters/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0